[sfcgal] 01/04: Imported Upstream version 1.1.0
Sven Geggus
giggls-guest at moszumanska.debian.org
Fri Jun 12 09:14:10 UTC 2015
This is an automated email from the git hooks/post-receive script.
giggls-guest pushed a commit to branch master
in repository sfcgal.
commit bca7157ff364a9bec262702739c85b5c90fc3835
Author: Sven Geggus <sven-deb at geggus.net>
Date: Wed Jun 10 10:52:10 2015 +0200
Imported Upstream version 1.1.0
---
.gitignore | 24 +
AUTHORS | 3 +
CMakeLists.txt | 246 +
LICENSE | 481 +
NEWS | 14 +
README.md | 6 +
cmake/Modules/FindCGAL.cmake | 92 +
cmake/Modules/FindGMP.cmake | 48 +
cmake/Modules/FindMPFR.cmake | 37 +
cmake/Modules/FindPostgreSQL.cmake | 57 +
cmake/Modules/FindSFCGAL.cmake | 77 +
cmake/Modules/Libtoolize.cmake | 49 +
cmake/Modules/PrecompiledHeader.cmake | 125 +
doc/CMakeLists.txt | 9 +
doc/Doxyfile.in | 1814 +
doc/images/Grid-PixelIsArea.svg | 484 +
doc/images/Grid-PixelIsPoint.svg | 583 +
doc/images/triangulatePolygon.svg | 279 +
doc/mainpage.h | 99 +
doc/sfcgal_viewer_demo.avi | Bin 0 -> 1963846 bytes
example/CGAL-basic_manip/CMakeLists.txt | 13 +
example/CGAL-basic_manip/main.cpp | 291 +
example/CGAL-cartesian_kernel/CMakeLists.txt | 13 +
example/CGAL-cartesian_kernel/main.cpp | 37 +
example/CGAL-point_generator/CMakeLists.txt | 13 +
example/CGAL-point_generator/main.cpp | 61 +
example/CGAL-polygon_triangulation2/CMakeLists.txt | 13 +
example/CGAL-polygon_triangulation2/main.cpp | 200 +
example/CGAL-triangulation2/CMakeLists.txt | 13 +
example/CGAL-triangulation2/main.cpp | 116 +
example/CMakeLists.txt | 14 +
example/SFCGAL-asc2osg/CMakeLists.txt | 14 +
example/SFCGAL-asc2osg/main.cpp | 85 +
example/SFCGAL-building/CMakeLists.txt | 18 +
example/SFCGAL-building/data-sample.wkt | 3 +
example/SFCGAL-building/main.cpp | 123 +
example/SFCGAL-export-osg/CMakeLists.txt | 14 +
example/SFCGAL-export-osg/main.cpp | 76 +
example/SFCGAL-offset/CMakeLists.txt | 13 +
example/SFCGAL-offset/main.cpp | 36 +
.../Triangle_2_Triangle_2_intersection_impl.h | 354 +
patches/CGAL-4.2/CGAL/Point_inside_polyhedron_3.h | 191 +
.../CGAL-4.2/CGAL/Triangle_3_Ray_3_do_intersect.h | 401 +
.../AABB_triangle_accessor_3_primitive.h | 52 +
.../Ray_3_Triangle_3_traversal_traits.h | 217 +
...ntersection_of_Polyhedra_3_refinement_visitor.h | 2193 ++
patches/CGAL-4.2/CGAL/use.h | 39 +
.../CGAL/Triangle_3_Triangle_3_intersection.h | 237 +
patches/README | 27 +
script/test-style-SFCGAL.sh | 54 +
sfcgal-config.in | 52 +
src/CMakeLists.txt | 78 +
src/Coordinate.cpp | 405 +
src/Coordinate.h | 235 +
src/Envelope.cpp | 352 +
src/Envelope.h | 227 +
src/Exception.cpp | 73 +
src/Exception.h | 117 +
src/Geometry.cpp | 204 +
src/Geometry.h | 286 +
src/GeometryCollection.cpp | 221 +
src/GeometryCollection.h | 146 +
src/GeometryVisitor.cpp | 203 +
src/GeometryVisitor.h | 85 +
src/Grid.cpp | 138 +
src/Grid.h | 239 +
src/Kernel.h | 41 +
src/LineString.cpp | 256 +
src/LineString.h | 319 +
src/MultiLineString.cpp | 110 +
src/MultiLineString.h | 101 +
src/MultiPoint.cpp | 113 +
src/MultiPoint.h | 105 +
src/MultiPolygon.cpp | 110 +
src/MultiPolygon.h | 103 +
src/MultiSolid.cpp | 110 +
src/MultiSolid.h | 102 +
src/Point.cpp | 287 +
src/Point.h | 231 +
src/Polygon.cpp | 281 +
src/Polygon.h | 283 +
src/PolyhedralSurface.cpp | 260 +
src/PolyhedralSurface.h | 192 +
src/PreparedGeometry.cpp | 102 +
src/PreparedGeometry.h | 145 +
src/Solid.cpp | 179 +
src/Solid.h | 207 +
src/Surface.cpp | 79 +
src/Surface.h | 69 +
src/Transform.cpp | 174 +
src/Transform.h | 59 +
src/Triangle.cpp | 214 +
src/Triangle.h | 164 +
src/TriangulatedSurface.cpp | 309 +
src/TriangulatedSurface.h | 193 +
src/Validity.h | 63 +
src/algorithm/BoundaryVisitor.cpp | 321 +
src/algorithm/BoundaryVisitor.h | 101 +
src/algorithm/ConsistentOrientationBuilder.cpp | 232 +
src/algorithm/ConsistentOrientationBuilder.h | 114 +
src/algorithm/Intersection2D.cpp | 164 +
src/algorithm/Intersection3D.cpp | 350 +
src/algorithm/area.cpp | 359 +
src/algorithm/area.h | 142 +
src/algorithm/collect.cpp | 67 +
src/algorithm/collect.h | 57 +
src/algorithm/collectionExtract.cpp | 91 +
src/algorithm/collectionExtract.h | 42 +
src/algorithm/collectionHomogenize.cpp | 95 +
src/algorithm/collectionHomogenize.h | 45 +
src/algorithm/collectionToMulti.cpp | 123 +
src/algorithm/collectionToMulti.h | 42 +
src/algorithm/connection.cpp | 164 +
src/algorithm/connection.h | 104 +
src/algorithm/convexHull.cpp | 184 +
src/algorithm/convexHull.h | 49 +
src/algorithm/covers.cpp | 265 +
src/algorithm/covers.h | 63 +
src/algorithm/difference.cpp | 431 +
src/algorithm/difference.h | 77 +
src/algorithm/differencePrimitives.cpp | 32 +
src/algorithm/differencePrimitives.h | 809 +
src/algorithm/distance.cpp | 612 +
src/algorithm/distance.h | 142 +
src/algorithm/distance3d.cpp | 877 +
src/algorithm/distance3d.h | 178 +
src/algorithm/extrude.cpp | 380 +
src/algorithm/extrude.h | 68 +
src/algorithm/force2D.cpp | 38 +
src/algorithm/force2D.h | 44 +
src/algorithm/force3D.cpp | 38 +
src/algorithm/force3D.h | 44 +
src/algorithm/intersection.cpp | 190 +
src/algorithm/intersection.h | 83 +
src/algorithm/intersects.cpp | 610 +
src/algorithm/intersects.h | 123 +
src/algorithm/isValid.cpp | 488 +
src/algorithm/isValid.h | 109 +
src/algorithm/length.cpp | 175 +
src/algorithm/length.h | 67 +
src/algorithm/minkowskiSum.cpp | 282 +
src/algorithm/minkowskiSum.h | 59 +
src/algorithm/normal.h | 89 +
src/algorithm/offset.cpp | 361 +
src/algorithm/offset.h | 59 +
src/algorithm/orientation.cpp | 169 +
src/algorithm/orientation.h | 83 +
src/algorithm/plane.h | 234 +
src/algorithm/straightSkeleton.cpp | 172 +
src/algorithm/straightSkeleton.h | 75 +
src/algorithm/tesselate.cpp | 95 +
src/algorithm/tesselate.h | 53 +
src/algorithm/translate.cpp | 64 +
src/algorithm/translate.h | 52 +
src/algorithm/union.cpp | 997 +
src/algorithm/union.h | 83 +
src/algorithm/volume.cpp | 97 +
src/algorithm/volume.h | 50 +
src/capi/sfcgal_c.cpp | 985 +
src/capi/sfcgal_c.h | 845 +
src/config.h.cmake | 41 +
src/detail/ComplexComparator.h | 46 +
src/detail/EnvelopeVisitor.cpp | 172 +
src/detail/EnvelopeVisitor.h | 63 +
src/detail/GeometrySet.cpp | 1070 +
src/detail/GeometrySet.h | 376 +
src/detail/GetPointsVisitor.cpp | 160 +
src/detail/GetPointsVisitor.h | 59 +
src/detail/Interval.cpp | 192 +
src/detail/Interval.h | 129 +
src/detail/TestGeometry.h | 250 +
src/detail/TypeForDimension.h | 169 +
src/detail/algorithm/coversPoints.cpp | 70 +
src/detail/algorithm/coversPoints.h | 49 +
src/detail/generator/building.cpp | 200 +
src/detail/generator/building.h | 54 +
src/detail/generator/disc.cpp | 64 +
src/detail/generator/disc.h | 49 +
src/detail/generator/hoch.cpp | 82 +
src/detail/generator/hoch.h | 44 +
src/detail/generator/sierpinski.cpp | 80 +
src/detail/generator/sierpinski.h | 44 +
src/detail/graph/Edge.cpp | 38 +
src/detail/graph/Edge.h | 42 +
src/detail/graph/GeometryGraph.h | 444 +
src/detail/graph/GeometryGraphBuilder.h | 230 +
src/detail/graph/Vertex.cpp | 38 +
src/detail/graph/Vertex.h | 47 +
src/detail/graph/algorithm/isHalfEdge.h | 77 +
src/detail/graph/algorithm/orientation.h | 108 +
src/detail/io/OsgFactory.cpp | 241 +
src/detail/io/OsgFactory.h | 114 +
src/detail/io/Serialization.cpp | 173 +
src/detail/io/Serialization.h | 165 +
src/detail/io/WktReader.cpp | 690 +
src/detail/io/WktReader.h | 168 +
src/detail/io/WktWriter.cpp | 525 +
src/detail/io/WktWriter.h | 94 +
src/detail/polygonSetToMultiPolygon.cpp | 50 +
src/detail/polygonSetToMultiPolygon.h | 42 +
src/detail/tools/CharArrayBuffer.cpp | 104 +
src/detail/tools/CharArrayBuffer.h | 60 +
src/detail/tools/InputStreamReader.h | 241 +
src/detail/tools/Log.cpp | 150 +
src/detail/tools/Log.h | 187 +
src/detail/tools/Registry.cpp | 160 +
src/detail/tools/Registry.h | 93 +
src/detail/transform/AffineTransform2.cpp | 50 +
src/detail/transform/AffineTransform2.h | 62 +
src/detail/transform/AffineTransform3.cpp | 135 +
src/detail/transform/AffineTransform3.h | 71 +
src/detail/transform/Force2D.cpp | 43 +
src/detail/transform/Force2D.h | 50 +
src/detail/transform/ForceOrderPoints.cpp | 112 +
src/detail/transform/ForceOrderPoints.h | 65 +
src/detail/transform/ForceZ.cpp | 52 +
src/detail/transform/ForceZ.h | 58 +
src/detail/transform/ForceZOrderPoints.cpp | 94 +
src/detail/transform/ForceZOrderPoints.h | 66 +
src/detail/transform/RoundTransform.cpp | 49 +
src/detail/transform/RoundTransform.h | 59 +
.../ConstraintDelaunayTriangulation.cpp | 172 +
.../triangulate/ConstraintDelaunayTriangulation.h | 209 +
src/detail/triangulate/markDomains.h | 112 +
.../triangulate/triangulateInGeometrySet.cpp | 134 +
src/detail/triangulate/triangulateInGeometrySet.h | 44 +
src/detail/ublas.h | 33 +
src/export.h | 57 +
src/io/GeometryStreams.cpp | 44 +
src/io/GeometryStreams.h | 44 +
src/io/asc.cpp | 125 +
src/io/asc.h | 43 +
src/io/ewkt.cpp | 71 +
src/io/ewkt.h | 52 +
src/io/osg.cpp | 64 +
src/io/osg.h | 63 +
src/io/vtk.h | 205 +
src/io/wkt.cpp | 65 +
src/io/wkt.h | 51 +
src/numeric.cpp | 63 +
src/numeric.h | 76 +
src/triangulate/triangulate2DZ.cpp | 169 +
src/triangulate/triangulate2DZ.h | 44 +
src/triangulate/triangulatePolygon.cpp | 230 +
src/triangulate/triangulatePolygon.h | 106 +
src/version.cpp | 33 +
src/version.h.cmake | 37 +
test/CMakeLists.txt | 28 +
test/bench/Bench.cpp | 89 +
test/bench/Bench.h | 97 +
test/bench/BenchArea.cpp | 82 +
test/bench/BenchContainer.cpp | 179 +
test/bench/BenchMinkowski.cpp | 76 +
test/bench/BenchTriangulation.cpp | 192 +
test/bench/BenchWKT.cpp | 130 +
test/bench/CMakeLists.txt | 13 +
test/bench/IntersectionPerfTest.cpp | 89 +
test/bench/KernelPerfTest.cpp | 85 +
test/bench/TestModule.cpp | 29 +
test/data/AreaTest.txt | 1001 +
test/data/CoversTest.txt | 168 +
test/data/DistanceTest.txt | 44 +
test/data/IntersectionTest.txt | 688 +
test/data/IntersectsTest.txt | 493 +
test/data/StraightSkeletonTest.txt | 3 +
test/data/TriangulatePolygonTest.txt | 46 +
test/data/WktTest.txt | 29 +
test/data/countries.wkt | 2 +
test/data/cow-nonormals.obj | 10388 ++++++
test/data/example.asc | 13 +
test/data/out.teapot.obj | 9964 +++++
test/data/rgc-france-ign.xyz | 36568 +++++++++++++++++++
test/data/rgc-france-ign.xyz.README | 7 +
test/data/teapot.obj | 9965 +++++
test/data/teddy.obj | 4790 +++
test/garden/CMakeLists.txt | 25 +
test/garden/main.cpp | 624 +
test/implementation_matrix.ods | Bin 0 -> 17008 bytes
test/regress/CMakeLists.txt | 11 +
test/regress/convex_hull/CMakeLists.txt | 20 +
test/regress/convex_hull/main.cpp | 220 +
test/regress/polygon_triangulator/CMakeLists.txt | 20 +
test/regress/polygon_triangulator/main.cpp | 268 +
test/regress/standalone/CMakeLists.txt | 23 +
test/regress/standalone/SFCGAL/ASCTest.cpp | 102 +
test/regress/standalone/SFCGAL/AreaTest.cpp | 115 +
.../SFCGAL/ConstraintDelaunayTriangulationTest.cpp | 86 +
test/regress/standalone/SFCGAL/DistanceTest.cpp | 137 +
test/regress/standalone/SFCGAL/IntersectsTest.cpp | 113 +
.../standalone/SFCGAL/StraightSkeletonTest.cpp | 79 +
.../standalone/SFCGAL/TriangulatePolygonTest.cpp | 127 +
.../regress/standalone/SFCGAL/WaveFrontObjTest.cpp | 71 +
test/regress/standalone/SFCGAL/WktTest.cpp | 74 +
test/regress/standalone/TestModule.cpp | 29 +
test/test_config.h.cmake | 6 +
test/unit/CGAL/AffineTransform3Test.cpp | 87 +
test/unit/CGAL/GmpqTest.cpp | 94 +
test/unit/CGAL/KernelTest.cpp | 67 +
test/unit/CGAL/Plane3Test.cpp | 52 +
test/unit/CGAL/WorkWithPoint3AsPoint2.cpp | 105 +
test/unit/CMakeLists.txt | 30 +
test/unit/SFCGAL/CoordinateTest.cpp | 191 +
test/unit/SFCGAL/EnvelopeTest.cpp | 133 +
test/unit/SFCGAL/GeometryCollectionTest.cpp | 163 +
test/unit/SFCGAL/GeometryTest.cpp | 87 +
test/unit/SFCGAL/GeometryVisitorTest.cpp | 167 +
test/unit/SFCGAL/GridTest.cpp | 180 +
test/unit/SFCGAL/KernelTest.cpp | 108 +
test/unit/SFCGAL/LineStringTest.cpp | 404 +
test/unit/SFCGAL/MultiLineStringTest.cpp | 89 +
test/unit/SFCGAL/MultiPointTest.cpp | 94 +
test/unit/SFCGAL/MultiPolygonTest.cpp | 95 +
test/unit/SFCGAL/MultiSolidTest.cpp | 95 +
test/unit/SFCGAL/NumericTest.cpp | 70 +
test/unit/SFCGAL/PointTest.cpp | 279 +
test/unit/SFCGAL/PolygonTest.cpp | 256 +
test/unit/SFCGAL/SolidTest.cpp | 114 +
test/unit/SFCGAL/TriangleTest.cpp | 247 +
test/unit/SFCGAL/TriangulatedSurfaceTest.cpp | 221 +
test/unit/SFCGAL/algorithm/AreaTest.cpp | 197 +
test/unit/SFCGAL/algorithm/BoundaryTest.cpp | 173 +
test/unit/SFCGAL/algorithm/ConnectedTest.cpp | 88 +
.../algorithm/ConsistentOrientationBuilderTest.cpp | 105 +
test/unit/SFCGAL/algorithm/ConvexHullTest.cpp | 177 +
test/unit/SFCGAL/algorithm/CoversPointsTest.cpp | 99 +
test/unit/SFCGAL/algorithm/CoversTest.cpp | 129 +
test/unit/SFCGAL/algorithm/DifferenceTest.cpp | 368 +
test/unit/SFCGAL/algorithm/DistanceTest.cpp | 247 +
test/unit/SFCGAL/algorithm/ExtrudeTest.cpp | 174 +
test/unit/SFCGAL/algorithm/Force3DTest.cpp | 91 +
test/unit/SFCGAL/algorithm/IntersectionTest.cpp | 243 +
test/unit/SFCGAL/algorithm/IntersectsTest.cpp | 115 +
test/unit/SFCGAL/algorithm/IsValidTest.cpp | 84 +
test/unit/SFCGAL/algorithm/LengthTest.cpp | 103 +
test/unit/SFCGAL/algorithm/MinkowskiSumTest.cpp | 137 +
test/unit/SFCGAL/algorithm/NormalTest.cpp | 117 +
test/unit/SFCGAL/algorithm/OffsetTest.cpp | 140 +
test/unit/SFCGAL/algorithm/OrientationTest.cpp | 187 +
test/unit/SFCGAL/algorithm/PlaneTest.cpp | 84 +
.../unit/SFCGAL/algorithm/StraightSkeletonTest.cpp | 123 +
test/unit/SFCGAL/algorithm/TesselateTest.cpp | 113 +
test/unit/SFCGAL/algorithm/TranslateTest.cpp | 65 +
test/unit/SFCGAL/algorithm/UnionTest.cpp | 401 +
test/unit/SFCGAL/algorithm/VolumeTest.cpp | 79 +
test/unit/SFCGAL/capi/sfcgal_cTest.cpp | 81 +
test/unit/SFCGAL/detail/ComplexComparatorTest.cpp | 45 +
test/unit/SFCGAL/detail/IntervalTest.cpp | 160 +
.../unit/SFCGAL/graph/GeometryGraphBuilderTest.cpp | 90 +
test/unit/SFCGAL/graph/GeometryGraphTest.cpp | 117 +
.../unit/SFCGAL/graph/algorithm/IsHalfEdgeTest.cpp | 80 +
test/unit/SFCGAL/io/SerializationTest.cpp | 157 +
test/unit/SFCGAL/io/WktReaderTest.cpp | 268 +
.../unit/SFCGAL/transform/AffineTransform2Test.cpp | 53 +
.../SFCGAL/transform/ForceZOrderPointsTest.cpp | 53 +
test/unit/SFCGAL/transform/RoundTest.cpp | 59 +
.../ConstraintDelaunayTriangulationTest.cpp | 114 +
.../unit/SFCGAL/triangulate/Triangulate2DZTest.cpp | 104 +
test/unit/TestModule.cpp | 41 +
viewer/CMakeLists.txt | 40 +
viewer/cmake/Modules/FindosgQt.cmake | 50 +
viewer/include/SFCGAL/viewer/GISManipulator.h | 44 +
viewer/include/SFCGAL/viewer/ViewerPlugin.h | 74 +
viewer/include/SFCGAL/viewer/ViewerWidget.h | 102 +
viewer/include/SFCGAL/viewer/ViewerWindow.h | 112 +
viewer/include/SFCGAL/viewer/plugins/DataPlugin.h | 70 +
viewer/include/SFCGAL/viewer/plugins/DemoPlugin.h | 76 +
viewer/include/SFCGAL/viewer/plugins/GridPlugin.h | 67 +
viewer/include/SFCGAL/viewer/plugins/PSQLPlugin.h | 160 +
viewer/include/db.h | 274 +
viewer/main.cpp | 105 +
viewer/src/SFCGAL/viewer/GISManipulator.cpp | 82 +
viewer/src/SFCGAL/viewer/ViewerPlugin.cpp | 67 +
viewer/src/SFCGAL/viewer/ViewerWidget.cpp | 353 +
viewer/src/SFCGAL/viewer/ViewerWindow.cpp | 259 +
viewer/src/SFCGAL/viewer/plugins/DataPlugin.cpp | 103 +
viewer/src/SFCGAL/viewer/plugins/DemoPlugin.cpp | 231 +
viewer/src/SFCGAL/viewer/plugins/GridPlugin.cpp | 122 +
viewer/src/SFCGAL/viewer/plugins/PSQLPlugin.cpp | 553 +
viewer/src/db.cpp | 66 +
379 files changed, 131336 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..88fe904
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,24 @@
+.settings
+.cproject
+.project
+bin
+lib
+Debug
+Release
+triangulation2.obj
+polygon_triangulation2.obj
+
+/test/test_config.h
+/doc/html
+/doc/latex
+/doc/Doxyfile
+
+/triangulation3d_in_plane.obj
+
+*.3ds
+
+gmon.out
+
+include/SFCGAL/version.h
+include/SFCGAL/config.h
+
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..96dc91f
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,3 @@
+Mickael Borne <mickael.borne at ign.fr>
+Hugo Mercier <hugo.mercier at oslandia.com>
+Vincent Mora <vincent.mora at oslandia.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..4089385
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,246 @@
+cmake_minimum_required( VERSION 2.8 )
+project( SFCGAL )
+
+set( CMAKE_DEBUG_POSTFIX "d" )
+
+#----------------------------------------------------------------------------
+# build options
+#----------------------------------------------------------------------------
+# Set a default build type if none was specified
+if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
+ message(STATUS "Setting build type to 'Release' as none was specified.")
+ set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
+ # Set the possible values of build type for cmake-gui
+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "RelWithDebInfo")
+endif()
+
+option( SFCGAL_BUILD_EXAMPLES "build examples" OFF )
+option( SFCGAL_BUILD_TESTS "build unit, garden and regress tests" OFF )
+option( SFCGAL_BUILD_BENCH "Build benchmarks" OFF )
+option( SFCGAL_BUILD_VIEWER "build viewer and OpenSceneGraph support (outputs in 3D formats)" OFF )
+
+#-- include finders and co
+set( CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules;${CMAKE_MODULE_PATH}" )
+
+set( SFCGAL_VERSION_MAJOR 1 )
+set( SFCGAL_VERSION_MINOR 1 )
+set( SFCGAL_VERSION_PATCH 0 )
+
+set( SFCGAL_VERSION "${SFCGAL_VERSION_MAJOR}.${SFCGAL_VERSION_MINOR}.${SFCGAL_VERSION_PATCH}" )
+
+# disabled for 1.0
+#include( PrecompiledHeader )
+#option( Use_precompiled_headers "Use precompiled headers" OFF )
+
+include( Libtoolize )
+
+#-----------------------------------------------------------
+# dependencies
+#-----------------------------------------------------------
+
+#-- BOOST --------------------------------------------------
+option( Boost_USE_AUTO_LINK "boost use autolink" OFF )
+if( NOT ${Boost_USE_AUTO_LINK} )
+ add_definitions( "-DBOOST_ALL_NO_LIB" )
+endif()
+
+option( Boost_USE_STATIC_LIBS "boost use dynamic libraries" OFF )
+if( Boost_USE_STATIC_LIBS )
+ message( STATUS "Boost_USE_STATIC_LIBS=ON" )
+ add_definitions( "-DBOOST_THREAD_USE_LIB" )
+else()
+ message( STATUS "Boost_USE_STATIC_LIBS=OFF" )
+# add_definitions( "-DBOOST_TEST_DYN_LINK" )
+ add_definitions( "-DBOOST_ALL_DYN_LINK" )
+endif()
+
+option( Boost_USE_MULTITHREAD "boost use multithread libraries" ON )
+if( ${Boost_USE_MULTITHREAD} )
+ message( STATUS "Boost_USE_MULTITHREAD=ON" )
+else()
+ message( STATUS "Boost_USE_MULTITHREAD=OFF" )
+endif()
+
+#-- minimalist build allowed with boost version older than 1.48
+set( SFCGAL_Boost_COMPONENTS date_time thread system serialization )
+#-- unit test
+if ( SFCGAL_BUILD_TESTS )
+ set( SFCGAL_Boost_COMPONENTS unit_test_framework program_options ${SFCGAL_Boost_COMPONENTS} )
+endif()
+#-- program_options
+if ( SFCGAL_BUILD_TESTS OR SFCGAL_BUILD_EXAMPLES OR SFCGAL_BUILD_OSG OR SFCGAL_BUILD_VIEWER )
+ set( SFCGAL_Boost_COMPONENTS program_options chrono filesystem timer ${SFCGAL_Boost_COMPONENTS} )
+endif()
+find_package( Boost COMPONENTS ${SFCGAL_Boost_COMPONENTS} REQUIRED )
+
+
+#-- GMP (facultative) -------------------------------------
+find_package( GMP )
+if( ${GMP_FOUND} )
+ message( STATUS "GMP_INCLUDE_DIRS = ${GMP_INCLUDE_DIRS}" )
+ message( STATUS "GMP_LIBRARIES = ${GMP_LIBRARIES}" )
+ set( SFCGAL_WITH_GMP ON )
+endif()
+
+
+
+#-- MPFR (needs GMP) --------------------------------------
+if( ${GMP_FOUND} )
+ find_package( MPFR )
+ if( ${MPFR_FOUND} )
+ message( STATUS "MPFR_INCLUDE_DIRS = ${MPFR_INCLUDE_DIRS}" )
+ message( STATUS "MPFR_LIBRARIES = ${MPFR_LIBRARIES}" )
+ set( SFCGAL_WITH_MPFR ON )
+ endif()
+endif()
+
+if( NOT ${GMP_FOUND} OR NOT ${MPFR_FOUND} )
+ message( WARNING "can't find GMP and MPFR, using default kernel" )
+ set( EPLU_USE_CARTESIAN_KERNEL ON )
+endif()
+
+
+#-- find CGAL ---------------------------------------------
+option( CGAL_USE_AUTOLINK "disable CGAL autolink" OFF )
+if( ${CGAL_USE_AUTOLINK} )
+ add_definitions( "-DCGAL_NO_AUTOLINK" )
+endif()
+
+find_package( CGAL 4.1 COMPONENTS Core REQUIRED )
+message( STATUS "CGAL ${CGAL_VERSION} found" )
+
+include_directories( ${CMAKE_BINARY_DIR}/include )
+
+# For CGAL versions < 4.3, we add a local directory that contains some tweaked include files from unreleased versions
+# They will overwrite files from the CGAL installation
+if( "${CGAL_VERSION}" VERSION_LESS "4.3" )
+ include_directories( patches/CGAL-4.2 )
+else()
+ include_directories( patches/CGAL-4.3 )
+ add_definitions( "-DCGAL_INTERSECTION_VERSION=1" )
+endif()
+
+#-- note that SYSTEM turns -I/path to -isystem and avoid warnings in CGAL and Boost
+include_directories( SYSTEM
+ ${CGAL_INCLUDE_DIRS}
+ ${Boost_INCLUDE_DIRS}
+ ${MPFR_INCLUDE_DIRS}
+ ${GMP_INCLUDE_DIRS}
+)
+link_directories(
+ ${CGAL_LIBRARY_DIRS}
+ ${Boost_LIBRARY_DIRS}
+ ${MPFR_LIBRARY_DIRS}
+ ${GMP_LIBRARY_DIRS}
+)
+
+#-- optional OpenSceneGraph support
+if ( SFCGAL_BUILD_VIEWER )
+ find_package( OpenSceneGraph COMPONENTS osgDB osgUtil REQUIRED )
+ include_directories( SYSTEM ${OPENSCENEGRAPH_INCLUDE_DIRS} )
+
+ # config.h generation
+ set( SFCGAL_WITH_OSG "ON" )
+ add_subdirectory( viewer )
+endif()
+
+
+
+#-- Warnings, frounding-math and gprof ------------------------------------------
+option( SFCGAL_WARNING_AS_ERROR "fail the build on warnings" OFF )
+option( SFCGAL_BUILD_WITH_GPROF "build with gprof" OFF )
+if(MSVC)
+ # Force to always compile with W4
+ if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
+ string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+ else()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
+ endif()
+elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
+ # Update if necessary
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-long-long -pedantic -Wpointer-arith -Wcast-align -Wcast-qual -Wno-overloaded-virtual -Wformat=2 -Winit-self -Wmissing-include-dirs -Wwrite-strings -Wno-error=undef")#-Wfloat-equal -Wconversion -Wshadow
+ if( SFCGAL_WARNING_AS_ERROR )
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wno-error=format")
+ endif()
+
+ # Allows profiling with gprof
+ if(SFCGAL_BUILD_WITH_GPROF)
+ set(CMAKE_EXE_LINKER_FLAGS_DEBUG "-pg")
+ endif()
+endif()
+
+
+if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
+ set(_LIBDIR_DEFAULT "lib")
+ # Override this default 'lib' with 'lib64' iff:
+ # - we are on Linux system but NOT cross-compiling
+ # - we are NOT on debian
+ # - we are on a 64 bits system
+ # reason is: amd64 ABI: http://www.x86-64.org/documentation/abi.pdf
+ # Note that the future of multi-arch handling may be even
+ # more complicated than that: http://wiki.debian.org/Multiarch
+ if(CMAKE_SYSTEM_NAME MATCHES "Linux"
+ AND NOT CMAKE_CROSSCOMPILING
+ AND NOT EXISTS "/etc/debian_version")
+ if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
+ message(AUTHOR_WARNING
+ "Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. "
+ "Please enable at least one language before including GNUInstallDirs.")
+ else()
+ if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
+ set(_LIBDIR_DEFAULT "lib64")
+ endif()
+ endif()
+ endif()
+ set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})")
+endif()
+
+SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
+SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+#SET(CMAKE_MACOSX_RPATH ON)
+
+#-- generate library headers
+configure_file( ${CMAKE_SOURCE_DIR}/src/config.h.cmake include/SFCGAL/config.h )
+configure_file( ${CMAKE_SOURCE_DIR}/src/version.h.cmake include/SFCGAL/version.h )
+
+enable_testing()
+
+#note : not available on windows without export/import
+OPTION( SFCGAL_USE_STATIC_LIBS "define if SFCGAL is build as a static library" OFF )
+
+# option : do we check geometry validity before each processing ?
+option( SFCGAL_CHECK_VALIDITY "Always checks geometry validity" ON )
+if ( NOT SFCGAL_CHECK_VALIDITY )
+ add_definitions( "-DSFCGAL_NEVER_CHECK_VALIDITY" )
+endif()
+
+#-- build the library
+add_subdirectory( src )
+
+#-- build test (todo only if boost use dyn link)
+add_subdirectory( test )
+
+#-- build examples
+if( SFCGAL_BUILD_EXAMPLES )
+ add_subdirectory( example )
+endif()
+
+#-- doxygen documentation (allows make doc when doxygen is found)
+add_subdirectory( doc )
+
+#-- install directories
+install(DIRECTORY ${CMAKE_BINARY_DIR}/include DESTINATION .)
+
+
+#-- create a libtool file for SFCGAL (needed by PostGIS)
+create_libtool_file( SFCGAL /lib )
+
+#-- sfcgal-config
+if ( "${CMAKE_BUILD_TYPE}" STREQUAL "Debug" )
+ set( SFCGAL_LIB_NAME "SFCGAL${CMAKE_DEBUG_POSTFIX}" )
+else()
+ set( SFCGAL_LIB_NAME "SFCGAL" )
+endif()
+#set( SFCGAL_LIB_NAME ${${CMAKE_BUILD_TYPE}
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/sfcgal-config.in ${CMAKE_CURRENT_BINARY_DIR}/sfcgal-config @ONLY)
+install( PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/sfcgal-config DESTINATION bin )
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..306fb50
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,481 @@
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..72d5f17
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,14 @@
+1.0.5:
+ * Fix validity check message when converting to 2D
+ * Fix a polygon orientation test (postgis bug #2818)
+ * Fix a bug in plane3D
+ * Add better handling of EMPTY in collections
+ * Compilation issues:
+ * Fix a cmake issue (FindOsgQT)
+ * Fix compilation issue with gcc < 4.5
+ * Avoid osg dependency when viewer is not built
+ * Fix postgresql include directory
+ * Add detection of lib64 directories
+1.0.4:
+ Fix compilation with CGAL 4.3
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..f42041c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,6 @@
+SFCGAL
+======
+
+SFCGAL is a C++ wrapper library around [CGAL](http://www.cgal.org) with the aim of supporting ISO 191007:2013 and OGC Simple Features for 3D operations.
+
+Please refer to the <a href="http://oslandia.github.io/SFCGAL">project page</a> for an updated installation procedure.
diff --git a/cmake/Modules/FindCGAL.cmake b/cmake/Modules/FindCGAL.cmake
new file mode 100644
index 0000000..17876b5
--- /dev/null
+++ b/cmake/Modules/FindCGAL.cmake
@@ -0,0 +1,92 @@
+find_path(CGAL_INCLUDE_DIRS CGAL/gmp.h
+ HINTS $ENV{CGAL_DIR}/include ${CGAL_DIR}/include ${CGAL_INCLUDE_DIRS}
+ PATH_SUFFIXES CGAL
+)
+
+if( MSVC10)
+ set( CGAL_LIBRARY_POSTFIX "-vc100-mt-${CGAL_VERSION}" )
+ set( CGAL_LIBRARY_POSTFIX_DEBUG "-vc100-mt-gd-${CGAL_VERSION}" )
+else()
+ set( CGAL_LIBRARY_POSTFIX "")
+ set( CGAL_LIBRARY_POSTFIX_DEBUG "d")
+endif()
+
+#-- incidates if debug version are found
+set( CGAL_DEBUG_FOUND ON )
+
+
+#-- find CGAL library
+find_library( CGAL_LIBRARY "CGAL${CGAL_LIBRARY_POSTFIX}" ${CGAL_LIBRARY}
+ HINTS ${CGAL_LIBRARY_DIRS} $ENV{CGAL_DIR}/lib
+)
+if( CGAL_LIBRARY )
+ get_filename_component(CGAL_LIBRARY_DIRS ${CGAL_LIBRARY} PATH)
+endif()
+
+if(CGAL_FIND_VERSION)
+ find_file(version_file CGAL/version.h HINTS $ENV{CGAL_DIR}/include ${CGAL_DIR}/include ${CGAL_INCLUDE_DIRS} PATH_SUFFIXES CGAL)
+ file(STRINGS ${version_file} version_str REGEX "# *define +CGAL_VERSION +")
+ string( REGEX REPLACE "# *define +CGAL_VERSION +" "" CGAL_VERSION ${version_str})
+ if("${CGAL_VERSION}" VERSION_LESS "${CGAL_FIND_VERSION}")
+ message(FATAL_ERROR "CGAL " ${CGAL_FIND_VERSION} " is required (found " ${CGAL_VERSION} " in ${version_file})" )
+ endif()
+
+endif()
+
+find_library( CGAL_LIBRARY_DEBUG "CGAL${CGAL_LIBRARY_POSTFIX_DEBUG}" ${CGAL_LIBRARY_DEBUG}
+ HINTS ${CGAL_LIBRARY_DIRS}
+)
+if( NOT CGAL_LIBRARY_DEBUG )
+ set( CGAL_DEBUG_FOUND OFF )
+endif()
+
+#-- CGAL components (Core, ImageIO)
+foreach( CGAL_COMPONENT ${CGAL_FIND_COMPONENTS} )
+ #-- find release
+ find_library( CGAL_${CGAL_COMPONENT}_LIBRARY "CGAL_${CGAL_COMPONENT}${CGAL_LIBRARY_POSTFIX}" "${CGAL_${CGAL_COMPONENT}_LIBRARY}"
+ HINTS ${CGAL_LIBRARY_DIRS} $ENV{CGAL_DIR}/lib
+ )
+ #-- find debug
+ find_library( CGAL_${CGAL_COMPONENT}_LIBRARY_DEBUG "CGAL_${CGAL_COMPONENT}${CGAL_LIBRARY_POSTFIX_DEBUG}" "${CGAL_${CGAL_COMPONENT}_LIBRARY_DEBUG}"
+ HINTS ${CGAL_LIBRARY_DIRS} $ENV{CGAL_DIR}/lib
+ )
+
+ if( NOT CGAL_${CGAL_COMPONENT}_LIBRARY_DEBUG )
+ set( CGAL_DEBUG_FOUND OFF )
+ endif()
+endforeach()
+
+
+#-- build variable CGAL_LIBRARIES
+
+set( CGAL_LIBRARIES "" )
+if( ${CGAL_DEBUG_FOUND} )
+ list( APPEND CGAL_LIBRARIES optimized ${CGAL_LIBRARY} debug ${CGAL_LIBRARY_DEBUG} )
+ foreach( CGAL_COMPONENT ${CGAL_FIND_COMPONENTS} )
+ list( APPEND CGAL_LIBRARIES optimized "${CGAL_${CGAL_COMPONENT}_LIBRARY}" debug "${CGAL_${CGAL_COMPONENT}_LIBRARY_DEBUG}" )
+ endforeach()
+else()
+ list( APPEND CGAL_LIBRARIES ${CGAL_LIBRARY} )
+ foreach( CGAL_COMPONENT ${CGAL_FIND_COMPONENTS} )
+ list( APPEND CGAL_LIBRARIES ${CGAL_${CGAL_COMPONENT}_LIBRARY} )
+ endforeach()
+endif()
+
+#-- report/validate
+set( CGAL_COMPONENT_LIBRARIES "" )
+set( CGAL_COMPONENT_LIBRARIES_DEBUG "" )
+foreach( CGAL_COMPONENT ${CGAL_FIND_COMPONENTS} )
+ list( APPEND CGAL_COMPONENT_LIBRARIES CGAL_${CGAL_COMPONENT}_LIBRARY )
+ list( APPEND CGAL_COMPONENT_LIBRARIES_DEBUG CGAL_${CGAL_COMPONENT}_LIBRARY_DEBUG )
+endforeach()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+ CGAL DEFAULT_MSG
+ CGAL_INCLUDE_DIRS CGAL_LIBRARIES ${CGAL_COMPONENT_LIBRARIES}
+)
+
+mark_as_advanced( CGAL_LIBRARY_DIRS CGAL_LIBRARY_DEBUG ${CGAL_COMPONENT_LIBRARIES_DEBUG} )
+
+
+
diff --git a/cmake/Modules/FindGMP.cmake b/cmake/Modules/FindGMP.cmake
new file mode 100644
index 0000000..1257da8
--- /dev/null
+++ b/cmake/Modules/FindGMP.cmake
@@ -0,0 +1,48 @@
+#-- GMP finder
+#
+# search variables :
+# GMP_DIR(cmake/environment) : gmp install directory
+# GMP_INCLUDE_DIR(cmake) : directory containing gmp.h
+# GMP_LIBRARY_DIR(cmake) : directory containing gmp libraries
+#
+# find options :
+# GMP_ENABLE_CXX : search for gmpxx library?
+#
+# defined variables :
+# GMP_FOUND : true if library found
+# GMP_INCLUDE_DIRS : full path to gmp libraries
+# GMP_LIBRARIES : full path to gmp libraries
+#
+
+option( GMP_ENABLE_CXX "enable cxx library" OFF )
+
+find_path(GMP_INCLUDE_DIRS gmp.h
+ HINTS $ENV{GMP_DIR} ${GMP_DIR} ${GMP_INCLUDE_DIRS}
+ PATH_SUFFIXES include
+)
+
+find_library(GMP_LIBRARY NAMES gmp gmp-10
+ HINTS $ENV{GMP_DIR} ${GMP_DIR}
+ PATH_SUFFIXES lib
+)
+set( GMP_LIBRARIES ${GMP_LIBRARY} )
+
+if( ${GMP_ENABLE_CXX} )
+ find_library(GMP_CXX_LIBRARY NAMES gmpxx gmpxx-4
+ HINTS $ENV{GMP_DIR} ${GMP_DIR}
+ PATH_SUFFIXES lib
+ )
+ set( GMP_LIBRARIES "${GMP_CXX_LIBRARY};${GMP_LIBRARIES}" )
+endif()
+
+# handle the QUIETLY and REQUIRED arguments and set <NAME>_FOUND to TRUE
+# if all listed variables are TRUE
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+ GMP DEFAULT_MSG
+ GMP_INCLUDE_DIRS GMP_LIBRARIES
+)
+
+mark_as_advanced(GMP_INCLUDE_DIRS GMP_LIBRARIES)
+
+
diff --git a/cmake/Modules/FindMPFR.cmake b/cmake/Modules/FindMPFR.cmake
new file mode 100644
index 0000000..e5a8b96
--- /dev/null
+++ b/cmake/Modules/FindMPFR.cmake
@@ -0,0 +1,37 @@
+#-- MPFR finder
+#
+# search variables :
+# MPFR_DIR(cmake/environment) : gmp install directory
+# MPFR_INCLUDE_DIR(cmake) : directory containing gmp.h
+# MPFR_LIBRARY_DIR(cmake) : directory containing gmp libraries
+#
+# defined variables :
+# MPFR_FOUND : true if library found
+# MPFR_INCLUDE_DIRS : full path to gmp libraries
+# MPFR_LIBRARIES : full path to gmp libraries
+#
+
+
+find_path(MPFR_INCLUDE_DIRS mpfr.h
+ HINTS $ENV{MPFR_DIR} ${MPFR_DIR}
+ PATH_SUFFIXES include
+)
+
+find_library(MPFR_LIBRARY NAMES mpfr
+ HINTS $ENV{MPFR_DIR} ${MPFR_DIR}
+ PATH_SUFFIXES lib
+)
+set( MPFR_LIBRARIES ${MPFR_LIBRARY} )
+
+
+# handle the QUIETLY and REQUIRED arguments and set <NAME>_FOUND to TRUE
+# if all listed variables are TRUE
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+ MPFR DEFAULT_MSG
+ MPFR_INCLUDE_DIRS MPFR_LIBRARIES
+)
+
+mark_as_advanced(MPFR_INCLUDE_DIRS MPFR_LIBRARIES )
+
+
diff --git a/cmake/Modules/FindPostgreSQL.cmake b/cmake/Modules/FindPostgreSQL.cmake
new file mode 100644
index 0000000..2ca3bf4
--- /dev/null
+++ b/cmake/Modules/FindPostgreSQL.cmake
@@ -0,0 +1,57 @@
+# - Find PostgreSQL
+# Find the PostgreSQL includes and client library
+# This module defines
+# POSTGRESQL_INCLUDE_DIR, where to find POSTGRESQL.h
+# POSTGRESQL_LIBRARIES, the libraries needed to use POSTGRESQL.
+# POSTGRESQL_FOUND, If false, do not try to use PostgreSQL.
+#
+# Copyright (c) 2006, Jaroslaw Staniek, <js at iidea.pl>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+# Add the postgresql and mysql include paths here
+
+if(POSTGRESQL_INCLUDE_DIR AND POSTGRESQL_LIBRARIES)
+
+ set(POSTGRESQL_FOUND TRUE)
+ message(STATUS "Enabled PostgreSQL: ${POSTGRESQL_INCLUDE_DIR}, ${POSTGRESQL_LIBRARIES}")
+
+else(POSTGRESQL_INCLUDE_DIR AND POSTGRESQL_LIBRARIES)
+
+ FIND_PATH(POSTGRESQL_INCLUDE_DIR libpq-fe.h
+ /usr/include/postgresql/
+ /usr/include/postgresql*/
+ /usr/pgsql/include
+ /usr/pgsql*/include
+ /usr/local/pgsql/include
+ /usr/local/include
+ /opt/local/include
+ /usr/include/pgsql
+ $ENV{ProgramFiles}/PostgreSQL/*/include
+ $ENV{SystemDrive}/PostgreSQL/*/include
+ )
+
+ FIND_LIBRARY(POSTGRESQL_LIBRARIES NAMES pq libpq
+ PATHS
+ /usr/lib
+ /usr/lib/postgresql
+ /usr/local/lib
+ /usr/pgsql*/lib
+ /usr/lib64
+ /usr/lib64/postgresql
+ /usr/local/lib64
+ /usr/pgsql*/lib64
+ $ENV{ProgramFiles}/PostgreSQL/*/lib/ms
+ $ENV{SystemDrive}/PostgreSQL/*/lib/ms
+ )
+
+ if(POSTGRESQL_INCLUDE_DIR AND POSTGRESQL_LIBRARIES)
+ set(POSTGRESQL_FOUND TRUE)
+ message(STATUS "Found PostgreSQL: ${POSTGRESQL_INCLUDE_DIR}, ${POSTGRESQL_LIBRARIES}")
+ else(POSTGRESQL_INCLUDE_DIR AND POSTGRESQL_LIBRARIES)
+ set(POSTGRESQL_FOUND FALSE)
+ message(STATUS "PostgreSQL not found.")
+ endif(POSTGRESQL_INCLUDE_DIR AND POSTGRESQL_LIBRARIES)
+
+endif(POSTGRESQL_INCLUDE_DIR AND POSTGRESQL_LIBRARIES)
diff --git a/cmake/Modules/FindSFCGAL.cmake b/cmake/Modules/FindSFCGAL.cmake
new file mode 100644
index 0000000..627ec93
--- /dev/null
+++ b/cmake/Modules/FindSFCGAL.cmake
@@ -0,0 +1,77 @@
+#-- SFCGAL finder
+#
+# search variables :
+# SFCGAL_DIR(cmake/environment) : SFCGAL install directory
+# SFCGAL_INCLUDE_DIR(cmake) : directory containing SFCGAL.h
+# SFCGAL_LIBRARY_DIR(cmake) : directory containing SFCGAL libraries
+#
+# defined variables :
+# SFCGAL_FOUND : true if library found
+# SFCGAL_INCLUDE_DIRS : full path to SFCGAL libraries
+# SFCGAL_LIBRARIES : full path to SFCGAL libraries
+#
+
+# -- parse version
+find_path(SFCGAL_INCLUDE_DIR SFCGAL/Kernel.h
+ HINTS $ENV{SFCGAL_DIR} ${SFCGAL_DIR} ${SFCGAL_INCLUDE_DIRS}
+ PATH_SUFFIXES include
+)
+
+# -- parse version
+IF(SFCGAL_INCLUDE_DIR)
+ IF(EXISTS "${SFCGAL_INCLUDE_DIR}/SFCGAL/version.h")
+ FILE(STRINGS "${SFCGAL_INCLUDE_DIR}/SFCGAL/version.h" sfcgal_version_str REGEX "^#define[\t ]+SFCGAL_VERSION[\t ]+\".*\"")
+
+ STRING(REGEX REPLACE "^#define[\t ]+SFCGAL_VERSION[\t ]+\"([^\"]*)\".*" "\\1" SFCGAL_VERSION "${sfcgal_version_str}")
+
+ # from http://www.cmake.org/Wiki/CMakeCompareVersionStrings
+ # Breaks up a string in the form n1.n2.n3 into three parts and stores
+ # them in major, minor, and patch. version should be a value, not a
+ # variable, while major, minor and patch should be variables.
+ IF(${SFCGAL_VERSION} MATCHES "[0-9]+\\.[0-9]+\\.[0-9]+")
+ STRING(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" SFCGAL_MAJOR_VERSION "${SFCGAL_VERSION}")
+ STRING(REGEX REPLACE "^[0-9]+\\.([0-9])+\\.[0-9]+" "\\1" SFCGAL_MINOR_VERSION "${SFCGAL_VERSION}")
+ STRING(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" SFCGAL_PATCH_VERSION "${SFCGAL_VERSION}")
+ ELSE()
+ MESSAGE( WARNING "SFCGAL_VERSION (${SFCGAL_VERSION}) doesn't match *.*.* form" )
+ ENDIF()
+
+
+ UNSET(sfcgal_version_str)
+ ELSE()
+ message( WARNING "can't parse SFCGAL version" )
+ ENDIF()
+ENDIF()
+
+
+
+# find library (Release)
+find_library(SFCGAL_LIBRARY NAMES SFCGAL
+ HINTS $ENV{SFCGAL_DIR} ${SFCGAL_DIR}
+ PATH_SUFFIXES lib
+)
+# find library (Debug)
+find_library(SFCGAL_LIBRARY_DEBUG NAMES SFCGALd
+ HINTS $ENV{SFCGAL_DIR} ${SFCGAL_DIR}
+ PATH_SUFFIXES lib
+)
+
+# set output variables
+set( SFCGAL_INCLUDE_DIRS "${SFCGAL_INCLUDE_DIR}" )
+if ( SFCGAL_LIBRARY_DEBUG )
+ set( SFCGAL_LIBRARIES "optimized;${SFCGAL_LIBRARY};debug;${SFCGAL_LIBRARY_DEBUG}" )
+else()
+ set( SFCGAL_LIBRARIES ${SFCGAL_LIBRARY} )
+endif()
+
+# handle the QUIETLY and REQUIRED arguments and set <NAME>_FOUND to TRUE
+# if all listed variables are TRUE
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+ SFCGAL DEFAULT_MSG
+ SFCGAL_INCLUDE_DIRS SFCGAL_LIBRARIES
+)
+
+mark_as_advanced(SFCGAL_INCLUDE_DIRS SFCGAL_LIBRARIES)
+
+
diff --git a/cmake/Modules/Libtoolize.cmake b/cmake/Modules/Libtoolize.cmake
new file mode 100644
index 0000000..b4f3496
--- /dev/null
+++ b/cmake/Modules/Libtoolize.cmake
@@ -0,0 +1,49 @@
+MACRO(GET_TARGET_PROPERTY_WITH_DEFAULT _variable _target _property _default_value)
+ GET_TARGET_PROPERTY (${_variable} ${_target} ${_property})
+ IF (${_variable} MATCHES NOTFOUND)
+ SET (${_variable} ${_default_value})
+ ENDIF (${_variable} MATCHES NOTFOUND)
+ ENDMACRO (GET_TARGET_PROPERTY_WITH_DEFAULT)
+
+ MACRO(CREATE_LIBTOOL_FILE _target _install_DIR)
+ GET_TARGET_PROPERTY(_target_location ${_target} LOCATION)
+ GET_TARGET_PROPERTY_WITH_DEFAULT(_target_static_lib ${_target} STATIC_LIB "")
+ GET_TARGET_PROPERTY_WITH_DEFAULT(_target_dependency_libs ${_target} LT_DEPENDENCY_LIBS "")
+ GET_TARGET_PROPERTY_WITH_DEFAULT(_target_current ${_target} LT_VERSION_CURRENT 0)
+ GET_TARGET_PROPERTY_WITH_DEFAULT(_target_age ${_target} LT_VERSION_AGE 0)
+ GET_TARGET_PROPERTY_WITH_DEFAULT(_target_revision ${_target} LT_VERSION_REVISION 0)
+ GET_TARGET_PROPERTY_WITH_DEFAULT(_target_installed ${_target} LT_INSTALLED yes)
+ GET_TARGET_PROPERTY_WITH_DEFAULT(_target_shouldnotlink ${_target} LT_SHOULDNOTLINK yes)
+ GET_TARGET_PROPERTY_WITH_DEFAULT(_target_dlopen ${_target} LT_DLOPEN "")
+ GET_TARGET_PROPERTY_WITH_DEFAULT(_target_dlpreopen ${_target} LT_DLPREOPEN "")
+ GET_FILENAME_COMPONENT(_laname ${_target_location} NAME_WE)
+ GET_FILENAME_COMPONENT(_soname ${_target_location} NAME)
+ SET(_laname ${PROJECT_BINARY_DIR}/${_laname}.la)
+ FILE(WRITE ${_laname} "# ${_laname} - a libtool library file\n")
+ FILE(APPEND ${_laname} "# Generated by CMake ${CMAKE_VERSION} (like GNU libtool)\n")
+ FILE(APPEND ${_laname} "\n# Please DO NOT delete this file!\n# It is necessary for linking the library with libtool.\n\n" )
+ FILE(APPEND ${_laname} "# The name that we can dlopen(3).\n")
+ FILE(APPEND ${_laname} "dlname='${_soname}'\n\n")
+ FILE(APPEND ${_laname} "# Names of this library.\n")
+ FILE(APPEND ${_laname} "library_names='${_soname}.${_target_current}.${_target_age}.${_target_revision} ${_soname}.${_target_current} ${_soname}'\n\n")
+ FILE(APPEND ${_laname} "# The name of the static archive.\n")
+ FILE(APPEND ${_laname} "old_library='${_target_static_lib}'\n\n")
+ FILE(APPEND ${_laname} "# Libraries that this one depends upon.\n")
+ FILE(APPEND ${_laname} "dependency_libs='${_target_dependency_libs}'\n\n")
+ FILE(APPEND ${_laname} "# Names of additional weak libraries provided by this library\n")
+ FILE(APPEND ${_laname} "weak_library_names=\n\n")
+ FILE(APPEND ${_laname} "# Version information for ${_laname}.\n")
+ FILE(APPEND ${_laname} "current=${_target_current}\n")
+ FILE(APPEND ${_laname} "age=${_target_age}\n")
+ FILE(APPEND ${_laname} "revision=${_target_revision}\n\n")
+ FILE(APPEND ${_laname} "# Is this an already installed library?\n")
+ FILE(APPEND ${_laname} "installed=${_target_installed}\n\n")
+ FILE(APPEND ${_laname} "# Should we warn about portability when linking against -modules?\n")
+ FILE(APPEND ${_laname} "shouldnotlink=${_target_shouldnotlink}\n\n")
+ FILE(APPEND ${_laname} "# Files to dlopen/dlpreopen\n")
+ FILE(APPEND ${_laname} "dlopen='${_target_dlopen}'\n")
+ FILE(APPEND ${_laname} "dlpreopen='${_target_dlpreopen}'\n\n")
+ FILE(APPEND ${_laname} "# Directory that this library needs to be installed in:\n")
+ FILE(APPEND ${_laname} "libdir='${CMAKE_INSTALL_PREFIX}${_install_DIR}'\n")
+ INSTALL( FILES ${_laname} DESTINATION ${CMAKE_INSTALL_PREFIX}${_install_DIR})
+ ENDMACRO(CREATE_LIBTOOL_FILE)
diff --git a/cmake/Modules/PrecompiledHeader.cmake b/cmake/Modules/PrecompiledHeader.cmake
new file mode 100644
index 0000000..cc53571
--- /dev/null
+++ b/cmake/Modules/PrecompiledHeader.cmake
@@ -0,0 +1,125 @@
+#
+# Original message : http://www.cmake.org/pipermail/cmake/2006-December/012360.html
+
+# - Try to find precompiled headers support for GCC 3.4 and 4.x
+# Once done this will define:
+#
+# Variable:
+# PCHSupport_FOUND
+#
+# Macro:
+# ADD_PRECOMPILED_HEADER
+
+if (CMAKE_CXX_COMPILER MATCHES ".*clang.*")
+ set(CMAKE_COMPILER_IS_CLANGXX TRUE)
+endif ()
+
+IF(CMAKE_COMPILER_IS_GNUCXX)
+ EXEC_PROGRAM(
+ ${CMAKE_CXX_COMPILER}
+ ARGS --version
+ OUTPUT_VARIABLE _compiler_output)
+ STRING(REGEX REPLACE ".* ([0-9]\\.[0-9]\\.[0-9]) .*" "\\1"
+ gcc_compiler_version ${_compiler_output})
+ #MESSAGE("GCC Version: ${gcc_compiler_version}")
+ IF(gcc_compiler_version MATCHES "4\\.[0-9]\\.[0-9]")
+ SET(PCHSupport_FOUND TRUE)
+ ELSE(gcc_compiler_version MATCHES "4\\.[0-9]\\.[0-9]")
+ IF(gcc_compiler_version MATCHES "3\\.4\\.[0-9]")
+ SET(PCHSupport_FOUND TRUE)
+ ENDIF(gcc_compiler_version MATCHES "3\\.4\\.[0-9]")
+ ENDIF(gcc_compiler_version MATCHES "4\\.[0-9]\\.[0-9]")
+
+ IF (PCHSupport_FOUND)
+ SET( PCH_Generate_cmd -x c++-header)
+ SET( PCH_Include_cmd "-Winvalid-pch -include" )
+ SET( PCH_Include_file _name )
+ ENDIF(PCHSupport_FOUND)
+ENDIF(CMAKE_COMPILER_IS_GNUCXX)
+
+IF(CMAKE_COMPILER_IS_CLANGXX)
+ set(PCHSupport_FOUND TRUE)
+ SET( PCH_Generate_cmd "")
+ SET( PCH_Include_cmd "-include-pch" )
+ SET( PCH_Include_file _output )
+ENDIF(CMAKE_COMPILER_IS_CLANGXX)
+
+MACRO(ADD_PRECOMPILED_HEADER _targetName _input )
+
+ IF(NOT CMAKE_BUILD_TYPE)
+ MESSAGE(FATAL_ERROR
+ "This is the ADD_PRECOMPILED_HEADER macro. "
+ "You must set CMAKE_BUILD_TYPE!"
+ )
+ ENDIF(NOT CMAKE_BUILD_TYPE)
+
+ GET_FILENAME_COMPONENT(_name ${_input} NAME)
+ GET_FILENAME_COMPONENT(_path ${_input} PATH)
+ SET(_outdir "${CMAKE_CURRENT_BINARY_DIR}/${_name}.gch")
+ SET(_output "${_outdir}/${CMAKE_BUILD_TYPE}.pch")
+
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${_outdir}
+ COMMAND mkdir ${_outdir} # TODO: {CMAKE_COMMAND} -E ...
+ )
+ #MAKE_DIRECTORY(${_outdir})
+
+ STRING(TOUPPER "CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}" _flags_var_name)
+ SET(_compile_FLAGS ${${_flags_var_name}})
+
+ GET_DIRECTORY_PROPERTY(_directory_flags INCLUDE_DIRECTORIES)
+
+
+ SET(_CMAKE_CURRENT_BINARY_DIR_included_before_path FALSE)
+ FOREACH(item ${_directory_flags})
+ IF(${item} STREQUAL ${_path} AND NOT _CMAKE_CURRENT_BINARY_DIR_included_before_path )
+ MESSAGE(FATAL_ERROR
+ "This is the ADD_PRECOMPILED_HEADER macro. "
+ "CMAKE_CURREN_BINARY_DIR has to mentioned at INCLUDE_DIRECTORIES's argument list before ${_path}, where ${_name} is located"
+ )
+ ENDIF(${item} STREQUAL ${_path} AND NOT _CMAKE_CURRENT_BINARY_DIR_included_before_path )
+
+ IF(${item} STREQUAL ${CMAKE_CURRENT_BINARY_DIR})
+ SET(_CMAKE_CURRENT_BINARY_DIR_included_before_path TRUE)
+ ENDIF(${item} STREQUAL ${CMAKE_CURRENT_BINARY_DIR})
+
+ LIST(APPEND _compile_FLAGS "-I${item}")
+ ENDFOREACH(item)
+
+ GET_DIRECTORY_PROPERTY(_directory_flags DEFINITIONS)
+ LIST(APPEND _compile_FLAGS ${_directory_flags})
+ LIST(APPEND _compile_FLAGS ${CMAKE_CXX_FLAGS} )
+ # get additional flags from the macro
+ LIST(APPEND _compile_FLAGS ${ARGN})
+
+ SEPARATE_ARGUMENTS(_compile_FLAGS)
+# MESSAGE("_compiler_FLAGS: ${_compiler_FLAGS}")
+# message(${_compile_FLAGS} )
+# message("COMMAND ${CMAKE_CXX_COMPILER} ${_compile_FLAGS} -x c++-header -o ${_output} ${_input}")
+
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_name}
+ COMMAND ${CMAKE_COMMAND} -E copy ${_input} ${CMAKE_CURRENT_BINARY_DIR}/${_name} # ensure same directory! Required by gcc
+ )
+
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${_output}
+ COMMAND ${CMAKE_CXX_COMPILER}
+ ${_compile_FLAGS}
+ ${PCH_Generate_cmd}
+ -o ${_output}
+ ${_input}
+ DEPENDS ${_input} ${_outdir} ${CMAKE_CURRENT_BINARY_DIR}/${_name}
+ )
+ ADD_CUSTOM_TARGET(${_targetName}_gch
+ DEPENDS ${_output}
+ )
+ ADD_DEPENDENCIES(${_targetName} ${_targetName}_gch )
+ SET_TARGET_PROPERTIES(${_targetName}
+ PROPERTIES
+# COMPILE_FLAGS "${PCH_Include_cmd} ${_name}"
+# COMPILE_FLAGS "${PCH_Include_cmd} ${_output}"
+ COMPILE_FLAGS "${PCH_Include_cmd} ${${PCH_Include_file}}"
+ )
+
+ENDMACRO(ADD_PRECOMPILED_HEADER)
\ No newline at end of file
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
new file mode 100644
index 0000000..82dc852
--- /dev/null
+++ b/doc/CMakeLists.txt
@@ -0,0 +1,9 @@
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile @ONLY)
+
+find_package(Doxygen QUIET)
+if(DOXYGEN_FOUND)
+ add_custom_target(doc ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMENT "Generating API documentation with Doxygen" VERBATIM
+ )
+endif(DOXYGEN_FOUND)
diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
new file mode 100644
index 0000000..79fd4c6
--- /dev/null
+++ b/doc/Doxyfile.in
@@ -0,0 +1,1814 @@
+# Doxyfile 1.7.6.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or sequence of words) that should
+# identify the project. Note that if you do not use Doxywizard you need
+# to put quotes around the project name if it contains spaces.
+
+PROJECT_NAME = SFCGAL
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = @SFCGAL_VERSION@
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer
+# a quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is
+# included in the documentation. The maximum height of the logo should not
+# exceed 55 pixels and the maximum width should not exceed 200 pixels.
+# Doxygen will copy the logo to the output directory.
+
+PROJECT_LOGO =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = .
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful if your file system
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding
+# "class=itcl::class" will allow you to use the command class in the
+# itcl::class meaning.
+
+TCL_SUBST =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given extension.
+# Doxygen has a built-in mapping, but you can override or extend it using this
+# tag. The format is ext=language, where ext is a file extension, and language
+# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
+# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
+# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
+# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also makes the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
+# unions are shown inside the group in which they are included (e.g. using
+# @ingroup) instead of on a separate page (for HTML and Man pages) or
+# section (for LaTeX and RTF).
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
+# unions with only public data fields will be shown inline in the documentation
+# of the scope in which they are defined (i.e. file, namespace, or group
+# documentation), provided this scope is documented. If set to NO (the default),
+# structs, classes, and unions are shown on a separate page (for HTML and Man
+# pages) or section (for LaTeX and RTF).
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penalty.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will roughly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+SYMBOL_CACHE_SIZE = 0
+
+# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
+# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
+# their name and scope. Since this can be an expensive process and often the
+# same symbol appear multiple times in the code, doxygen keeps a cache of
+# pre-resolved symbols. If the cache is too small doxygen will become slower.
+# If the cache is too large, memory is wasted. The cache size is given by this
+# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+LOOKUP_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = YES
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
+# do proper type resolution of all parameters of a function it will reject a
+# match between the prototype and the implementation of a member function even
+# if there is only one candidate or it is obvious which candidate to choose
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
+# will still accept a match between prototype and implementation in such cases.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = NO
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = NO
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or macro consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and macros in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = NO
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = NO
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page. This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. The create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option.
+# You can optionally specify a file name after the option, if omitted
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files
+# containing the references data. This must be a list of .bib files. The
+# .bib extension is automatically appended if omitted. Using this command
+# requires the bibtex tool to be installed. See also
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
+# feature you need bibtex and perl available in the search path.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = ../include \
+ .
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.d \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.idl \
+ *.odl \
+ *.cs \
+ *.php \
+ *.php3 \
+ *.inc \
+ *.m \
+ *.mm \
+ *.dox \
+ *.py \
+ *.f90 \
+ *.f \
+ *.for \
+ *.vhd \
+ *.vhdl
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS = CGAL* boost* osg*
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty or if
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
+# and it is also possible to disable source filtering for a specific pattern
+# using *.ext= (so without naming a filter). This option only has effect when
+# FILTER_SOURCE_FILES is enabled.
+
+FILTER_SOURCE_PATTERNS =
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code. Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header. Note that when using a custom header you are responsible
+# for the proper inclusion of any scripts and style sheets that doxygen
+# needs, which is dependent on the configuration options used.
+# It is advised to generate a default header using "doxygen -w html
+# header.html footer.html stylesheet.css YourConfigFile" and then modify
+# that header. Note that the header is subject to change so you typically
+# have to redo this when upgrading to a newer version of doxygen or when
+# changing the value of configuration settings such as GENERATE_TREEVIEW!
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# style sheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that
+# the files will be copied as-is; there are no commands or markers available.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+# Doxygen will adjust the colors in the style sheet and background images
+# according to this color. Hue is specified as an angle on a colorwheel,
+# see http://en.wikipedia.org/wiki/Hue for more information.
+# For instance the value 0 represents red, 60 is yellow, 120 is green,
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+# the colors in the HTML output. For a value of 0 the output will use
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+# the luminance component of the colors in the HTML output. Values below
+# 100 gradually make the output lighter, whereas values above 100 make
+# the output darker. The value divided by 100 is the actual gamma applied,
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP = YES
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
+# that can be used as input for Qt's qhelpgenerator to generate a
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
+# add. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+# will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
+# the help appears.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
+# this name.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
+# at top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it. Since the tabs have the same information as the
+# navigation tree you can set this option to NO if you already set
+# GENERATE_TREEVIEW to YES.
+
+DISABLE_INDEX = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+# Since the tree basically has the same information as the tab index you
+# could consider to set DISABLE_INDEX to NO when enabling this option.
+
+GENERATE_TREEVIEW = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML
+# documentation. Note that a value of 0 will completely suppress the enum
+# values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE = 4
+
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are
+# not supported properly for IE 6.0, but are supported on all modern browsers.
+# Note that when changing this option you need to delete any form_*.png files
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
+# (see http://www.mathjax.org) which uses client side Javascript for the
+# rendering instead of using prerendered bitmaps. Use this if you do not
+# have LaTeX installed or if you want to formulas look prettier in the HTML
+# output. When enabled you also need to install MathJax separately and
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you need to specify the location relative to the
+# HTML output directory using the MATHJAX_RELPATH option. The destination
+# directory should contain the MathJax.js script. For instance, if the mathjax
+# directory is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the
+# mathjax.org site, so you can quickly see the result without installing
+# MathJax, but it is strongly recommended to install a local copy of MathJax
+# before deployment.
+
+MATHJAX_RELPATH = http://www.mathjax.org/mathjax
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
+# names that should be enabled during MathJax rendering.
+
+MATHJAX_EXTENSIONS =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE = NO
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a PHP enabled web server instead of at the web client
+# using Javascript. Doxygen will generate the search PHP script and index
+# file to put on the web server. The advantage of the server
+# based approach is that it scales better to large projects and allows
+# full text search. The disadvantages are that it is more difficult to setup
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
+# the generated latex document. The footer should contain everything after
+# the last chapter. If it is left blank doxygen will generate a
+# standard footer. Notice: only use this tag if you know what you are doing!
+
+LATEX_FOOTER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
+# http://en.wikipedia.org/wiki/BibTeX for more info.
+
+LATEX_BIB_STYLE = plain
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load style sheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# pointed to by INCLUDE_PATH will be searched when a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition that
+# overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all references to function-like macros
+# that are alone on a line, have an all uppercase name, and do not end with a
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option also works with HAVE_DOT disabled, but it is recommended to
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
+# allowed to run in parallel. When set to 0 (the default) doxygen will
+# base this on the number of processors available in the system. You can set it
+# explicitly to a value larger than 0 to get control over the balance
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS = 0
+
+# By default doxygen will use the Helvetica font for all dot files that
+# doxygen generates. When you want a differently looking font you can specify
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find
+# the font, which can be done by putting it in a standard location or by setting
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
+# directory containing the font.
+
+DOT_FONTNAME = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the Helvetica font.
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
+# set the path where dot can find it.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are svg, png, jpg, or gif.
+# If left blank png will be used. If you choose svg you need to set
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible in IE 9+ (other browsers do not have this requirement).
+
+DOT_IMAGE_FORMAT = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+# Note that this requires a modern browser other than Internet Explorer.
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible. Older versions of IE do not have SVG support.
+
+INTERACTIVE_SVG = NO
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the
+# \mscfile command).
+
+MSCFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
diff --git a/doc/images/Grid-PixelIsArea.svg b/doc/images/Grid-PixelIsArea.svg
new file mode 100644
index 0000000..e63f414
--- /dev/null
+++ b/doc/images/Grid-PixelIsArea.svg
@@ -0,0 +1,484 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="316.52319"
+ height="193.41264"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.3.1 r9886"
+ sodipodi:docname="Grid-PixelIsArea.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.979899"
+ inkscape:cx="300.04949"
+ inkscape:cy="122.13334"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1680"
+ inkscape:window-height="974"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1"
+ fit-margin-top="5"
+ fit-margin-left="5"
+ fit-margin-right="5"
+ fit-margin-bottom="5" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Calque 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-161.40584,-181.39552)">
+ <g
+ id="g4440"
+ transform="translate(1.1537116,0)">
+ <path
+ transform="translate(126.90041,40.65864)"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ sodipodi:ry="4.2931485"
+ sodipodi:rx="4.2931485"
+ sodipodi:cy="188.42921"
+ sodipodi:cx="78.53936"
+ id="path4118"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ <path
+ transform="translate(168.69548,40.406105)"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ sodipodi:ry="4.2931485"
+ sodipodi:rx="4.2931485"
+ sodipodi:cy="188.42921"
+ sodipodi:cx="78.53936"
+ id="path4118-6"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ <path
+ transform="translate(215.66757,40.406105)"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ sodipodi:ry="4.2931485"
+ sodipodi:rx="4.2931485"
+ sodipodi:cy="188.42921"
+ sodipodi:cx="78.53936"
+ id="path4118-5"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ <path
+ transform="translate(262.63967,40.658643)"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ sodipodi:ry="4.2931485"
+ sodipodi:rx="4.2931485"
+ sodipodi:cy="188.42921"
+ sodipodi:cx="78.53936"
+ id="path4118-1"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ <path
+ transform="translate(308.60161,40.911181)"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ sodipodi:ry="4.2931485"
+ sodipodi:rx="4.2931485"
+ sodipodi:cy="188.42921"
+ sodipodi:cx="78.53936"
+ id="path4118-8"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ <path
+ transform="translate(353.04832,40.406105)"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ sodipodi:ry="4.2931485"
+ sodipodi:rx="4.2931485"
+ sodipodi:cy="188.42921"
+ sodipodi:cx="78.53936"
+ id="path4118-9"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ </g>
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1.0162915px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 457.14286,206.6479 -272.85715,0 0,138.69679"
+ id="path2985"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 451.03311,201.81374 6.06092,5.05076 -6.06092,5.05076"
+ id="path2987"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 179.59794,337.71515 4.54569,7.07107 4.04061,-7.57614"
+ id="path2989"
+ inkscape:connector-curvature="0" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="469.24741"
+ y="212.09474"
+ id="text2991"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan2993"
+ x="469.24741"
+ y="212.09474">i</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="181.41338"
+ y="365.64801"
+ id="text2991-0"
+ sodipodi:linespacing="125%"
+ inkscape:transform-center-x="-5.3027344"><tspan
+ sodipodi:role="line"
+ id="tspan2993-5"
+ x="181.41338"
+ y="365.64801">j</tspan></text>
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:0.97067976px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 457.14286,206.29075 0,139.31385"
+ id="path3035"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 183.21429,345.57647 274.28571,0"
+ id="path3037"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 224.28572,203.43361 0,7.85714"
+ id="path3807"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 271.42857,203.43361 0,7.85714"
+ id="path3807-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 317.5,203.43361 0,7.85714"
+ id="path3807-8-0"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 363.21428,202.71933 0,7.85714"
+ id="path3807-8-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 407.85714,203.07647 0,7.85714"
+ id="path3807-8-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 187.5,206.6479 -7.85714,0"
+ id="path3807-7"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 187.5,253.79075 -7.85714,0"
+ id="path3807-8-09"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 187.5,299.86218 -7.85714,0"
+ id="path3807-8-0-1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 188.21428,345.57646 -7.85714,0"
+ id="path3807-8-9-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 183.92857,202.71933 0,7.85714"
+ id="path3807-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 183.21429,299.50504 274.28571,0"
+ id="path3037-1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 185.35715,253.79075 274.28571,0"
+ id="path3037-0"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:0.97067976px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 224.28572,207.34811 0,139.31385"
+ id="path3035-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:0.97067976px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 271.07143,206.99097 0,139.31385"
+ id="path3035-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:0.97067976px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 317.5,205.91954 0,139.31385"
+ id="path3035-88"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:0.97067976px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 363.21428,205.56239 0,139.31385"
+ id="path3035-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:0.97067976px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 408.21429,206.99097 0,139.31385"
+ id="path3035-38"
+ inkscape:connector-curvature="0" />
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="166.8555"
+ y="233.57973"
+ id="text3985"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3987"
+ x="166.8555"
+ y="233.57973">0</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="248.50787"
+ y="197.83299"
+ id="text3985-5"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3987-7"
+ x="248.50787"
+ y="197.83299">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="289.88565"
+ y="197.91209"
+ id="text3985-6"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3987-5"
+ x="289.88565"
+ y="197.91209">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="336.61011"
+ y="197.82713"
+ id="text3985-7"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3987-53"
+ x="336.61011"
+ y="197.82713">3</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="386.72217"
+ y="197.83299"
+ id="text3985-2"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3987-0"
+ x="386.72217"
+ y="197.83299">4</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="428.69171"
+ y="197.74803"
+ id="text3985-4"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3987-6"
+ x="428.69171"
+ y="197.74803">5</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="166.7471"
+ y="278.9537"
+ id="text3985-1"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3987-3"
+ x="166.7471"
+ y="278.9537">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="167.0137"
+ y="325.17892"
+ id="text3985-1-2"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3987-3-4"
+ x="167.0137"
+ y="325.17892">2</tspan></text>
+ <g
+ transform="translate(1.1537116,46.22028)"
+ id="g4440-7">
+ <path
+ transform="translate(126.90041,40.65864)"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ sodipodi:ry="4.2931485"
+ sodipodi:rx="4.2931485"
+ sodipodi:cy="188.42921"
+ sodipodi:cx="78.53936"
+ id="path4118-0"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ <path
+ transform="translate(168.69548,40.406105)"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ sodipodi:ry="4.2931485"
+ sodipodi:rx="4.2931485"
+ sodipodi:cy="188.42921"
+ sodipodi:cx="78.53936"
+ id="path4118-6-0"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ <path
+ transform="translate(215.66757,40.406105)"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ sodipodi:ry="4.2931485"
+ sodipodi:rx="4.2931485"
+ sodipodi:cy="188.42921"
+ sodipodi:cx="78.53936"
+ id="path4118-5-6"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ <path
+ transform="translate(262.63967,40.658643)"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ sodipodi:ry="4.2931485"
+ sodipodi:rx="4.2931485"
+ sodipodi:cy="188.42921"
+ sodipodi:cx="78.53936"
+ id="path4118-1-9"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ <path
+ transform="translate(308.60161,40.911181)"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ sodipodi:ry="4.2931485"
+ sodipodi:rx="4.2931485"
+ sodipodi:cy="188.42921"
+ sodipodi:cx="78.53936"
+ id="path4118-8-0"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ <path
+ transform="translate(353.04832,40.406105)"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ sodipodi:ry="4.2931485"
+ sodipodi:rx="4.2931485"
+ sodipodi:cy="188.42921"
+ sodipodi:cx="78.53936"
+ id="path4118-9-4"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ </g>
+ <g
+ transform="translate(1.1537116,90.666992)"
+ id="g4440-3">
+ <path
+ transform="translate(126.90041,40.65864)"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ sodipodi:ry="4.2931485"
+ sodipodi:rx="4.2931485"
+ sodipodi:cy="188.42921"
+ sodipodi:cx="78.53936"
+ id="path4118-05"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ <path
+ transform="translate(168.69548,40.406105)"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ sodipodi:ry="4.2931485"
+ sodipodi:rx="4.2931485"
+ sodipodi:cy="188.42921"
+ sodipodi:cx="78.53936"
+ id="path4118-6-7"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ <path
+ transform="translate(215.66757,40.406105)"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ sodipodi:ry="4.2931485"
+ sodipodi:rx="4.2931485"
+ sodipodi:cy="188.42921"
+ sodipodi:cx="78.53936"
+ id="path4118-5-9"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ <path
+ transform="translate(262.63967,40.658643)"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ sodipodi:ry="4.2931485"
+ sodipodi:rx="4.2931485"
+ sodipodi:cy="188.42921"
+ sodipodi:cx="78.53936"
+ id="path4118-1-6"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ <path
+ transform="translate(308.60161,40.911181)"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ sodipodi:ry="4.2931485"
+ sodipodi:rx="4.2931485"
+ sodipodi:cy="188.42921"
+ sodipodi:cx="78.53936"
+ id="path4118-8-6"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ <path
+ transform="translate(353.04832,40.406105)"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ sodipodi:ry="4.2931485"
+ sodipodi:rx="4.2931485"
+ sodipodi:cy="188.42921"
+ sodipodi:cx="78.53936"
+ id="path4118-9-8"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="202.59138"
+ y="197.74776"
+ id="text3985-67"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3987-4"
+ x="202.59138"
+ y="197.74776">0</tspan></text>
+ </g>
+</svg>
diff --git a/doc/images/Grid-PixelIsPoint.svg b/doc/images/Grid-PixelIsPoint.svg
new file mode 100644
index 0000000..a542ef8
--- /dev/null
+++ b/doc/images/Grid-PixelIsPoint.svg
@@ -0,0 +1,583 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="316.52319"
+ height="193.41264"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.3.1 r9886"
+ sodipodi:docname="Grid.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.4"
+ inkscape:cx="316.77908"
+ inkscape:cy="108.08116"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1680"
+ inkscape:window-height="974"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1"
+ fit-margin-top="5"
+ fit-margin-left="5"
+ fit-margin-right="5"
+ fit-margin-bottom="5" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Calque 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-161.40584,-181.39552)">
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(105.05586,17.172593)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-6"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(145.20943,17.930211)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-5"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(192.18152,17.930211)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-1"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(239.15362,17.425135)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-8"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(285.11556,18.435287)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-9"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(329.56227,17.930211)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-7"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(378.55467,17.930211)" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1.0162915px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 457.14286,206.6479 -272.85715,0 0,138.69679"
+ id="path2985"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 451.03311,201.81374 6.06092,5.05076 -6.06092,5.05076"
+ id="path2987"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 179.59794,337.71515 4.54569,7.07107 4.04061,-7.57614"
+ id="path2989"
+ inkscape:connector-curvature="0" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="469.24741"
+ y="212.09474"
+ id="text2991"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan2993"
+ x="469.24741"
+ y="212.09474">i</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="181.41338"
+ y="365.64801"
+ id="text2991-0"
+ sodipodi:linespacing="125%"
+ inkscape:transform-center-x="-5.3027344"><tspan
+ sodipodi:role="line"
+ id="tspan2993-5"
+ x="181.41338"
+ y="365.64801">j</tspan></text>
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:0.97067976px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 457.14286,206.29075 0,139.31385"
+ id="path3035"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 183.21429,345.57647 274.28571,0"
+ id="path3037"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 224.28572,203.43361 0,7.85714"
+ id="path3807"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 271.42857,203.43361 0,7.85714"
+ id="path3807-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 317.5,203.43361 0,7.85714"
+ id="path3807-8-0"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 363.21428,202.71933 0,7.85714"
+ id="path3807-8-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 407.85714,203.07647 0,7.85714"
+ id="path3807-8-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 187.5,206.6479 -7.85714,0"
+ id="path3807-7"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 187.5,253.79075 -7.85714,0"
+ id="path3807-8-09"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 187.5,299.86218 -7.85714,0"
+ id="path3807-8-0-1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 188.21428,345.57646 -7.85714,0"
+ id="path3807-8-9-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 183.92857,202.71933 0,7.85714"
+ id="path3807-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 183.21429,299.50504 274.28571,0"
+ id="path3037-1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 185.35715,253.79075 274.28571,0"
+ id="path3037-0"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:0.97067976px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 224.28572,207.34811 0,139.31385"
+ id="path3035-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:0.97067976px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 271.07143,206.99097 0,139.31385"
+ id="path3035-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:0.97067976px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 317.5,205.91954 0,139.31385"
+ id="path3035-88"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:0.97067976px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 363.21428,205.56239 0,139.31385"
+ id="path3035-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:0.97067976px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 408.21429,206.99097 0,139.31385"
+ id="path3035-38"
+ inkscape:connector-curvature="0" />
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="178.57143"
+ y="197.71931"
+ id="text3985"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3987"
+ x="178.57143"
+ y="197.71931">0</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="220.47127"
+ y="196.73035"
+ id="text3985-5"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3987-7"
+ x="220.47127"
+ y="196.73035">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="266.89981"
+ y="195.65892"
+ id="text3985-6"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3987-5"
+ x="266.89981"
+ y="195.65892">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="312.61411"
+ y="195.30177"
+ id="text3985-7"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3987-53"
+ x="312.61411"
+ y="195.30177">3</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="358.68555"
+ y="196.01605"
+ id="text3985-2"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3987-0"
+ x="358.68555"
+ y="196.01605">4</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="403.68555"
+ y="195.65892"
+ id="text3985-4"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3987-6"
+ x="403.68555"
+ y="195.65892">5</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="452.97125"
+ y="196.37321"
+ id="text3985-53"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3987-9"
+ x="452.97125"
+ y="196.37321">6</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="167.61412"
+ y="256.73035"
+ id="text3985-1"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3987-3"
+ x="167.61412"
+ y="256.73035">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="166.43428"
+ y="302.4505"
+ id="text3985-1-2"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3987-3-4"
+ x="166.43428"
+ y="302.4505">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="165.49178"
+ y="349.23035"
+ id="text3985-7-7"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3987-53-4"
+ x="165.49178"
+ y="349.23035">3</tspan></text>
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-88-0"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(104.92959,64.776028)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-6-4-1"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(145.08316,65.533648)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-5-8-4"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(192.05525,65.533648)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-1-7-9"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(239.02735,65.028578)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-8-1-2"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(284.9893,66.038728)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-9-3-5"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(329.43601,65.533648)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-7-8-1"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(378.42841,65.533648)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-88-8"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(104.92959,110.23289)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-6-4-0"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(145.08316,110.99051)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-5-8-8"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(192.05525,110.99051)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-1-7-5"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(239.02735,110.48544)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-8-1-21"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(284.9893,111.49559)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-9-3-9"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(329.43601,110.99051)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-7-8-6"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(378.42841,110.99051)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-88-9"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(105.93975,156.19484)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-6-4-6"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(146.09332,156.95246)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-5-8-9"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(193.06541,156.95246)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-1-7-6"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(240.03751,156.44739)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-8-1-6"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(285.99945,157.45754)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-9-3-2"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(330.44616,156.95246)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#3809ff;fill-opacity:1;stroke:#cccccc;stroke-width:0.047;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4118-7-8-9"
+ sodipodi:cx="78.53936"
+ sodipodi:cy="188.42921"
+ sodipodi:rx="4.2931485"
+ sodipodi:ry="4.2931485"
+ d="m 82.832509,188.42921 c 0,2.37104 -1.922108,4.29315 -4.293149,4.29315 -2.37104,0 -4.293148,-1.92211 -4.293148,-4.29315 0,-2.37104 1.922108,-4.29314 4.293148,-4.29314 2.371041,0 4.293149,1.9221 4.293149,4.29314 z"
+ transform="translate(379.43856,156.95246)" />
+ </g>
+</svg>
diff --git a/doc/images/triangulatePolygon.svg b/doc/images/triangulatePolygon.svg
new file mode 100644
index 0000000..546f713
--- /dev/null
+++ b/doc/images/triangulatePolygon.svg
@@ -0,0 +1,279 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="653.125"
+ height="496.96582"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.3.1 r9886"
+ sodipodi:docname="triangulatePolygon.svg">
+ <defs
+ id="defs4">
+ <marker
+ inkscape:stockid="Arrow1Lend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Lend"
+ style="overflow:visible">
+ <path
+ id="path3956"
+ d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+ transform="matrix(-0.8,0,0,-0.8,-10,0)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Lend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Lend-8"
+ style="overflow:visible">
+ <path
+ inkscape:connector-curvature="0"
+ id="path3956-0"
+ d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+ transform="matrix(-0.8,0,0,-0.8,-10,0)" />
+ </marker>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="1"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.7"
+ inkscape:cx="408.65378"
+ inkscape:cy="213.45536"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1680"
+ inkscape:window-height="974"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1"
+ fit-margin-top="5"
+ fit-margin-left="5"
+ fit-margin-right="5"
+ fit-margin-bottom="5" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Calque 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-39.46875,-29.21875)">
+ <path
+ style="fill:#e2e2e2;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 51.4375,169.5 45,365.21875 148.5625,319.5 94.28125,273.78125 130,212.375 l 1.4375,52.84375 134.28125,-90 L 51.4375,169.5 z M 73.75,181.625 132.34375,186.65625 100,250.3125 64.65625,229.09375 73.75,181.625 z"
+ id="path2985"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#e2e2e2;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 471.72573,321.52312 -6.4375,195.71874 103.5625,-45.71875 -54.28125,-45.71875 35.71875,-61.40624 1.4375,52.84374 134.28125,-89.99999 -214.28125,-5.71875 z m 22.3125,12.125 58.59375,5.03125 -32.34375,63.65625 -35.34375,-21.21875 9.09375,-47.46875 z"
+ id="path2985-49" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 471.54046,321.34677 22.85714,11.42857"
+ id="path3816"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 520.33692,401.52535 -5.59801,23.57143"
+ id="path3818"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 484.88397,380.50908 29.08852,44.88968"
+ id="path3820"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 471.36188,320.81106 13.57143,59.64286"
+ id="path3822"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 464.93331,517.23963 19.28572,-137.5"
+ id="path3824"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 514.21903,425.45392 465.6476,517.23963"
+ id="path3826"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 519.21903,401.88249 31.07143,-37.14286"
+ id="path3828"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 553.1476,338.66821 -2.85714,26.07142"
+ id="path3830"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 685.29046,327.23963 550.6476,366.16821"
+ id="path3832"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 552.07617,338.66821 685.29046,327.23963"
+ id="path3834"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 494.21903,332.59678 192.14286,-5.35715"
+ id="path3836"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#e2e2e2;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 470.4915,35.053179 464.054,230.77192 567.6165,185.05317 513.33525,139.33442 549.054,77.928179 550.4915,130.77192 684.77275,40.771929 z"
+ id="path2985-49-7"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 470.30623,34.876829 22.85714,11.42857"
+ id="path3816-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 519.10269,115.05541 -5.59801,23.57143"
+ id="path3818-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 483.64974,94.039137 29.08852,44.889683"
+ id="path3820-4"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 470.12765,34.341119 13.57143,59.642858"
+ id="path3822-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 463.69908,230.76969 482.9848,93.269687"
+ id="path3824-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 512.9848,138.98398 -48.57143,91.78571"
+ id="path3826-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 517.9848,115.41255 549.05623,78.269689"
+ id="path3828-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 551.91337,52.198269 -2.85714,26.07142"
+ id="path3830-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 684.05623,40.769689 549.41337,79.698269"
+ id="path3832-0"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 550.84194,52.198269 684.05623,40.769689"
+ id="path3834-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 492.9848,46.126839 192.14286,-5.35715"
+ id="path3836-7"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 492.9848,46.842237 25.35714,68.928573 -35,-21.785713 z"
+ id="path3910"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 492.27051,46.485094 58.92858,5"
+ id="path3912"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 552.04837,51.806086 517.70318,115.95078"
+ id="path3914"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#e2e2e2;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 512.90496,139.43682 37.1231,-8.58629 -1.01015,-51.770326 z"
+ id="path3916"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#e2e2e2;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 512.90496,138.93175 37.37564,-8.08122 17.42513,54.29569 z"
+ id="path3918"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#e2e2e2;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 685.64104,40.441869 567.20066,185.39876 550.2806,131.10306 z"
+ id="path3920"
+ inkscape:connector-curvature="0" />
+ <text
+ xml:space="preserve"
+ style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="144.4518"
+ y="77.56498"
+ id="text3922"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3924"
+ x="144.4518"
+ y="77.56498">Triangulate2DZ</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="72.988625"
+ y="512.86426"
+ id="text3922-2"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3924-0"
+ x="72.988625"
+ y="512.86426">TriangulatePolygon</tspan></text>
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Lend)"
+ d="m 316.17774,183.63099 94.95434,-33.33503"
+ id="path3947"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Lend)"
+ d="m 318.19805,324.54727 94.95434,33.33503"
+ id="path3947-7"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/doc/mainpage.h b/doc/mainpage.h
new file mode 100644
index 0000000..36946e3
--- /dev/null
+++ b/doc/mainpage.h
@@ -0,0 +1,99 @@
+/**
+ *
+ * @mainpage SFCGAL
+ *
+ * SFCGAL is a wrapper around CGAL library that intents to implement 2D and 3D
+ * operations on OGC standards models (Simple Feature Access, CityGML,...)
+ *
+ * @section intro_sec Introduction
+ *
+ * SFCGAL relies on a single CGAL Kernel : The Exact Predicate Exact Construction Kernel (Epeck). SFCGAL::Kernel is a typedef
+ * on Epeck on this Kernel.
+ *
+ * SFCGAL::Coordinate class provides a type erasure on CGAL points in order to fit the dynamic is3D() world. SFCGAL::Coordinate
+ * hides either a dummy empty entity, either a CGAL::Point_2, or a CGAL::Point_3 in the Epeck kernel.
+ *
+ * Furthermore, conversions to double that would break constructive robustness are avoided.
+ *
+ * @section dependencies_sec Dependencies
+ *
+ * <ul>
+ * <li>CGAL 4.1+ (http://www.cgal.org/)</li>
+ * <li>Boost library (http://www.boost.org/)</li>
+ * </ul>
+ *
+ * @section geometric_model_sec Geometric model
+ *
+ * The Geometric Model is an extension of OGC Simple Feature Access providing solids (SFCGAL::Solid) defined
+ * in the ISO 19107 and implemented in CityGML.
+ *
+ * Primitives
+ *
+ * <ul>
+ * <li>SFCGAL::Point is a Point defined by SFCGAL::Coordinate</li>
+ * <li>SFCGAL::LineString is a defined by an ordered list of SFCGAL::Point</li>
+ * <li>SFCGAL::Polygon is a polygon with optional holes, defined by an exterior ring and interior rings</li>
+ * <li>SFCGAL::Triangle is a Triangle defined by 3 points (*)</li>
+ * <li>SFCGAL::Solid is a solid with optional holes (**), defined by an exterior shell and interior shells</li>
+ * </ul>
+ *
+ * Geometry collections
+ *
+ * <ul>
+ * <li>SFCGAL::GeometryCollection is a list of geometries that might mix types</li>
+ * <li>SFCGAL::MultiPoint is GeometryCollection restricted to SFCGAL::Point</li>
+ * <li>SFCGAL::MultiLineString is GeometryCollection restricted to SFCGAL::LineString</li>
+ * <li>SFCGAL::MultiPolygon is GeometryCollection restricted to SFCGAL::Polygon</li>
+ * </ul>
+ *
+ * Geometries with shared coordinates
+ *
+ * <ul>
+ * <li>SFCGAL::TriangulatedSurface is a triangle set with shared components</li>
+ * <li>SFCGAL::PolyhedralSurface is a polygon set with shared components</li>
+ * </ul>
+ *
+ *
+ * (*) SFCGAL doesn't respect the standard on this point. SFCGAL::Triangle doesn't inherit SFCGAL::Polygon for different reasons
+ * <ul>
+ * <li>Library is not query-only, geometries can be edited. We should expose triangle.addInteriorRing and throws exceptions on it.</li>
+ * <li>Inherits Polygon would brought useless structure to handle exterior and interior rings</li>
+ * <li>CGAL model relies on 3 points</li>
+ * </ul>
+ * On the other hand, it leads to convert between Triangle and Polygon and to duplicate some codes (area for example) so that it could to change
+ * that and conform.
+ *
+ * (**) A solid may be represented with holes, but no algorithm supports them for now.
+ *
+ * <b>Note on orientations</b>: geometries (surfaces in 2D and volumes in 3D) are oriented. The orientation is used with geometries that have 'holes'. for instance, interior rings of a 2D polygon have an orientation that is reversed to the exterior ring's orientation. The same would apply on solid' shells.
+ * However, there is no enforcement for a particular orientation on exterior rings / shells. This behaviour on solids is subject to changes since OGC standards on Solids are not yet stabilized.
+ * Exceptions to this rule are stated in the reference manual (@link SFCGAL::algorithm::minkowskiSum example @endlink).
+ *
+ * @section geo_validity_policy Geometry validation policy
+ *
+ * Every processing algorithm takes <b>valid</b> geometries as input parameters (no self intersection, etc.). Validity of geometries is tested with the algorithm::isValid() function and corresponds to validity preconditions asked for by OGC standards.
+ *
+ * Since these validity checkings may be slow, each algorithm comes with a variant where no actual check is made (taking a NoValidityCheck tag as additional parameter).
+ *
+ * Validity checking could also be bypassed at a global level, by setting to 'OFF' the 'SFCGAL_CHECK_VALIDITY' CMake option.
+ *
+ * @section api API
+ *
+ * Two sets of functionalities are exposed and will be maintained as a stable API :
+ * <ul>
+ * <li>@link public_api the C++ public API @endlink</li>
+ * <li>@link capi the C public API @endlink</li>
+ * </ul>
+ *
+ * Some other elements of the documentation are tagged as @link detail 'details' @endlink which means they are for internal use only and are subject
+ * to changes within future releases.
+ *
+ * @defgroup public_api Public C++ API
+ * @defgroup capi Public C API
+ *
+ * @defgroup detail Implementation details
+ *
+ * @defgroup incomplete Incomplete or buggy functions
+ *
+ *
+ */
diff --git a/doc/sfcgal_viewer_demo.avi b/doc/sfcgal_viewer_demo.avi
new file mode 100644
index 0000000..4c8b47c
Binary files /dev/null and b/doc/sfcgal_viewer_demo.avi differ
diff --git a/example/CGAL-basic_manip/CMakeLists.txt b/example/CGAL-basic_manip/CMakeLists.txt
new file mode 100644
index 0000000..e429356
--- /dev/null
+++ b/example/CGAL-basic_manip/CMakeLists.txt
@@ -0,0 +1,13 @@
+GET_FILENAME_COMPONENT( EXAMPLE_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME )
+add_executable( example-${EXAMPLE_NAME}
+ main.cpp
+)
+target_link_libraries( example-${EXAMPLE_NAME}
+ SFCGAL
+ ${CGAL_LIBRARIES}
+ ${MPFR_LIBRARIES}
+ ${GMP_LIBRARIES}
+ ${Boost_LIBRARIES}
+)
+set_target_properties( example-${EXAMPLE_NAME} PROPERTIES DEBUG_POSTFIX "d" )
+install( TARGETS example-${EXAMPLE_NAME} DESTINATION bin )
\ No newline at end of file
diff --git a/example/CGAL-basic_manip/main.cpp b/example/CGAL-basic_manip/main.cpp
new file mode 100644
index 0000000..0f41df8
--- /dev/null
+++ b/example/CGAL-basic_manip/main.cpp
@@ -0,0 +1,291 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <iostream>
+
+//#include <CGAL/Cartesian.h>
+//#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+#include <CGAL/Point_2.h>
+#include <CGAL/Point_3.h>
+#include <CGAL/Segment_2.h>
+#include <CGAL/Segment_3.h>
+#include <CGAL/Polygon_2.h>
+#include <CGAL/Polygon_with_holes_2.h>
+#include <CGAL/Arr_segment_traits_2.h>
+#include <CGAL/Arrangement_2.h>
+#include <CGAL/Nef_polyhedron_3.h>
+#include <CGAL/bounding_box.h>
+#include <CGAL/box_intersection_d.h>
+
+/**
+ * Defines the default Kernel used by SFCGAL
+ * @todo allow to choose between differents Kernels
+ */
+//typedef CGAL::Cartesian< double > Kernel ;
+typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel ;
+
+/**
+ * Defines a 2D mathematical vector
+ */
+typedef Kernel::Vector_2 Vector_2 ;
+/**
+ * Defines a 3D mathematical vector
+ */
+typedef Kernel::Vector_3 Vector_3 ;
+
+/**
+ * Defines the Point_2 in the default Kernel
+ */
+typedef Kernel::Point_2 Point_2 ;
+/**
+ * Defines the Point_3 in the default Kernel
+ */
+typedef Kernel::Point_3 Point_3 ;
+
+typedef Kernel::Triangle_3 Triangle_3 ;
+
+/**
+ * Defines a Segment_2 in the default Kernel
+ */
+typedef CGAL::Segment_2< Kernel > Segment_2 ;
+/**
+ * Defines a Segment_3 in the default Kernel
+ */
+typedef CGAL::Segment_3< Kernel > Segment_3 ;
+
+/**
+ * A polygon defined by an exterior ring
+ */
+typedef CGAL::Polygon_2< Kernel > Polygon_2 ;
+/**
+ * A polygon defined by an exterior ring and interior rings
+ */
+typedef CGAL::Polygon_with_holes_2< Kernel > Polygon_with_holes_2 ;
+
+
+int main(){
+
+ ///------------- 2D -----------------------------------------------------------------------
+
+ std::cout << "--- Vector_2 ----" << std::endl;
+ {
+ Vector_2 a( 1.0, 1.0 );
+ Vector_2 b( 3.0, 4.0 );
+ std::cout << "a : " << a << std::endl;
+ std::cout << "b : " << b << std::endl;
+ std::cout << "a+b : " << (a+b) << std::endl;
+
+ std::cout << "b.squared_length() : "<< a.squared_length() << std::endl ;
+ }
+
+ std::cout << "--- Point_2 ----" << std::endl;
+ {
+ Point_2 a( 0.0, 0.0 );
+ Point_2 b( 3.0, 4.0 );
+ std::cout << "a : " << a << std::endl ;
+ std::cout << "b : " << b << std::endl ;
+ }
+
+ std::cout << "--- Segment_2 ----" << std::endl;
+ {
+ Segment_2 ab(
+ Point_2( 0.0, 0.0 ),
+ Point_2( 1.0, 1.0 )
+ );
+ std::cout << "ab : " << ab << std::endl;
+ }
+
+
+
+ std::cout << "--- Polygon_2 ----" << std::endl;
+ {
+ std::vector< Point_2 > exteriorRing ;
+ exteriorRing.push_back( Point_2(0.0,0.0) );
+ exteriorRing.push_back( Point_2(1.0,0.0) );
+ exteriorRing.push_back( Point_2(0.5,1.0) );
+ // CGAL polygon are not closed duplicating last point
+ //exteriorRing.push_back( Point_2(0.0,0.0) );
+
+ Polygon_2 polygon( exteriorRing.begin(), exteriorRing.end() );
+
+ //some basic test
+ std::cout << "polygon.area() : " << polygon.area() << std::endl ;
+ std::cout << "polygon.is_convex() : " << polygon.is_convex() << std::endl ;
+ std::cout << "polygon.is_clockwise_oriented() : " << polygon.is_clockwise_oriented() << std::endl ;
+ std::cout << "polygon.bbox() : " << polygon.bbox() << std::endl ;
+ std::cout << "polygon.is_simple() : " << polygon.is_simple() << std::endl ;
+
+ //polygon.bottom_vertex();
+ //polygon.bounded_side();
+
+ std::cout << polygon << std::endl ;
+ }
+
+ std::cout << "--- Polygon_with_holes_2 ----" << std::endl;
+ {
+ //create rings
+ std::vector< Point_2 > exteriorRing ;
+ exteriorRing.push_back( Point_2( 0.0, 0.0 ) );
+ exteriorRing.push_back( Point_2( 1.0, 0.0 ) );
+ exteriorRing.push_back( Point_2( 1.0, 1.0 ) );
+ exteriorRing.push_back( Point_2( 0.0, 1.0 ) );
+
+ std::vector< Point_2 > interiorRing ;
+ interiorRing.push_back( Point_2( 0.2, 0.2 ) );
+ interiorRing.push_back( Point_2( 0.8, 0.2 ) );
+ interiorRing.push_back( Point_2( 0.8, 0.8 ) );
+ interiorRing.push_back( Point_2( 0.2, 0.8 ) );
+
+ // create polygon
+ Polygon_with_holes_2 polygon( Polygon_2( exteriorRing.begin(), exteriorRing.end() ) );
+ polygon.add_hole( Polygon_2( interiorRing.begin(), interiorRing.end() ) );
+
+ // print wkt
+ std::cout << polygon << std::endl ;
+ }
+
+
+ ///------------- 3D -----------------------------------------------------------------------
+
+
+ std::cout << "--- Point_3 ----" << std::endl;
+ {
+ Point_3 a( 0.0, 0.0, 0.0 );
+ Point_3 b( 3.0, 4.0, 5.0 );
+ std::cout << "a : " << a << std::endl ;
+ std::cout << "b : " << b << std::endl ;
+
+ std::cout << "a < b : " << ( a < b ) << std::endl;
+ }
+ std::cout << "--- Segment_3 ----" << std::endl;
+ {
+ Segment_3 ab(
+ Point_3( 0.0, 0.0, 0.0 ),
+ Point_3( 3.0, 4.0, 5.0 )
+ );
+
+ std::cout << ab.source() << " => " << ab.target() << std::endl;
+ std::cout << ab << std::endl;
+ }
+ std::cout << "--- Triangle_3 ---" << std::endl;
+ {
+ Triangle_3 tri( Point_3( 0.0, 0.0, 1.0),
+ Point_3( 1.0, 0.0, 1.0),
+ Point_3( 0.0, 1.0, 1.0) );
+ Point_3 p( 0.2, 0.2, 1.0 );
+ Point_3 p2( 0.2, 0.2, 0.0 );
+ std::cout << "p : " << p << std::endl;
+ std::cout << "p2 : " << p2 << std::endl;
+ std::cout << "tri: " << tri << std::endl;
+ std::cout << "tri.has_on(p) : " << tri.has_on( p ) << std::endl;
+ std::cout << "tri.has_on(p2): " << tri.has_on( p2 ) << std::endl;
+ }
+ std::cout << "--- 2D Arrangements ---" << std::endl;
+ {
+ typedef CGAL::Arr_segment_traits_2<Kernel> Traits_2;
+ typedef Traits_2::Point_2 APoint_2;
+ typedef Traits_2::X_monotone_curve_2 ASegment_2;
+ typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
+
+ Arrangement_2 arr;
+ std::vector<ASegment_2> segs;
+ segs.push_back( ASegment_2( APoint_2( 0.0, 0.0 ), APoint_2( 2.0, 0.0 ) ) );
+ segs.push_back( ASegment_2( APoint_2( 2.0, 0.0 ), APoint_2( 1.0, 1.0 ) ) );
+ segs.push_back( ASegment_2( APoint_2( 1.0, 1.0 ), APoint_2( 1.0, -1.0 ) ) );
+ segs.push_back( ASegment_2( APoint_2( 1.0, -1.0 ), APoint_2( 0.0, 0.0 ) ) );
+ segs.push_back( ASegment_2( APoint_2( 1.0, -1.0 ), APoint_2( 0.0, 0.0 ) ) );
+ CGAL::insert( arr, segs.begin(), segs.end() );
+
+ std::cout << "# of vertices: " << arr.number_of_vertices() << std::endl;
+ std::cout << "# of faces: " << arr.number_of_faces() << std::endl;
+ std::cout << "autointersects ? " << (arr.number_of_vertices() > 4 ? "YES" : "NO") << std::endl;
+
+ arr.clear();
+ segs.clear();
+ // a triangle
+ segs.push_back( ASegment_2( APoint_2( 0.0, 0.0 ), APoint_2( 1.0, 1.0 ) ) );
+ segs.push_back( ASegment_2( APoint_2( 1.0, 1.0 ), APoint_2( 1.0, 0.0 ) ) );
+ segs.push_back( ASegment_2( APoint_2( 1.0, 0.0 ), APoint_2( 0.0, 0.0 ) ) );
+ // and a segment contained in the triangle
+ segs.push_back( ASegment_2( APoint_2( 0.55, 0.5 ), APoint_2( 0.6, 0.5 ) ) );
+ CGAL::insert( arr, segs.begin(), segs.end() );
+ std::cout << "# of vertices: " << arr.number_of_vertices() << std::endl;
+ std::cout << "# of faces: " << arr.number_of_faces() << std::endl;
+ Arrangement_2::Face_iterator it;
+ for ( it = arr.faces_begin(); it != arr.faces_end(); it++ ) {
+ std::cout << "unbounded: " << it->is_unbounded() << " has holes: " << (it->holes_begin() != it->holes_end()) << std::endl;
+ }
+ }
+ std::cout << "--- Nef_polyhedron_3 ---" << std::endl;
+ {
+ typedef CGAL::Nef_polyhedron_3<Kernel> Nef_polyhedron;
+ typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
+
+ Polyhedron poly1;
+ poly1.make_tetrahedron( Point_3( 0.0, -1.0, -1.0 ),
+ Point_3( 2.0, -1.0, -1.0 ),
+ Point_3( 1.5, 1.0, -1.0 ),
+ Point_3( 1.0, 0.0, 1.0 ) );
+ Nef_polyhedron nef1( poly1 );
+ std::cout << "nef1.is_valid() " << nef1.is_valid() << std::endl;
+ std::cout << "nef1.is_empty() " << nef1.is_empty() << std::endl;
+
+ typedef Nef_polyhedron::Halffacet_const_iterator GeometryIterator;
+ typedef CGAL::Box_intersection_d::Box_with_handle_d<double,3,GeometryIterator> Box;
+ std::list<Box> boxes;
+
+ // browse faces
+ Nef_polyhedron::Halffacet_const_iterator it;
+ for ( it = nef1.halffacets_begin(); it != nef1.halffacets_end(); ++it ) {
+ CGAL::Iso_cuboid_3<Kernel> bbox;
+
+ std::list<CGAL::Point_3<Kernel> > points;
+ Nef_polyhedron::SHalfedge_const_handle edge( it->facet_cycles_begin() );
+ Nef_polyhedron::SHalfedge_around_facet_const_circulator hc(edge);
+ Nef_polyhedron::SHalfedge_around_facet_const_circulator hc_end(hc);
+ do {
+ points.push_back( hc->source()->center_vertex()->point() );
+ ++hc;
+ } while (hc != hc_end);
+ bbox = CGAL::bounding_box( points.begin(), points.end() );
+ boxes.push_back( Box(bbox.bbox(), it) );
+ }
+ // TODO use CGAL::box_intersection_d()
+
+ Polyhedron poly2;
+ poly2.make_tetrahedron( Point_3( -1.0, -1.0, -1.0 ),
+ Point_3( 1.0, -1.0, -1.0 ),
+ Point_3( 0.5, 1.0, -1.0 ),
+ Point_3( 0.0, 0.0, 1.0 ) );
+
+ Nef_polyhedron nef2( poly2 );
+ std::cout << "# of vertices: " << nef1.number_of_vertices() << std::endl;
+ std::cout << "# of volumes: " << nef1.number_of_volumes() << std::endl;
+ std::cout << "# of edges: " << nef1.number_of_edges() << std::endl;
+ std::cout << "# of facets: " << nef1.number_of_facets() << std::endl;
+
+ nef1 = nef1.join(nef2);
+ std::cout << "# of vertices: " << nef1.number_of_vertices() << std::endl;
+ std::cout << "# of volumes: " << nef1.number_of_volumes() << std::endl;
+ std::cout << "# of edges: " << nef1.number_of_edges() << std::endl;
+ std::cout << "# of facets: " << nef1.number_of_facets() << std::endl;
+ }
+ return 0;
+}
diff --git a/example/CGAL-cartesian_kernel/CMakeLists.txt b/example/CGAL-cartesian_kernel/CMakeLists.txt
new file mode 100644
index 0000000..e429356
--- /dev/null
+++ b/example/CGAL-cartesian_kernel/CMakeLists.txt
@@ -0,0 +1,13 @@
+GET_FILENAME_COMPONENT( EXAMPLE_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME )
+add_executable( example-${EXAMPLE_NAME}
+ main.cpp
+)
+target_link_libraries( example-${EXAMPLE_NAME}
+ SFCGAL
+ ${CGAL_LIBRARIES}
+ ${MPFR_LIBRARIES}
+ ${GMP_LIBRARIES}
+ ${Boost_LIBRARIES}
+)
+set_target_properties( example-${EXAMPLE_NAME} PROPERTIES DEBUG_POSTFIX "d" )
+install( TARGETS example-${EXAMPLE_NAME} DESTINATION bin )
\ No newline at end of file
diff --git a/example/CGAL-cartesian_kernel/main.cpp b/example/CGAL-cartesian_kernel/main.cpp
new file mode 100644
index 0000000..48c3a04
--- /dev/null
+++ b/example/CGAL-cartesian_kernel/main.cpp
@@ -0,0 +1,37 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <CGAL/Cartesian.h>
+#include <CGAL/squared_distance_2.h>
+
+
+
+//declaration Kernel simple
+typedef CGAL::Cartesian< double > K ;
+typedef K::Point_2 Point_2 ;
+
+
+int main(){
+ Point_2 a( 0.0, 0.0 );
+ Point_2 b( 3.0, 4.0 );
+ K::Compute_squared_distance_2 squared_distance;
+ std::cout << squared_distance( a, b ) << std::endl;
+ return 0;
+}
+
diff --git a/example/CGAL-point_generator/CMakeLists.txt b/example/CGAL-point_generator/CMakeLists.txt
new file mode 100644
index 0000000..e429356
--- /dev/null
+++ b/example/CGAL-point_generator/CMakeLists.txt
@@ -0,0 +1,13 @@
+GET_FILENAME_COMPONENT( EXAMPLE_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME )
+add_executable( example-${EXAMPLE_NAME}
+ main.cpp
+)
+target_link_libraries( example-${EXAMPLE_NAME}
+ SFCGAL
+ ${CGAL_LIBRARIES}
+ ${MPFR_LIBRARIES}
+ ${GMP_LIBRARIES}
+ ${Boost_LIBRARIES}
+)
+set_target_properties( example-${EXAMPLE_NAME} PROPERTIES DEBUG_POSTFIX "d" )
+install( TARGETS example-${EXAMPLE_NAME} DESTINATION bin )
\ No newline at end of file
diff --git a/example/CGAL-point_generator/main.cpp b/example/CGAL-point_generator/main.cpp
new file mode 100644
index 0000000..c41edf3
--- /dev/null
+++ b/example/CGAL-point_generator/main.cpp
@@ -0,0 +1,61 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <iostream>
+#include <algorithm>
+
+#include <CGAL/Cartesian.h>
+#include <CGAL/point_generators_2.h>
+#include <CGAL/point_generators_3.h>
+
+
+typedef CGAL::Cartesian< double > Kernel ;
+typedef Kernel::Point_2 Point_2;
+typedef Kernel::Point_3 Point_3;
+typedef CGAL::Creator_uniform_2< double, Point_2 > Creator_2;
+typedef CGAL::Creator_uniform_3< double, Point_3 > Creator_3;
+
+
+int main()
+{
+
+ //-- generate points in disc
+ {
+ CGAL::Random_points_in_disc_2< Point_2, Creator_2 > g( 150.0 );
+
+ size_t n = 100U;
+ for ( size_t i = 0; i < n; i++ ){
+ Point_2 p = *(++g) ;
+ std::cout << p << std::endl;
+ }
+ }
+
+ //-- generate points in sphere
+ {
+ CGAL::Random_points_in_sphere_3< Point_3, Creator_3 > g( 150.0 );
+
+ size_t n = 100U;
+ for ( size_t i = 0; i < n; i++ ){
+ Point_3 p = *(++g) ;
+ std::cout << p << std::endl;
+ }
+ }
+
+ return 0;
+}
diff --git a/example/CGAL-polygon_triangulation2/CMakeLists.txt b/example/CGAL-polygon_triangulation2/CMakeLists.txt
new file mode 100644
index 0000000..e429356
--- /dev/null
+++ b/example/CGAL-polygon_triangulation2/CMakeLists.txt
@@ -0,0 +1,13 @@
+GET_FILENAME_COMPONENT( EXAMPLE_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME )
+add_executable( example-${EXAMPLE_NAME}
+ main.cpp
+)
+target_link_libraries( example-${EXAMPLE_NAME}
+ SFCGAL
+ ${CGAL_LIBRARIES}
+ ${MPFR_LIBRARIES}
+ ${GMP_LIBRARIES}
+ ${Boost_LIBRARIES}
+)
+set_target_properties( example-${EXAMPLE_NAME} PROPERTIES DEBUG_POSTFIX "d" )
+install( TARGETS example-${EXAMPLE_NAME} DESTINATION bin )
\ No newline at end of file
diff --git a/example/CGAL-polygon_triangulation2/main.cpp b/example/CGAL-polygon_triangulation2/main.cpp
new file mode 100644
index 0000000..4cb5dfa
--- /dev/null
+++ b/example/CGAL-polygon_triangulation2/main.cpp
@@ -0,0 +1,200 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+#include <CGAL/Constrained_Delaunay_triangulation_2.h>
+#include <CGAL/Triangulation_vertex_base_with_info_2.h>
+#include <CGAL/Triangulation_face_base_with_info_2.h>
+#include <CGAL/Polygon_2.h>
+
+#include <iostream>
+#include <fstream>
+
+/**
+ * face information (depth)
+ */
+struct FaceInfo2 {
+ FaceInfo2() {
+ }
+ int nesting_level;
+
+ bool in_domain() {
+ return nesting_level % 2 == 1;
+ }
+};
+
+
+typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
+typedef CGAL::Triangulation_vertex_base_with_info_2< unsigned int, Kernel > triangulation_vertex_base ;
+typedef CGAL::Triangulation_face_base_with_info_2<FaceInfo2, Kernel> triangulation_face_base;
+typedef CGAL::Constrained_triangulation_face_base_2<Kernel, triangulation_face_base> constrained_triangulation_face_base;
+typedef CGAL::Triangulation_data_structure_2<
+ triangulation_vertex_base,
+ constrained_triangulation_face_base > triangulation_data_structure;
+
+//typedef CGAL::Exact_predicates_tag Itag;
+typedef CGAL::Constrained_Delaunay_triangulation_2<
+ Kernel,
+ triangulation_data_structure,
+ CGAL::Exact_predicates_tag > CDT;
+
+typedef CDT::Point triangulation_point;
+typedef CGAL::Point_2<Kernel> Point_2;
+typedef CGAL::Polygon_2<Kernel> Polygon_2;
+
+
+
+void mark_domains(CDT& ct, CDT::Face_handle start, int index, std::list<CDT::Edge>& border) {
+ if (start->info().nesting_level != -1) {
+ return;
+ }
+ std::list<CDT::Face_handle> queue;
+ queue.push_back(start);
+
+ while (!queue.empty()) {
+ CDT::Face_handle fh = queue.front();
+ queue.pop_front();
+ if (fh->info().nesting_level == -1) {
+ fh->info().nesting_level = index;
+ for (int i = 0; i < 3; i++) {
+ CDT::Edge e(fh, i);
+ CDT::Face_handle n = fh->neighbor(i);
+ if (n->info().nesting_level == -1) {
+ if (ct.is_constrained(e))
+ border.push_back(e);
+ else
+ queue.push_back(n);
+ }
+ }
+ }
+ }
+}
+
+//explore set of facets connected with non constrained edges,
+//and attribute to each such set a nesting level.
+//We start from facets incident to the infinite vertex, with a nesting
+//level of 0. Then we recursively consider the non-explored facets incident
+//to constrained edges bounding the former set and increase the nesting level by 1.
+//Facets in the domain are those with an odd nesting level.
+void mark_domains(CDT& cdt) {
+ for (CDT::All_faces_iterator it = cdt.all_faces_begin(); it
+ != cdt.all_faces_end(); ++it) {
+ it->info().nesting_level = -1;
+ }
+
+ int index = 0;
+ std::list<CDT::Edge> border;
+ mark_domains(cdt, cdt.infinite_face(), index++, border);
+ while (!border.empty()) {
+ CDT::Edge e = border.front();
+ border.pop_front();
+ CDT::Face_handle n = e.first->neighbor(e.second);
+ if (n->info().nesting_level == -1) {
+ mark_domains(cdt, n, e.first->info().nesting_level + 1, border);
+ }
+ }
+}
+
+void insert_polygon( CDT& cdt, const Polygon_2& polygon ) {
+ if (polygon.is_empty())
+ return;
+ CDT::Vertex_handle v_prev = cdt.insert( *CGAL::cpp0x::prev( polygon.vertices_end() ) );
+ for (Polygon_2::Vertex_iterator vit = polygon.vertices_begin(); vit != polygon.vertices_end(); ++vit) {
+ CDT::Vertex_handle vh = cdt.insert(*vit);
+ cdt.insert_constraint(vh, v_prev);
+ v_prev = vh;
+ }
+}
+
+int main() {
+ //construct two non-intersecting nested polygons
+ Polygon_2 polygon1;
+ polygon1.push_back(Point_2(0.0, 0.0));
+ polygon1.push_back(Point_2(2.0, 0.0));
+ polygon1.push_back(Point_2(1.7, 1.0));
+ polygon1.push_back(Point_2(2.0, 2.0));
+ polygon1.push_back(Point_2(0.0, 2.0));
+ Polygon_2 polygon2;
+ polygon2.push_back(Point_2(0.5, 0.5));
+ polygon2.push_back(Point_2(1.5, 0.5));
+ polygon2.push_back(Point_2(1.5, 1.5));
+ polygon2.push_back(Point_2(0.5, 1.5));
+
+ //Insert the polyons into a constrained triangulation
+ CDT cdt;
+ insert_polygon(cdt, polygon1);
+ insert_polygon(cdt, polygon2);
+
+ //Extract point and provide the an index
+ std::vector< triangulation_point > points ;
+ for ( CDT::Vertex_iterator it = cdt.vertices_begin(); it != cdt.vertices_end(); ++it ){
+ it->info() = points.size() ;
+ points.push_back( it->point() );
+ }
+
+
+ //Mark facets that are inside the domain bounded by the polygon
+ mark_domains(cdt);
+
+ //
+ int count = 0;
+ for (CDT::Finite_faces_iterator fit = cdt.finite_faces_begin(); fit != cdt.finite_faces_end(); ++fit) {
+ if (fit->info().in_domain()){
+ ++count;
+ }
+ }
+
+
+ /*
+ * export
+ */
+
+ std::ofstream ofs("polygon_triangulation2.obj");
+ if ( ! ofs.good() ){
+ std::cout << "can't open file" << std::endl;
+ return 1 ;
+ }
+
+ //-- print vertices
+ ofs << "# " << points.size() << " vertices"<< std::endl ;
+ for ( size_t i = 0; i < points.size(); i++ ){
+ ofs << "v " << points[i] << " 0.0" << std::endl;
+ }
+
+ //-- print faces
+ ofs << "# " << cdt.number_of_faces() << " faces"<< std::endl ;
+ // warning : Delaunay_triangulation_2::All_faces_iterator iterator over infinite faces
+ for ( CDT::Finite_faces_iterator it = cdt.finite_faces_begin(); it != cdt.finite_faces_end(); ++it )
+ {
+ //ignore holes
+ if ( ! it->info().in_domain() ){
+ continue ;
+ }
+ size_t ia = it->vertex(0)->info();
+ size_t ib = it->vertex(1)->info();
+ size_t ic = it->vertex(2)->info();
+
+ assert( it->is_valid() );
+ //assert ( ia < cdt.number_of_vertices() || ib < tri.number_of_vertices() || ic < tri.number_of_vertices() ) ;
+
+ ofs << "f " << ( ia + 1 ) << " " << ( ib + 1 ) << " " << ( ic + 1 ) << std::endl;
+ }
+
+ return 0;
+}
diff --git a/example/CGAL-triangulation2/CMakeLists.txt b/example/CGAL-triangulation2/CMakeLists.txt
new file mode 100644
index 0000000..e429356
--- /dev/null
+++ b/example/CGAL-triangulation2/CMakeLists.txt
@@ -0,0 +1,13 @@
+GET_FILENAME_COMPONENT( EXAMPLE_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME )
+add_executable( example-${EXAMPLE_NAME}
+ main.cpp
+)
+target_link_libraries( example-${EXAMPLE_NAME}
+ SFCGAL
+ ${CGAL_LIBRARIES}
+ ${MPFR_LIBRARIES}
+ ${GMP_LIBRARIES}
+ ${Boost_LIBRARIES}
+)
+set_target_properties( example-${EXAMPLE_NAME} PROPERTIES DEBUG_POSTFIX "d" )
+install( TARGETS example-${EXAMPLE_NAME} DESTINATION bin )
\ No newline at end of file
diff --git a/example/CGAL-triangulation2/main.cpp b/example/CGAL-triangulation2/main.cpp
new file mode 100644
index 0000000..6910767
--- /dev/null
+++ b/example/CGAL-triangulation2/main.cpp
@@ -0,0 +1,116 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <fstream>
+
+
+#include <CGAL/Cartesian.h>
+#include <CGAL/Point_2.h>
+#include <CGAL/Point_3.h>
+#include <CGAL/Segment_2.h>
+#include <CGAL/Segment_3.h>
+#include <CGAL/Polygon_2.h>
+#include <CGAL/Polygon_with_holes_2.h>
+
+
+typedef CGAL::Cartesian< double > Kernel ;
+typedef Kernel::Vector_2 Vector_2 ;
+typedef Kernel::Vector_3 Vector_3 ;
+typedef Kernel::Point_2 Point_2 ;
+typedef Kernel::Point_3 Point_3 ;
+typedef CGAL::Segment_2< Kernel > Segment_2 ;
+typedef CGAL::Segment_3< Kernel > Segment_3 ;
+typedef CGAL::Polygon_2< Kernel > Polygon_2 ;
+typedef CGAL::Polygon_with_holes_2< Kernel > Polygon_with_holes_2 ;
+
+
+#include <CGAL/Delaunay_triangulation_2.h>
+#include <CGAL/Triangulation_vertex_base_with_info_2.h>
+
+//-- Info on vertex (unsigned int, an idenfier)
+typedef CGAL::Triangulation_vertex_base_with_info_2< unsigned int, Kernel > Vb ;
+typedef CGAL::Triangulation_data_structure_2< Vb > Tds ;
+
+//-- Triangulation
+typedef CGAL::Delaunay_triangulation_2< Kernel, Tds > Delaunay_triangulation_2 ;
+
+
+//-- point generator
+#include <CGAL/point_generators_2.h>
+typedef CGAL::Creator_uniform_2< double, Point_2 > Creator_2;
+
+
+
+
+/**
+ * Generate a terrain and export to wavefront obj format
+ */
+int main()
+{
+ std::ofstream ofs("triangulation2.obj");
+ if ( ! ofs.good() ){
+ std::cout << "can't open file" << std::endl;
+ return 1 ;
+ }
+
+ const size_t n = 1000 ;
+
+ CGAL::Random_points_in_disc_2< Point_2, Creator_2 > g( 5.0 );
+
+ //-- triangulate points
+ Delaunay_triangulation_2 tri;
+
+ // create points and associates ids
+ std::vector< Point_2 > points;
+ for ( size_t i = 0; i < n; i++ ){
+ Point_2 point2d = *(++g) ;
+ Delaunay_triangulation_2::Vertex_handle v = tri.insert( point2d );
+ v->info() = i ;
+ points.push_back( point2d );
+ }
+
+
+ // print vertices
+ ofs << "# " << tri.number_of_vertices() << " vertices"<< std::endl ;
+ for ( size_t i = 0; i < n; i++ ){
+ ofs << "v " << points[i] << " 0.0" << std::endl;
+ }
+
+ // print faces
+ ofs << "# " << tri.number_of_faces() << " faces"<< std::endl ;
+
+ //-- print triangles
+ // warning : Delaunay_triangulation_2::All_faces_iterator iterator over infinite faces
+ for ( Delaunay_triangulation_2::Finite_faces_iterator it = tri.finite_faces_begin();
+ it != tri.finite_faces_end(); ++it )
+ {
+ size_t ia = it->vertex(0)->info();
+ size_t ib = it->vertex(1)->info();
+ size_t ic = it->vertex(2)->info();
+
+ assert( it->is_valid() );
+ assert ( ia < tri.number_of_vertices() || ib < tri.number_of_vertices() || ic < tri.number_of_vertices() ) ;
+
+ ofs << "f " << ( ia + 1 ) << " " << ( ib + 1 ) << " " << ( ic + 1 ) << std::endl;
+ }
+
+
+ return 0;
+}
+
diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt
new file mode 100644
index 0000000..55b9fd4
--- /dev/null
+++ b/example/CMakeLists.txt
@@ -0,0 +1,14 @@
+add_subdirectory( CGAL-basic_manip )
+add_subdirectory( CGAL-cartesian_kernel )
+add_subdirectory( CGAL-point_generator )
+add_subdirectory( CGAL-triangulation2 )
+add_subdirectory( CGAL-polygon_triangulation2 )
+add_subdirectory( SFCGAL-offset )
+
+if ( SFCGAL_WITH_OSG )
+ add_subdirectory( SFCGAL-export-osg )
+ add_subdirectory( SFCGAL-asc2osg )
+ add_subdirectory( SFCGAL-building )
+endif()
+
+
diff --git a/example/SFCGAL-asc2osg/CMakeLists.txt b/example/SFCGAL-asc2osg/CMakeLists.txt
new file mode 100644
index 0000000..94afac2
--- /dev/null
+++ b/example/SFCGAL-asc2osg/CMakeLists.txt
@@ -0,0 +1,14 @@
+GET_FILENAME_COMPONENT( EXAMPLE_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME )
+add_executable( example-${EXAMPLE_NAME}
+ main.cpp
+)
+target_link_libraries( example-${EXAMPLE_NAME}
+ SFCGAL
+ ${CGAL_LIBRARIES}
+ ${MPFR_LIBRARIES}
+ ${GMP_LIBRARIES}
+ ${OPENSCENEGRAPH_LIBRARIES}
+ ${Boost_LIBRARIES}
+)
+set_target_properties( example-${EXAMPLE_NAME} PROPERTIES DEBUG_POSTFIX "d" )
+install( TARGETS example-${EXAMPLE_NAME} DESTINATION bin )
\ No newline at end of file
diff --git a/example/SFCGAL-asc2osg/main.cpp b/example/SFCGAL-asc2osg/main.cpp
new file mode 100644
index 0000000..b0bb8f0
--- /dev/null
+++ b/example/SFCGAL-asc2osg/main.cpp
@@ -0,0 +1,85 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <iostream>
+#include <fstream>
+
+#include <boost/filesystem.hpp>
+
+#include <SFCGAL/Exception.h>
+#include <SFCGAL/Grid.h>
+#include <SFCGAL/io/asc.h>
+#include <SFCGAL/io/osg.h>
+
+using namespace SFCGAL ;
+
+int main( int argc, char* argv[] ){
+ if ( argc < 3 ){
+ std::cout << "asc2wkt <input-file> <output-file> [-no-zero]" << std::endl ;
+ return 1 ;
+ }
+
+ std::string inputFile( argv[1] );
+ std::string outputFile( argv[2] );
+
+ std::ifstream ifs( argv[1] );
+ if ( ! ifs.good() ){
+ std::cerr << "can't open input file ('" << argv[1] << "')" << std::endl;
+ return 1 ;
+ }
+
+ bool filterZeros = false ;
+ for ( int i = 1; i < argc; i++ ){
+ if ( std::string("-no-zero") == argv[i] ){
+ filterZeros = true ;
+ }
+ }
+
+
+ try {
+ std::cout << "-- loading grid" << std::endl ;
+ std::auto_ptr< Grid > grid( io::readASC( ifs ) );
+
+ if ( filterZeros ){
+ std::cout << "-- filtering zeros" << std::endl ;
+ for ( size_t i = 0; i < grid->nrows(); i++ ){
+ for ( size_t j = 0; j < grid->ncols(); j++ ){
+ if ( abs(grid->z(i,j)) == 0.0 ){
+ grid->z(i,j) = NaN() ;
+ }
+ }
+ }
+ }
+
+ std::cout << "-- triangulate grid" << std::endl ;
+ std::auto_ptr< TriangulatedSurface > triangulatedSurface( grid->toTrianguledSurface() );
+ std::cout << "-- save with osg" << std::endl ;
+ io::osgWriteFile( *triangulatedSurface, outputFile );
+
+ } catch ( Exception & e ){
+ std::cerr << e.diagnostic() << std::endl ;
+ return 1 ;
+ } catch ( std::exception& e ){
+ std::cerr << e.what() << std::endl ;
+ return 1 ;
+ }
+
+
+ return 0 ;
+}
diff --git a/example/SFCGAL-building/CMakeLists.txt b/example/SFCGAL-building/CMakeLists.txt
new file mode 100644
index 0000000..1e225f3
--- /dev/null
+++ b/example/SFCGAL-building/CMakeLists.txt
@@ -0,0 +1,18 @@
+GET_FILENAME_COMPONENT( EXAMPLE_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME )
+add_executable( example-${EXAMPLE_NAME}
+ main.cpp
+)
+target_link_libraries( example-${EXAMPLE_NAME}
+ SFCGAL
+ ${CGAL_LIBRARIES}
+ ${MPFR_LIBRARIES}
+ ${GMP_LIBRARIES}
+ ${Boost_LIBRARIES}
+)
+if(SFCGAL_WITH_OSG)
+ target_link_libraries( example-${EXAMPLE_NAME}
+ ${OPENSCENEGRAPH_LIBRARIES}
+ )
+endif()
+set_target_properties( example-${EXAMPLE_NAME} PROPERTIES DEBUG_POSTFIX "d" )
+install( TARGETS example-${EXAMPLE_NAME} DESTINATION bin )
\ No newline at end of file
diff --git a/example/SFCGAL-building/data-sample.wkt b/example/SFCGAL-building/data-sample.wkt
new file mode 100644
index 0000000..0d741c3
--- /dev/null
+++ b/example/SFCGAL-building/data-sample.wkt
@@ -0,0 +1,3 @@
+POLYGON((20 20,30 20,30 30,20 30,20 20))|10.0|1.0
+POLYGON((0 0,10 0,10 5,0 5,0 0),(1 1,6 1,6 4,1 4,1 1))|5.0|1.0
+POLYGON((50 50,70 50,70 70,60 70,60 60,50 60,50 50))|5.0|0.40
diff --git a/example/SFCGAL-building/main.cpp b/example/SFCGAL-building/main.cpp
new file mode 100644
index 0000000..573112a
--- /dev/null
+++ b/example/SFCGAL-building/main.cpp
@@ -0,0 +1,123 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+#include <boost/lexical_cast.hpp>
+
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/Exception.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/detail/generator/building.h>
+
+// optional osg support for outputs
+#include <SFCGAL/io/osg.h>
+
+using namespace SFCGAL ;
+
+
+
+class InputData {
+public:
+ InputData( const std::string & wkt_ = "", double wallHeight_ = 5.0, double roofSlope_ = 1.0 ):
+ wkt(wkt_),
+ roofSlope(roofSlope_),
+ wallHeight(wallHeight_)
+ {
+
+ }
+public:
+ std::string wkt ;
+ double roofSlope ;
+ double wallHeight ;
+};
+
+
+/**
+ * @brief read input file
+ */
+std::vector< InputData > readInputFile( const std::string & filename ){
+ std::vector< InputData > result ;
+
+ std::ifstream ifs(filename.c_str());
+ if ( ! ifs.good() ){
+ BOOST_THROW_EXCEPTION( Exception("can't open file") );
+ return result ;
+ }
+
+ std::string line ;
+ while ( std::getline(ifs,line) ){
+ std::istringstream iss( line );
+
+ std::string wkt ;
+ std::string wallHeight = "10.0" ;
+ std::string roofSlope = "1.0" ;
+
+ std::getline( iss, wkt, '|' ) && std::getline( iss, wallHeight, '|' ) && std::getline( iss, roofSlope, '|' ) ;
+ if ( ! wkt.empty() ){
+ result.push_back(
+ InputData(
+ wkt,
+ boost::lexical_cast< double >( wallHeight ),
+ boost::lexical_cast< double >( roofSlope )
+ )
+ );
+ }
+ }
+ ifs.close();
+ return result ;
+}
+
+void processFile( const std::string & filename ){
+ std::vector< InputData > data = readInputFile(filename);
+
+ std::auto_ptr< GeometryCollection > result( new GeometryCollection() );
+
+ std::cout << "#" << data.size() << std::endl;
+ for ( size_t i = 0; i < data.size(); i++ ){
+ std::auto_ptr< Geometry > g( io::readWkt( data[i].wkt ) );
+ std::auto_ptr< Geometry > building( generator::building( *g, data[i].wallHeight, data[i].roofSlope ) ) ;
+ result->addGeometry( building.release() );
+ }
+
+ io::osgWriteFile( *result, "building.osg" );
+}
+
+
+
+int main( int argc, char* argv[] ){
+ if ( argc < 2 ){
+ std::cerr << "usage : SFCGAL-building <input-file>" << std::endl ;
+ std::cerr << "file format : " << std::endl;
+ std::cerr << "<wkt(polygon|multipolygon)|wallHeight>|<roofSlope>" << std::endl;
+ return 0 ;
+ }
+
+ try {
+ processFile( argv[1] ) ;
+ return 0 ;
+ }catch( Exception & e ){
+ std::cerr << e.diagnostic() << std::endl;
+ return 1;
+ }
+
+ return 0 ;
+}
diff --git a/example/SFCGAL-export-osg/CMakeLists.txt b/example/SFCGAL-export-osg/CMakeLists.txt
new file mode 100644
index 0000000..94afac2
--- /dev/null
+++ b/example/SFCGAL-export-osg/CMakeLists.txt
@@ -0,0 +1,14 @@
+GET_FILENAME_COMPONENT( EXAMPLE_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME )
+add_executable( example-${EXAMPLE_NAME}
+ main.cpp
+)
+target_link_libraries( example-${EXAMPLE_NAME}
+ SFCGAL
+ ${CGAL_LIBRARIES}
+ ${MPFR_LIBRARIES}
+ ${GMP_LIBRARIES}
+ ${OPENSCENEGRAPH_LIBRARIES}
+ ${Boost_LIBRARIES}
+)
+set_target_properties( example-${EXAMPLE_NAME} PROPERTIES DEBUG_POSTFIX "d" )
+install( TARGETS example-${EXAMPLE_NAME} DESTINATION bin )
\ No newline at end of file
diff --git a/example/SFCGAL-export-osg/main.cpp b/example/SFCGAL-export-osg/main.cpp
new file mode 100644
index 0000000..52e380e
--- /dev/null
+++ b/example/SFCGAL-export-osg/main.cpp
@@ -0,0 +1,76 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <iostream>
+
+#include <SFCGAL/io/wkt.h>
+
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/algorithm/translate.h>
+#include <SFCGAL/algorithm/offset.h>
+#include <SFCGAL/algorithm/extrude.h>
+
+#include <SFCGAL/detail/io/OsgFactory.h>
+
+
+
+#include <osg/Geometry>
+#include <osg/Group>
+#include <osg/Geode>
+
+#include <osgDB/WriteFile>
+
+using namespace SFCGAL ;
+
+int main(){
+ detail::io::OsgFactory factory ;
+ std::auto_ptr< Geometry > g( io::readWkt("MULTILINESTRING((-2.705287 -6.782348, -2.052957 -4.368728, -0.356900 -3.912097, 0.980376 -4.857975, 1.339158 -5.966935, 0.328047 -7.043280, -1.987724 -8.706720, -1.922491 -10.076613, -1.726792 -11.087724, 0.882527 -12.457616, 3.491846 -12.490233, 4.242025 -11.120341, 3.720161 -9.489516, 2.480735 -9.098118, -0.519982 -9.130735, -0.291667 -8.413172, 0.915143 -7.075896, 1.958871 -6.619265, 3.883244 -6.358333, 5.677151 -6.651882, 6.231631 -7.238978, [...]
+
+ osg::ref_ptr< osg::Group > root = new osg::Group ;
+
+ // save base
+ {
+ osg::Geometry * osgGeometry = factory.createGeometry( *g );
+ osg::Geode* geode = new osg::Geode;
+ geode->setName( "base" );
+ geode->addDrawable( osgGeometry );
+ root->addChild( geode );
+ }
+
+ //buffer & extrude
+ {
+ double radius = 0.7 ;
+ std::auto_ptr< MultiPolygon > buffer( algorithm::offset( *g, radius ) );
+ algorithm::translate( *buffer, Kernel::Vector_3( 0.0, 0.0, radius ) );
+
+ std::auto_ptr< Geometry > extruded( algorithm::extrude(*buffer,3.0,3.0,3.0) );
+
+ osg::Geometry * osgGeometry = factory.createGeometry( *extruded );
+ osg::Geode* geode = new osg::Geode;
+ geode->setName( "extruded" );
+ geode->addDrawable( osgGeometry );
+
+ root->addChild( geode );
+ }
+
+
+ osgDB::writeNodeFile( *root, "SFCGAL-export-osg.3ds" ) ;
+ osgDB::writeNodeFile( *root, "SFCGAL-export-osg.osg" ) ;
+ return 0 ;
+}
diff --git a/example/SFCGAL-offset/CMakeLists.txt b/example/SFCGAL-offset/CMakeLists.txt
new file mode 100644
index 0000000..e429356
--- /dev/null
+++ b/example/SFCGAL-offset/CMakeLists.txt
@@ -0,0 +1,13 @@
+GET_FILENAME_COMPONENT( EXAMPLE_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME )
+add_executable( example-${EXAMPLE_NAME}
+ main.cpp
+)
+target_link_libraries( example-${EXAMPLE_NAME}
+ SFCGAL
+ ${CGAL_LIBRARIES}
+ ${MPFR_LIBRARIES}
+ ${GMP_LIBRARIES}
+ ${Boost_LIBRARIES}
+)
+set_target_properties( example-${EXAMPLE_NAME} PROPERTIES DEBUG_POSTFIX "d" )
+install( TARGETS example-${EXAMPLE_NAME} DESTINATION bin )
\ No newline at end of file
diff --git a/example/SFCGAL-offset/main.cpp b/example/SFCGAL-offset/main.cpp
new file mode 100644
index 0000000..1eb3c7d
--- /dev/null
+++ b/example/SFCGAL-offset/main.cpp
@@ -0,0 +1,36 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <SFCGAL/MultiPolygon.h>
+
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/offset.h>
+
+using namespace SFCGAL ;
+
+int main(){
+ std::auto_ptr< Geometry > g( io::readWkt("MULTIPOINT(0 0,5 6,3 2,7 1,4 1,3 5,2 9)") );
+
+ for ( size_t i = 1; i <= 50; i++ ){
+ std::auto_ptr< Geometry > buffer( algorithm::offset( *g, 0.2*i ) );
+ std::cout << buffer->asText(5) << std::endl ;
+ }
+
+ return 0 ;
+}
diff --git a/patches/CGAL-4.2/CGAL/Intersections_2/Triangle_2_Triangle_2_intersection_impl.h b/patches/CGAL-4.2/CGAL/Intersections_2/Triangle_2_Triangle_2_intersection_impl.h
new file mode 100644
index 0000000..8005bac
--- /dev/null
+++ b/patches/CGAL-4.2/CGAL/Intersections_2/Triangle_2_Triangle_2_intersection_impl.h
@@ -0,0 +1,354 @@
+// Copyright (c) 2000
+// Utrecht University (The Netherlands),
+// ETH Zurich (Switzerland),
+// INRIA Sophia-Antipolis (France),
+// Max-Planck-Institute Saarbruecken (Germany),
+// and Tel-Aviv University (Israel). All rights reserved.
+//
+// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 3 of the License,
+// or (at your option) any later version.
+//
+// Licensees holding a valid commercial license may use this file in
+// accordance with the commercial license agreement provided with the software.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/releases/CGAL-4.1-branch/Intersections_2/include/CGAL/Intersections_2/Triangle_2_Triangle_2_intersection_impl.h $
+// $Id: Triangle_2_Triangle_2_intersection_impl.h 71169 2012-08-10 13:34:02Z lrineau $
+//
+//
+// Author(s) : Geert-Jan Giezeman
+
+#include <CGAL/Segment_2.h>
+#include <CGAL/Triangle_2.h>
+#include <CGAL/Line_2.h>
+#include <CGAL/kernel_assertions.h>
+#include <CGAL/number_utils.h>
+#include <vector>
+
+#include <CGAL/Line_2_Line_2_intersection.h>
+
+namespace CGAL {
+
+namespace internal {
+
+template <class K>
+struct Pointlist_2_rec_ {
+ Pointlist_2_rec_ *next;
+ typename K::Point_2 point;
+ Oriented_side side;
+};
+
+template <class K>
+struct Pointlist_2_ {
+ int size;
+ Pointlist_2_rec_<K> *first;
+ Pointlist_2_() ;
+ ~Pointlist_2_() ;
+};
+
+
+
+template <class K>
+Pointlist_2_<K>::Pointlist_2_()
+{
+ size = 0;
+ first = 0;
+}
+
+template <class K>
+Pointlist_2_<K>::~Pointlist_2_()
+{
+ Pointlist_2_rec_<K> *cur;
+ for (int i=0; i<size; i++) {
+ cur = first;
+ first = cur->next;
+ delete cur;
+ }
+}
+
+
+
+
+template <class K>
+void _init_list(Pointlist_2_<K> &list,
+ const typename K::Triangle_2 &trian)
+{
+ // check on degeneracies of trian.
+ if (!trian.is_degenerate()) {
+ list.size = 3;
+ list.first = 0;
+ for (int i=0; i<3; i++) {
+ Pointlist_2_rec_<K> *newrec =
+ new Pointlist_2_rec_<K>;
+ newrec->next = list.first;
+ list.first = newrec;
+ newrec->point = trian[i];
+ }
+ } else {
+ // _not_implemented();
+ CGAL_kernel_assertion(false);
+ }
+}
+
+
+
+template <class K>
+void _cut_off(Pointlist_2_<K> &list,
+ const typename K::Line_2 &cutter)
+{
+ int i;
+ int add = 0;
+ const int sz = list.size;
+ Pointlist_2_rec_<K> *cur, *last=0, *newrec;
+ for (i=0, cur = list.first; i<sz; i++, cur = cur->next) {
+ cur->side = cutter.oriented_side(cur->point);
+ last = cur;
+ }
+ for (cur = list.first, i=0; i<sz; i++, cur = cur->next) {
+ if ((cur->side == ON_POSITIVE_SIDE
+ && last->side == ON_NEGATIVE_SIDE)
+ || (cur->side == ON_NEGATIVE_SIDE
+ && last->side == ON_POSITIVE_SIDE)) {
+ // add a vertex after cur
+ add++;
+ typename K::Line_2 l(cur->point, last->point);
+ list.size++;
+ newrec = new Pointlist_2_rec_<K>;
+ newrec->next = last->next;
+ last->next = newrec;
+ newrec->side = ON_ORIENTED_BOUNDARY;
+ Line_2_Line_2_pair<K> linepair(&cutter, &l);
+ CGAL_kernel_assertion_code(typename Line_2_Line_2_pair<K>::Intersection_results isr =)
+ linepair.intersection_type();
+ CGAL_kernel_assertion(isr == Line_2_Line_2_pair<K>::POINT);
+ newrec->point = linepair.intersection_point();
+ }
+ last = cur;
+ }
+ CGAL_kernel_assertion(add <= 2);
+ Pointlist_2_rec_<K> **curpt;
+ curpt = &list.first;
+ while (*curpt != 0) {
+ cur = *curpt;
+ if (cur->side == ON_NEGATIVE_SIDE) {
+ add--;
+ list.size--;
+ *curpt = cur->next;
+ delete cur;
+ } else {
+ curpt = &cur->next;
+ }
+ }
+ if (sz == 2 && add == 1) {
+ cur = list.first;
+ if (cur->side == ON_ORIENTED_BOUNDARY) {
+ list.size--;
+ list.first = cur->next;
+ delete cur;
+ } else {
+ list.size--;
+ last = cur;
+ cur = cur->next;
+ last->next = cur->next;
+ delete cur;
+ }
+ }
+}
+
+
+template <class K>
+class Triangle_2_Triangle_2_pair {
+public:
+ enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT, TRIANGLE, POLYGON};
+ Triangle_2_Triangle_2_pair(typename K::Triangle_2 const *trian1,
+ typename K::Triangle_2 const *trian2)
+ : _trian1(trian1), _trian2(trian2), _known(false) {}
+
+ Intersection_results intersection_type() const;
+
+ typename K::Point_2 intersection_point() const;
+ typename K::Segment_2 intersection_segment() const;
+ typename K::Triangle_2 intersection_triangle() const;
+ bool intersection(/*Polygon_2<R> &result*/) const;
+ int vertex_count() const;
+ typename K::Point_2 vertex(int i) const;
+protected:
+ typename K::Triangle_2 const* _trian1;
+ typename K::Triangle_2 const * _trian2;
+ mutable bool _known;
+ mutable Intersection_results _result;
+ mutable Pointlist_2_<K> _pointlist;
+};
+
+template <class K>
+typename Triangle_2_Triangle_2_pair<K>::Intersection_results
+Triangle_2_Triangle_2_pair<K>::intersection_type() const
+{
+ typedef typename K::Line_2 Line_2;
+ if (_known)
+ return _result;
+// The non const this pointer is used to cast away const.
+ _known = true;
+ if (!do_overlap(_trian1->bbox(), _trian2->bbox())) {
+ _result = NO_INTERSECTION;
+ return _result;
+ }
+ _init_list(_pointlist, *_trian1);
+ if (_trian2->is_degenerate()) {
+ // _not_implemented();
+ CGAL_kernel_assertion(false);
+ } else {
+ Line_2 l(_trian2->vertex(0), _trian2->vertex(1));
+ if (l.oriented_side(_trian2->vertex(2)) == ON_POSITIVE_SIDE) {
+ // counterclockwise triangle
+ _cut_off(_pointlist, l);
+ l = Line_2(_trian2->vertex(1), _trian2->vertex(2));
+ _cut_off(_pointlist, l);
+ l = Line_2(_trian2->vertex(2), _trian2->vertex(0));
+ _cut_off(_pointlist, l);
+ } else {
+ l = l.opposite();
+ _cut_off(_pointlist, l);
+ l = Line_2(_trian2->vertex(0), _trian2->vertex(2));
+ _cut_off(_pointlist, l);
+ l = Line_2(_trian2->vertex(2), _trian2->vertex(1));
+ _cut_off(_pointlist, l);
+ }
+ }
+ switch (_pointlist.size) {
+ case 0:
+ _result = NO_INTERSECTION;
+ break;
+ case 1:
+ _result = POINT;
+ break;
+ case 2:
+ _result = SEGMENT;
+ break;
+ case 3:
+ _result = TRIANGLE;
+ break;
+ default:
+ _result = POLYGON;
+ }
+ return _result;
+}
+
+
+template <class K>
+bool
+Triangle_2_Triangle_2_pair<K>::intersection(
+ /* Polygon_2<R> &result */) const
+{
+ if (!_known)
+ intersection_type();
+ if (_result != TRIANGLE && _result != POLYGON)
+ return false;
+ Pointlist_2_rec_<K> *cur;
+ int i;
+ for (i=0, cur = _pointlist.first;
+ i<_pointlist.size;
+ i++, cur = cur->next) {
+ std::cout << to_double(cur->point.x()) << ' ';
+ std::cout << to_double(cur->point.y()) << ' ';
+ }
+ std::cout << std::endl;
+ return true;
+}
+
+template <class K>
+int
+Triangle_2_Triangle_2_pair<K>::vertex_count() const
+{
+ CGAL_kernel_assertion(_known);
+ return _pointlist.size;
+}
+
+template <class K>
+typename K::Point_2
+Triangle_2_Triangle_2_pair<K>::vertex(int n) const
+{
+ CGAL_kernel_assertion(_known);
+ CGAL_kernel_assertion(n >= 0 && n < _pointlist.size);
+ Pointlist_2_rec_<K> *cur;
+ int k;
+ for (k=0, cur = _pointlist.first;
+ k < n;
+ k++, cur = cur->next) {
+ }
+ return cur->point;
+}
+
+template <class K>
+typename K::Triangle_2
+Triangle_2_Triangle_2_pair<K>::intersection_triangle() const
+{
+ typedef typename K::Triangle_2 Triangle_2;
+ if (!_known)
+ intersection_type();
+ CGAL_kernel_assertion(_result == TRIANGLE);
+ return Triangle_2(_pointlist.first->point,
+ _pointlist.first->next->point,
+ _pointlist.first->next->next->point);
+}
+
+template <class K>
+typename K::Segment_2
+Triangle_2_Triangle_2_pair<K>::intersection_segment() const
+{
+ typedef typename K::Segment_2 Segment_2;
+ if (!_known)
+ intersection_type();
+ CGAL_kernel_assertion(_result == SEGMENT);
+ return Segment_2(_pointlist.first->point,
+ _pointlist.first->next->point);
+}
+
+template <class K>
+typename K::Point_2
+Triangle_2_Triangle_2_pair<K>::intersection_point() const
+{
+ if (!_known)
+ intersection_type();
+ CGAL_kernel_assertion(_result == POINT);
+ return _pointlist.first->point;
+}
+
+
+
+template <class K>
+Object
+intersection(const typename K::Triangle_2 &tr1,
+ const typename K::Triangle_2 &tr2,
+ const K&)
+{
+ typedef Triangle_2_Triangle_2_pair<K> is_t;
+ is_t ispair(&tr1, &tr2);
+ switch (ispair.intersection_type()) {
+ case is_t::NO_INTERSECTION:
+ default:
+ return Object();
+ case is_t::POINT:
+ return make_object(ispair.intersection_point());
+ case is_t::SEGMENT:
+ return make_object(ispair.intersection_segment());
+ case is_t::TRIANGLE:
+ return make_object(ispair.intersection_triangle());
+ case is_t::POLYGON: {
+ typedef std::vector<typename K::Point_2> Container;
+ Container points(ispair.vertex_count());
+ for (int i =0; i < ispair.vertex_count(); i++) {
+ points[i] = ispair.vertex(i);
+ }
+ return make_object(points);
+ }
+ }
+}
+
+} // namespace internal
+
+} //namespace CGAL
diff --git a/patches/CGAL-4.2/CGAL/Point_inside_polyhedron_3.h b/patches/CGAL-4.2/CGAL/Point_inside_polyhedron_3.h
new file mode 100644
index 0000000..5b9da2d
--- /dev/null
+++ b/patches/CGAL-4.2/CGAL/Point_inside_polyhedron_3.h
@@ -0,0 +1,191 @@
+// Copyright (c) 2013 GeometryFactory (France).
+// All rights reserved.
+//
+// This file is part of CGAL (www.cgal.org).
+// You can redistribute it and/or modify it under the terms of the GNU
+// General Public License as published by the Free Software Foundation,
+// either version 3 of the License, or (at your option) any later version.
+//
+// Licensees holding a valid commercial license may use this file in
+// accordance with the commercial license agreement provided with the software.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $URL$
+// $Id$
+//
+//
+// Author(s) : Sebastien Loriot and Ilker O. Yaz
+
+
+#ifndef CGAL_POINT_INSIDE_POLYHEDRON_H
+#define CGAL_POINT_INSIDE_POLYHEDRON_H
+
+#include <CGAL/internal/Operations_on_polyhedra/Ray_3_Triangle_3_traversal_traits.h>
+#include <CGAL/internal/Operations_on_polyhedra/AABB_triangle_accessor_3_primitive.h>
+
+#include <CGAL/AABB_tree.h>
+#include <CGAL/AABB_traits.h>
+#include <CGAL/point_generators_3.h>
+#include <CGAL/Triangle_accessor_3.h>
+
+#include <boost/optional.hpp>
+
+namespace CGAL {
+
+/**
+ * This class provides an efficient point location functionality with respect to a domain bounded
+ * by one or several disjoint triangulated closed polyhedral (manifold) surfaces.
+ * In case several polyhedral surface are provided as input, a point is said to be inside the domain
+ * if an odd number of surfaces is crossed when walking from infinity to the point.
+ * The implementation is based on an AABB-tree.
+ * @tparam Polyhedron a triangulated polyhedral surface
+ * @tparam Kernel a \cgal kernel
+ * @tparam TriangleAccessor a model of the concept `TriangleAccessor_3`, with `TriangleAccessor_3::Triangle_3` being `Kernel::Triangle_3`.
+ * If `Polyhedron` is a \cgal Polyhedron, a default is provided.
+ * \todo Doc: move the concept `TriangleAccessor_3` into the "Operation on Polyhedra" package
+ * \todo Code: Use this class as an implementation detail of Mesh_3's Polyhedral_mesh_domain_3
+ * \todo Code: current version puts all polyhedra under one AABB, more proper approach might be using separate AABB for each polyhedron
+ * and filtering query point with bboxes of polyhedra...
+ */
+template <class Polyhedron,
+ class Kernel,
+ class TriangleAccessor_3 = Triangle_accessor_3<Polyhedron, typename Polyhedron::Traits>
+>
+class Point_inside_polyhedron_3{
+ // typedefs
+ typedef CGAL::internal::AABB_triangle_accessor_3_primitive<Kernel, TriangleAccessor_3> Primitive;
+ typedef CGAL::AABB_traits<Kernel, Primitive> Traits;
+ typedef typename Traits::Bounding_box Bounding_box;
+ typedef CGAL::AABB_tree<Traits> Tree;
+ typedef typename Kernel::Point_3 Point;
+ typedef typename Kernel::Ray_3 Ray;
+ //members
+ typename Kernel::Construct_ray_3 ray_functor;
+ typename Kernel::Construct_vector_3 vector_functor;
+ Tree tree;
+
+ const static unsigned int seed = 1340818006;
+
+public:
+ /**
+ * Default constructor. The domain is considered to be empty.
+ */
+ Point_inside_polyhedron_3(const Kernel& kernel=Kernel())
+ : ray_functor(kernel.construct_ray_3_object()),
+ vector_functor(kernel.construct_vector_3_object())
+ { }
+
+ /**
+ * Constructor with one polyhedral surface. `polyhedron` must be closed and triangulated.
+ */
+ Point_inside_polyhedron_3(const Polyhedron& polyhedron, const Kernel& kernel=Kernel())
+ : ray_functor(kernel.construct_ray_3_object()),
+ vector_functor(kernel.construct_vector_3_object())
+ {
+ add_polyhedron(polyhedron);
+ }
+
+ /**
+ * Constructor with several polyhedral surfaces. All the polyhedral surfaces must be closed, triangulated and disjoint.
+ * \tparam InputIterator is an input iterator with `Polyhedron` or `cpp11::reference_wrapper<Polyhedron>` as value type.
+ */
+ template <class InputIterator>
+ Point_inside_polyhedron_3(InputIterator begin, InputIterator beyond, const Kernel& kernel=Kernel())
+ : ray_functor(kernel.construct_ray_3_object()),
+ vector_functor(kernel.construct_vector_3_object())
+ {
+ add_polyhedra(begin, beyond);
+ }
+
+ /**
+ * Builds internal AABB tree. Optional to call, since the tree is automatically built at the time of first query.
+ */
+ void build() { tree.build(); }
+
+ /**
+ * `polyhedron` is added as input
+ */
+ void add_polyhedron(const Polyhedron& polyhedron)
+ {
+ CGAL_assertion(polyhedron.is_pure_triangle());
+ CGAL_assertion(polyhedron.is_closed());
+
+ tree.insert(TriangleAccessor_3().triangles_begin(polyhedron),
+ TriangleAccessor_3().triangles_end(polyhedron));
+ }
+
+ /**
+ * The polyhedral surfaces in the range `[begin,beyond[` are added as input
+ * \tparam InputIterator is an input iterator with `Polyhedron` or `cpp11::reference_wrapper<Polyhedron>` as value type.
+ */
+ template<class InputIterator>
+ void add_polyhedra(InputIterator begin, InputIterator beyond)
+ {
+ for(; begin != beyond; ++begin) {
+ add_polyhedron(*begin);
+ }
+ }
+
+ /**
+ * Query function to determine point location.
+ * @return
+ * - CGAL::ON_BOUNDED_SIDE if the point is inside the polyhedron
+ * - CGAL::ON_BOUNDARY if the point is on polyhedron
+ * - CGAL::ON_UNBOUNDED_SIDE if the point is outside polyhedron
+ */
+ Bounded_side operator()(const Point& point) const
+ {
+ const Bounding_box& bbox = tree.bbox();
+
+ if( point.x() < bbox.xmin() || point.x() > bbox.xmax()
+ || point.y() < bbox.ymin() || point.y() > bbox.ymax()
+ || point.z() < bbox.zmin() || point.z() > bbox.zmax() )
+ {
+ return ON_UNBOUNDED_SIDE;
+ }
+
+ //the direction of the vertical ray depends on the position of the point in the bbox
+ //in order to limit the expected number of nodes visited.
+ Ray query = ray_functor(point, vector_functor(0,0,(2*point.z() < tree.bbox().zmax()+tree.bbox().zmin()?-1:1)));
+ boost::optional<Bounded_side> res = is_inside_ray_tree_traversal<Ray,true>(query);
+
+ if(!res) {
+ CGAL::Random rg(seed); // seed some value for make it easy to debug
+ Random_points_on_sphere_3<Point> random_point(1.,rg);
+
+ do { //retry with a random ray
+ query = ray_functor(point, vector_functor(CGAL::ORIGIN,*random_point++));
+ res = is_inside_ray_tree_traversal<Ray,false>(query);
+ } while (!res);
+ }
+ return *res;
+ }
+
+private:
+ template <class Query,bool ray_is_vertical>
+ boost::optional<Bounded_side>
+ is_inside_ray_tree_traversal(const Query& query) const
+ {
+ std::pair<boost::logic::tribool,std::size_t> status( boost::logic::tribool(boost::logic::indeterminate), 0);
+
+ internal::Ray_3_Triangle_3_traversal_traits<Traits,Kernel,Boolean_tag<ray_is_vertical> > traversal_traits(status);
+ tree.traversal(query, traversal_traits);
+
+ if ( !boost::logic::indeterminate(status.first) )
+ {
+ if (status.first) {
+ return (status.second&1) == 1 ? ON_BOUNDED_SIDE : ON_UNBOUNDED_SIDE;
+ }
+ //otherwise the point is on the facet
+ return ON_BOUNDARY;
+ }
+ return boost::optional<Bounded_side>(); // indeterminate
+ }
+
+};
+
+} // namespace CGAL
+
+#endif //CGAL_POINT_INSIDE_POLYHEDRON_H
diff --git a/patches/CGAL-4.2/CGAL/Triangle_3_Ray_3_do_intersect.h b/patches/CGAL-4.2/CGAL/Triangle_3_Ray_3_do_intersect.h
new file mode 100644
index 0000000..aa49549
--- /dev/null
+++ b/patches/CGAL-4.2/CGAL/Triangle_3_Ray_3_do_intersect.h
@@ -0,0 +1,401 @@
+// Copyright (c) 2003 INRIA Sophia-Antipolis (France).
+// All rights reserved.
+//
+// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 3 of the License,
+// or (at your option) any later version.
+//
+// Licensees holding a valid commercial license may use this file in
+// accordance with the commercial license agreement provided with the software.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $URL: svn+ssh://sloriot@scm.gforge.inria.fr/svn/cgal/branches/features/inside_polyhedron_test-GF/Intersections_3/include/CGAL/Triangle_3_Ray_3_do_intersect.h $
+// $Id: Triangle_3_Ray_3_do_intersect.h 68143 2012-03-22 11:08:05Z sloriot $
+//
+//
+// Author(s) : Philippe Guigue
+
+#ifndef CGAL_TRIANGLE_3_RAY_3_DO_INTERSECT_H
+#define CGAL_TRIANGLE_3_RAY_3_DO_INTERSECT_H
+
+namespace CGAL {
+
+namespace internal {
+
+namespace R3T3_intersection{
+ enum type {COPLANAR_RAY=3,ENDPOINT_IN_TRIANGLE=4,CROSS_SEGMENT=1,CROSS_VERTEX=2,CROSS_FACET=0};
+} //R3T3_intersection
+
+struct r3t3_do_intersect_empty_visitor{
+ typedef bool result_type;
+ result_type result(bool b){return b;}
+ void update(Orientation){}
+ void ray_coplanar(){}
+ void end_point_in_triangle(){}
+};
+
+struct r3t3_do_intersect_endpoint_position_visitor{
+ int m_intersection_type;
+ r3t3_do_intersect_endpoint_position_visitor():
+ m_intersection_type(0){}
+ typedef std::pair<bool,R3T3_intersection::type> result_type;
+ result_type result(bool b){
+ CGAL_assertion(m_intersection_type>-1 && m_intersection_type<5);
+ return std::make_pair(b,enum_cast<R3T3_intersection::type>(m_intersection_type));
+ }
+ void update(Orientation orient)
+ {
+ if (orient==ZERO) ++m_intersection_type;
+ }
+ void ray_coplanar(){
+ m_intersection_type=3;
+ }
+ void end_point_in_triangle(){
+ m_intersection_type=4;
+ }
+};
+
+//the template parameter Visitor here is used to offer the posibility to use
+//r3t3_do_intersect_endpoint_position_visitor to track whether the endpoint of
+//the ray lies inside the plane of the triangle or not. It is used for example
+//in the function that checks whether a point is inside a polyhedron; if the ray
+//is on an edge of the triangle, we try with another random ray (as this case does not
+//happen often in practice).
+//By default an empty visitor is used to avoid penalizing the running time.
+
+template <class K,class Visitor>
+typename Visitor::result_type
+do_intersect_coplanar(const typename K::Triangle_3 &t,
+ const typename K::Ray_3 &r,
+ const K & k,
+ Visitor visitor);
+
+template <class K,class Visitor>
+typename Visitor::result_type
+ do_intersect(const typename K::Triangle_3 &t,
+ const typename K::Ray_3 &r,
+ const K & k,
+ Visitor visitor)
+{
+
+ CGAL_kernel_precondition( ! k.is_degenerate_3_object()(t) ) ;
+ CGAL_kernel_precondition( ! k.is_degenerate_3_object()(r) ) ;
+
+ typedef typename K::Point_3 Point_3;
+
+ typename K::Construct_vertex_3 vertex_on =
+ k.construct_vertex_3_object();
+
+ typename K::Orientation_3 orientation =
+ k.orientation_3_object();
+
+
+ const Point_3 & a = vertex_on(t,0);
+ const Point_3 & b = vertex_on(t,1);
+ const Point_3 & c = vertex_on(t,2);
+
+ typename K::Construct_vector_3 construct_vector =
+ k.construct_vector_3_object();
+
+ typename K::Construct_ray_3 construct_ray =
+ k.construct_ray_3_object();
+
+ typename K::Construct_point_on_3 point_on =
+ k.construct_point_on_3_object();
+
+ const Point_3 & p = point_on(r,0);
+ const Point_3 & q = point_on(r,1);
+
+
+ const Orientation ray_direction =
+ orientation(a,b,c,point_on(construct_ray(a, construct_vector(r)),1));
+
+ if (ray_direction == COPLANAR ) {
+ if (orientation(a,b,c,p) == COPLANAR)
+ return do_intersect_coplanar(t,r,k,visitor);
+ else return visitor.result(false);
+ }
+
+ const Orientation abcp = orientation(a,b,c,p);
+
+ switch ( abcp ) {
+ case POSITIVE:
+ switch ( ray_direction ) {
+ case POSITIVE:
+ // the ray lies in the positive open halfspaces defined by the
+ // triangle's supporting plane
+ return visitor.result(false);
+
+ case NEGATIVE:{
+ // The ray straddles the triangle's plane
+ // p sees the triangle in counterclockwise order
+ Orientation
+ orient=orientation(p,q,a,b);
+ if (orient == POSITIVE ) return visitor.result(false);
+ visitor.update(orient);
+ orient=orientation(p,q,b,c);
+ if (orient == POSITIVE ) return visitor.result(false);
+ visitor.update(orient);
+ orient=orientation(p,q,c,a);
+ if (orient == POSITIVE ) return visitor.result(false);
+ visitor.update(orient);
+ return visitor.result(true);
+ }
+ // case COPLANAR: should not happen
+ default: // should not happen.
+ CGAL_kernel_assertion(false);
+ return visitor.result(false);
+ }
+
+ case NEGATIVE:
+ switch ( ray_direction ) {
+ case POSITIVE:{
+ // The ray straddles the triangle's plane
+ // q sees the triangle in counterclockwise order
+ Orientation
+ orient=orientation(q,p,a,b);
+ if (orient == POSITIVE ) return visitor.result(false);
+ visitor.update(orient);
+ orient=orientation(q,p,b,c);
+ if (orient == POSITIVE ) return visitor.result(false);
+ visitor.update(orient);
+ orient=orientation(q,p,c,a);
+ if (orient == POSITIVE ) return visitor.result(false);
+ visitor.update(orient);
+ return visitor.result(true);
+
+ }
+ case NEGATIVE:
+ // the ray lies in the negative open halfspaces defined by the
+ // triangle's supporting plane
+ return visitor.result(false);
+
+ // case COPLANAR: should not happen
+
+ default: // should not happen.
+ CGAL_kernel_assertion(false);
+ return visitor.result(false);
+ }
+
+ case COPLANAR: // p belongs to the triangle's supporting plane
+ visitor.end_point_in_triangle();
+ switch ( ray_direction ) {
+ case POSITIVE:
+ // q sees the triangle in counterclockwise order
+ return visitor.result(
+ orientation(q,p,a,b) != POSITIVE
+ && orientation(q,p,b,c) != POSITIVE
+ && orientation(q,p,c,a) != POSITIVE);
+
+ case NEGATIVE:
+ // q sees the triangle in clockwise order
+ return visitor.result(
+ orientation(p,q,a,b) != POSITIVE
+ && orientation(p,q,b,c) != POSITIVE
+ && orientation(p,q,c,a) != POSITIVE);
+
+ // case COPLANAR: should not happen
+
+ default: // should not happen.
+ CGAL_kernel_assertion(false);
+ return visitor.result(false);
+ }
+
+ default: // should not happen.
+ CGAL_kernel_assertion(false);
+ return visitor.result(false);
+
+ }
+}
+
+template <class K>
+bool do_intersect(const typename K::Triangle_3 &t,
+ const typename K::Ray_3 &r,
+ const K & k)
+{
+ return do_intersect(t,r,k,r3t3_do_intersect_empty_visitor());
+}
+
+
+template <class K>
+inline
+bool do_intersect(const typename K::Ray_3 &r,
+ const typename K::Triangle_3 &t,
+ const K & k)
+{
+ return do_intersect(t,r, k);
+}
+
+
+template <class K,class Visitor>
+typename Visitor::result_type
+do_intersect_coplanar(const typename K::Triangle_3 &t,
+ const typename K::Ray_3 &r,
+ const K & k,
+ Visitor visitor)
+{
+ visitor.ray_coplanar();
+ CGAL_kernel_precondition( ! k.is_degenerate_3_object()(t) ) ;
+ CGAL_kernel_precondition( ! k.is_degenerate_3_object()(r) ) ;
+
+ typedef typename K::Point_3 Point_3;
+
+ typename K::Construct_point_on_3 point_on =
+ k.construct_point_on_3_object();
+
+ typename K::Construct_vertex_3 vertex_on =
+ k.construct_vertex_3_object();
+
+ typename K::Coplanar_orientation_3 coplanar_orientation =
+ k.coplanar_orientation_3_object();
+
+
+ const Point_3 & p = point_on(r,0);
+ const Point_3 & q = point_on(r,1);
+
+ const Point_3 & A = vertex_on(t,0);
+ const Point_3 & B = vertex_on(t,1);
+ const Point_3 & C = vertex_on(t,2);
+
+
+ const Point_3 * a = &A;
+ const Point_3 * b = &B;
+ const Point_3 * c = &C;
+ // Determine the orientation of the triangle in the common plane
+
+ if (coplanar_orientation(A,B,C) != POSITIVE)
+ {
+ // The triangle is not counterclockwise oriented
+ // swap two vertices.
+ b = &C;
+ c = &B;
+ }
+
+ // Test whether the ray's supporting line intersects the
+ // triangle in the common plane
+
+ const Orientation pqa = coplanar_orientation(p,q,*a);
+ const Orientation pqb = coplanar_orientation(p,q,*b);
+ const Orientation pqc = coplanar_orientation(p,q,*c);
+
+
+ switch ( pqa ) {
+ case POSITIVE:
+ switch ( pqb ) {
+ case POSITIVE:
+ if (pqc == POSITIVE)
+ // the triangle lies in the positive halfspace
+ // defined by the ray's supporting line.
+ return visitor.result(false);
+ // c is isolated on the negative side
+ return visitor.result( coplanar_orientation(*a,*c,p) != POSITIVE );
+
+ case NEGATIVE:
+ if (pqc == POSITIVE) // b is isolated on the negative side
+ return visitor.result( coplanar_orientation(*c,*b,p) != POSITIVE );
+ // a is isolated on the positive side
+ return visitor.result( coplanar_orientation(*a,*c,p) != POSITIVE );
+
+ case COLLINEAR:
+ if (pqc == POSITIVE) // b is isolated on the negative side
+ return visitor.result( coplanar_orientation(*c,*b,p) != POSITIVE );
+ // a is isolated on the positive side
+ return visitor.result( coplanar_orientation(*a,*c,p) != POSITIVE );
+
+ default: // should not happen.
+ CGAL_kernel_assertion(false);
+ return visitor.result(false);
+ }
+
+ case NEGATIVE:
+ switch ( pqb ) {
+ case POSITIVE:
+ if (pqc == POSITIVE) // a is isolated on the negative side
+ return visitor.result( coplanar_orientation(*b,*a,p) != POSITIVE );
+ // b is isolated on the positive side
+ return visitor.result( coplanar_orientation(*b,*a,p) != POSITIVE );
+
+ case NEGATIVE:
+ if (pqc == NEGATIVE)
+ // the triangle lies in the negative halfspace
+ // defined by the ray's supporting line.
+ return visitor.result( false );
+ // c is isolated on the positive side
+ return visitor.result( coplanar_orientation(*c,*b,p) != POSITIVE );
+ case COLLINEAR:
+ if (pqc == NEGATIVE) // b is isolated on the positive side
+ return visitor.result( coplanar_orientation(*b,*a,p) != POSITIVE );
+ // a is isolated on the negative side
+ return visitor.result( coplanar_orientation(*b,*a,p) != POSITIVE );
+
+ default: // should not happen.
+ CGAL_kernel_assertion(false);
+ return visitor.result(false);
+ }
+
+ case COLLINEAR:
+ switch ( pqb ) {
+ case POSITIVE:
+ if (pqc == POSITIVE) // a is isolated on the negative side
+ return visitor.result( coplanar_orientation(*b,*a,p) != POSITIVE );
+ // b is isolated on the positive side
+ return visitor.result( coplanar_orientation(*b,*a,p) != POSITIVE );
+ case NEGATIVE:
+ if (pqc == NEGATIVE) // a is isolated on the positive side
+ return visitor.result( coplanar_orientation(*a,*c,p) != POSITIVE );
+ // b is isolated on the negative side
+ return visitor.result( coplanar_orientation(*c,*b,p) != POSITIVE );
+
+ case COLLINEAR:
+ if (pqc == POSITIVE) // c is isolated on the positive side
+ return visitor.result( coplanar_orientation(*c,*b,p) != POSITIVE );
+ // c is isolated on the negative side
+ return visitor.result( coplanar_orientation(*a,*c,p) != POSITIVE );
+ // case pqc == COLLINEAR is imposiible
+
+ default: // should not happen.
+ CGAL_kernel_assertion(false);
+ return visitor.result(false);
+ }
+
+ default: // should not happen.
+ CGAL_kernel_assertion(false);
+ return visitor.result(false);
+ }
+}
+
+
+} // namespace internal
+
+
+template <class K>
+inline bool do_intersect(const Ray_3<K> &r,
+ const Triangle_3<K> &t)
+{
+ return typename K::Do_intersect_3()(t,r);
+}
+
+template <class K>
+inline bool do_intersect(const Triangle_3<K> &t,
+ const Ray_3<K> &r)
+{
+ return typename K::Do_intersect_3()(t,r);
+}
+
+
+/*
+template <class K>
+inline bool do_intersect(const Ray_3<K> &r,
+ const Triangle_3<K> &t,
+ const K & k )
+{
+ return internal::do_intersect(t,r,k);
+}
+*/
+
+} //namespace CGAL
+
+#endif // CGAL_TRIANGLE_3_RAY_3_DO_INTERSECT_H
diff --git a/patches/CGAL-4.2/CGAL/internal/Operations_on_polyhedra/AABB_triangle_accessor_3_primitive.h b/patches/CGAL-4.2/CGAL/internal/Operations_on_polyhedra/AABB_triangle_accessor_3_primitive.h
new file mode 100644
index 0000000..dc43799
--- /dev/null
+++ b/patches/CGAL-4.2/CGAL/internal/Operations_on_polyhedra/AABB_triangle_accessor_3_primitive.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2013 GeometryFactory (France).
+// All rights reserved.
+//
+// This file is part of CGAL (www.cgal.org).
+// You can redistribute it and/or modify it under the terms of the GNU
+// General Public License as published by the Free Software Foundation,
+// either version 3 of the License, or (at your option) any later version.
+//
+// Licensees holding a valid commercial license may use this file in
+// accordance with the commercial license agreement provided with the software.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $URL$
+// $Id$
+//
+//
+// Author(s) : Ilker O. Yaz
+
+#ifndef CGAL_POINT_INSIDE_POLYHEDRON_AABB_TRIANGLE_ACCESSOR_3_PRIMITIVE_H
+#define CGAL_POINT_INSIDE_POLYHEDRON_AABB_TRIANGLE_ACCESSOR_3_PRIMITIVE_H
+
+namespace CGAL {
+namespace internal {
+
+template<typename GeomTraits, typename TriangleAccessor_3>
+class AABB_triangle_accessor_3_primitive
+{
+public:
+ typedef typename GeomTraits::Point_3 Point;
+ typedef typename TriangleAccessor_3::Triangle_handle Id;
+ typedef typename GeomTraits::Triangle_3 Datum;
+
+ AABB_triangle_accessor_3_primitive(const Id& handle)
+ : m_triangle_handle(handle) { }
+
+ Datum datum() const { return TriangleAccessor_3().triangle(m_triangle_handle); }
+ Point reference_point() const { return datum().vertex(0); }
+
+ const Id& id() const { return m_triangle_handle; }
+ Id& id() { return m_triangle_handle; }
+
+private:
+ Id m_triangle_handle;
+};
+
+}// namespace internal
+}// namespace CGAL
+
+
+#endif // CGAL_POINT_INSIDE_POLYHEDRON_AABB_TRIANGLE_ACCESSOR_3_PRIMITIVE_H
diff --git a/patches/CGAL-4.2/CGAL/internal/Operations_on_polyhedra/Ray_3_Triangle_3_traversal_traits.h b/patches/CGAL-4.2/CGAL/internal/Operations_on_polyhedra/Ray_3_Triangle_3_traversal_traits.h
new file mode 100644
index 0000000..344899e
--- /dev/null
+++ b/patches/CGAL-4.2/CGAL/internal/Operations_on_polyhedra/Ray_3_Triangle_3_traversal_traits.h
@@ -0,0 +1,217 @@
+// Copyright (c) 2013 GeometryFactory (France).
+// All rights reserved.
+//
+// This file is part of CGAL (www.cgal.org).
+// You can redistribute it and/or modify it under the terms of the GNU
+// General Public License as published by the Free Software Foundation,
+// either version 3 of the License, or (at your option) any later version.
+//
+// Licensees holding a valid commercial license may use this file in
+// accordance with the commercial license agreement provided with the software.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $URL$
+// $Id$
+//
+//
+// Author(s) : Sebastien Loriot
+
+
+#ifndef CGAL_POINT_INSIDE_POLYHEDRON_RAY_3_TRIANGLE_3_TRAVERSAL_TRAITS_H
+#define CGAL_POINT_INSIDE_POLYHEDRON_RAY_3_TRIANGLE_3_TRAVERSAL_TRAITS_H
+
+#include <boost/logic/tribool.hpp>
+
+namespace CGAL {
+namespace internal {
+
+template<typename AABBTraits, class Kernel, class Tag_ray_is_vertical=Tag_false>
+class Ray_3_Triangle_3_traversal_traits
+{
+protected:
+ //the status indicates whether the query point is strictly inside the polyhedron, and the number of intersected triangles if yes
+ std::pair<boost::logic::tribool,std::size_t>& m_status;
+ bool m_stop;
+ typedef typename AABBTraits::Primitive Primitive;
+
+public:
+ Ray_3_Triangle_3_traversal_traits(std::pair<boost::logic::tribool,std::size_t>& status)
+ :m_status(status),m_stop(false)
+ {m_status.first=true;}
+
+ bool go_further() const { return !m_stop; }
+
+ template<class Query>
+ void intersection(const Query& query, const Primitive& primitive)
+ {
+ internal::r3t3_do_intersect_endpoint_position_visitor visitor;
+ std::pair<bool,internal::R3T3_intersection::type> res=
+ internal::do_intersect(primitive.datum(),query,Kernel(),visitor);
+
+ if (res.first){
+ switch (res.second){
+ case internal::R3T3_intersection::CROSS_FACET:
+ ++m_status.second;
+ break;
+ case internal::R3T3_intersection::ENDPOINT_IN_TRIANGLE:
+ m_status.first=false;
+ m_stop=true;
+ break;
+ default:
+ m_status.first=boost::logic::indeterminate;
+ m_stop=true;
+ }
+ }
+ }
+
+ template<class Query,class Node>
+ bool do_intersect(const Query& query, const Node& node) const
+ {
+ return AABBTraits().do_intersect_object()(query, node.bbox());
+ }
+};
+
+
+//specialization for vertical ray
+template<typename AABBTraits, class Kernel>
+class Ray_3_Triangle_3_traversal_traits<AABBTraits,Kernel,Tag_true>:
+ public Ray_3_Triangle_3_traversal_traits<AABBTraits,Kernel,Tag_false>
+{
+ typedef Ray_3_Triangle_3_traversal_traits<AABBTraits,Kernel,Tag_false> Base;
+ typedef typename Kernel::Point_3 Point;
+ typedef typename Base::Primitive Primitive;
+public:
+ Ray_3_Triangle_3_traversal_traits(std::pair<boost::logic::tribool,std::size_t>& status):Base(status){}
+
+ template <class Query>
+ bool do_intersect(const Query& query, const Bbox_3& bbox) const
+ {
+ const Point& source=query.point(0);
+ const Point& target=query.point(1);
+
+ bool inc_z=target.z()>source.z();
+
+ //the ray does not intersect the z-slab
+ if ( ( inc_z && source.z()>bbox.zmax() )|| (!inc_z && source.z()<bbox.zmin()) ) return false;
+
+ //the source is not in the x-slab
+ if (source.x() > bbox.xmax() || source.x()<bbox.xmin()) return false;
+ //check if the source is not in the y-slab
+ return source.y() <= bbox.ymax() && source.y()>=bbox.ymin();
+ }
+
+ template <class Query,class Node>
+ bool do_intersect(const Query& query, const Node& node) const
+ {
+ return do_intersect(query,node.bbox());
+ }
+
+private:
+ typename Kernel::Point_2 x_project(const typename Kernel::Point_3& p) const{
+ return typename Kernel::Point_2(p.y(),p.z());
+ }
+ typename Kernel::Point_2 y_project(const typename Kernel::Point_3& p) const{
+ return typename Kernel::Point_2(p.x(),p.z());
+ }
+ typename Kernel::Point_2 z_project(const typename Kernel::Point_3& p) const{
+ return typename Kernel::Point_2(p.x(),p.y());
+ }
+public:
+ template<class Query>
+ void intersection(const Query& query, const Primitive& primitive)
+ {
+ typename Kernel::Triangle_3 t=primitive.datum();
+ if ( !do_intersect(query,t.bbox()) ) return;
+
+ typename Kernel::Point_2 p0=z_project(t[0]);
+ typename Kernel::Point_2 p1=z_project(t[1]);
+ typename Kernel::Point_2 p2=z_project(t[2]);
+ int indices[3]={0,1,2}; //to track whether triangle points have been swapt
+ typename Kernel::Point_2 q=z_project( query.source() );
+
+ Orientation orient_2=orientation(p0,p1,p2);
+
+ //check whether the face has a normal vector in the xy-plane
+ if (orient_2==COLLINEAR){
+ //in that case the projection of the triangle along the z-axis is a segment.
+ const typename Kernel::Point_2& other_point = p0!=p1?p1:p2;
+ //~ if ( orientation(p0,other_point,q) != COLLINEAR ) return;///no intersection
+ if ( orientation(p0,other_point,q) != COLLINEAR ) return;///no intersection
+
+ //check if the ray source is above or below the triangle and compare it
+ //with the direction of the ray
+ //TODO and if yes return
+ //this is just an optimisation, the current code is valid
+
+ this->m_status.first=boost::logic::indeterminate;
+ this->m_stop=true;
+ return;
+ }
+
+
+ //regular case
+ if (orient_2==NEGATIVE){
+ std::swap(p1,p2);
+ std::swap(indices[1],indices[2]);
+ }
+
+ //check whether the ray intersect the supporting plane
+ Orientation orient_3 = orientation(t[indices[0]],t[indices[1]],t[indices[2]],query.source());
+ if ( orient_3!=COPLANAR &&
+ (
+ //indicates whether the ray is oriented toward the positive side of the plane
+ ( POSITIVE == sign( query.to_vector().z() ) )
+ ==
+ //indicates whether the source of the ray is in the positive side of the plane
+ (orient_3==POSITIVE)
+ )
+ ) return; //no intersection
+
+
+ //position against first segment
+ switch( orientation(p0,p1,q) ){
+ case COLLINEAR:
+ this->m_status.first=boost::logic::indeterminate;
+ this->m_stop=true;
+ case NEGATIVE:
+ return;
+ default:
+ {}
+ }
+ //position against second segment
+ switch( orientation(p1,p2,q) ){
+ case COLLINEAR:
+ this->m_status.first=boost::logic::indeterminate;
+ this->m_stop=true;
+ case NEGATIVE:
+ return;
+ default:
+ {}
+ }
+ //position against third segment
+ switch( orientation(p2,p0,q) ){
+ case COLLINEAR:
+ this->m_status.first=boost::logic::indeterminate;
+ this->m_stop=true;
+ case NEGATIVE:
+ return;
+ default:
+ {}
+ }
+
+ if (orient_3==COPLANAR){
+ //the endpoint is inside the triangle
+ this->m_status.first=false;
+ this->m_stop=true;
+ }
+ else
+ ++(this->m_status.second);
+ }
+};
+
+}// namespace internal
+}// namespace CGAL
+
+#endif
diff --git a/patches/CGAL-4.2/CGAL/intersection_of_Polyhedra_3_refinement_visitor.h b/patches/CGAL-4.2/CGAL/intersection_of_Polyhedra_3_refinement_visitor.h
new file mode 100644
index 0000000..3bb1e90
--- /dev/null
+++ b/patches/CGAL-4.2/CGAL/intersection_of_Polyhedra_3_refinement_visitor.h
@@ -0,0 +1,2193 @@
+// Copyright (c) 2011 GeometryFactory (France).
+// All rights reserved.
+//
+// This file is part of CGAL (www.cgal.org).
+// You can redistribute it and/or modify it under the terms of the GNU
+// General Public License as published by the Free Software Foundation,
+// either version 3 of the License, or (at your option) any later version.
+//
+// Licensees holding a valid commercial license may use this file in
+// accordance with the commercial license agreement provided with the software.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $UR$
+// $Id$
+//
+//
+// Author(s) : Sebastien Loriot
+
+#ifndef CGAL_INTERSECTION_OF_POLYHEDRA_3_REFINEMENT_VISITOR_H
+#define CGAL_INTERSECTION_OF_POLYHEDRA_3_REFINEMENT_VISITOR_H
+
+#include <CGAL/use.h>
+#include <CGAL/intersection_of_Polyhedra_3.h>
+#include <CGAL/internal/corefinement/Polyhedron_subset_extraction.h>
+#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+#include <CGAL/Constrained_Delaunay_triangulation_2.h>
+#include <CGAL/Triangulation_vertex_base_with_info_2.h>
+
+#include <CGAL/internal/corefinement/Combinatorial_map_for_corefinement.h>
+
+#include <CGAL/Point_inside_polyhedron_3.h>
+
+#include <boost/optional.hpp>
+#include <boost/next_prior.hpp>
+
+#include <fstream>
+#include <sstream>
+
+// TODOCUMENT
+// --We suppose that the two input polyhedra are triangulated orientable surfaces.
+// --Any polyhedron defines two bounding volumes: one inside and one outside.
+// The convention used is the following: the normal of a triangle always indicates
+// the outside of the object.
+// --The input polyhedra should not touch at only one point locally. If so, the current
+// implementation just ignore it (TAG SL001)
+// --Polyhedron type should be list-based or should guarantee no reallocation. We use maps
+// on pointer of halfedges,facets and vertices
+// --Polyhedral_mesh_domain requires the domain tp be closed: do not provided as input
+// an open polyhedral surface and a polyhedron with a connected component free from intersection
+//OPTIMIZATIONS
+// --cdt: try using intervals? in that case, only points inside the face should be considered
+// and points on edge should be handled by hand (simply start using the point opposite to the edge)
+// --filtered_order_around_edge: can be done using the original supporting planes
+// --in intersection_of_Polyhedra_3: upon call to Triangle_segment_intersection_point::add_new_node, interval and exact nodes are
+// inserted into a vector. Since we do not know the final size of vector this lead to reallocation of data.
+// --in Triangle_segment_intersection_point, try using EPEC instead of Interval_nt+SC<Gmpq>
+// --use a sorted pair of indices in edge_to_hedge+simplify the code TAG_SLXX1
+// --in sew_2_marked_darts arrange how darts are passed to avoid comparing to a Point_3
+//TODO:
+// --validity of the embedding: points inserted in polyhedron are approximation of the real
+// intersection points. It may happen that because of the approximation, the embedding gets
+// wrong. To avoid this, for each new triangle created, we should make an orientation test
+// with the approximated point to check if this is correct. If not, points must be moved
+// within their double interval so that all triangles incident to each of these points are correctly
+// oriented. This is probably an expensive test that can be activated only with a template parameter
+// of something similar.
+namespace CGAL
+{
+
+ namespace internal_IOP
+ {
+ template <class Polyhedron>
+ struct Compare_unik_address{
+ typedef typename Polyhedron::Halfedge_handle Halfedge_handle;
+ typedef typename Polyhedron::Halfedge_const_handle Halfedge_const_handle;
+ typedef typename Polyhedron::Halfedge Halfedge;
+
+ bool operator()(Halfedge_handle h1,Halfedge_handle h2) const {
+ Halfedge* ph1=&(*h1) < &(*h1->opposite()) ? &(*h1) : &(*h1->opposite());
+ Halfedge* ph2=&(*h2) < &(*h2->opposite()) ? &(*h2) : &(*h2->opposite());
+ return ph1 < ph2;
+ }
+
+ bool operator()(Halfedge_const_handle h1,Halfedge_const_handle h2) const {
+ const Halfedge* ph1=&(*h1) < &(*h1->opposite()) ? &(*h1) : &(*h1->opposite());
+ const Halfedge* ph2=&(*h2) < &(*h2->opposite()) ? &(*h2) : &(*h2->opposite());
+ return ph1 < ph2;
+ }
+ };
+
+ template <class Polyhedron>
+ struct Compare_address{
+ typedef typename Polyhedron::Halfedge_handle Halfedge_handle;
+ typedef typename Polyhedron::Halfedge_const_handle Halfedge_const_handle;
+ typedef typename Polyhedron::Halfedge Halfedge;
+
+ bool operator()(Halfedge_handle h1,Halfedge_handle h2) const {
+ return &(*h1) < &(*h2);
+ }
+
+ bool operator()(Halfedge_const_handle h1,Halfedge_const_handle h2) const {
+ return &(*h1) < &(*h2);
+ }
+ };
+
+ template <class Polyhedron>
+ class Non_intersection_halfedge{
+ typedef std::map< typename Polyhedron::Halfedge_const_handle,
+ std::pair<int,int>,
+ Compare_unik_address<Polyhedron>
+ > Intersection_hedges_set;
+ Intersection_hedges_set intersection_hedges_;
+ public:
+ Non_intersection_halfedge(const Intersection_hedges_set& the_set) : intersection_hedges_(the_set){}
+
+
+ bool operator()(typename Polyhedron::Halfedge_const_handle h) const
+ {
+ return intersection_hedges_.find(h)==intersection_hedges_.end();
+ }
+ };
+
+
+ template <class HDS>
+ class Triangulate_a_face : public CGAL::Modifier_base<HDS> {
+ typedef typename HDS::Halfedge_handle Halfedge_handle;
+ typedef typename HDS::Vertex_handle Vertex_handle;
+ typedef typename HDS::Face_handle Face_handle;
+ typedef typename HDS::Vertex Vertex;
+ typedef typename HDS::Halfedge Halfedge;
+ typedef typename HDS::Face Face;
+
+ //data members
+ Face_handle current_face;
+ std::map<int,typename Vertex::Point > nodes_;
+ std::map<int,Vertex_handle>& node_to_polyhedron_vertex_;
+ std::map<std::pair<int,int>,Halfedge_handle>& edge_to_hedge_;
+ std::vector<std::pair<int,int> > edges_to_create_;
+ std::vector<CGAL::cpp11::tuple<int,int,int> > faces_to_create_;
+
+ typename HDS::Halfedge::Base*
+ unlock_halfedge(Halfedge_handle h){
+ return static_cast<typename HDS::Halfedge::Base*>(&(*h));
+ }
+
+ typename HDS::Face::Base*
+ unlock_face(Face_handle f){
+ return static_cast<typename HDS::Face::Base*>(&(*f));
+ }
+
+ public:
+
+ template <class Nodes_vector,class Triangulation>
+ Triangulate_a_face( Face_handle face,
+ const Nodes_vector& nodes,
+ const std::vector<int>& node_ids,
+ std::map<int,Vertex_handle>& node_to_polyhedron_vertex,
+ std::map<std::pair<int,int>,Halfedge_handle>& edge_to_hedge,
+ const Triangulation& triangulation)
+ :current_face(face),node_to_polyhedron_vertex_(node_to_polyhedron_vertex),edge_to_hedge_(edge_to_hedge)
+ {
+ //grab vertices to be inserted to copy them from the vector
+ for (std::vector<int>::const_iterator it=node_ids.begin();it!=node_ids.end();++it)
+ {
+ nodes_.insert(std::make_pair(*it,nodes[*it]));
+ }
+ //grab edges that are not on the convex hull (these have already been created)
+ for (typename Triangulation::Finite_edges_iterator
+ it=triangulation.finite_edges_begin();
+ it!=triangulation.finite_edges_end();
+ ++it)
+ {
+ typename Triangulation::Vertex_handle v0=it->first->vertex((it->second+1)%3);
+ typename Triangulation::Vertex_handle v1=it->first->vertex((it->second+2)%3);
+ //warning in degenerate cases you can insert outsite expected convex hull edges: need exact here.
+ //an alternative is to test if one the incident faces are infinite (cf assertion below)
+ if ( edge_to_hedge_.find(std::make_pair(v0->info(),v1->info()))==edge_to_hedge_.end() &&
+ edge_to_hedge_.find(std::make_pair(v1->info(),v0->info()))==edge_to_hedge_.end() )
+ {
+ edges_to_create_.push_back( std::make_pair(v0->info(),v1->info()) );
+ }
+ else
+ CGAL_assertion( triangulation.is_infinite(it->first->vertex(it->second)) || triangulation.is_infinite( triangulation.mirror_vertex(it->first,it->second)) );
+ }
+ //grab triangles.
+ for (typename Triangulation::Finite_faces_iterator
+ it=triangulation.finite_faces_begin();
+ it!=triangulation.finite_faces_end();
+ ++it)
+ {
+ typename Triangulation::Vertex_handle v0=it->vertex(0);
+ typename Triangulation::Vertex_handle v1=it->vertex(1);
+ typename Triangulation::Vertex_handle v2=it->vertex(2);
+ //warning in degenerate case we can have non wanted triangles: need exact here
+ faces_to_create_.push_back( CGAL::cpp11::make_tuple( v0->info(),v1->info(),v2->info() ) );
+ }
+ }
+
+
+
+ void operator()( HDS& hds) {
+// std::cerr << "node_to_polyhedron_vertex_"<< std::endl;
+// for (typename std::map<int,Vertex_handle>::iterator it=node_to_polyhedron_vertex_.begin();it!=node_to_polyhedron_vertex_.end();++it)
+// std::cerr << it->first << " " << &(*(it->second)) << std::endl;
+
+ //insert the intersection point interior to the face inside the polyhedron and
+ //save their Polyhedron::vertex_handle
+ for (typename std::map<int,typename Vertex::Point>::iterator it=nodes_.begin();it!=nodes_.end();++it)
+ {
+ Vertex_handle v=hds.vertices_push_back(Vertex(it->second));
+ CGAL_assertion( node_to_polyhedron_vertex_.find( it->first ) == node_to_polyhedron_vertex_.end());
+ node_to_polyhedron_vertex_.insert( std::make_pair(it->first,v) );
+// std::cerr << "vertices " << it->first << " " << &(*v) << std::endl;
+ }
+
+ //insert the new halfedge and set their incident vertex
+ for (typename std::vector<std::pair<int,int> >::iterator
+ it=edges_to_create_.begin();it!=edges_to_create_.end();++it)
+ {
+ Halfedge_handle he=hds.edges_push_back(Halfedge(),Halfedge());
+
+ //associate edge <i,j> to halfedge going from i to j with j as incident vertex
+ CGAL_assertion(node_to_polyhedron_vertex_.find(it->second)!= node_to_polyhedron_vertex_.end());
+ Vertex_handle v=node_to_polyhedron_vertex_.find(it->second)->second;
+ unlock_halfedge(he)->set_vertex( v );
+ v->set_halfedge(he);
+// std::cerr << " --in edge " << &(*v) << std::endl;
+ edge_to_hedge_.insert( std::make_pair(*it,he) );
+ v=node_to_polyhedron_vertex_.find(it->first)->second;
+// std::cerr << " --in edge " << &(*v) << std::endl;
+ unlock_halfedge( he->opposite() )->set_vertex( v );
+ v->set_halfedge(he->opposite());
+ edge_to_hedge_.insert( std::make_pair(std::make_pair(it->second,it->first),he->opposite()) );
+// std::cerr << "edges " << it->first << " " << it->second << std::endl;
+ }
+
+ std::vector<CGAL::cpp11::tuple<int,int,int> >::iterator it=faces_to_create_.begin();
+
+ //create the new faces and update adjacencies
+ while (true)
+ {
+ int i=cpp11::get<0>(*it),j=cpp11::get<1>(*it),k=cpp11::get<2>(*it);
+// std::cerr << "faces " << i << " " << j << " " << k<< std::endl;
+ Halfedge_handle current = edge_to_hedge_.find(std::make_pair(i,j))->second;
+ Halfedge_handle next = edge_to_hedge_.find(std::make_pair(j,k))->second;
+ Halfedge_handle previous = edge_to_hedge_.find(std::make_pair(k,i))->second;
+
+
+ CGAL_assertion (edge_to_hedge_.find(std::make_pair(i,j))!=edge_to_hedge_.end());
+ CGAL_assertion (edge_to_hedge_.find(std::make_pair(j,k))!=edge_to_hedge_.end());
+ CGAL_assertion (edge_to_hedge_.find(std::make_pair(k,i))!=edge_to_hedge_.end());
+
+ CGAL_assertion(current->vertex()==node_to_polyhedron_vertex_.find(j)->second);
+ CGAL_assertion(next->vertex()==node_to_polyhedron_vertex_.find(k)->second);
+ CGAL_assertion(previous->vertex()==node_to_polyhedron_vertex_.find(i)->second);
+
+ unlock_halfedge(current)->set_next(next);
+ unlock_halfedge(next)->set_next(previous);
+ unlock_halfedge(previous)->set_next(current);
+
+ unlock_halfedge(current)->set_prev(previous);
+ unlock_halfedge(next)->set_prev(current);
+ unlock_halfedge(previous)->set_prev(next);
+
+ //update face halfedge
+ unlock_face(current_face)->set_halfedge(current);
+
+ //update face of halfedges
+ unlock_halfedge(current) ->set_face(current_face);
+ unlock_halfedge(next) ->set_face(current_face);
+ unlock_halfedge(previous) ->set_face(current_face);
+
+ if ( ++it!=faces_to_create_.end() )
+ current_face=hds.faces_push_back(Face());
+ else
+ break;
+ }
+ }
+ };
+
+ } //namespace internal_IOP
+
+
+//Considering the plane with normal vector [O_prime,O] and containing O.
+//We define the counterclockwise order around O when looking from the side of the plane
+//into which the vector [O_prime,O] is pointing.
+//We consider the portion of the plane defined by rotating a ray starting at O
+//from the planar projection of P1 to the planar projection of P2 in counterclockwise order.
+//The predicates indicates whether the planar projection of point Q lies in this portion of the plane.
+//Preconditions:
+// O_prime,O,P1 are not collinear
+// O_prime,O,P2 are not collinear
+// O_prime,O,Q are not collinear
+// O_prime,O,P1,Q are not coplanar or coplanar_orientation(O,O_prime,P1,Q)==NEGATIVE
+// O_prime,O,P2,Q are not coplanar or coplanar_orientation(O,O_prime,P2,Q)==NEGATIVE
+template <class Kernel>
+bool is_in_interior_of_object(
+ const typename Kernel::Point_3& O_prime,const typename Kernel::Point_3& O,
+ const typename Kernel::Point_3& P1,const typename Kernel::Point_3& P2,
+ const typename Kernel::Point_3& Q)
+{
+ //guarantee to have non-flat triangles
+ CGAL_precondition( !collinear(O_prime,O,P1) );
+ CGAL_precondition( !collinear(O_prime,O,P2) );
+ CGAL_precondition( !collinear(O_prime,O,Q) );
+
+ //no two triangles are coplanar and on the same side of their common edge
+ CGAL_precondition( !coplanar(O_prime,O,P1,Q) || coplanar_orientation(O,O_prime,P1,Q)==NEGATIVE );
+ CGAL_precondition( !coplanar(O_prime,O,P2,Q) || coplanar_orientation(O,O_prime,P2,Q)==NEGATIVE );
+
+ Sign s0 = sign( determinant(O-O_prime,P1-O,P2-O) );
+
+ if ( s0==ZERO ){
+ //O, O_prime, P1 and P2 are coplanar
+ Orientation o=orientation(O_prime,O,P1,Q);
+ CGAL_precondition(o!=COPLANAR);
+ return o==POSITIVE;
+ }
+
+ //O, O_prime, P1 and P2 are not coplanar
+ Sign s1 = sign( determinant(O-O_prime,P1-O,Q -O) );
+ Sign s2 = sign( determinant(O-O_prime,Q -O,P2-O) );
+
+ if (s0 == POSITIVE) // the angle P1,O,P2 is smaller that Pi.
+ return ( s1 == POSITIVE ) && ( s2 ==POSITIVE ); //true if the angles P1,O,Q and Q,O,P2 are smaller than Pi
+ else
+ return ( s1 != NEGATIVE ) || ( s2 != NEGATIVE ); //true if the angle P1,O,Q or the angle Q,O,P2 is smaller than or equal to Pi
+}
+
+//import into the combinatorial map facets in the given range.
+//they are supposed to be in the same connected component.
+//two volume are created (each facets gives two opposite orientation 2-cell in the map)
+template<class Polyhedron, class Map, class Face_iterator, class Non_special_edge_predicate,class Halfedge_to_dart_map_ >
+typename Map::Dart_handle import_from_polyhedron_subset( Map& amap,
+ Face_iterator faces_begin,
+ Face_iterator faces_end,
+ const Non_special_edge_predicate& is_non_special_edge,
+ Halfedge_to_dart_map_& selected_hedge_to_dart,
+ int mark_index
+ )
+{
+ typedef typename Polyhedron::Halfedge_const_handle Halfedge_const_handle;
+ typedef std::map < Halfedge_const_handle, typename Map::Dart_handle,internal_IOP::Compare_address<Polyhedron> > Halfedge_to_dart_map;
+
+ Halfedge_to_dart_map hedge_to_dart;
+ typename Map::Dart_handle first_dart = NULL;
+ // First traversal to build the darts and link them.
+ for (Face_iterator it_face = faces_begin; it_face != faces_end; ++it_face)
+ {
+ Halfedge_const_handle start=(*it_face)->halfedge();
+
+ CGAL_precondition(start->next()!=start);
+
+ Halfedge_const_handle current=start;
+ typename Map::Dart_handle prev = NULL;
+ typename Map::Dart_handle first_dart_of_face = NULL;
+ do
+ {
+ typename Map::Dart_handle d = amap.create_dart();
+ amap.template link_beta<3>(d,amap.create_dart()); //for opposite volume
+ hedge_to_dart[current] = d;
+
+ if (prev != NULL){
+ amap.template link_beta<1>(prev, d);
+ amap.template link_beta<1>(d->beta(3),prev->beta(3));//for opposite volume
+ }
+ else
+ {
+ first_dart_of_face = d;
+ if (first_dart==NULL) first_dart=d;
+ }
+
+ if ( is_non_special_edge (current) ){
+ if ( !current->is_border_edge() ){
+ CGAL_assertion(current != current->opposite());
+ typename Halfedge_to_dart_map::iterator it = hedge_to_dart.find(current->opposite());
+ if (it != hedge_to_dart.end()){ //link the opposites halfedges only when both corresponding darts have been created
+ amap.template link_beta<2>(d, it->second);
+ amap.template link_beta<2>(d->beta(3), it->second->beta(3));//for opposite volume
+ }
+ }
+ }
+ else{
+ typename Halfedge_to_dart_map_::iterator it_hedge_map=selected_hedge_to_dart.find(current);
+ //all marked hedges are not the selected one for its polyline
+ if ( it_hedge_map!=selected_hedge_to_dart.end() ) it_hedge_map->second=d;
+ //darts d and d->beta(3) are special edges
+ amap.mark(d,mark_index);
+ amap.mark(d->beta(3),mark_index);
+ }
+ prev = d;
+ current=current->next();
+ }
+ while (current != start);
+ amap.template link_beta<1>(prev, first_dart_of_face);
+ amap.template link_beta<1>(first_dart_of_face->beta(3),prev->beta(3));//for opposite volume
+ }
+
+ // Second traversal to update the geometry.
+ // We run one again through the facets of the HDS.
+ for (Face_iterator it_face = faces_begin; it_face != faces_end; ++it_face)
+ {
+ Halfedge_const_handle start=(*it_face)->halfedge();
+ Halfedge_const_handle current=start;
+ do
+ {
+ typename Map::Dart_handle d = hedge_to_dart[current]; // Get the dart associated to the Halfedge
+ if (d->template attribute<0>() == NULL)
+ {
+ amap.template set_attribute<0>(d,
+ amap.template create_attribute<0>(current->opposite()->vertex()->point()));
+ }
+ current=current->next();
+ }
+ while (current != start);
+ }
+
+ return first_dart;
+}
+
+ //turn around the target vertex of dart to find a marked dart
+template <class Combinatorial_map_3>
+boost::optional<typename Combinatorial_map_3::Dart_handle>
+next_marked_dart_around_target_vertex(
+ const Combinatorial_map_3& final_map,
+ typename Combinatorial_map_3::Dart_handle dart,
+ int mark_index)
+{
+ CGAL_precondition(final_map.is_marked(dart,mark_index));
+ typename Combinatorial_map_3::Dart_handle next=dart->beta(1);
+ while ( ! final_map.is_marked(next,mark_index) ){
+ if (next->is_free(2) )//we reach a boundary
+ return boost::optional<typename Combinatorial_map_3::Dart_handle>();
+ next=next->beta(2)->beta(1);
+ }
+ if (next == dart) //no new dart have been found
+ return boost::optional<typename Combinatorial_map_3::Dart_handle>();
+ CGAL_precondition(&dart->beta(1)->template attribute<0>()->point() == &next->template attribute<0>()->point());
+ return boost::optional<typename Combinatorial_map_3::Dart_handle> (next);
+}
+
+//turn around the target vertex of dart to find a marked dart
+//with expected_target as target vertex
+template <class Combinatorial_map_3>
+typename Combinatorial_map_3::Dart_handle
+get_next_marked_dart_around_target_vertex(
+ const Combinatorial_map_3& final_map,
+ typename Combinatorial_map_3::Dart_handle dart,
+ int mark_index)
+{
+ CGAL_precondition(final_map.is_marked(dart,mark_index));
+ typename Combinatorial_map_3::Dart_handle next=dart->beta(1);
+ while ( !final_map.is_marked(next,mark_index) ){
+ CGAL_assertion( !next->is_free(2) );
+ next=next->beta(2)->beta(1);
+ CGAL_assertion(next != dart);
+ }
+ CGAL_precondition(&dart->beta(1)->template attribute<0>()->point() == &next->template attribute<0>()->point());
+ return next;
+}
+
+//turn around the source vertex of dart to find a marked dart
+//with expected_source as source vertex
+template <class Combinatorial_map_3>
+typename Combinatorial_map_3::Dart_handle
+get_next_marked_dart_around_source_vertex(
+ const Combinatorial_map_3& final_map,
+ typename Combinatorial_map_3::Dart_handle dart,
+ int mark_index)
+{
+ CGAL_precondition(final_map.is_marked(dart,mark_index));
+ typename Combinatorial_map_3::Dart_handle next=dart->beta(0);
+ while ( ! final_map.is_marked(next,mark_index) ){
+ CGAL_assertion( !next->is_free(2) );
+ next=next->beta(2)->beta(0);
+ CGAL_assertion(next != dart);
+ }
+ CGAL_precondition(&dart->template attribute<0>()->point() == &next->beta(1)->template attribute<0>()->point());
+ return next;
+}
+
+//given two marked darts, this function links these two darts with beta<2>
+//but in addition it follows the marked darts connected to the same vertex
+//(there should be only one) to connect them all together
+//( this function is a kind of zipper ;) )
+template <class Combinatorial_map_3,class Nodes_vector>
+void sew_2_marked_darts( Combinatorial_map_3& final_map,
+ typename Combinatorial_map_3::Dart_handle dart_1 ,
+ typename Combinatorial_map_3::Dart_handle dart_2 ,
+ int mark_index,
+ const Nodes_vector& nodes,
+ const std::pair<int,int>& indices,
+ const std::pair<bool,int>& polyline_info)
+{
+ CGAL_precondition( dart_1->is_free(2) );
+ CGAL_precondition( dart_2->is_free(2) );
+ CGAL_precondition( final_map.is_marked(dart_1,mark_index) );
+ CGAL_precondition( final_map.is_marked(dart_2,mark_index) );
+ CGAL_precondition( dart_1->template attribute<0>()->point() == dart_2->beta(1)->template attribute<0>()->point() );
+ CGAL_precondition( dart_1->beta(1)->template attribute<0>()->point() == dart_2->template attribute<0>()->point() );
+
+ int src_index = ( ( indices.first < indices.second) == polyline_info.first )
+ ? indices.second:indices.first;
+
+ if ( dart_1->template attribute<0>()->point() != nodes[ src_index ] ) std::swap(dart_1,dart_2);
+
+ int nb_segs=polyline_info.second-1,k=1;
+
+ do{
+ CGAL_precondition( final_map.template is_sewable<2>(dart_1,dart_2) );
+ final_map.template sew<2>(dart_1,dart_2);
+
+ if (k==nb_segs) break;
+
+ dart_1=get_next_marked_dart_around_target_vertex(final_map,dart_1,mark_index);
+ dart_2=get_next_marked_dart_around_source_vertex(final_map,dart_2,mark_index);
+ }
+ while(++k);
+}
+
+//not_top and not_down are two darts from volumes that get merged with an existing
+//other one because of a set of identical coplanar triangles.
+//top and down is the dart of the volumes "replacing" that of not_top and not down respectively,
+//The function is considering all triangles that are bounded by a cycle of marked edges.
+//The volume not_top and not_down are part of are those that will disappear at the
+//end of the main algorithm.
+//( this function is a kind of facet gluer ;) )
+template <class Combinatorial_map_3>
+void sew_3_marked_darts( Combinatorial_map_3& final_map,
+ typename Combinatorial_map_3::Dart_handle not_top ,
+ typename Combinatorial_map_3::Dart_handle not_down ,
+ typename Combinatorial_map_3::Dart_handle top ,
+ typename Combinatorial_map_3::Dart_handle down ,
+ int mark_index,
+ std::set<typename Combinatorial_map_3::Dart_handle>& darts_to_remove)
+{
+ typedef boost::optional<typename Combinatorial_map_3::Dart_handle> O_Dart_handle;
+
+ if ( not_top->template attribute<3>()->info().is_empty ){
+ CGAL_assertion(not_down->template attribute<3>()->info().is_empty);
+ return;
+ }
+
+ CGAL_assertion(!not_down->template attribute<3>()->info().is_empty);
+
+ //merge attribute of the two volumes:
+ internal_IOP::Volume_on_merge merge_attributes;
+ merge_attributes(*top->template attribute<3>(),*not_top->template attribute<3>());
+ merge_attributes(*down->template attribute<3>(),*not_down->template attribute<3>());
+
+ //set volume attributes as empty to avoid double sew_3 of the same topological disk of triangles
+ not_top->template attribute<3>()->info().is_empty=true;
+ not_down->template attribute<3>()->info().is_empty=true;
+
+ CGAL_precondition( final_map.is_marked(not_top,mark_index) && final_map.is_marked(top,mark_index) );
+ CGAL_precondition( final_map.is_marked(not_down,mark_index) && final_map.is_marked(down,mark_index) );
+ CGAL_precondition( not_top->template attribute<0>()->point() == not_down->beta(1)->template attribute<0>()->point() );
+ CGAL_precondition( not_top->beta(1)->template attribute<0>()->point() == not_down->template attribute<0>()->point() );
+ CGAL_precondition( not_top->template attribute<0>()->point() == top->template attribute<0>()->point() );
+ CGAL_precondition( not_down->template attribute<0>()->point() == down->template attribute<0>()->point() );
+
+ CGAL_assertion( top->beta(3)==down );
+
+ //set to be removed the darts of the two no longer used volumes
+ typename Combinatorial_map_3::Dart_handle start=not_top;
+ do
+ {
+ CGAL_assertion(!not_top->is_free(3));
+ darts_to_remove.insert(not_top); darts_to_remove.insert(not_top->beta(1)); darts_to_remove.insert(not_top->beta(1)->beta(1));
+ darts_to_remove.insert(not_top->beta(3)); darts_to_remove.insert(not_top->beta(3)->beta(1)); darts_to_remove.insert(not_top->beta(3)->beta(1)->beta(1));
+ O_Dart_handle current_1=next_marked_dart_around_target_vertex(final_map,not_top,mark_index);
+ CGAL_precondition(current_1);
+ not_top=*current_1;
+ }
+ while(not_top!=start);
+}
+
+template<class Tag>
+struct Halfedge_marker{
+ template <class Halfedge_handle>
+ static void mark(Halfedge_handle){}
+};
+
+template<>
+struct Halfedge_marker<Tag_true>{
+ template <class Halfedge_handle>
+ static void mark(Halfedge_handle h){h->set_mark();}
+};
+
+template<class Polyhedron,class Kernel=typename Polyhedron::Traits::Kernel,class Mark_intersection_halfedges=Tag_false>
+class Node_visitor_refine_polyhedra{
+//typedefs
+ typedef typename Polyhedron::Halfedge_handle Halfedge_handle;
+ typedef typename Polyhedron::Halfedge_const_handle Halfedge_const_handle;
+ typedef typename Polyhedron::Face_handle Face_handle;
+ typedef typename Polyhedron::Halfedge Halfedge;
+ typedef typename Polyhedron::Vertex_handle Vertex_handle;
+ typedef internal_IOP::Compare_handles<Polyhedron,CGAL::Tag_false> Cmp_handle; //This ensures uniqueness of edges when comparing halfedges
+ typedef internal_IOP::Compare_unik_address<Polyhedron> Cmp_unik_ad; //This ensures uniqueness of edges when comparing halfedges
+
+ //constrained triangulation used for triangulation interior of faces
+ #ifdef DO_NO_USE_EXACT_CDT
+ typedef CGAL::Triangulation_vertex_base_with_info_2<int,Kernel> Vbi;
+ typedef CGAL::Constrained_triangulation_face_base_2<Kernel> Fb;
+ typedef CGAL::Triangulation_data_structure_2<Vbi,Fb> TDS_2;
+ typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel,TDS_2,CGAL::No_intersection_tag> CDT; //DO WE NEED DELAUNAY????
+ #else
+ typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_kernel;
+ typedef CGAL::Triangulation_vertex_base_with_info_2<int,Exact_kernel> Vbi;
+ typedef CGAL::Constrained_triangulation_face_base_2<Exact_kernel> Fb;
+ typedef CGAL::Triangulation_data_structure_2<Vbi,Fb> TDS_2;
+ typedef CGAL::Constrained_Delaunay_triangulation_2<Exact_kernel,TDS_2,CGAL::No_intersection_tag> CDT; //DO WE NEED DELAUNAY????
+ #endif
+
+ typedef std::map<Halfedge_handle,Polyhedron*,Cmp_unik_ad> Hedge_to_polyhedron_map;
+
+ typedef std::vector<int> Node_ids;
+ typedef std::set<int> Node_id_set; //avoid having duplicated node on edge of coplanar triangles
+ typedef std::map< Face_handle,Node_ids,Cmp_handle > In_face_map;
+ typedef std::map< Halfedge_handle,Node_id_set,Cmp_unik_ad > In_halfedge_map;
+ //to keep the correspondance between node_id and vertex_handle in each polyhedron
+ typedef std::map<int,Vertex_handle> Node_to_polyhedron_vertex_map;
+ typedef std::map<Polyhedron*, Node_to_polyhedron_vertex_map > Poly_to_map_node;
+ //to maintain an polyhedron halfedge on each polyline + pair<bool,int>
+ //with first = "is the key (pair<int,int>) was reversed?" and second is the number of edges +1 in the polyline
+ typedef std::map< std::pair<int,int>, std::pair< std::map<Polyhedron*,Halfedge_handle>,std::pair<bool,int> > > An_edge_per_polyline_map;
+ //to handle coplanar halfedge of polyhedra that are full in the intersection
+ typedef std::map< int,Halfedge_handle > Node_to_target_of_hedge_map;
+ typedef std::map< Polyhedron*,Node_to_target_of_hedge_map> Poly_to_vertices_on_intersection_map;
+
+ //Combinatorial map typedefs
+ typedef internal_IOP::Item_with_points_and_volume_info<Kernel,Polyhedron> Items;
+ typedef CGAL::Combinatorial_map<3,Items> Combinatorial_map_3_;
+ typedef typename Combinatorial_map_3_::Dart_handle Dart_handle;
+
+//data members
+ Hedge_to_polyhedron_map hedge_to_polyhedron;
+ In_face_map in_face;
+ In_halfedge_map in_hedge;
+ std::map< int,std::set<int> > graph_of_constraints;
+ std::map< int,std::set<int> > coplanar_constraints;
+ An_edge_per_polyline_map an_edge_per_polyline;
+ typename An_edge_per_polyline_map::iterator last_polyline;
+ Poly_to_vertices_on_intersection_map poly_to_vertices_on_inter;
+ Poly_to_map_node polyhedron_to_map_node_to_polyhedron_vertex;
+ std::set<int> non_manifold_nodes; //contain nodes that are original vertices of input polyhedron and that neighborhood is not a topological disk
+ std::map<Vertex_handle,int> nodes_that_are_original_vertices;//to keep the correspondance between original polyhedron vertices that are also nodes
+
+ Combinatorial_map_3_* final_map_ptr;
+ Combinatorial_map_3_& final_map() {return *final_map_ptr;}
+ bool final_map_comes_from_outside;
+ // new_hedge hedge
+ // -----------> ----------->
+ // v
+ // <----------- <-----------
+ // new_opposite opposite
+ //
+ Vertex_handle split_edge( Halfedge_handle hedge,
+ const typename Kernel::Point_3& point,
+ Polyhedron& P)
+ {
+ internal_IOP::Split_halfedge_at_point<typename Polyhedron::HalfedgeDS> delegated(hedge,point);
+ P.delegate( delegated );
+ CGAL_assertion(P.is_valid());
+
+ Vertex_handle v=boost::prior(P.vertices_end());
+ CGAL_assertion(v->point()==point);
+ return v;
+ }
+
+ //sort node ids so that we can split the hedge
+ //consecutively
+ template <class Nodes_vector>
+ void sort_vertices_along_hedge(std::vector<int>& node_ids,Halfedge_handle hedge,const Nodes_vector& nodes)
+ {
+ std::sort(node_ids.begin(),
+ node_ids.end(),
+ internal_IOP::Order_along_a_halfedge<Polyhedron,Nodes_vector,Is_polyhedron_const>(hedge,nodes)
+ );
+ }
+
+ //insert intersection as constrained edges in a CDT triangulation
+ template <class CDT>
+ void insert_constrained_edges_coplanar_case(int node_id,
+ CDT& triangulation,
+ std::map<int,typename CDT::Vertex_handle>& id_to_CDT_vh)
+ {
+ if (node_id < number_coplanar_vertices){
+ //XSL_TAG_CPL_VERT
+ //Insert constrained edges from coplanar facets that have been retriangulated. This ensure that triangulations are compatible
+ std::map< int,std::set<int> >::iterator it_neighbors=coplanar_constraints.find(node_id);
+ if (it_neighbors!=coplanar_constraints.end())
+ {
+ typename CDT::Vertex_handle vh=id_to_CDT_vh.find(node_id)->second;
+ for (std::set<int>::iterator it_n=it_neighbors->second.begin();it_n!=it_neighbors->second.end();++it_n){
+ typename std::map<int,typename CDT::Vertex_handle>::iterator it_vh=id_to_CDT_vh.find(*it_n);
+ // this condition ensures to consider only graph edges that are in the same triangle (not in a neighbor one when involving node on a triangle edge)
+ // here we can't make the difference between a point on the interior or the boundary, so points_on_triangle is not used.
+ if ( it_vh!=id_to_CDT_vh.end() ){
+ triangulation.insert_constraint(vh,id_to_CDT_vh.find(*it_n)->second);
+ }
+ }
+ }
+ }
+ }
+ //insert intersection as constrained edges in a CDT triangulation
+ template <class CDT,class Constrained_edges_map>
+ void insert_constrained_edges(Node_ids& node_ids, //index of vertices we are interested in
+ CDT& triangulation,
+ std::map<int,typename CDT::Vertex_handle>& id_to_CDT_vh,
+ Constrained_edges_map& constrained_edges, //list of pair of int to indicate edges that are constrained
+ bool points_on_triangle=false)
+ {
+ for (Node_ids::iterator it_node_id=node_ids.begin();it_node_id!=node_ids.end();++it_node_id){
+ std::map< int,std::set<int> >::iterator it_neighbors=graph_of_constraints.find(*it_node_id);
+ if (it_neighbors!=graph_of_constraints.end())
+ {
+ typename CDT::Vertex_handle vh=id_to_CDT_vh.find(*it_node_id)->second;
+ for (std::set<int>::iterator it_n=it_neighbors->second.begin();it_n!=it_neighbors->second.end();++it_n){
+ typename std::map<int,typename CDT::Vertex_handle>::iterator it_vh=id_to_CDT_vh.find(*it_n);
+ // this condition ensures to consider only graph edges that are in the same triangle (not in a neighbor one when involving node on a triangle edge)
+ if ( !points_on_triangle || it_vh!=id_to_CDT_vh.end() ){
+ CGAL_assertion(it_vh!=id_to_CDT_vh.end());
+ triangulation.insert_constraint(vh,id_to_CDT_vh.find(*it_n)->second);
+ constrained_edges.push_back(std::make_pair(*it_node_id,*it_n));
+ }
+ }
+ }
+ #ifdef CGAL_COREFINEMENT_DEBUG
+ else
+ {
+ std::cout << "X0: Found an isolated point" << std::endl;
+ }
+ #endif
+
+ insert_constrained_edges_coplanar_case(*it_node_id,triangulation,id_to_CDT_vh);
+ }
+ }
+
+ std::pair<int,int> make_sorted_pair(int i,int j) const {return i<j ? std::make_pair(i,j):std::make_pair(j,i);}
+
+ void update_edge_per_polyline(Polyhedron* P,std::pair<int,int> indices,typename Polyhedron::Halfedge_handle hedge)
+ {
+ std::pair<int,int> sorted_pair=make_sorted_pair(indices.first,indices.second);
+ typename An_edge_per_polyline_map::iterator it=an_edge_per_polyline.find(sorted_pair);
+ if (it!=an_edge_per_polyline.end()){
+ it->second.first.insert(std::make_pair( P,sorted_pair.first==indices.first?hedge:hedge->opposite() ));
+ }
+ }
+
+ int node_index_of_incident_vertex(Halfedge_const_handle h,
+ const std::map<Halfedge_const_handle,std::pair<int,int>,Cmp_unik_ad >& border_halfedges)
+ {
+ //WARNING this may be expensive
+ typedef std::map<Halfedge_const_handle,std::pair<int,int>,Cmp_unik_ad > Border_halfedges_map;
+
+ Halfedge_const_handle start=h;
+ Halfedge_const_handle curr=start;
+ do{
+ typename Border_halfedges_map::const_iterator it_border=border_halfedges.find( curr );
+ if (it_border!=border_halfedges.end())
+ return it_border->first==curr?it_border->second.second:it_border->second.first;
+ curr=curr->next()->opposite();
+ }while(curr!=start);
+
+ return -1;
+ }
+
+ template <class Nodes_vector>
+ bool filtered_order_around_edge(int O_prime_index,
+ int O_index,
+ int P1_index,
+ int P2_index,
+ int Q_index,
+ Vertex_handle P1,
+ Vertex_handle P2,
+ Vertex_handle Q,
+ const Nodes_vector& nodes)
+ {
+ try{
+ return is_in_interior_of_object<typename Nodes_vector::Ikernel>(
+ nodes.interval_node(O_prime_index),
+ nodes.interval_node(O_index),
+ P1_index == -1 ? nodes.to_interval(P1->point()): nodes.interval_node(P1_index),
+ P2_index == -1 ? nodes.to_interval(P2->point()): nodes.interval_node(P2_index),
+ Q_index == -1 ? nodes.to_interval(Q->point()) : nodes.interval_node(Q_index )
+ );
+ }
+ catch(Uncertain_conversion_exception&){
+ return is_in_interior_of_object<typename Nodes_vector::Exact_kernel>(
+ nodes.exact_node(O_prime_index),
+ nodes.exact_node(O_index),
+ P1_index == -1 ? nodes.to_exact(P1->point()): nodes.exact_node(P1_index),
+ P2_index == -1 ? nodes.to_exact(P2->point()): nodes.exact_node(P2_index),
+ Q_index == -1 ? nodes.to_exact(Q->point()) : nodes.exact_node(Q_index )
+ );
+ }
+ }
+
+//keep track of the fact that a polyhedron original vertex is a node
+void all_incident_faces_got_a_node_as_vertex(Halfedge_handle incident_to_vertex_edge,int node_id)
+{
+ nodes_that_are_original_vertices.insert(std::make_pair(incident_to_vertex_edge->vertex(),node_id));
+}
+
+//if an original polyhedron vertex is also a node, do no use a fake id
+void set_triangle_boundary_indices(
+ Vertex_handle* triangle_boundary,
+ int* triangle_boundary_indices)
+{
+ triangle_boundary_indices[0]=-1;
+ triangle_boundary_indices[1]=-2;
+ triangle_boundary_indices[2]=-3;
+
+ for (int k=0;k<3;++k){
+ typename std::map<Vertex_handle,int>::iterator it=nodes_that_are_original_vertices.find(triangle_boundary[k]);
+ if (it!=nodes_that_are_original_vertices.end())
+ triangle_boundary_indices[k]=it->second;
+ }
+}
+
+//======================================================================//
+//functions internally used to glue piece of the final combinatorial map//
+//======================================================================//
+
+
+ //-----first polyhedron
+template <class Halfedge_to_dart_map>
+inline Dart_handle get_associated_dart(Halfedge_handle hedge,Halfedge_to_dart_map& selected_hedge_to_dart){
+ typename Halfedge_to_dart_map::iterator it_saved_dart=selected_hedge_to_dart.find(hedge);
+ CGAL_assertion(it_saved_dart!=selected_hedge_to_dart.end());
+ return it_saved_dart->second;
+}
+
+//first_hedge defines four volumes, second_hedge only two
+//first_poly is not needed as inside/outside volume is update during the merge
+//of the sew. Only second_poly is needed
+template <class Nodes_vector,class Border_halfedges_map,class Halfedge_to_dart_map>
+void sew_2_three_volumes_case( Halfedge_handle first_hedge, Halfedge_handle second_hedge,
+ const std::pair<int,int>& indices,
+ const Nodes_vector& nodes,
+ Border_halfedges_map& border_halfedges,
+ Halfedge_to_dart_map& selected_hedge_to_dart,
+ Polyhedron* /*first_poly*/, Polyhedron* second_poly,
+ int mark_index,
+ std::set<Dart_handle>& darts_to_remove,
+ const std::pair<bool,int>& polyline_info)
+{
+ bool took_opposite=second_hedge->is_border();
+ if (took_opposite) second_hedge=second_hedge->opposite();
+
+ Vertex_handle P1=first_hedge->opposite()->next()->vertex();
+ Vertex_handle P2=first_hedge->next()->vertex();
+ // when looking from the side of indices.second, the interior of the first polyhedron is described
+ // by turning counterclockwise from P1 to P2
+
+ Vertex_handle Q = second_hedge->next()->vertex();
+
+ //check if the third point of each triangular face is an original point (stay -1)
+ //or a intersection point (in that case we need the index of the corresponding node to
+ //have the exact value of the point)
+ int index_p1=node_index_of_incident_vertex(first_hedge->opposite()->next(),border_halfedges);
+ int index_p2=node_index_of_incident_vertex(first_hedge->next(),border_halfedges);
+ int index_q =node_index_of_incident_vertex(second_hedge->next(),border_halfedges);
+
+ //Recover the dart that will be the start point of the different sewing
+ // dof_X_outside = dart of face of , meaning the triangle containing the
+ // point X and part of the volume outside of the corresponding polyhedron
+ //-----first polyhedron
+ Dart_handle dof_P1_outside = get_associated_dart(first_hedge->opposite(),selected_hedge_to_dart);
+ Dart_handle dof_P2_outside = get_associated_dart(first_hedge,selected_hedge_to_dart);
+ //-----second polyhedron
+ Dart_handle dof_Q_outside = get_associated_dart(second_hedge,selected_hedge_to_dart);
+
+ if (index_p1!=-1 && index_p1==index_q){
+ Dart_handle top=dof_P1_outside->beta(3), not_top=took_opposite?dof_Q_outside->beta(3):dof_Q_outside;
+ Dart_handle down=dof_P1_outside, not_down=took_opposite?dof_Q_outside:dof_Q_outside->beta(3);
+
+ if ( top->template attribute<3>()->info().is_empty ) std::swap(not_top,top);
+ if ( down->template attribute<3>()->info().is_empty ) std::swap(not_down,down);
+ CGAL_assertion( !top->template attribute<3>()->info().is_empty );
+ CGAL_assertion( !down->template attribute<3>()->info().is_empty );
+
+ sew_2_marked_darts( final_map(),top , dof_P2_outside->beta(3) ,mark_index, nodes, indices, polyline_info); //P1P2 or QP2
+ sew_2_marked_darts( final_map(),dof_P2_outside , down ,mark_index, nodes, indices, polyline_info); //P2Q or P2P1
+ sew_3_marked_darts( final_map(),not_top,not_down,top,down,mark_index,darts_to_remove);
+
+ return;
+ }
+
+ if (index_p2!=-1 && index_p2==index_q){
+ Dart_handle top=dof_P2_outside->beta(3), not_top=took_opposite?dof_Q_outside:dof_Q_outside->beta(3);
+ Dart_handle down=dof_P2_outside, not_down=took_opposite?dof_Q_outside->beta(3):dof_Q_outside;
+
+ if ( top->template attribute<3>()->info().is_empty ) std::swap(not_top,top);
+ if ( down->template attribute<3>()->info().is_empty ) std::swap(not_down,down);
+ CGAL_assertion( !top->template attribute<3>()->info().is_empty );
+ CGAL_assertion( !down->template attribute<3>()->info().is_empty );
+
+ sew_2_marked_darts( final_map(),dof_P1_outside->beta(3) , top ,mark_index, nodes, indices, polyline_info); //P1Q or P1P2
+ sew_2_marked_darts( final_map(),down , dof_P1_outside ,mark_index, nodes, indices, polyline_info); //QP1 or P2P1
+ sew_3_marked_darts( final_map(),not_top,not_down,top,down,mark_index,darts_to_remove);
+
+ return;
+ }
+
+ bool Q_is_between_P1P2 = filtered_order_around_edge(indices.first,indices.second,index_p1,index_p2,index_q,P1,P2,Q,nodes);
+
+
+ if (Q_is_between_P1P2)
+ {
+ // poly_first - poly_second = took_opposite?P1Q:QP2
+ // poly_second - poly_first = {0}
+ // poly_first \cap poly_second = took_opposite?QP2:P1Q
+ // opposite( poly_first U poly_second ) = P2P1
+ sew_2_marked_darts( final_map(),dof_P1_outside->beta(3) , took_opposite?dof_Q_outside:dof_Q_outside->beta(3) ,mark_index, nodes, indices, polyline_info); //P1Q
+ sew_2_marked_darts( final_map(),took_opposite?dof_Q_outside->beta(3):dof_Q_outside , dof_P2_outside->beta(3) ,mark_index, nodes, indices, polyline_info); //QP2
+ sew_2_marked_darts( final_map(),dof_P2_outside , dof_P1_outside ,mark_index, nodes, indices, polyline_info); //P2P1
+ dof_P1_outside->template attribute<3>()->info().outside.insert(second_poly); //update P2P1 outside poly
+ }
+ else
+ {
+ // poly_first - poly_second = P1P2
+ // poly_second - poly_first = took_opposite?QP1:P2Q
+ // poly_first \cap poly_second = {0}
+ // opposite( poly_first U poly_second ) = took_opposite?P2Q:QP1
+ sew_2_marked_darts( final_map(),dof_P2_outside , took_opposite?dof_Q_outside:dof_Q_outside->beta(3) ,mark_index, nodes, indices, polyline_info); //P2Q
+ sew_2_marked_darts( final_map(),took_opposite?dof_Q_outside->beta(3):dof_Q_outside , dof_P1_outside ,mark_index, nodes, indices, polyline_info); //QP1
+ sew_2_marked_darts( final_map(),dof_P1_outside->beta(3) , dof_P2_outside->beta(3) ,mark_index, nodes, indices, polyline_info); //P1P2
+ dof_P1_outside->beta(3)->template attribute<3>()->info().outside.insert(second_poly); //update P1P2 outside poly
+ }
+}
+
+//first_hedge defines two volumes, second_hedge only two
+template <class Halfedge_to_dart_map,class Border_halfedges_map,class Nodes_vector>
+void sew_2_two_volumes_case( Halfedge_handle first_hedge, Halfedge_handle second_hedge,
+ Border_halfedges_map& border_halfedges,
+ Halfedge_to_dart_map& selected_hedge_to_dart,
+ int mark_index,
+ std::set<Dart_handle>& darts_to_remove,
+ const Nodes_vector& nodes,
+ const std::pair<int,int>& indices,
+ const std::pair<bool,int>& polyline_info)
+{
+ bool first_took_opposite=first_hedge->is_border();
+ if (first_took_opposite) first_hedge=first_hedge->opposite();
+ bool second_took_opposite=second_hedge->is_border();
+ if (second_took_opposite) second_hedge=second_hedge->opposite();
+
+ //-----first polyhedron
+ Dart_handle dof_P_outside = get_associated_dart(first_hedge,selected_hedge_to_dart);
+ //-----second polyhedron
+ Dart_handle dof_Q_outside = get_associated_dart(second_hedge,selected_hedge_to_dart);
+
+
+
+
+ int index_p =node_index_of_incident_vertex(first_hedge->next(),border_halfedges);
+ int index_q =node_index_of_incident_vertex(second_hedge->next(),border_halfedges);
+
+ if (index_p!=-1 && index_q!=-1 && index_p==index_q){
+ Dart_handle top=dof_P_outside, not_top=dof_Q_outside->beta(3);
+ Dart_handle down=dof_P_outside->beta(3), not_down=dof_Q_outside;
+
+ if (first_took_opposite==second_took_opposite)
+ {
+ top=dof_P_outside->beta(3); not_top=dof_Q_outside->beta(3);
+ down=dof_P_outside; not_down=dof_Q_outside;
+ }
+
+ if ( top->template attribute<3>()->info().is_empty ) std::swap(not_top,top);
+ if ( down->template attribute<3>()->info().is_empty ) std::swap(not_down,down);
+ CGAL_assertion( !top->template attribute<3>()->info().is_empty );
+ CGAL_assertion( !down->template attribute<3>()->info().is_empty );
+
+ sew_3_marked_darts( final_map(),not_top,not_down,top,down,mark_index,darts_to_remove);
+
+ return;
+ }
+
+
+
+ //since the edge is shared, the inside of each polyhedron must be on opposite orientation halfedges
+ if (first_took_opposite==second_took_opposite)
+ {
+ //sew out with in
+ sew_2_marked_darts( final_map(),dof_P_outside->beta(3) , dof_Q_outside ,mark_index, nodes, indices, polyline_info); //PQ
+ sew_2_marked_darts( final_map(),dof_Q_outside->beta(3) , dof_P_outside ,mark_index, nodes, indices, polyline_info); //QP
+ }
+ else
+ {
+ //sew in with in
+ sew_2_marked_darts( final_map(),dof_P_outside , dof_Q_outside ,mark_index, nodes, indices, polyline_info); //PQ
+ sew_2_marked_darts( final_map(),dof_Q_outside->beta(3), dof_P_outside->beta(3) ,mark_index, nodes, indices, polyline_info); //QP
+ }
+}
+
+//4 volume case with 2 identical volume
+//Q2 is supposed to be identical to P2
+template <class Nodes_vector,class Halfedge_to_dart_map>
+void sew_2_four_volumes_case_1( Halfedge_handle first_hedge, Halfedge_handle second_hedge,
+ const std::pair<int,int>& indices,
+ const Nodes_vector& nodes,
+ int index_p1, int index_p2, int index_q1,
+ Halfedge_to_dart_map& selected_hedge_to_dart,
+ int mark_index,
+ std::set<Dart_handle>& darts_to_remove,
+ const std::pair<bool,int>& polyline_info,
+ bool swap_in_out_Q=false)
+{
+ Vertex_handle P1=first_hedge->opposite()->next()->vertex();
+ Vertex_handle P2=first_hedge->next()->vertex();
+ // when looking from the side of indices.second, the interior of the first polyhedron is described
+ // by turning counterclockwise from P1 to P2
+ Vertex_handle Q1=second_hedge->opposite()->next()->vertex();
+ // Vertex_handle Q2=second_hedge->next()->vertex();
+ bool Q1_is_between_P1P2 = filtered_order_around_edge(indices.first,indices.second,index_p1,index_p2,index_q1,P1,P2,Q1,nodes);
+
+
+ //Recover the dart that will be the start point of the different sewing
+ // dof_X_outside = dart of face of , meaning the triangle containing the
+ // point X and part of the volume outside of the corresponding polyhedron
+ //-----first polyhedron
+ Dart_handle dof_P1_outside = get_associated_dart(first_hedge->opposite(),selected_hedge_to_dart);
+ Dart_handle dof_P2_outside = get_associated_dart(first_hedge,selected_hedge_to_dart);
+ //-----second polyhedron
+ Dart_handle dof_Q1_outside = get_associated_dart(second_hedge->opposite(),selected_hedge_to_dart);
+ Dart_handle dof_Q2_outside = get_associated_dart(second_hedge,selected_hedge_to_dart);
+
+ if( swap_in_out_Q ){
+ dof_Q1_outside=dof_Q1_outside->beta(3);
+ dof_Q2_outside=dof_Q2_outside->beta(3);
+ }
+
+ if (Q1_is_between_P1P2){
+ Dart_handle top=dof_Q2_outside->beta(3), not_top=dof_P2_outside->beta(3);
+ Dart_handle down=dof_Q2_outside, not_down=dof_P2_outside;
+ if ( top->template attribute<3>()->info().is_empty ) std::swap(not_top,top);
+ if ( down->template attribute<3>()->info().is_empty ) std::swap(not_down,down);
+ CGAL_assertion( !top->template attribute<3>()->info().is_empty );
+ CGAL_assertion( !down->template attribute<3>()->info().is_empty );
+
+ // poly_first - poly_second = P1Q1
+ // poly_second - poly_first = {0}
+ // poly_first \cap poly_second = Q1P2 or Q1Q2
+ // opposite( poly_first U poly_second ) = Q2P1 or P2P1
+ sew_2_marked_darts( final_map(),dof_P1_outside->beta(3) , dof_Q1_outside ,mark_index, nodes, indices, polyline_info); //P1Q1
+ sew_2_marked_darts( final_map(),dof_Q1_outside->beta(3) , top ,mark_index, nodes, indices, polyline_info); //Q1P2 or Q1Q2
+ sew_2_marked_darts( final_map(),down , dof_P1_outside ,mark_index, nodes, indices, polyline_info); //Q2P1 or P2P1
+ sew_3_marked_darts( final_map(),not_top,not_down,top,down,mark_index,darts_to_remove);
+
+ }
+ else{
+ Dart_handle top=dof_Q2_outside->beta(3), not_top=dof_P2_outside->beta(3);
+ Dart_handle down=dof_Q2_outside, not_down=dof_P2_outside;
+ if ( top->template attribute<3>()->info().is_empty ) std::swap(not_top,top);
+ if ( down->template attribute<3>()->info().is_empty ) std::swap(not_down,down);
+ CGAL_assertion( !top->template attribute<3>()->info().is_empty );
+ CGAL_assertion( !down->template attribute<3>()->info().is_empty );
+
+ // poly_first - poly_second = {0}
+ // poly_second - poly_first = Q1P1
+ // poly_first \cap poly_second = P1P2 or P1Q2
+ // opposite( poly_first U poly_second ) = Q2Q1 or P2Q1
+ sew_2_marked_darts( final_map(),dof_Q1_outside->beta(3) , dof_P1_outside ,mark_index, nodes, indices, polyline_info); //Q1P1
+ sew_2_marked_darts( final_map(),dof_P1_outside->beta(3) , top ,mark_index, nodes, indices, polyline_info); //P1P2 or P1Q2
+ sew_2_marked_darts( final_map(),down , dof_Q1_outside ,mark_index, nodes, indices, polyline_info); //Q2Q1 or P2Q1
+ sew_3_marked_darts( final_map(),not_top,not_down,top,down,mark_index,darts_to_remove);
+ }
+}
+
+template <class Nodes_vector,class Halfedge_to_dart_map>
+bool coplanar_triangles_case_handled(Halfedge_handle first_hedge,Halfedge_handle second_hedge,
+ const std::pair<int,int>& indices,
+ const Nodes_vector& nodes,
+ int index_p1, int index_p2, int index_q1,int index_q2,
+ Halfedge_to_dart_map& selected_hedge_to_dart,
+ int mark_index,
+ std::set<Dart_handle>& darts_to_remove,
+ const std::pair<bool,int>& polyline_info)
+{
+ if( index_p1!=-1 ){
+ if (index_p1==index_q1){
+ if(index_p2!=-1){
+ CGAL_assertion(index_p2!=index_q1);
+ if(index_p2==index_q2){
+ //-----first polyhedron
+ Dart_handle dof_P1_outside = get_associated_dart(first_hedge->opposite(),selected_hedge_to_dart);
+ Dart_handle dof_P2_outside = get_associated_dart(first_hedge,selected_hedge_to_dart);
+ //-----second polyhedron
+ Dart_handle dof_Q1_outside = get_associated_dart(second_hedge->opposite(),selected_hedge_to_dart);
+ Dart_handle dof_Q2_outside = get_associated_dart(second_hedge,selected_hedge_to_dart);
+
+ Dart_handle top_1=dof_P1_outside->beta(3), not_top_1=dof_Q1_outside->beta(3);
+ Dart_handle top_2=dof_P2_outside->beta(3), not_top_2=dof_Q2_outside->beta(3);
+ Dart_handle down_1=dof_P1_outside, not_down_1=dof_Q1_outside;
+ Dart_handle down_2=dof_P2_outside, not_down_2=dof_Q2_outside;
+ if ( top_1->template attribute<3>()->info().is_empty ) std::swap(top_1,not_top_1);
+ if ( top_2->template attribute<3>()->info().is_empty ) std::swap(top_2,not_top_2);
+ if ( down_1->template attribute<3>()->info().is_empty ) std::swap(down_1,not_down_1);
+ if ( down_2->template attribute<3>()->info().is_empty ) std::swap(down_2,not_down_2);
+ CGAL_assertion( !top_1->template attribute<3>()->info().is_empty );
+ CGAL_assertion( !top_2->template attribute<3>()->info().is_empty );
+ CGAL_assertion( !down_1->template attribute<3>()->info().is_empty );
+ CGAL_assertion( !down_2->template attribute<3>()->info().is_empty );
+
+ // poly_first - poly_second = {0}
+ // poly_second - poly_first = {0}
+ // poly_first \cap poly_second = P1P2 or Q1Q2 or P1Q1 or Q1P2
+ // opposite( poly_first U poly_second ) = P2P1 or Q2Q1 or P2Q1 or Q2P1
+ sew_2_marked_darts( final_map(),top_1 , top_2 ,mark_index, nodes, indices, polyline_info); //P1P2 or Q1Q2 or P1Q1 or Q1P2
+ sew_2_marked_darts( final_map(),down_2 , down_1 ,mark_index, nodes, indices, polyline_info); //P2P1 or Q2Q1 or P2Q1 or Q2P1
+ sew_3_marked_darts( final_map(),not_top_1, not_down_1 ,top_1,down_1,mark_index,darts_to_remove);
+ sew_3_marked_darts( final_map(),not_top_2, not_down_2 ,top_2,down_2,mark_index,darts_to_remove);
+ return true;
+ }
+ }
+ sew_2_four_volumes_case_1(first_hedge->opposite(),second_hedge->opposite(),std::make_pair(indices.second,indices.first),nodes,index_p2,index_p1,index_q2,selected_hedge_to_dart,mark_index,darts_to_remove,polyline_info);
+ return true;
+ }
+ if (index_p1==index_q2){
+ if(index_p2!=-1){
+ CGAL_assertion(index_p2!=index_q2);
+ if(index_p2==index_q1){
+ //-----first polyhedron
+ Dart_handle dof_P1_outside = get_associated_dart(first_hedge->opposite(),selected_hedge_to_dart);
+ Dart_handle dof_P2_outside = get_associated_dart(first_hedge,selected_hedge_to_dart);
+ //-----second polyhedron
+ Dart_handle dof_Q1_outside = get_associated_dart(second_hedge->opposite(),selected_hedge_to_dart);
+ Dart_handle dof_Q2_outside = get_associated_dart(second_hedge,selected_hedge_to_dart);
+
+ Dart_handle top_1=dof_P1_outside->beta(3), not_top_1=dof_Q2_outside;
+ Dart_handle top_2=dof_P2_outside->beta(3), not_top_2=dof_Q1_outside;
+ Dart_handle down_1=dof_P1_outside, not_down_1=dof_Q2_outside->beta(3);
+ Dart_handle down_2=dof_P2_outside, not_down_2=dof_Q1_outside->beta(3);
+ if ( top_1->template attribute<3>()->info().is_empty ) std::swap(top_1,not_top_1);
+ if ( top_2->template attribute<3>()->info().is_empty ) std::swap(top_2,not_top_2);
+ if ( down_1->template attribute<3>()->info().is_empty ) std::swap(down_1,not_down_1);
+ if ( down_2->template attribute<3>()->info().is_empty ) std::swap(down_2,not_down_2);
+ CGAL_assertion( !top_1->template attribute<3>()->info().is_empty );
+ CGAL_assertion( !top_2->template attribute<3>()->info().is_empty );
+ CGAL_assertion( !down_1->template attribute<3>()->info().is_empty );
+ CGAL_assertion( !down_2->template attribute<3>()->info().is_empty );
+
+ // poly_first - poly_second = P1P2 or P1Q1 or Q2P2 or Q2Q1
+ // poly_second - poly_first = Q1Q2 or Q1P1 or P2P1 or P2Q2
+ // poly_first \cap poly_second = {0}
+ // opposite( poly_first U poly_second ) = all space
+ sew_2_marked_darts( final_map(),top_1 , top_2 ,mark_index, nodes, indices, polyline_info); //P1P2 or Q1Q2 or P1Q1 or Q1P2
+ sew_2_marked_darts( final_map(),down_2 , down_1 ,mark_index, nodes, indices, polyline_info); //P2P1 or Q2Q1 or P2Q1 or Q2P1
+ sew_3_marked_darts( final_map(),not_top_1, not_down_1 ,top_1,down_1,mark_index,darts_to_remove);
+ sew_3_marked_darts( final_map(),not_top_2, not_down_2 ,top_2,down_2,mark_index,darts_to_remove);
+ return true;
+ }
+ }
+ sew_2_four_volumes_case_1(first_hedge->opposite(),second_hedge,std::make_pair(indices.second,indices.first),nodes,index_p2,index_p1,index_q1,selected_hedge_to_dart,mark_index,darts_to_remove,polyline_info,true);
+ return true;
+ }
+ }
+
+ if(index_p2!=-1){
+ if (index_p2==index_q1){
+ sew_2_four_volumes_case_1(first_hedge,second_hedge->opposite(),indices,nodes,index_p1,index_p2,index_q2,selected_hedge_to_dart,mark_index,darts_to_remove,polyline_info,true);
+ return true;
+ }
+ if(index_p2==index_q2){
+ sew_2_four_volumes_case_1(first_hedge,second_hedge,indices,nodes,index_p1,index_p2,index_q1,selected_hedge_to_dart,mark_index,darts_to_remove,polyline_info);
+ return true;
+ }
+ }
+
+
+ return false;
+}
+
+//===//
+//end//
+//===//
+ bool do_not_build_cmap; //set to true in the case only the corefinement must be done
+ int number_coplanar_vertices; //number of intersection points between coplanar facets, see fixes XSL_TAG_CPL_VERT
+public:
+ Node_visitor_refine_polyhedra (Combinatorial_map_3_* ptr=NULL,bool do_not_build_cmap_=false):do_not_build_cmap(do_not_build_cmap_)
+ {
+ if (ptr!=NULL){
+ final_map_comes_from_outside=true;
+ final_map_ptr=ptr;
+ }
+ else{
+ final_map_comes_from_outside=false;
+ final_map_ptr=new Combinatorial_map_3_();
+ }
+ }
+
+ ~Node_visitor_refine_polyhedra(){
+ if(!final_map_comes_from_outside) delete final_map_ptr;
+ }
+
+
+ typedef internal_IOP::Predicates_on_constructions Node_storage_type;
+ typedef Tag_false Is_polyhedron_const;
+ static const bool do_need_vertex_graph = true; //because we need to know which edges are constrained
+
+ typedef Combinatorial_map_3_ Combinatorial_map_3;
+ typedef internal_IOP::Volume_info<Polyhedron> Volume_info;
+
+ const Combinatorial_map_3& combinatorial_map() const {return *final_map_ptr;}
+
+ void set_number_of_intersection_points_from_coplanar_facets(int n){
+ number_coplanar_vertices=n;
+ }
+
+ void check_node_on_non_manifold_vertex(int node_id,Halfedge_handle hedge){
+ //we turn around the hedge and check no halfedge is a border halfedge
+ Halfedge_handle curr=hedge;
+ do{
+ if ( curr->is_border_edge() ){
+ non_manifold_nodes.insert(node_id);
+ return;
+ }
+ curr=curr->next()->opposite();
+ }
+ while(curr!=hedge);
+ }
+
+ void check_node_on_non_manifold_edge(int node_id,Halfedge_handle hedge){
+ if ( hedge->is_border_edge() ) non_manifold_nodes.insert(node_id);
+ }
+
+ void new_node_added(int node_id,
+ internal_IOP::Intersection_type type,
+ Halfedge_handle principal_edge,
+ Halfedge_handle additional_edge,
+ bool is_vertex_coplanar,
+ bool is_vertex_opposite_coplanar)
+ {
+ switch(type)
+ {
+ case internal_IOP::FACET: //Facet intersected by an edge
+ {
+ typename In_face_map::iterator it_fmap=in_face.insert(std::make_pair(additional_edge->face(), Node_ids())).first;
+ it_fmap->second.push_back(node_id);
+ }
+ break;
+ case internal_IOP::EDGE: //Edge intersected by an edge
+ {
+ typename In_halfedge_map::iterator it_hedge_map=in_hedge.insert(std::make_pair(additional_edge,Node_id_set())).first;
+ it_hedge_map->second.insert(node_id);
+ check_node_on_non_manifold_edge(node_id,additional_edge);
+ }
+ break;
+ case internal_IOP::VERTEX:
+ {
+ //grab original vertex that is on commom intersection
+ typename Hedge_to_polyhedron_map::iterator it=hedge_to_polyhedron.find(additional_edge->facet()->halfedge());
+ CGAL_assertion(it!=hedge_to_polyhedron.end());
+ poly_to_vertices_on_inter[it->second].insert(std::make_pair(node_id,additional_edge));
+ polyhedron_to_map_node_to_polyhedron_vertex[it->second].insert(std::make_pair(node_id,additional_edge->vertex()));
+ all_incident_faces_got_a_node_as_vertex(additional_edge,node_id);
+ check_node_on_non_manifold_vertex(node_id,additional_edge);
+ }
+ break;
+ default:
+ return;
+ }
+
+ CGAL_assertion(!is_vertex_coplanar || !is_vertex_opposite_coplanar); //coplanar edge are not forwarded
+
+
+ if ( is_vertex_coplanar )
+ {
+ //grab original vertex that is on commom intersection
+ typename Hedge_to_polyhedron_map::iterator it=hedge_to_polyhedron.find(principal_edge->facet()->halfedge());
+ poly_to_vertices_on_inter[it->second].insert(std::make_pair(node_id,principal_edge));
+ polyhedron_to_map_node_to_polyhedron_vertex[it->second].insert(std::make_pair(node_id,principal_edge->vertex()));
+ all_incident_faces_got_a_node_as_vertex(principal_edge,node_id);
+ check_node_on_non_manifold_vertex(node_id,principal_edge);
+ }
+ else{
+ if ( is_vertex_opposite_coplanar ){
+ //grab original vertex that is on commom intersection
+ typename Hedge_to_polyhedron_map::iterator it=hedge_to_polyhedron.find(principal_edge->facet()->halfedge());
+ poly_to_vertices_on_inter[it->second].insert(std::make_pair(node_id,principal_edge->opposite()));
+ polyhedron_to_map_node_to_polyhedron_vertex[it->second].insert(std::make_pair(node_id,principal_edge->opposite()->vertex()));
+ all_incident_faces_got_a_node_as_vertex(principal_edge->opposite(),node_id);
+ check_node_on_non_manifold_vertex(node_id,principal_edge->opposite());
+ }
+ else{
+ //handle intersection on principal edge
+ typename In_halfedge_map::iterator it_hedge_map=in_hedge.insert(std::make_pair(principal_edge,Node_id_set())).first;
+ it_hedge_map->second.insert(node_id);
+ check_node_on_non_manifold_edge(node_id,principal_edge);
+ }
+ }
+ }
+
+ template<class Iterator>
+ void annotate_graph(Iterator begin,Iterator end)
+ {
+// std::cout << "Annotation graph..." << std::endl;
+ for (Iterator it=begin;it!=end;++it)
+ {
+ int node_id=it->first;
+ if (non_manifold_nodes.find(node_id)!=non_manifold_nodes.end()) it->second.make_terminal();
+ const std::set<int>& neighbors = it->second.neighbors;
+ graph_of_constraints.insert(std::make_pair(node_id,neighbors));
+ }
+ }
+
+ void update_terminal_nodes(std::vector<bool>&)
+ {
+ CGAL_assertion(!"Must not call this function");
+ }
+
+ void add_filtered_intersection(Halfedge_handle eh,Halfedge_handle fh,Polyhedron& Pe,Polyhedron& Pf){
+ //use the representant halfedge of the facet as key
+ //--set polyhedron for the two facets incident to the edge
+ hedge_to_polyhedron.insert(std::make_pair(eh->facet()->halfedge(),&Pe));
+ if ( !eh->opposite()->is_border() )
+ hedge_to_polyhedron.insert(std::make_pair(eh->opposite()->facet()->halfedge(),&Pe));
+ //--set polyhedron for the facet intersected by the edge
+ hedge_to_polyhedron.insert(std::make_pair(fh->facet()->halfedge(),&Pf));
+ }
+
+
+ struct Polyhedron_face_boundary{
+ std::vector<int> node_ids_array[3]; // the node_ids on each halfedges
+ std::map<Halfedge_handle,int,Cmp_unik_ad> hedges_ids;
+ Halfedge_handle halfedges[3]; //the three halfedges of the original face
+ Vertex_handle vertices[3]; //the three vertices of the original face
+ //node_ids_array[0] corresponds to the original edge vertices[0],vertices[1] = halfedges[0]
+ //node_ids_array[1] corresponds to the original edge vertices[1],vertices[2] = halfedges[1]
+ //node_ids_array[2] corresponds to the original edge vertices[2],vertices[0] = halfedges[2]
+ Polyhedron_face_boundary(Halfedge_handle first)
+ {
+ CGAL_assertion(first->next()->next()->next()==first); //the face is a triangle
+ hedges_ids.insert(std::make_pair(first,0));
+ hedges_ids.insert(std::make_pair(first->next(),1));
+ hedges_ids.insert(std::make_pair(first->next()->next(),2));
+ halfedges[0]=first;
+ halfedges[1]=first->next();
+ halfedges[2]=first->next()->next();
+
+ vertices[0]=halfedges[0]->opposite()->vertex();
+ vertices[1]=halfedges[1]->opposite()->vertex();
+ vertices[2]=halfedges[2]->opposite()->vertex();
+ }
+
+ //used when object was create with hedge but opposite was used to split the original face
+ void update_original_halfedge(Halfedge_handle original,Halfedge_handle new_hedge)
+ {
+ typename std::map<Halfedge_handle,int,Cmp_unik_ad>::iterator it_id=hedges_ids.find(original);
+ CGAL_assertion(it_id!=hedges_ids.end());
+ int index=it_id->second;
+ CGAL_assertion(halfedges[index]==original);
+ hedges_ids.erase(it_id);
+ hedges_ids.insert(std::make_pair(new_hedge,index));
+ halfedges[index]=new_hedge;
+ }
+
+ template <class Iterator>
+ void copy_node_ids(Halfedge_handle hedge,Iterator begin,Iterator end)
+ {
+ typename std::map<Halfedge_handle,int,Cmp_unik_ad>::iterator it_id=hedges_ids.find(hedge);
+ CGAL_assertion(it_id!=hedges_ids.end());
+ std::copy(begin,end,std::back_inserter(node_ids_array[it_id->second]));
+ }
+ };
+
+
+ void start_new_polyline(int i, int j)
+ {
+ if ( i==j ) //case of a single point
+ {
+ //TAG SL001
+ //nothing is done
+ return;
+ }
+ std::pair<typename An_edge_per_polyline_map::iterator,bool> res=
+ an_edge_per_polyline.insert(
+ std::make_pair( make_sorted_pair(i,j),
+ std::make_pair( std::map<Polyhedron*,Halfedge_handle>(),std::make_pair(false,0)) )
+ );
+ CGAL_assertion(res.second);
+ last_polyline=res.first;
+ if ( i !=last_polyline->first.first )
+ last_polyline->second.second.first=true;
+ }
+
+ void add_node_to_polyline(int){
+ ++(last_polyline->second.second.second);
+ }
+
+ void new_input_polyhedron(Polyhedron& P)
+ {
+ typedef std::pair<typename Poly_to_map_node::iterator,bool> Res;
+ CGAL_USE_TYPE(Res);
+ CGAL_assertion_code(Res res = )
+ polyhedron_to_map_node_to_polyhedron_vertex.insert(std::make_pair( &P,Node_to_polyhedron_vertex_map() ));
+ CGAL_assertion(res.second == true);
+ }
+
+ //1) split_halfedges and retriangulate faces with no intersection point interior to the facet
+ //2) retriangulate using a constrained Delaunay triangulation each triangle in each Polyhedron that contains at least
+ // one intersection point inside the facet
+ //3) mark polyhedron edges that are on the intersection
+ //4) create one output polyhedron per connected component of polyhedron, connected by an edge which is not an intersection edge
+ //5) import each piece into a common combinatorial map
+ //6) glue all the pieces together
+ template <class Nodes_vector>
+ void finalize(const Nodes_vector& nodes){
+ //mark halfedge that are on the intersection
+ //SL: I needed to use a map because to get the orientation around the edge,
+ // I need to know in the case the third vertex is a node its index (for exact construction)
+ typedef std::map<Halfedge_const_handle,std::pair<int,int>,Cmp_unik_ad > Border_halfedges_map;
+ Border_halfedges_map border_halfedges;
+
+ //Additionnal stuct to mark halfedge of the original polyhedra that are on the intersection
+ typedef Halfedge_marker<Mark_intersection_halfedges> Marker;
+
+ //store for each triangle facet which boundary is intersected by the other surface,
+ //original vertices (and halfedges in the refined mesh pointing on these vertices)
+ typedef std::map<Face_handle,Polyhedron_face_boundary,Cmp_handle> Faces_boundary;
+ Faces_boundary faces_boundary;
+
+ //0) For each polyhedron, collect original vertices that belongs to the intersection.
+ // From the graph of constaints, extract intersection edges that are incident to such vertices. In case
+ // there exists another original vertex adjacent to the first one found, this halfedge must be
+ // marked on the boundary (and possibly update an_edge_per_polyline).
+ // This is done first to avoid halfedges stored to be modified in the steps following.
+ for (typename Poly_to_vertices_on_intersection_map::iterator
+ it=poly_to_vertices_on_inter.begin();
+ it!=poly_to_vertices_on_inter.end();
+ ++it)
+ {
+ Polyhedron* poly=it->first;
+ std::set<std::pair<int,int> > already_done;
+ Node_to_target_of_hedge_map& nodes_to_hedge=it->second;
+ for(typename Node_to_target_of_hedge_map::iterator
+ it_node_2_hedge=nodes_to_hedge.begin();
+ it_node_2_hedge!=nodes_to_hedge.end();
+ ++it_node_2_hedge)
+ {
+ int node_id_of_first=it_node_2_hedge->first;
+ std::map< int,std::set<int> >::iterator it_neighbors=graph_of_constraints.find(node_id_of_first);
+ if ( it_neighbors!=graph_of_constraints.end() )
+ {
+ std::set<int>& neighbors=it_neighbors->second;
+ for (std::set<int>::iterator it_id=neighbors.begin();it_id!=neighbors.end();++it_id){
+ if ( already_done.find(std::make_pair(*it_id,node_id_of_first))!=already_done.end() ) continue;//already done for the opposite
+ typename Node_to_target_of_hedge_map::iterator it_node_2_hedge_two=nodes_to_hedge.find(*it_id);
+ if ( it_node_2_hedge_two!=nodes_to_hedge.end() ) //a full edge is on intersection
+ {
+ //get the corresponding halfedge with vertex corresponding to node_id_of_first
+ Halfedge_handle hedge=it_node_2_hedge->second;
+ #ifndef NDEBUG
+ Halfedge_handle start=hedge;
+ #endif
+ while ( hedge->opposite()->vertex()!=it_node_2_hedge_two->second->vertex() ){
+ hedge=hedge->next()->opposite();
+ #ifndef NDEBUG
+ CGAL_assertion(hedge!=start);
+ #endif
+ }
+ std::pair<int,int> edge_pair(*it_id,node_id_of_first);
+ border_halfedges.insert( std::make_pair(hedge,edge_pair) );
+ Marker::mark(hedge);
+ update_edge_per_polyline(poly,edge_pair,hedge);
+ //save the fact that we already handle this edge
+ already_done.insert(std::make_pair(node_id_of_first,*it_id));
+ }
+ }
+ }
+ #ifdef CGAL_COREFINEMENT_DEBUG
+ else
+ {
+ std::cout << "X1: Found an isolated point" << std::endl;
+ }
+ #endif
+ }
+ }
+
+ //1) First split halfedges cut by the intersection polyline(s)
+ for (typename In_halfedge_map::iterator it=in_hedge.begin();it!=in_hedge.end();++it)
+ {
+ Halfedge_handle hedge=it->first; //the halfedge to be split (and its opposite too)
+ Node_ids node_ids; //indices of the intersection points to be inserted
+ //we used a set to avoid having duplicated nodes reported on an edge of two coplanar triangles
+ std::copy(it->second.begin(),it->second.end(),std::back_inserter(node_ids));
+ typename Hedge_to_polyhedron_map::iterator it_poly=hedge_to_polyhedron.find( hedge->facet()->halfedge() );
+ CGAL_assertion(it_poly!=hedge_to_polyhedron.end());
+ Polyhedron* P=it_poly->second; //the polyhedron in which vertices should be added
+
+ sort_vertices_along_hedge(node_ids,hedge,nodes);
+
+ //save original face and nodes for face of hedge (1)
+ if ( !hedge->is_border() ){
+ typename Faces_boundary::iterator it_face=faces_boundary.find(hedge->face());
+ if (it_face==faces_boundary.end())
+ it_face=faces_boundary.insert(std::make_pair(hedge->face(),Polyhedron_face_boundary(hedge))).first;
+ it_face->second.copy_node_ids(hedge,node_ids.begin(),node_ids.end());
+ }
+
+ //save original face and nodes for face of hedge->opposite (2)
+ typename Faces_boundary::iterator opposite_original_info=faces_boundary.end();
+ if ( !hedge->opposite()->is_border() ){
+ opposite_original_info=faces_boundary.find(hedge->opposite()->face());
+ if (opposite_original_info==faces_boundary.end())
+ opposite_original_info=faces_boundary.insert(std::make_pair(hedge->opposite()->face(),Polyhedron_face_boundary(hedge->opposite()))).first;
+ opposite_original_info->second.copy_node_ids(hedge->opposite(),node_ids.rbegin(),node_ids.rend());
+ }
+
+ typename Poly_to_map_node::iterator it_map=polyhedron_to_map_node_to_polyhedron_vertex.find(P);
+ CGAL_assertion(it_map!=polyhedron_to_map_node_to_polyhedron_vertex.end());
+ //a map to identify the vertex in the polyhedron corresponding to an intersection point
+ Node_to_polyhedron_vertex_map& node_to_polyhedron_vertex=it_map->second;
+
+ #ifndef NDEBUG
+ Vertex_handle original_vertex=hedge->opposite()->vertex();
+ #endif
+
+ //We need an edge incident to the source vertex of hedge. This is the first opposite edge created.
+ bool first=true; Halfedge_handle hedge_incident_to_src;
+ //do split the edges
+ for (std::vector<int>::const_iterator it_id=node_ids.begin();it_id!=node_ids.end();++it_id){
+ Vertex_handle v=split_edge(hedge,nodes[*it_id],*P);
+ node_to_polyhedron_vertex.insert(std::make_pair(*it_id,v));
+ if (first){
+ first=false;
+ hedge_incident_to_src=hedge->opposite()->next();
+ }
+ }
+
+ #ifndef NDEBUG
+ CGAL_assertion(hedge_incident_to_src->vertex()==original_vertex);
+ CGAL_assertion(hedge_incident_to_src->face()==hedge->opposite()->face());
+ #endif
+
+ //save original face and nodes for face of hedge->opposite (2)
+ if ( !hedge->opposite()->is_border() ){
+ CGAL_assertion(opposite_original_info!=faces_boundary.end());
+ opposite_original_info->second.update_original_halfedge(hedge->opposite(),hedge_incident_to_src);
+ }
+
+ //insert the two incident faces in in_face map so that they will be triangulated.
+ if (!hedge->is_border()) in_face.insert(std::make_pair(hedge->face(),Node_ids()));
+ if (!hedge->opposite()->is_border()) in_face.insert(std::make_pair(hedge->opposite()->face(),Node_ids()));
+ }
+
+ //2)triangulation of the triangle faces containing intersection point in their interior
+ // and also those with intersection points only on the boundary.
+ for (typename In_face_map::iterator it=in_face.begin();it!=in_face.end();++it)
+ {
+ Face_handle f = it->first; //the face to be retriangulated
+ Node_ids& node_ids = it->second; //the index of the intersection point that are interior to the face
+ typename Faces_boundary::iterator it_fb=faces_boundary.find(f);
+
+
+ typename Hedge_to_polyhedron_map::iterator it_polyhedron = hedge_to_polyhedron.find (f->halfedge()); //we can do this because the halfedge is still the same (at least its address)+no Face::set_halfedge called
+ CGAL_assertion(it_polyhedron != hedge_to_polyhedron.end());
+ Polyhedron* P=it_polyhedron->second;
+ typename Poly_to_map_node::iterator it_map=polyhedron_to_map_node_to_polyhedron_vertex.find(P);
+ CGAL_assertion(it_map!=polyhedron_to_map_node_to_polyhedron_vertex.end());
+ //a map to identify the vertex in the polyhedron corresponding to an intersection point
+ Node_to_polyhedron_vertex_map& node_to_polyhedron_vertex=it_map->second;
+
+ std::map<int,typename CDT::Vertex_handle> id_to_CDT_vh;
+
+ //associate an edge of the triangulation to a halfedge in a given polyhedron
+ std::map<std::pair<int,int>,Halfedge_handle> edge_to_hedge;
+
+ Vertex_handle triangle_boundary[3];
+ int triangle_boundary_indices[3]; //the node_id of the triangle original vertex or a fake id
+ if (it_fb!=faces_boundary.end()){ //the boundary of the triangle face was refined
+ triangle_boundary[0]=it_fb->second.vertices[0];
+ triangle_boundary[1]=it_fb->second.vertices[1];
+ triangle_boundary[2]=it_fb->second.vertices[2];
+ set_triangle_boundary_indices(triangle_boundary,triangle_boundary_indices);
+ }
+ else{
+ triangle_boundary[0]=f->halfedge()->vertex(); //-1
+ triangle_boundary[1]=f->halfedge()->next()->vertex(); //-2
+ triangle_boundary[2]=f->halfedge()->next()->next()->vertex(); //-3
+ CGAL_assertion(f->halfedge()->next()->next()->next()==f->halfedge());//check this is a triangle
+ set_triangle_boundary_indices(triangle_boundary,triangle_boundary_indices);
+ edge_to_hedge.insert (std::make_pair( std::make_pair( triangle_boundary_indices[2],triangle_boundary_indices[0] ) , f->halfedge() ) );
+ edge_to_hedge.insert (std::make_pair( std::make_pair( triangle_boundary_indices[0],triangle_boundary_indices[1] ) , f->halfedge()->next() ) );
+ edge_to_hedge.insert (std::make_pair( std::make_pair( triangle_boundary_indices[1],triangle_boundary_indices[2] ) , f->halfedge()->next()->next() ) );
+ }
+
+
+ #ifdef DO_NO_USE_EXACT_CDT
+ typename Kernel::Plane_3 plane(triangle_boundary[0]->point(),triangle_boundary[1]->point(),triangle_boundary[2]->point());
+ #else
+ CGAL::Cartesian_converter<Kernel,Exact_kernel> convert;
+ typename Exact_kernel::Plane_3 plane(convert(triangle_boundary[0]->point()),convert(triangle_boundary[1]->point()),convert(triangle_boundary[2]->point()));
+ #endif
+ CDT triangulation;
+ //insert point inside face
+ for (std::vector<int>::iterator it_node_id=node_ids.begin();it_node_id!=node_ids.end();++it_node_id){
+ #ifdef DO_NO_USE_EXACT_CDT
+ typename CDT::Vertex_handle vh=triangulation.insert(plane.to_2d(nodes[*it_node_id]));
+ #else
+ typename CDT::Vertex_handle vh=triangulation.insert(plane.to_2d(nodes.exact_node(*it_node_id)));
+ #endif
+ vh->info()=*it_node_id;
+ id_to_CDT_vh.insert(std::make_pair(*it_node_id,vh));
+ }
+
+
+ typename CDT::Vertex_handle triangle_vertices[3];
+ #ifdef DO_NO_USE_EXACT_CDT
+ triangle_vertices[0]=triangulation.insert(plane.to_2d(triangle_boundary[0]->point()));
+ triangle_vertices[1]=triangulation.insert(plane.to_2d(triangle_boundary[1]->point()));
+ triangle_vertices[2]=triangulation.insert(plane.to_2d(triangle_boundary[2]->point()));
+ #else
+ //we can do this because these are input points.
+ triangle_vertices[0]=triangulation.insert(plane.to_2d(convert(triangle_boundary[0]->point())));
+ triangle_vertices[1]=triangulation.insert(plane.to_2d(convert(triangle_boundary[1]->point())));
+ triangle_vertices[2]=triangulation.insert(plane.to_2d(convert(triangle_boundary[2]->point())));
+ #endif
+
+ triangle_vertices[0]->info()=triangle_boundary_indices[0];
+ triangle_vertices[1]->info()=triangle_boundary_indices[1];
+ triangle_vertices[2]->info()=triangle_boundary_indices[2];
+ //insert face_extremities: we use operator[] because indice -1,-2,-3 are used in each loop and are specific to the current face
+ node_to_polyhedron_vertex[-1]=triangle_boundary[0];
+ node_to_polyhedron_vertex[-2]=triangle_boundary[1];
+ node_to_polyhedron_vertex[-3]=triangle_boundary[2];
+
+ //if one of the triangle original vertex is also a node
+ for (int ik=0;ik<3;++ik){
+ if ( triangle_boundary_indices[ik]>=0 )
+ id_to_CDT_vh.insert(std::make_pair(triangle_boundary_indices[ik],triangle_vertices[ik]));
+ }
+ //insert points on edges
+ #ifdef DO_NO_USE_EXACT_CDT
+ //and constrains these edges
+ #endif
+ if (it_fb!=faces_boundary.end()) //is there at least one intersection point on the boundary of the face?
+ {
+ //in the following loop, for each original edge of the triangle, we insert the constrained edges
+ // and we recover the halfedge_handle corresponding to these constrained (they are already in the polyhedron)
+ for (int i=0;i<3;++i){
+// std::cerr << "Boundary edges" << std::endl;
+// std::cerr << " " << -1-i <<std::endl;
+ //handle case of halfedge starting at triangle_vertices[i] and ending at triangle_vertices[(i+1)%3]
+ Node_ids& bounding_ids=it_fb->second.node_ids_array[i];
+ typename CDT::Vertex_handle previous=triangle_vertices[i];
+ int previous_index=triangle_boundary_indices[i]; //index of original Polyhedron vertex
+ Halfedge_handle hedge = it_fb->second.halfedges[ (i+2) % 3]->next();
+ CGAL_assertion( hedge->opposite()->vertex()==it_fb->second.vertices[i] );
+ if (!bounding_ids.empty()){ //is there al least one intersection point on this edge?
+ for (Node_ids::iterator it_id=bounding_ids.begin();it_id!=bounding_ids.end();++it_id){
+// std::cerr << " "<< *it_id << std::endl;
+ #ifdef DO_NO_USE_EXACT_CDT
+ typename CDT::Vertex_handle vh=triangulation.insert(plane.to_2d(nodes[*it_id]));
+ #else
+ typename CDT::Vertex_handle vh=triangulation.insert(plane.to_2d(nodes.exact_node(*it_id)));
+ #endif
+ vh->info()=*it_id;
+ id_to_CDT_vh.insert(std::make_pair(*it_id,vh));
+ #ifdef DO_NO_USE_EXACT_CDT
+ triangulation.insert_constraint(previous,vh);
+ #endif
+ edge_to_hedge.insert (std::make_pair( std::make_pair(previous_index,*it_id),hedge) );
+ previous=vh;
+ hedge=hedge->next();
+ previous_index=*it_id;
+ }
+ }
+ else{
+ CGAL_assertion( it_fb->second.halfedges[i]->vertex() == it_fb->second.vertices[ (i+1) % 3 ] );
+ CGAL_assertion( it_fb->second.halfedges[i]->opposite()->vertex() == it_fb->second.vertices[ i ] );
+ }
+ CGAL_assertion(hedge==it_fb->second.halfedges[i]);
+ edge_to_hedge.insert (std::make_pair( std::make_pair(previous_index,triangle_boundary_indices[(i+1) % 3]) , it_fb->second.halfedges[i] ) );
+// std::cerr << " " << -1 - ( (i+1) % 3 ) <<std::endl;
+ #ifdef DO_NO_USE_EXACT_CDT
+ triangulation.insert_constraint(previous,triangle_vertices[(i+1)%3]);
+ #endif
+ }
+ }
+
+ std::list<std::pair<int,int> > constrained_edges;
+
+ //insert constraints that are interior to the triangle (in the case no edges are collinear in the meshes)
+ insert_constrained_edges(node_ids,triangulation,id_to_CDT_vh,constrained_edges);
+
+ //insert constraints between points that are on the boundary (not a contrained on the triangle boundary)
+ if (it_fb!=faces_boundary.end()) //is there at least one intersection point on the boundary of the face?
+ {
+ for (int i=0;i<3;++i){
+ Node_ids& bounding_ids=it_fb->second.node_ids_array[i];
+ insert_constrained_edges(bounding_ids,triangulation,id_to_CDT_vh,constrained_edges,true);
+ }
+ }
+
+ //insert coplanar edges for endpoints of triangles
+ for (int i=0;i<3;++i){
+ int nindex=triangle_vertices[i]->info();
+ if ( nindex >=0 )
+ insert_constrained_edges_coplanar_case(nindex,triangulation,id_to_CDT_vh);
+ }
+
+ //XSL_TAG_CPL_VERT
+ //collect edges incident to a point that is the intersection of two coplanar faces.
+ //This ensure that triangulations are compatible.
+ if (it_fb!=faces_boundary.end()) //is there at least one intersection point on the boundary of the face?
+ {
+ for (typename CDT::Finite_vertices_iterator vit=triangulation.finite_vertices_begin(),
+ vit_end=triangulation.finite_vertices_end();vit_end!=vit;++vit)
+ {
+ //skip original vertices (that are not nodes) and non-coplanar facet issued vertices
+ //(this is working because intersection points between coplanar facets are the first inserted)
+ if ( vit->info() < 0 || vit->info() >= number_coplanar_vertices) continue;
+ std::map< int,std::set<int> >::iterator res=coplanar_constraints.insert(std::make_pair(vit->info(),std::set<int>())).first;
+ //turn around the vertex and get incident edge
+ typename CDT::Edge_circulator start=triangulation.incident_edges(vit);
+ typename CDT::Edge_circulator curr=start;
+ do{
+ if (triangulation.is_infinite(*curr) ) continue;
+ typename CDT::Edge mirror_edge=triangulation.mirror_edge(*curr);
+ if ( triangulation.is_infinite( curr->first->vertex(curr->second) ) ||
+ triangulation.is_infinite( mirror_edge.first->vertex(mirror_edge.second) ) )
+ continue; //skip edges that are on the boundary of the triangle (these are already constrained)
+ //insert edges in the set of constraints
+ int nindex =
+ curr->first->vertex( (curr->second+1)%3 )==static_cast<typename CDT::Vertex_handle>(vit)?
+ (curr->second+2)%3:(curr->second+1)%3;
+ typename CDT::Vertex_handle vn=curr->first->vertex(nindex);
+ if ( vit->info() > vn->info() ) continue; //take only one out of the two edges + skip negative vn->info()
+ CGAL_assertion(vn->info()>=0);
+ res->second.insert( vn->info() );
+ }while(start!=++curr);
+ }
+
+// this is a working alternative that should be slower
+// for (typename CDT::Finite_edges_iterator eit=triangulation.finite_edges_begin(),
+// eit_end=triangulation.finite_edges_end();eit_end!=eit;++eit)
+// {
+// typename CDT::Edge mirror_edge=triangulation.mirror_edge(*eit);
+// if ( triangulation.is_infinite( eit->first->vertex(eit->second) ) ||
+// triangulation.is_infinite( mirror_edge.first->vertex(mirror_edge.second) ) )
+// continue; //skip edges that are on the boundary of the triangle (these are already constrained)
+// typename CDT::Vertex_handle v1=eit->first->vertex( (eit->second+1)%3 ),
+// v2=eit->first->vertex( (eit->second+2)%3 );
+// if (v1->info()<0 || v2->info()<0) continue;
+// if ( v1->info() > v2->info() ) std::swap(v1,v2);
+// coplanar_constraints.insert(std::make_pair(v1->info(),std::set<int>())).first->second.insert(v2->info());
+// }
+ }
+
+
+ //create a modifier to insert nodes and copy the triangulation of the face
+ //inside the polyhedron
+ internal_IOP::Triangulate_a_face<typename Polyhedron::HalfedgeDS> modifier(f,nodes,node_ids,node_to_polyhedron_vertex,edge_to_hedge,triangulation);
+
+ CGAL_assertion(P->is_valid());
+ P->delegate(modifier);
+ CGAL_assertion(P->is_valid());
+
+ //3) mark halfedges that are common to two polyhedral surfaces
+ //recover halfedges inserted that are on the intersection
+ for (std::list<std::pair<int,int> >::iterator it_cst=constrained_edges.begin();it_cst!=constrained_edges.end();++it_cst)
+ {
+ typename std::map<std::pair<int,int>,Halfedge_handle>::iterator it_poly_hedge=edge_to_hedge.find(*it_cst);
+ //we cannot have an assertion here in the case an edge or part of an edge is a constraints.
+ //Indeed, the graph_of_constraints report an edge 0,1 and 1,0 for example while only one of the two
+ //is defined as one of them defines an adjacent face
+ //CGAL_assertion(it_poly_hedge!=edge_to_hedge.end());
+ if( it_poly_hedge!=edge_to_hedge.end() ){
+ border_halfedges.insert( std::make_pair(Halfedge_const_handle(it_poly_hedge->second),*it_cst) );
+ Marker::mark(it_poly_hedge->second);
+ update_edge_per_polyline(P,it_poly_hedge->first,it_poly_hedge->second);
+ }
+ else{
+ //WARNING: in few case this is needed if the marked edge is on the border
+ //to optimize it might be better to only use sorted pair. TAG_SLXX1
+ std::pair<int,int> opposite_pair(it_cst->second,it_cst->first);
+ it_poly_hedge=edge_to_hedge.find(opposite_pair);
+ CGAL_assertion( it_poly_hedge!=edge_to_hedge.end() );
+
+ border_halfedges.insert( std::make_pair(Halfedge_const_handle(it_poly_hedge->second),opposite_pair) );
+ Marker::mark(it_poly_hedge->second);
+ update_edge_per_polyline(P,it_poly_hedge->first,it_poly_hedge->second);
+ }
+ }
+ }
+
+ if (do_not_build_cmap) return;
+
+ //4) create one output polyhedron per connected component of polyhedron,
+ // connected by an edge which is not an intersection edge
+ //5) import into a Combinatorial map
+ #ifdef CGAL_COREFINEMENT_DEBUG
+ std::cout << "Nb marked edges " << border_halfedges.size() << std::endl;
+// for (typename Border_halfedges_map::iterator it=border_halfedges.begin();it!=border_halfedges.end();++it)
+// std::cout << it->first->opposite()->vertex()->point() << " " << it->first->vertex()->point() << " is constrained " << std::endl;
+ std::cout << "Nb polylines " << an_edge_per_polyline.size() << std::endl;
+ #endif
+
+ internal_IOP::Non_intersection_halfedge<Polyhedron> criterium(border_halfedges);
+
+ int mark_index=final_map().get_new_mark(); //mark used to tag dart that are on an intersection
+
+ //define a map that will contain the correspondance between selected halfedges of the boundary and
+ //their corresponding Dart_handle in the cmap.
+ typedef std::map<Halfedge_const_handle,typename Combinatorial_map_3::Dart_handle,internal_IOP::Compare_address<Polyhedron> > Halfedge_to_dart_map;
+ Halfedge_to_dart_map selected_hedge_to_dart;
+ for (typename An_edge_per_polyline_map::iterator it=an_edge_per_polyline.begin();it!=an_edge_per_polyline.end();++it)
+ {
+ CGAL_assertion(it->second.first.size()==2);
+ //orientation of faces around the edge (to be sure we can do it)
+ Halfedge_handle first_hedge=it->second.first.begin()->second;
+ Halfedge_handle second_hedge=boost::next(it->second.first.begin())->second;
+
+ if (!first_hedge->is_border()) selected_hedge_to_dart.insert(std::make_pair(first_hedge,Dart_handle(NULL)));
+ if (!first_hedge->opposite()->is_border()) selected_hedge_to_dart.insert(std::make_pair(first_hedge->opposite(),Dart_handle(NULL)));
+ if (!second_hedge->is_border()) selected_hedge_to_dart.insert(std::make_pair(second_hedge,Dart_handle(NULL)));
+ if (!second_hedge->opposite()->is_border()) selected_hedge_to_dart.insert(std::make_pair(second_hedge->opposite(),Dart_handle(NULL)));
+ }
+
+ #ifdef CGAL_COREFINEMENT_DEBUG
+ int polynb=0;
+ #endif
+ for (typename Poly_to_map_node::iterator
+ it=polyhedron_to_map_node_to_polyhedron_vertex.begin();
+ it!=polyhedron_to_map_node_to_polyhedron_vertex.end();
+ ++it
+ )
+ {
+ typedef typename Polyhedron::Facet_const_handle Facet_const_handle;
+ typedef ::CGAL::Union_find<Facet_const_handle> UF;
+ typedef typename UF::handle UF_handle;
+ typedef std::map<Facet_const_handle,std::list<Facet_const_handle>,internal::Compare_handle_ptr<Polyhedron> > Result;
+ typedef std::map<Facet_const_handle,UF_handle,internal::Compare_handle_ptr<Polyhedron> > Facet_to_handle_map;
+
+ UF uf;
+ Facet_to_handle_map map_f2h;
+ Result result;
+ Polyhedron* current_poly=it->first;
+
+ #ifdef CGAL_COREFINEMENT_DEBUG
+ std::cout << "writing poly debug"<< std::endl;
+ std::stringstream ss;
+ ss << "output_debug-" << ++polynb << ".off";
+ std::ofstream output_debug(ss.str().c_str());
+ output_debug << *current_poly;
+ #endif
+
+ extract_connected_components(*(current_poly),criterium,uf,map_f2h,result);
+
+
+ //add each connected component in the map with 2 volumes per component.
+ for (typename Result::iterator it_res=result.begin();it_res!=result.end();++it_res)
+ {
+ //create in the final Cmap a 2D component containing faces of a connected component
+ //(twice: one with same orientation and one with the opposite orientation to model the other volume)
+ Dart_handle d = import_from_polyhedron_subset<Polyhedron>(final_map(),it_res->second.begin(),it_res->second.end(),criterium,selected_hedge_to_dart,mark_index);
+ //set an attribute to one volume represented by this component to indicates
+ //a part outside of the polyhedron current_poly
+ typename Combinatorial_map_3_::template Attribute_range<3>::type::iterator attrib=final_map().template create_attribute<3>();
+ attrib->info().outside.insert(current_poly);
+ final_map().template set_attribute<3>(d,attrib);
+ //set the attribute for the opposite volume: represent a part inside current_poly
+ attrib=final_map().template create_attribute<3>();
+ attrib->info().inside.insert(current_poly);
+ final_map().template set_attribute<3>(d->beta(3),attrib);
+
+ #ifdef CGAL_COREFINEMENT_DEBUG
+ final_map().display_characteristics(std::cout);
+ std::cout << std::endl;
+ #endif
+ }
+ }
+ #ifndef NDEBUG
+ for(typename Halfedge_to_dart_map::iterator it=selected_hedge_to_dart.begin();it!=selected_hedge_to_dart.end();++it)
+ CGAL_assertion(it->second!=Dart_handle(NULL));
+ #endif
+
+ CGAL_assertion(final_map().is_valid());
+
+ std::set<Dart_handle> darts_to_remove;
+
+ //6) Glue pieces together
+ // using one edge per intersection polyline, we merge the different volumes
+ for (typename An_edge_per_polyline_map::iterator it=an_edge_per_polyline.begin();it!=an_edge_per_polyline.end();++it)
+ {
+ CGAL_assertion(it->second.first.size()==2);
+ //orientation of faces around the edge (to be sure we can do it)
+ std::pair<int,int> indices = it->first;
+ const std::pair<bool,int>& polyline_info=it->second.second;
+
+ //get the two halfedges incident to the edge [indices.first,indices.second]
+ Halfedge_handle first_hedge=it->second.first.begin()->second;
+ Halfedge_handle second_hedge=boost::next(it->second.first.begin())->second;
+
+ CGAL_assertion(nodes[indices.second]==first_hedge->vertex()->point());
+ CGAL_assertion(nodes[indices.first]==first_hedge->opposite()->vertex()->point());
+ CGAL_assertion(nodes[indices.second]==second_hedge->vertex()->point());
+ CGAL_assertion(nodes[indices.first]==second_hedge->opposite()->vertex()->point());
+
+ Polyhedron* first_poly = it->second.first.begin()->first;
+ Polyhedron* second_poly = boost::next(it->second.first.begin())->first;
+
+ //different handling depending on the number of incident triangles to the edge.
+ //After sewing there are two,three or four volumes if there are two,three or four incident triangles respectively
+ if ( first_hedge->is_border() || first_hedge->opposite()->is_border() ){
+ if (second_hedge->is_border() || second_hedge->opposite()->is_border())
+ sew_2_two_volumes_case(first_hedge,second_hedge,border_halfedges,selected_hedge_to_dart,mark_index,darts_to_remove,nodes,indices,polyline_info);
+ else
+ sew_2_three_volumes_case(second_hedge, first_hedge,indices,nodes,border_halfedges,selected_hedge_to_dart,second_poly,first_poly,mark_index,darts_to_remove,polyline_info);
+ }
+ else
+ if (second_hedge->is_border() || second_hedge->opposite()->is_border())
+ sew_2_three_volumes_case(first_hedge, second_hedge,indices,nodes,border_halfedges,selected_hedge_to_dart,first_poly,second_poly,mark_index,darts_to_remove,polyline_info);
+ else
+ {
+ //Sort the four triangle facets around their common edge
+ // we suppose that the exterior of the polyhedron is indicated by
+ // counterclockwise oriented facets.
+ Vertex_handle P1=first_hedge->opposite()->next()->vertex();
+ Vertex_handle P2=first_hedge->next()->vertex();
+ // when looking from the side of indices.second, the interior of the first polyhedron is described
+ // by turning counterclockwise from P1 to P2
+ Vertex_handle Q1=second_hedge->opposite()->next()->vertex();
+ Vertex_handle Q2=second_hedge->next()->vertex();
+ // when looking from the side of indices.second, the interior of the second polyhedron is described
+ // by turning from Q1 to Q2
+
+ //check if the third point of each triangular face is an original point (stay -1)
+ //or a intersection point (in that case we need the index of the corresponding node to
+ //have the exact value of the point)
+ int index_p1=node_index_of_incident_vertex(first_hedge->opposite()->next(),border_halfedges);
+ int index_p2=node_index_of_incident_vertex(first_hedge->next(),border_halfedges);
+ int index_q1=node_index_of_incident_vertex(second_hedge->opposite()->next(),border_halfedges);
+ int index_q2=node_index_of_incident_vertex(second_hedge->next(),border_halfedges);
+
+ #ifdef CGAL_COREFINEMENT_DEBUG
+ std::cout << index_p1 << " " << index_p2 << " " << index_q1 << " " <<index_q2 << std::endl;
+ std::cout << nodes[indices.first] << " | " << nodes[indices.second] << std::endl;
+ std::cout << P1->point() << " | " << P2->point() << " | " << Q1->point() << " | " <<Q2->point() << std::endl;
+ #endif
+
+ if ( coplanar_triangles_case_handled(first_hedge,second_hedge,indices,nodes,index_p1,index_p2,index_q1,index_q2,selected_hedge_to_dart,mark_index,darts_to_remove,polyline_info) )
+ continue;
+
+ CGAL_assertion(P1->point() !=Q1->point() && P1->point()!=Q2->point() && P2->point() !=Q1->point() && P2->point()!=Q2->point());
+
+ bool Q1_is_between_P1P2 = filtered_order_around_edge(indices.first,indices.second,index_p1,index_p2,index_q1,P1,P2,Q1,nodes);
+ bool Q2_is_between_P1P2 = filtered_order_around_edge(indices.first,indices.second,index_p1,index_p2,index_q2,P1,P2,Q2,nodes);
+
+
+ //Recover the dart that will be the start point of the different sewing
+ // dof_X_outside = dart of face of , meaning the triangle containing the
+ // point X and part of the volume outside of the corresponding polyhedron
+ //-----first polyhedron
+ Dart_handle dof_P1_outside = get_associated_dart(first_hedge->opposite(),selected_hedge_to_dart);
+ Dart_handle dof_P2_outside = get_associated_dart(first_hedge,selected_hedge_to_dart);
+ //-----second polyhedron
+ Dart_handle dof_Q1_outside = get_associated_dart(second_hedge->opposite(),selected_hedge_to_dart);
+ Dart_handle dof_Q2_outside = get_associated_dart(second_hedge,selected_hedge_to_dart);
+
+ if ( Q1_is_between_P1P2 ){
+ if( Q2_is_between_P1P2 )
+ {
+ bool P1_is_between_Q1Q2 = filtered_order_around_edge(indices.first,indices.second,index_q1,index_q2,index_p1,Q1,Q2,P1,nodes);
+ if (!P1_is_between_Q1Q2){
+ // poly_first - poly_second = P1Q1 U Q2P2
+ // poly_second - poly_first = {0}
+ // poly_first \cap poly_second = Q1Q2
+ // opposite( poly_first U poly_second ) = P2P1
+ sew_2_marked_darts( final_map(),dof_P1_outside->beta(3) , dof_Q1_outside ,mark_index, nodes, indices, polyline_info); //P1Q1
+ sew_2_marked_darts( final_map(),dof_Q2_outside , dof_P2_outside->beta(3) ,mark_index, nodes, indices, polyline_info); //Q2P2
+ sew_2_marked_darts( final_map(),dof_Q1_outside->beta(3) , dof_Q2_outside->beta(3) ,mark_index, nodes, indices, polyline_info); //Q1Q2
+ sew_2_marked_darts( final_map(),dof_P2_outside , dof_P1_outside ,mark_index, nodes, indices, polyline_info); //P2P1
+ //update inside outside info (because darts from the same volume have been merged)
+ dof_Q1_outside->beta(3)->template attribute<3>()->info().inside.insert(first_poly); //update Q1Q2 inside poly
+ dof_P2_outside->template attribute<3>()->info().outside.insert(second_poly);//update P2P1 outside poly
+ }
+ else{
+ // poly_first - poly_second = Q2Q1
+ // poly_second - poly_first = P2P1
+ // poly_first \cap poly_second = P1Q2 U Q1P2
+ // opposite( poly_first U poly_second ) = {O}
+ sew_2_marked_darts( final_map(),dof_Q2_outside , dof_Q1_outside ,mark_index, nodes, indices, polyline_info); //Q2Q1
+ sew_2_marked_darts( final_map(),dof_P2_outside , dof_P1_outside ,mark_index, nodes, indices, polyline_info); //P2P1
+ sew_2_marked_darts( final_map(),dof_Q1_outside->beta(3) , dof_P2_outside->beta(3) ,mark_index, nodes, indices, polyline_info); //Q1P2
+ sew_2_marked_darts( final_map(),dof_P1_outside->beta(3) , dof_Q2_outside->beta(3) ,mark_index, nodes, indices, polyline_info); //P1Q2
+ //update inside outside info (because darts from the same volume have been merged)
+ dof_Q2_outside->template attribute<3>()->info().inside.insert(first_poly); //update Q2Q1 inside poly
+ dof_P2_outside->template attribute<3>()->info().inside.insert(second_poly);//update P2P1 inside poly
+ }
+ }
+ else
+ {
+ // poly_first - poly_second = P1Q1
+ // poly_second - poly_first = P2Q2
+ // poly_first \cap poly_second = Q1P2
+ // opposite( poly_first U poly_second ) = Q2P1
+ sew_2_marked_darts( final_map(),dof_P1_outside->beta(3) , dof_Q1_outside ,mark_index, nodes, indices, polyline_info); //P1Q1
+ sew_2_marked_darts( final_map(),dof_P2_outside , dof_Q2_outside->beta(3) ,mark_index, nodes, indices, polyline_info); //P2Q2
+ sew_2_marked_darts( final_map(),dof_Q1_outside->beta(3) , dof_P2_outside->beta(3) ,mark_index, nodes, indices, polyline_info); //Q1P2
+ sew_2_marked_darts( final_map(),dof_Q2_outside , dof_P1_outside ,mark_index, nodes, indices, polyline_info); //Q2P1
+ }
+ }
+ else
+ {
+ if( Q2_is_between_P1P2 )
+ {
+ // poly_first - poly_second = Q2P2
+ // poly_second - poly_first = Q1P1
+ // poly_first \cap poly_second = P1Q2
+ // opposite( poly_first U poly_second ) = P2Q1
+ sew_2_marked_darts( final_map(),dof_Q2_outside , dof_P2_outside->beta(3) ,mark_index, nodes, indices, polyline_info); //Q2P2
+ sew_2_marked_darts( final_map(),dof_Q1_outside->beta(3) , dof_P1_outside ,mark_index, nodes, indices, polyline_info); //Q1P1
+ sew_2_marked_darts( final_map(),dof_P1_outside->beta(3) , dof_Q2_outside->beta(3) ,mark_index, nodes, indices, polyline_info); //P1Q2
+ sew_2_marked_darts( final_map(),dof_P2_outside , dof_Q1_outside ,mark_index, nodes, indices, polyline_info); //P2Q1
+ }
+ else
+ {
+ bool P1_is_between_Q1Q2 = filtered_order_around_edge(indices.first,indices.second,index_q1,index_q2,index_p1,Q1,Q2,P1,nodes);
+ if (!P1_is_between_Q1Q2){
+ // poly_first - poly_second = P1P2
+ // poly_second - poly_first = Q1Q2
+ // poly_first \cap poly_second = {0}
+ // opposite( poly_first U poly_second ) = P2Q1 U Q2P1
+ sew_2_marked_darts( final_map(),dof_P1_outside->beta(3) , dof_P2_outside->beta(3) ,mark_index, nodes, indices, polyline_info); //P1P2
+ sew_2_marked_darts( final_map(),dof_Q1_outside->beta(3) , dof_Q2_outside->beta(3) ,mark_index, nodes, indices, polyline_info); //Q1Q2
+ sew_2_marked_darts( final_map(),dof_P2_outside , dof_Q1_outside ,mark_index, nodes, indices, polyline_info); //P2Q1
+ sew_2_marked_darts( final_map(),dof_Q2_outside , dof_P1_outside ,mark_index, nodes, indices, polyline_info); //Q2P1
+ //update inside outside info (because darts from the same volume have been merged)
+ dof_Q1_outside->beta(3)->template attribute<3>()->info().outside.insert(first_poly); //update Q1Q2 outside poly
+ dof_P1_outside->beta(3)->template attribute<3>()->info().outside.insert(second_poly);//update P2P1 outside poly
+ }
+ else{
+ // poly_first - poly_second = {0}
+ // poly_second - poly_first = Q1P1 U P2Q2
+ // poly_first \cap poly_second = P1P2
+ // opposite( poly_first U poly_second ) = Q2Q1
+ sew_2_marked_darts( final_map(),dof_Q1_outside->beta(3) , dof_P1_outside ,mark_index, nodes, indices, polyline_info); //Q1P1
+ sew_2_marked_darts( final_map(),dof_P2_outside , dof_Q2_outside->beta(3) ,mark_index, nodes, indices, polyline_info); //P2Q2
+ sew_2_marked_darts( final_map(),dof_P1_outside->beta(3) , dof_P2_outside->beta(3) ,mark_index, nodes, indices, polyline_info); //P1P2
+ sew_2_marked_darts( final_map(),dof_Q2_outside , dof_Q1_outside ,mark_index, nodes, indices, polyline_info); //Q2Q1
+ //update inside outside info (because darts from the same volume have been merged)
+ dof_P1_outside->beta(3)->template attribute<3>()->info().inside.insert(second_poly); //update P1P2 inside poly
+ dof_Q2_outside->template attribute<3>()->info().outside.insert(first_poly);//update Q2Q1 outside poly
+ }
+ }
+ }
+ }
+ }
+
+ #ifdef CGAL_COREFINEMENT_DEBUG
+ std::cout << "number of darts to remove: " << darts_to_remove.size() <<std::endl;
+ #endif
+ //remove darts from empty volumes
+ for (typename std::set<Dart_handle>::iterator itdart=darts_to_remove.begin(),end=darts_to_remove.end();itdart!=end;++itdart){
+ final_map().erase_dart(*itdart);
+ }
+
+ //remove empty volumes
+ typedef typename Combinatorial_map_3_::template Attribute_range<3>::type Volume_attribute_range;
+ Volume_attribute_range& ratrib=final_map().template attributes<3>();
+ typename Volume_attribute_range::iterator curr=ratrib.begin(),end=ratrib.end();
+ do{
+ if (curr->info().is_empty)
+ final_map().template erase_attribute<3>(curr++);
+ else
+ ++curr;
+ }
+ while(curr!=end);
+
+ CGAL_assertion(final_map().is_valid());
+
+ //update the info of each volume knowing about only one polyhedron:
+ //this happens when one polyhedron has a connected component
+ //that do not intersect the other polyhedron
+
+ typedef Point_inside_polyhedron_3<Polyhedron, Kernel> Inside_poly_test;
+
+ CGAL_precondition(polyhedron_to_map_node_to_polyhedron_vertex.size()==2);
+ Polyhedron* Poly_A = polyhedron_to_map_node_to_polyhedron_vertex.begin()->first;
+ Polyhedron* Poly_B = boost::next(polyhedron_to_map_node_to_polyhedron_vertex.begin())->first;
+ Inside_poly_test* inside_A_test_ptr=NULL;
+ Inside_poly_test* inside_B_test_ptr=NULL;
+
+ #ifdef CGAL_COREFINEMENT_DEBUG
+ final_map().display_characteristics(std::cout); std::cout << "\n";
+ #endif
+
+ typename Combinatorial_map_3::template One_dart_per_cell_range<3> cell_range=final_map().template one_dart_per_cell<3>();
+ for (typename Combinatorial_map_3::template One_dart_per_cell_range<3>::iterator
+ it = cell_range.begin(), it_end=cell_range.end();
+ it_end!= it;
+ ++it )
+ {
+ internal_IOP::Volume_info<Polyhedron>& info=it->template attribute<3>()->info();
+ std::size_t inside_size=info.inside.size();
+ std::size_t outside_size=info.outside.size();
+
+ // if a volume is not classified wrt the two polyhedra, it means the component we look at does not
+ // is a disjoint (but maybe at a vertex TAG SL001)
+ if ( inside_size + outside_size == 1)
+ {
+ bool is_inside = (inside_size==1);
+ Polyhedron* current_poly= is_inside? (*info.inside.begin()):(*info.outside.begin());
+ Polyhedron* test_poly;
+ Inside_poly_test* inside_test_ptr;
+ if ( current_poly==Poly_A)
+ {
+ test_poly=Poly_B;
+ if (inside_B_test_ptr == NULL) inside_B_test_ptr=new Inside_poly_test(*Poly_B);
+ inside_test_ptr=inside_B_test_ptr;
+ }
+ else
+ {
+ test_poly=Poly_A;
+ if (inside_A_test_ptr == NULL) inside_A_test_ptr=new Inside_poly_test(*Poly_A);
+ inside_test_ptr=inside_A_test_ptr;
+ }
+
+ // We need to find a point of the volume that is not on the boundary of the other volume.
+ // Then the position of this point give the position of the volume. If all the points are on
+ // the bounday, we take the mid-point of an edge (which must not be on the boundary otherwise
+ // it contradicts the fact that volumes are disjoint
+ // We first use the dart we have since one_dart_per_incident_cell has a non-negligeable cost.
+ typename Kernel::Point_3 query=it->template attribute<0>()->point();
+ CGAL::Bounded_side res = (*inside_test_ptr)(query);
+ if (res==ON_BOUNDARY)
+ {
+ typedef typename Combinatorial_map_3::
+ template One_dart_per_incident_cell_range<0,3> Vertex_range;
+
+ Vertex_range vertex_range =
+ final_map().template one_dart_per_incident_cell<0,3>(it);
+ typename Vertex_range::iterator vit = vertex_range.begin();
+
+ CGAL_assertion( typename Combinatorial_map_3::Dart_handle(vit) ==
+ typename Combinatorial_map_3::Dart_handle(it) );
+ ++vit;
+ for ( ; vit!=vertex_range.end(); ++vit)
+ {
+ query=vit->template attribute<0>()->point();
+ res = (*inside_test_ptr)(query);
+ if ( res != ON_BOUNDARY ) break;
+ }
+
+ //take edge midpoint
+ if (res == ON_BOUNDARY)
+ {
+ /// \todo see do a better test here. At least the construction cannot fail
+ /// but the mid-point can fall outside of the volume...
+ #ifdef CGAL_COREFINEMENT_DEBUG
+ #warning this is not exact!!!
+ #endif
+ typename Kernel::Point_3 p1=it->template attribute<0>()->point();
+ typename Kernel::Point_3 p2=it->beta(1)->template attribute<0>()->point();
+ query=midpoint(p1,p2);
+ res = (*inside_test_ptr)(query);
+ }
+
+ CGAL_assertion( res!= ON_BOUNDARY );
+ }
+
+ if (res == ON_BOUNDED_SIDE )
+ info.inside.insert(test_poly);
+ else
+ info.outside.insert(test_poly);
+ }
+
+ #ifdef CGAL_COREFINEMENT_DEBUG
+ std::cout << "This volume has inside: ";
+ for (typename std::set<Polyhedron*>::iterator itpoly=info.inside.begin();itpoly!=info.inside.end();++itpoly)
+ std::cout << " " << *itpoly;
+ std::cout << " and outside: ";
+ for (typename std::set<Polyhedron*>::iterator itpoly=info.outside.begin();itpoly!=info.outside.end();++itpoly)
+ std::cout << " " << *itpoly;
+ std::cout << std::endl;
+ #endif
+ }
+ if (inside_A_test_ptr!=NULL) delete inside_A_test_ptr;
+ if (inside_B_test_ptr!=NULL) delete inside_B_test_ptr;
+ }
+};
+
+}//namespace CGAL
+
+
+
+#endif //CGAL_INTERSECTION_OF_POLYHEDRA_3_REFINEMENT_VISITOR_H
diff --git a/patches/CGAL-4.2/CGAL/use.h b/patches/CGAL-4.2/CGAL/use.h
new file mode 100644
index 0000000..58cab5f
--- /dev/null
+++ b/patches/CGAL-4.2/CGAL/use.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2007 INRIA Sophia-Antipolis (France).
+// All rights reserved.
+//
+// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 3 of the License,
+// or (at your option) any later version.
+//
+// Licensees holding a valid commercial license may use this file in
+// accordance with the commercial license agreement provided with the software.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $URL$
+// $Id$
+//
+// Author(s) : Sylvain Pion
+
+#ifndef CGAL_USE_H
+#define CGAL_USE_H
+
+namespace CGAL { namespace internal {
+
+template < typename T > inline
+void use(const T&) {}
+
+template<typename> void use_type() {}
+
+} }
+
+/// CGAL_USE() is a macro which aims at removing "variable is unused" warnings.
+#define CGAL_USE(x) ::CGAL::internal::use(x)
+
+/// CGAL_USE_TYPE() is a macro which aims at removing "typedef locally
+/// defined but not used" warnings.
+#define CGAL_USE_TYPE(T) ::CGAL::internal::use_type<T>()
+
+#endif // CGAL_USE_H
diff --git a/patches/CGAL-4.3/CGAL/Triangle_3_Triangle_3_intersection.h b/patches/CGAL-4.3/CGAL/Triangle_3_Triangle_3_intersection.h
new file mode 100644
index 0000000..162813a
--- /dev/null
+++ b/patches/CGAL-4.3/CGAL/Triangle_3_Triangle_3_intersection.h
@@ -0,0 +1,237 @@
+// Copyright (c) 2010 GeometryFactory (France).
+// All rights reserved.
+//
+// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 3 of the License,
+// or (at your option) any later version.
+//
+// Licensees holding a valid commercial license may use this file in
+// accordance with the commercial license agreement provided with the software.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $URL$
+// $Id$
+//
+//
+// Author(s) : Sebastien Loriot
+//
+
+#ifndef CGAL_TRIANGLE_3_TRIANGLE_3_INTERSECTION_H
+#define CGAL_TRIANGLE_3_TRIANGLE_3_INTERSECTION_H
+
+#include <CGAL/Intersection_traits_3.h>
+
+#include <boost/next_prior.hpp>
+#include <list>
+#include <vector>
+#include <map>
+
+namespace CGAL {
+
+ template <class K>
+ class Triangle_3;
+
+namespace internal{
+
+template <class Kernel>
+void intersection_coplanar_triangles_cutoff(
+ const typename Kernel::Point_3& p,
+ const typename Kernel::Point_3& q,
+ const typename Kernel::Point_3& r,
+ const Kernel& k,
+ std::list<typename Kernel::Point_3>& inter_pts
+)
+{
+ if ( inter_pts.empty() ) return;
+ typedef typename std::list<typename Kernel::Point_3>::iterator Iterator;
+ typename Kernel::Coplanar_orientation_3 orient=k.coplanar_orientation_3_object();
+ typename Kernel::Construct_line_3 Line_3=k.construct_line_3_object();
+ //orient(p,q,r,r) is POSITIVE
+ std::map<const typename Kernel::Point_3*,Orientation> orientations;
+ for (Iterator it=inter_pts.begin();it!=inter_pts.end();++it)
+ orientations[ &(*it) ]=orient(p,q,r,*it);
+
+ int pt_added=0;
+
+ const typename Kernel::Point_3* prev = &(*boost::prior(inter_pts.end()));
+ Iterator stop = inter_pts.size() > 2 ? inter_pts.end() : boost::prior(inter_pts.end());
+ for (Iterator it=inter_pts.begin();it!=stop;++it)
+ {
+ const typename Kernel::Point_3& curr=*it;
+ Orientation or_prev=orientations[prev],or_curr=orientations[&curr];
+ if ( (or_prev==POSITIVE && or_curr==NEGATIVE) || (or_prev==NEGATIVE && or_curr==POSITIVE) )
+ {
+ typename Intersection_traits<Kernel, typename Kernel::Line_3,
+ typename Kernel::Line_3>
+ ::result_type
+ obj = intersection(Line_3(p,q),Line_3(*prev,curr),k);
+ // assert "not empty"
+ CGAL_kernel_assertion(obj);
+ const typename Kernel::Point_3* inter=intersect_get<typename Kernel::Point_3>(obj);
+ CGAL_kernel_assertion(inter!=NULL);
+ prev=&(* inter_pts.insert(it,*inter) );
+ orientations[prev]=COLLINEAR;
+ ++pt_added;
+ }
+ prev=&(*it);
+ }
+
+ CGAL_kernel_assertion(pt_added<3);
+ Iterator it=inter_pts.begin();
+ while(it!=inter_pts.end())
+ {
+ if (orientations[&(*it)]==NEGATIVE)
+ inter_pts.erase(it++);
+ else
+ ++it;
+ }
+}
+
+template <class K>
+typename Intersection_traits<K, typename K::Triangle_3, typename K::Triangle_3>::result_type
+intersection_coplanar_triangles(
+ const typename K::Triangle_3& t1,
+ const typename K::Triangle_3& t2,
+ const K& k)
+{
+ const typename K::Point_3& p=t1.vertex(0),q=t1.vertex(1),r=t1.vertex(2);
+
+ std::list<typename K::Point_3> inter_pts;
+ inter_pts.push_back(t2.vertex(0));
+ inter_pts.push_back(t2.vertex(1));
+ inter_pts.push_back(t2.vertex(2));
+
+ //intersect t2 with the three half planes which intersection defines t1
+ intersection_coplanar_triangles_cutoff(p,q,r,k,inter_pts); //line pq
+ intersection_coplanar_triangles_cutoff(q,r,p,k,inter_pts); //line qr
+ intersection_coplanar_triangles_cutoff(r,p,q,k,inter_pts); //line rp
+
+ switch ( inter_pts.size() ) {
+ case 0:
+ return intersection_return<typename K::Intersect_3, typename K::Triangle_3, typename K::Triangle_3>();
+ case 1:
+ return intersection_return<typename K::Intersect_3, typename K::Triangle_3, typename K::Triangle_3>( * inter_pts.begin() );
+ case 2:
+ return intersection_return<typename K::Intersect_3, typename K::Triangle_3, typename K::Triangle_3>( k.construct_segment_3_object()(*inter_pts.begin(),
+ *boost::next(inter_pts.begin())) );
+ case 3:
+ return intersection_return<typename K::Intersect_3, typename K::Triangle_3, typename K::Triangle_3>( k.construct_triangle_3_object()(*inter_pts.begin(),
+ *boost::next(inter_pts.begin()),
+ *boost::prior(inter_pts.end())) );
+ default:
+ return intersection_return<typename K::Intersect_3, typename K::Triangle_3, typename K::Triangle_3>( std::vector<typename K::Point_3>(inter_pts.begin(),inter_pts.end()) );
+ }
+}
+
+template<typename K>
+struct Triangle_Line_visitor {
+ typedef typename Intersection_traits<K, typename K::Triangle_3, typename K::Triangle_3 >
+ ::result_type result_type;
+
+ result_type
+ operator()(const typename K::Point_3& p, const typename K::Segment_3& s) const {
+ if ( s.has_on(p) )
+ return intersection_return<typename K::Intersect_3, typename K::Triangle_3, typename K::Triangle_3>(p);
+ else
+ return result_type();
+ }
+
+ result_type
+ operator()(const typename K::Segment_3& s, const typename K::Point_3& p) const {
+ return operator()(p,s);
+ }
+
+ result_type
+ operator()(const typename K::Point_3& p1, const typename K::Point_3& p2) const {
+ if (p1==p2)
+ return intersection_return<typename K::Intersect_3, typename K::Triangle_3, typename K::Triangle_3>(p1);
+ else
+ return result_type();
+ }
+
+ result_type
+ operator()(const typename K::Segment_3& s1, const typename K::Segment_3& s2) const {
+ typename Intersection_traits<K, typename K::Segment_3, typename K::Segment_3>::result_type
+ v = intersection_collinear_segments(s1,s2,K());
+
+ if(v) {
+ if(const typename K::Segment_3* s = intersect_get<typename K::Segment_3>(v))
+ return intersection_return<typename K::Intersect_3, typename K::Triangle_3, typename K::Triangle_3>(*s);
+ if(const typename K::Point_3* p = intersect_get<typename K::Point_3>(v))
+ return intersection_return<typename K::Intersect_3, typename K::Triangle_3, typename K::Triangle_3>(*p);
+ }
+
+ return result_type();
+ }
+};
+
+template <class K>
+typename Intersection_traits<K, typename K::Triangle_3, typename K::Triangle_3>::result_type
+intersection(
+ const typename K::Triangle_3& t1,
+ const typename K::Triangle_3& t2,
+ const K& k)
+{
+ CGAL_precondition(!t1.is_degenerate() && !t2.is_degenerate());
+
+ typename Intersection_traits<K, typename K::Plane_3, typename K::Plane_3>::result_type
+ v = internal::intersection(t1.supporting_plane(), t2.supporting_plane(), k);
+
+ if(!v) {
+ // empty plane plane intersection
+ return intersection_return<typename K::Intersect_3, typename K::Triangle_3, typename K::Triangle_3>();
+ }
+
+ if(intersect_get<typename K::Plane_3>(v)) {
+ //coplanar triangles
+ return intersection_coplanar_triangles(t1,t2,k);
+ }
+
+ if(const typename K::Line_3* line=intersect_get<typename K::Line_3>(v)) {
+ //The supporting planes of the triangles intersect along a line.
+ typedef
+ typename Intersection_traits<K, typename K::Triangle_3, typename K::Line_3>::result_type
+ Triangle_Line_Inter;
+
+ Triangle_Line_Inter inter1 = intersection_coplanar(t1,*line,k);
+ Triangle_Line_Inter inter2 = intersection_coplanar(t2,*line,k);
+ if(!inter1 || !inter2) {
+ // one of the intersection is empty
+ return intersection_return<typename K::Intersect_3, typename K::Triangle_3, typename K::Triangle_3>();
+ }
+ #if CGAL_INTERSECTION_VERSION < 2
+ // apply the binary visitor manually
+ Triangle_Line_visitor<K> vis;
+ if(const typename K::Point_3* p1 = intersect_get<typename K::Point_3>(inter1)) {
+ if(const typename K::Point_3* p2 = intersect_get<typename K::Point_3>(inter2)) {
+ return vis(*p1, *p2);
+ } else if(const typename K::Segment_3* s2 = intersect_get<typename K::Segment_3>(inter2)) {
+ return vis(*p1, *s2);
+ }
+ } else if(const typename K::Segment_3* s1 = intersect_get<typename K::Segment_3>(inter1)) {
+ if(const typename K::Point_3* p2 = intersect_get<typename K::Point_3>(inter2)) {
+ return vis(*s1, *p2);
+ } else if(const typename K::Segment_3* s2 = intersect_get<typename K::Segment_3>(inter2)) {
+ return vis(*s1, *s2);
+ }
+ }
+ #else
+ return boost::apply_visitor(Triangle_Line_visitor<K>(), *inter1, *inter2);
+ #endif
+ }
+ return intersection_return<typename K::Intersect_3, typename K::Triangle_3, typename K::Triangle_3>();
+}
+
+}//namespace internal
+
+CGAL_INTERSECTION_FUNCTION_SELF(Triangle_3, 3)
+
+} // namespace CGAL
+
+
+
+
+#endif //CGAL_TRIANGLE_3_TRIANGLE_3_INTERSECTION_H
diff --git a/patches/README b/patches/README
new file mode 100644
index 0000000..b49e665
--- /dev/null
+++ b/patches/README
@@ -0,0 +1,27 @@
+This directory includes some backports and fixes from CGAL 4.2 and 4.3.
+It is included with the CMake directive include_directories()
+in order to overload system include files.
+
+* When compiling SFCGAL with CGAL < 4.3, CGAL-4.2 is included. It contains :
+
+From 4.2 :
+
+use.h
+
+From 4.3 :
+
+intersection_of_Polyhedra_3_refinement_visitor.h
+Triangle_3_Ray_3_do_intersect.h
+Point_inside_polyhedron_3.h
+internal/Operations_on_polyhedra/AABB_triangle_accessor_3_primitive.h
+internal/Operations_on_polyhedra/Ray_3_Triangle_3_traversal_traits.h
+
+File fixing a memory leak :
+
+Triangle_2_Triangle_2_intersection_impl.h
+
+* When compiling SFCGAL with version 4.3, CGAL-4.3 is included.
+
+It contains a bug fix for Triangle_3_Triangle_3_intersection
+
+
diff --git a/script/test-style-SFCGAL.sh b/script/test-style-SFCGAL.sh
new file mode 100755
index 0000000..504176d
--- /dev/null
+++ b/script/test-style-SFCGAL.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+
+base=$(dirname $(dirname $0)) # we should be in SFCAGL/script
+
+if [ ! -f "$base/src/version.h.cmake" ]; then
+ echo "Can't find $base/src/version.h.cmake"
+ exit 1
+fi
+
+for a in $@; do
+ case $a in
+ --fix)
+ fix=true;;
+ -*)
+ echo unknown option $a
+ exit 1;;
+ *)
+ file=$a;;
+ esac
+done
+
+
+err=""
+for dir in "$base/src" "$base/test" "$base/viewer"; do
+ #echo processing $dir
+ for src in $(find $dir -name '*.cpp' -or -name '*.h'); do
+ #echo " " $src
+ astyle -n --style=stroustrup --indent=spaces=4 \
+ --break-closing-brackets --break-blocks --align-pointer=type \
+ --add-brackets --pad-paren-in < $src > astyle.tmp.out
+ dif=$(diff $src astyle.tmp.out)
+ if [ -n "$dif" ]; then
+ #echo diff in $src
+ if [ $fix ]; then
+ cp astyle.tmp.out $src
+ else
+
+ err="$err $src"
+ echo "$dif" > test-style-diff-$(basename $src)
+ fi
+ fi
+ done
+done
+
+n=0
+for e in $err; do
+ echo "diff in $e"
+ n=$(($n + 1))
+done
+
+if [ -n "$err" ]; then
+ echo "******* $n errors found"
+ exit 1
+fi
diff --git a/sfcgal-config.in b/sfcgal-config.in
new file mode 100755
index 0000000..a0e992c
--- /dev/null
+++ b/sfcgal-config.in
@@ -0,0 +1,52 @@
+#!/bin/sh
+prefix=@CMAKE_INSTALL_PREFIX@
+libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
+
+usage()
+{
+ cat <<EOF
+Usage: sfcgal-config [OPTIONS]
+Options:
+ [--prefix]
+ [--version]
+ [--libs]
+ [--cflags]
+ [--ldflags]
+ [--static]
+EOF
+ exit $1
+}
+if test $# -eq 0; then
+ usage 1 1>&2
+fi
+while test $# -gt 0; do
+case "$1" in
+ -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+esac
+case $1 in
+ --prefix)
+ echo ${prefix}
+ ;;
+ --version)
+ echo @SFCGAL_VERSION@
+ ;;
+ --static)
+ echo @SFCGAL_USE_STATIC_LIBS@
+ ;;
+ --cflags)
+ echo -I${prefix}/include
+ ;;
+ --libs)
+ echo -L${libdir} -l at SFCGAL_LIB_NAME@
+ ;;
+ --ldflags)
+ echo -L${libdir}
+ ;;
+ *)
+ usage 1 1>&2
+ ;;
+ esac
+ shift
+done
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..f0af617
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,78 @@
+file( GLOB_RECURSE SFCGAL_SOURCES "*.cpp" )
+file( GLOB_RECURSE SFCGAL_HEADERS "*.h" )
+
+file( GLOB_RECURSE SFCGAL_HEADERS_COPIED RELATIVE ${CMAKE_SOURCE_DIR}/src "*.h" )
+add_custom_target(copy)
+foreach (header ${SFCGAL_HEADERS_COPIED})
+ add_custom_command(TARGET copy
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/src/${header} ${CMAKE_BINARY_DIR}/include/SFCGAL/${header} DEPENDS ${CMAKE_SOURCE_DIR}/src/${header})
+endforeach()
+
+if ( NOT SFCGAL_WITH_OSG )
+ message( STATUS "removing ${CMAKE_SOURCE_DIR}/src/io/osg.h and ${CMAKE_SOURCE_DIR}/src/SFCGAL/io/osg.cpp from the library")
+ list(REMOVE_ITEM SFCGAL_HEADERS "${CMAKE_SOURCE_DIR}/src/io/osg.h")
+ list(REMOVE_ITEM SFCGAL_SOURCES "${CMAKE_SOURCE_DIR}/src/io/osg.cpp")
+endif()
+
+if( SFCGAL_USE_STATIC_LIBS )
+ add_definitions( "-fPIC" )
+ add_library(
+ SFCGAL
+ ${SFCGAL_HEADERS}
+ ${SFCGAL_SOURCES}
+ )
+
+else()
+ add_definitions( "-DSFCGAL_BUILD_SHARED" )
+ add_library(
+ SFCGAL SHARED
+ ${SFCGAL_HEADERS}
+ ${SFCGAL_SOURCES}
+ )
+endif()
+
+add_dependencies( SFCGAL copy )
+
+# set VERSION and SOVERSION
+set_target_properties( SFCGAL PROPERTIES VERSION ${SFCGAL_VERSION}
+ SOVERSION ${SFCGAL_VERSION_MAJOR} )
+
+target_link_libraries( SFCGAL ${CGAL_LIBRARIES} )
+if( ${SFCGAL_WITH_MPFR} )
+ target_link_libraries( SFCGAL ${MPFR_LIBRARIES} )
+endif( ${SFCGAL_WITH_MPFR} )
+
+if( ${SFCGAL_WITH_GMP} )
+ target_link_libraries( SFCGAL ${GMP_LIBRARIES} )
+endif( ${SFCGAL_WITH_GMP} )
+
+if( ${SFCGAL_WITH_OSG} )
+ target_link_libraries( SFCGAL ${OPENSCENEGRAPH_LIBRARIES} )
+endif()
+target_link_libraries( SFCGAL ${Boost_LIBRARIES} )
+
+if ( ${Use_precompiled_headers} )
+ if(PCHSupport_FOUND)
+ # Add "-fPIC" for shared library build
+ if( ${SFCGAL_USE_STATIC_LIBS} )
+ set( pch_option "" )
+ else()
+ set( pch_option "-fPIC" )
+ endif()
+ add_precompiled_header(SFCGAL
+ include/CGAL/all.h
+ ${pch_option}
+ )
+ endif()
+endif()
+
+# install library
+install(
+ TARGETS
+ SFCGAL
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ BUNDLE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
diff --git a/src/Coordinate.cpp b/src/Coordinate.cpp
new file mode 100644
index 0000000..773f5c4
--- /dev/null
+++ b/src/Coordinate.cpp
@@ -0,0 +1,405 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/Coordinate.h>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Exception.h>
+#include <SFCGAL/numeric.h>
+
+namespace SFCGAL {
+
+///
+///
+///
+Coordinate::Coordinate():
+ _storage( Coordinate::Empty() )
+{
+}
+
+///
+///
+///
+Coordinate::Coordinate( const Kernel::FT& x, const Kernel::FT& y ):
+ _storage( Kernel::Point_2( x, y ) )
+{
+
+}
+
+///
+///
+///
+Coordinate::Coordinate( const Kernel::FT& x, const Kernel::FT& y, const Kernel::FT& z ):
+ _storage( Kernel::Point_3( x, y, z ) )
+{
+
+}
+
+
+///
+///
+///
+Coordinate::Coordinate( const double& x, const double& y )
+{
+ if ( !std::isfinite( x ) || !std::isfinite( y ) ) {
+ BOOST_THROW_EXCEPTION( NonFiniteValueException( "cannot create coordinate with non finite value" ) );
+ }
+
+ _storage = Kernel::Point_2( x, y );
+}
+
+///
+///
+///
+Coordinate::Coordinate( const double& x, const double& y, const double& z )
+{
+ if ( !std::isfinite( x ) || !std::isfinite( y ) || !std::isfinite( z ) ) {
+ BOOST_THROW_EXCEPTION( NonFiniteValueException( "cannot create coordinate with non finite value" ) );
+ }
+
+ _storage = Kernel::Point_3( x, y, z );
+}
+
+///
+///
+///
+Coordinate::Coordinate( const Kernel::Point_2& other ):
+ _storage( other )
+{
+
+}
+
+///
+///
+///
+Coordinate::Coordinate( const Kernel::Point_3& other ):
+ _storage( other )
+{
+
+}
+
+
+///
+///
+///
+Coordinate::Coordinate( const Coordinate& other ):
+ _storage( other._storage )
+{
+
+}
+
+///
+///
+///
+Coordinate& Coordinate::operator = ( const Coordinate& other )
+{
+ _storage = other._storage;
+ return *this ;
+}
+
+///
+///
+///
+Coordinate::~Coordinate()
+{
+
+}
+
+
+class CoordinateDimensionVisitor : public boost::static_visitor<int> {
+public:
+ int operator()( const Coordinate::Empty& ) const {
+ return 0;
+ }
+ int operator()( const Kernel::Point_2& ) const {
+ return 2;
+ }
+ int operator()( const Kernel::Point_3& ) const {
+ return 3;
+ }
+};
+
+
+///
+///
+///
+int Coordinate::coordinateDimension() const
+{
+ CoordinateDimensionVisitor visitor;
+ return boost::apply_visitor( visitor, _storage );
+}
+
+
+///
+///
+///
+bool Coordinate::isEmpty() const
+{
+ return _storage.which() == 0;
+}
+
+///
+///
+///
+bool Coordinate::is3D() const
+{
+ return _storage.which() == 2;
+}
+
+class GetXVisitor : public boost::static_visitor<Kernel::FT> {
+public:
+ Kernel::FT operator()( const Coordinate::Empty& ) const {
+ BOOST_THROW_EXCEPTION( Exception( "trying to get an empty coordinate x value" ) );
+ return 0;
+ }
+ Kernel::FT operator()( const Kernel::Point_2& storage ) const {
+ return storage.x();
+ }
+ Kernel::FT operator()( const Kernel::Point_3& storage ) const {
+ return storage.x();
+ }
+};
+
+///
+///
+///
+Kernel::FT Coordinate::x() const
+{
+ GetXVisitor visitor;
+ return boost::apply_visitor( visitor, _storage );
+}
+
+class GetYVisitor : public boost::static_visitor<Kernel::FT> {
+public:
+ Kernel::FT operator()( const Coordinate::Empty& ) const {
+ BOOST_THROW_EXCEPTION( Exception( "trying to get an empty coordinate y value" ) );
+ return 0;
+ }
+ Kernel::FT operator()( const Kernel::Point_2& storage ) const {
+ return storage.y();
+ }
+ Kernel::FT operator()( const Kernel::Point_3& storage ) const {
+ return storage.y();
+ }
+};
+
+///
+///
+///
+Kernel::FT Coordinate::y() const
+{
+ GetYVisitor visitor;
+ return boost::apply_visitor( visitor, _storage );
+}
+
+class GetZVisitor : public boost::static_visitor<Kernel::FT> {
+public:
+ Kernel::FT operator()( const Coordinate::Empty& ) const {
+ BOOST_THROW_EXCEPTION( Exception( "trying to get an empty coordinate z value" ) );
+ return 0;
+ }
+ Kernel::FT operator()( const Kernel::Point_2& ) const {
+ return 0;
+ }
+ Kernel::FT operator()( const Kernel::Point_3& storage ) const {
+ return storage.z();
+ }
+};
+
+///
+///
+///
+Kernel::FT Coordinate::z() const
+{
+ GetZVisitor visitor;
+ return boost::apply_visitor( visitor, _storage );
+}
+
+//----------------------
+
+
+class RoundVisitor : public boost::static_visitor<> {
+public:
+ RoundVisitor( const long& scaleFactor ):
+ _scaleFactor( scaleFactor ) {
+
+ }
+
+ void operator()( Coordinate::Empty& ) const {
+
+ }
+ void operator()( Kernel::Point_2& storage ) const {
+ storage = Kernel::Point_2(
+ _roundFT( storage.x() ),
+ _roundFT( storage.y() )
+ );
+ }
+ void operator()( Kernel::Point_3& storage ) const {
+ storage = Kernel::Point_3(
+ _roundFT( storage.x() ),
+ _roundFT( storage.y() ),
+ _roundFT( storage.z() )
+ );
+ }
+
+
+
+private:
+ long _scaleFactor ;
+
+
+ Kernel::FT _roundFT( const Kernel::FT& v ) const {
+ return Kernel::FT( CGAL::Gmpq(
+ SFCGAL::round( v.exact() * _scaleFactor ),
+ _scaleFactor
+ ) ) ;
+ }
+
+};
+
+
+Coordinate& Coordinate::round( const long& scaleFactor )
+{
+ RoundVisitor roundVisitor( scaleFactor ) ;
+ boost::apply_visitor( roundVisitor, _storage ) ;
+ return *this ;
+}
+
+
+
+//----------------------
+
+class ToPoint2Visitor : public boost::static_visitor<Kernel::Point_2> {
+public:
+ Kernel::Point_2 operator()( const Coordinate::Empty& ) const {
+ return Kernel::Point_2( CGAL::ORIGIN );
+ }
+ Kernel::Point_2 operator()( const Kernel::Point_2& storage ) const {
+ return storage;
+ }
+ Kernel::Point_2 operator()( const Kernel::Point_3& storage ) const {
+ return Kernel::Point_2( storage.x(), storage.y() );
+ }
+};
+
+///
+///
+///
+Kernel::Point_2 Coordinate::toPoint_2() const
+{
+ ToPoint2Visitor visitor;
+ return boost::apply_visitor( visitor, _storage );
+}
+
+class ToPoint3Visitor : public boost::static_visitor<Kernel::Point_3> {
+public:
+ Kernel::Point_3 operator()( const Coordinate::Empty& /*storage*/ ) const {
+ return Kernel::Point_3( CGAL::ORIGIN );
+ }
+ Kernel::Point_3 operator()( const Kernel::Point_2& storage ) const {
+ return Kernel::Point_3( storage.x(), storage.y(), 0.0 );
+ }
+ Kernel::Point_3 operator()( const Kernel::Point_3& storage ) const {
+ return storage;
+ }
+};
+
+///
+///
+///
+Kernel::Point_3 Coordinate::toPoint_3() const
+{
+ ToPoint3Visitor visitor;
+ return boost::apply_visitor( visitor, _storage );
+}
+
+///
+///
+///
+bool Coordinate::operator < ( const Coordinate& other ) const
+{
+ // no empty comparison
+ if ( isEmpty() || other.isEmpty() ) {
+ BOOST_THROW_EXCEPTION( Exception( "try to compare empty points using a < b " ) );
+ }
+
+ // no mixed dimension comparison
+ if ( ( is3D() && ! other.is3D() ) || ( ! is3D() && other.is3D() ) ) {
+ BOOST_THROW_EXCEPTION( Exception( "try to compare empty points with different coordinate dimension using a < b" ) );
+ }
+
+ // comparison along x
+ if ( x() < other.x() ) {
+ return true ;
+ }
+ else if ( other.x() < x() ) {
+ return false;
+ }
+
+ // comparison along y
+ if ( y() < other.y() ) {
+ return true ;
+ }
+ else if ( other.y() < y() ) {
+ return false;
+ }
+
+ // comparison along z if possible
+ if ( is3D() ) {
+ if ( z() < other.z() ) {
+ return true ;
+ }
+ else if ( other.z() < z() ) {
+ return false;
+ }
+ }
+
+ // points are equals
+ return false;
+}
+
+///
+///
+///
+bool Coordinate::operator == ( const Coordinate& other ) const
+{
+ if ( isEmpty() ) {
+ return other.isEmpty() ;
+ }
+
+ if ( is3D() || other.is3D() ) {
+ return x() == other.x() && y() == other.y() && z() == other.z() ;
+ }
+ else {
+ return x() == other.x() && y() == other.y() ;
+ }
+}
+
+///
+///
+///
+bool Coordinate::operator != ( const Coordinate& other ) const
+{
+ return ! ( *this == other );
+}
+
+
+}//SFCGAL
+
diff --git a/src/Coordinate.h b/src/Coordinate.h
new file mode 100644
index 0000000..00d9285
--- /dev/null
+++ b/src/Coordinate.h
@@ -0,0 +1,235 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_COORDINATE_H_
+#define _SFCGAL_COORDINATE_H_
+
+#include <SFCGAL/config.h>
+
+#include <boost/assert.hpp>
+#include <boost/array.hpp>
+#include <boost/variant.hpp>
+#include <boost/serialization/split_member.hpp>
+
+#include <SFCGAL/numeric.h>
+
+#include <SFCGAL/Kernel.h>
+
+namespace SFCGAL {
+
+/**
+ * @brief Represents the Coordinate of a Point (wraps either an empty structure, or a Kernel::Point_2,
+ * or a Kernel::Point_3)
+ */
+class SFCGAL_API Coordinate {
+public:
+ /**
+ * Empty Coordinate constructor
+ */
+ Coordinate() ;
+ /**
+ * XY Constructor with exact coordinates
+ */
+ Coordinate( const Kernel::FT& x, const Kernel::FT& y ) ;
+ /**
+ * XYZ Constructor with exact coordinates
+ */
+ Coordinate( const Kernel::FT& x, const Kernel::FT& y, const Kernel::FT& z ) ;
+ /**
+ * XYZ constructor
+ * @warning x,y,z must not be not be NaN nor inf
+ */
+ Coordinate( const double& x, const double& y, const double& z ) ;
+
+ /**
+ * XY constructor
+ * @warning x,y must not be not be NaN nor inf
+ */
+ Coordinate( const double& x, const double& y ) ;
+ /**
+ * Constructor from CGAL::Point_2<K>
+ */
+ Coordinate( const Kernel::Point_2& other ) ;
+ /**
+ * Constructor from CGAL::Point_3<K>
+ */
+ Coordinate( const Kernel::Point_3& other ) ;
+
+ /**
+ * copy constructor
+ */
+ Coordinate( const Coordinate& other ) ;
+ /**
+ * assign operator
+ */
+ Coordinate& operator = ( const Coordinate& other ) ;
+ /**
+ * destructor
+ */
+ ~Coordinate() ;
+
+ /**
+ * @brief Get the dimension of the coordinates
+ */
+ int coordinateDimension() const ;
+ /**
+ * @brief Tests if the coordinates are empty
+ */
+ bool isEmpty() const ;
+ /**
+ * @brief Tests if Z is defined
+ */
+ bool is3D() const ;
+
+ //--- accessors
+
+ /**
+ * @brief Gets the x value
+ * @warning Exact, NaN for empty coordinates
+ */
+ Kernel::FT x() const;
+
+ /**
+ * @brief Gets the y value
+ * @warning Exact, NaN for empty coordinates
+ */
+ Kernel::FT y() const;
+
+ /**
+ * @brief Gets the z value
+ * @warning Exact, NaN for empty or 0 for 2D coordinates
+ */
+ Kernel::FT z() const;
+
+ //-- helper
+
+ /**
+ * @brief round coordinates with a scale factor
+ * @return *this
+ */
+ Coordinate& round( const long& scaleFactor = 1 ) ;
+
+
+ //-- comparator
+
+ /**
+ * @brief Compares two points (lexicographic order)
+ *
+ * @warning coordinates must have the same dimension
+ */
+ bool operator < ( const Coordinate& other ) const ;
+
+ /**
+ * @brief Compares with an other point
+ *
+ * @warning coordinates must have the same dimension
+ */
+ bool operator == ( const Coordinate& other ) const ;
+ /**
+ * @brief Compares with an other point
+ *
+ * @warning coordinates must have the same dimension
+ */
+ bool operator != ( const Coordinate& other ) const ;
+
+ /**
+ * @brief Converts to Kernel::Vector_2
+ */
+ inline Kernel::Vector_2 toVector_2() const {
+ return Kernel::Vector_2( CGAL::ORIGIN, toPoint_2() );
+ }
+
+ /**
+ * @brief Converts to Kernel::Vector_3
+ */
+ inline Kernel::Vector_3 toVector_3() const {
+ return Kernel::Vector_3( CGAL::ORIGIN, toPoint_3() );
+ }
+
+ /**
+ * @brief Converts to Kernel::Point_2
+ */
+ Kernel::Point_2 toPoint_2() const;
+
+ /**
+ * @brief Converts to Kernel::Point_3
+ */
+ Kernel::Point_3 toPoint_3() const;
+
+ // class for Empty coordinate
+ class Empty {};
+private:
+ boost::variant< Empty, Kernel::Point_2, Kernel::Point_3 > _storage;
+
+public:
+ /**
+ * Serialization
+ */
+ template <class Archive>
+ void save( Archive& ar, const unsigned int /*version*/ ) const {
+ int dim = coordinateDimension();
+ ar << dim;
+
+ if ( _storage.which() > 0 ) {
+ const Kernel::FT& x_ = x();
+ const Kernel::FT& y_ = y();
+ ar << x_;
+ ar << y_;
+
+ if ( _storage.which() == 2 ) {
+ const Kernel::FT& z_ = z();
+ ar << z_;
+ }
+ }
+ }
+
+ template <class Archive>
+ void load( Archive& ar, const unsigned int /*version*/ ) {
+ int dim;
+ ar >> dim;
+
+ if ( dim == 0 ) {
+ _storage = Empty();
+ }
+ else if ( dim == 2 ) {
+ Kernel::FT x_, y_;
+ ar >> x_;
+ ar >> y_;
+ _storage = Kernel::Point_2( x_, y_ );
+ }
+ else if ( dim == 3 ) {
+ Kernel::FT x_, y_, z_;
+ ar >> x_;
+ ar >> y_;
+ ar >> z_;
+ _storage = Kernel::Point_3( x_, y_, z_ );
+ }
+ }
+
+ template<class Archive>
+ void serialize( Archive& ar, const unsigned int version ) {
+ boost::serialization::split_member( ar, *this, version );
+ }
+};
+
+
+}//SFCGAL
+
+#endif
diff --git a/src/Envelope.cpp b/src/Envelope.cpp
new file mode 100644
index 0000000..d9d88ae
--- /dev/null
+++ b/src/Envelope.cpp
@@ -0,0 +1,352 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/Envelope.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/PolyhedralSurface.h>
+
+namespace SFCGAL {
+
+///
+///
+///
+Envelope::Envelope()
+{
+ for ( size_t i = 0; i < 3; i++ ) {
+ _bounds[i] = detail::Interval();
+ }
+}
+
+///
+///
+///
+Envelope::Envelope(
+ const double& xmin, const double& xmax,
+ const double& ymin, const double& ymax
+)
+{
+ _bounds[0] = detail::Interval( xmin,xmax );
+ _bounds[1] = detail::Interval( ymin,ymax );
+ _bounds[2] = detail::Interval();
+}
+
+///
+///
+///
+Envelope::Envelope(
+ const double& xmin, const double& xmax,
+ const double& ymin, const double& ymax,
+ const double& zmin, const double& zmax
+)
+{
+ _bounds[0] = detail::Interval( xmin,xmax );
+ _bounds[1] = detail::Interval( ymin,ymax );
+ _bounds[2] = detail::Interval( zmin,zmax );
+}
+
+///
+///
+///
+Envelope::Envelope( const Coordinate& p )
+{
+ expandToInclude( p );
+}
+
+///
+///
+///
+Envelope::Envelope( const Coordinate& p1, const Coordinate& p2 )
+{
+ expandToInclude( p1 );
+ expandToInclude( p2 );
+}
+
+///
+///
+///
+Envelope::Envelope( const Envelope& other )
+{
+ for ( size_t i = 0; i < 3; i++ ) {
+ _bounds[i] = other._bounds[i] ;
+ }
+}
+
+///
+///
+///
+Envelope& Envelope::operator = ( const Envelope& other )
+{
+ for ( size_t i = 0; i < 3; i++ ) {
+ _bounds[i] = other._bounds[i] ;
+ }
+
+ return *this ;
+}
+
+///
+///
+///
+Envelope::~Envelope()
+{
+
+}
+
+
+///
+///
+///
+bool Envelope::isEmpty() const
+{
+ return _bounds[0].isEmpty() || _bounds[1].isEmpty() ;
+}
+
+///
+///
+///
+bool Envelope::is3D() const
+{
+ return ! isEmpty() && ! _bounds[2].isEmpty() ;
+}
+
+///
+///
+///
+void Envelope::expandToInclude( const Coordinate& coordinate )
+{
+ if ( ! coordinate.isEmpty() ) {
+ _bounds[0].expandToInclude( CGAL::to_double( coordinate.x() ) );
+ _bounds[1].expandToInclude( CGAL::to_double( coordinate.y() ) );
+ }
+
+ if ( coordinate.is3D() ) {
+ _bounds[2].expandToInclude( CGAL::to_double( coordinate.z() ) );
+ }
+}
+
+///
+///
+///
+bool Envelope::contains( const Envelope& a, const Envelope& b )
+{
+ if ( a.is3D() ) {
+ return b.xMin() >= a.xMin() &&
+ b.xMax() <= a.xMax() &&
+ b.yMin() >= a.yMin() &&
+ b.yMax() <= a.yMax() &&
+ b.zMin() >= a.zMin() &&
+ b.zMax() <= a.zMax();
+ }
+
+ return b.xMin() >= a.xMin() &&
+ b.xMax() <= a.xMax() &&
+ b.yMin() >= a.yMin() &&
+ b.yMax() <= a.yMax();
+}
+
+///
+///
+///
+bool Envelope::overlaps( const Envelope& a, const Envelope& b )
+{
+ if ( a.is3D() ) {
+ CGAL::Bbox_3 abox = a.toBbox_3();
+ CGAL::Bbox_3 bbox = b.toBbox_3();
+ return CGAL::do_overlap( abox, bbox );
+ }
+
+ CGAL::Bbox_2 abox = a.toBbox_2();
+ CGAL::Bbox_2 bbox = b.toBbox_2();
+ return CGAL::do_overlap( abox, bbox );
+}
+
+///
+///
+///
+std::auto_ptr< LineString > Envelope::toRing() const
+{
+ std::auto_ptr< LineString > ring( new LineString() ) ;
+
+ if ( isEmpty() ) {
+ return ring ;
+ }
+
+ ring->addPoint( new Point( xMin(), yMin() ) );
+ ring->addPoint( new Point( xMax(), yMin() ) );
+ ring->addPoint( new Point( xMax(), yMax() ) );
+ ring->addPoint( new Point( xMin(), yMax() ) );
+ ring->addPoint( ring->startPoint() );
+
+ return ring ;
+}
+
+///
+///
+///
+std::auto_ptr< Polygon > Envelope::toPolygon() const
+{
+ return std::auto_ptr< Polygon >( new Polygon( toRing().release() ) ) ;
+}
+
+
+///
+///
+///
+std::auto_ptr< PolyhedralSurface > Envelope::toShell() const
+{
+ std::auto_ptr< PolyhedralSurface > shell( new PolyhedralSurface() ) ;
+
+ if ( ! is3D() ) {
+ return shell ;
+ }
+
+ Point a( xMin(), yMin(), zMin() );
+ Point b( xMax(), yMin(), zMin() );
+ Point c( xMax(), yMax(), zMin() );
+ Point d( xMin(), yMax(), zMin() );
+
+ Point e( xMin(), yMin(), zMax() );
+ Point f( xMax(), yMin(), zMax() );
+ Point g( xMax(), yMax(), zMax() );
+ Point h( xMin(), yMax(), zMax() );
+
+ //bottom : a,d,c,b
+ {
+ LineString ring ;
+ ring.addPoint( a );
+ ring.addPoint( d );
+ ring.addPoint( c );
+ ring.addPoint( b );
+ ring.addPoint( ring.startPoint() );
+
+ shell->addPolygon( Polygon( ring ) ) ;
+ }
+
+ //top : e,f,g,h
+ {
+ LineString ring ;
+ ring.addPoint( e );
+ ring.addPoint( f );
+ ring.addPoint( g );
+ ring.addPoint( h );
+ ring.addPoint( ring.startPoint() );
+
+ shell->addPolygon( Polygon( ring ) ) ;
+ }
+
+ //front : a,b,f,e
+ {
+ LineString ring ;
+ ring.addPoint( a );
+ ring.addPoint( b );
+ ring.addPoint( f );
+ ring.addPoint( e );
+ ring.addPoint( ring.startPoint() );
+
+ shell->addPolygon( Polygon( ring ) ) ;
+ }
+
+ //back : c,d,h,g
+ {
+ LineString ring ;
+ ring.addPoint( c );
+ ring.addPoint( d );
+ ring.addPoint( h );
+ ring.addPoint( g );
+ ring.addPoint( ring.startPoint() );
+
+ shell->addPolygon( Polygon( ring ) ) ;
+ }
+
+ //right : b,c,g,f
+ {
+ LineString ring ;
+ ring.addPoint( b );
+ ring.addPoint( c );
+ ring.addPoint( g );
+ ring.addPoint( f );
+ ring.addPoint( ring.startPoint() );
+
+ shell->addPolygon( Polygon( ring ) ) ;
+ }
+
+ //left : a,e,h,d
+ {
+ LineString ring ;
+ ring.addPoint( a );
+ ring.addPoint( e );
+ ring.addPoint( h );
+ ring.addPoint( d );
+ ring.addPoint( ring.startPoint() );
+
+ shell->addPolygon( Polygon( ring ) ) ;
+ }
+
+ return shell ;
+}
+
+///
+///
+///
+std::auto_ptr< Solid > Envelope::toSolid() const
+{
+ return std::auto_ptr< Solid >(
+ new Solid( toShell().release() )
+ );
+}
+
+
+///
+///
+///
+std::ostream& Envelope::print( std::ostream& ostr ) const
+{
+ ostr << "[ " << xMin();
+ ostr << ", " << xMax();
+ ostr << ", " << yMin();
+ ostr << ", " << yMax();
+
+ if ( is3D() ) {
+ ostr << ", " << zMin() << ", " << zMax();
+ }
+
+ ostr << " ]";
+ return ostr;
+}
+
+bool operator==( const Envelope& a, const Envelope& b )
+{
+ if ( a.is3D() ) {
+ return a.xMin() == b.xMin() &&
+ a.yMin() == b.yMin() &&
+ a.zMin() == b.zMin() &&
+ a.xMax() == b.xMax() &&
+ a.yMax() == b.yMax() &&
+ a.zMax() == b.zMax();
+ }
+
+ return a.xMin() == b.xMin() &&
+ a.yMin() == b.yMin() &&
+ a.xMax() == b.xMax() &&
+ a.yMax() == b.yMax();
+}
+}//SFCGAL
+
diff --git a/src/Envelope.h b/src/Envelope.h
new file mode 100644
index 0000000..5a6c9c9
--- /dev/null
+++ b/src/Envelope.h
@@ -0,0 +1,227 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_ENVELOPE_H_
+#define _SFCGAL_ENVELOPE_H_
+
+#include <memory>
+#include <boost/assert.hpp>
+
+#include <CGAL/Bbox_2.h>
+#include <CGAL/Bbox_3.h>
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/detail/Interval.h>
+#include <SFCGAL/Coordinate.h>
+
+namespace SFCGAL {
+
+class LineString ;
+class Polygon ;
+class Solid ;
+class PolyhedralSurface ;
+
+/**
+ * Represents a bounding box
+ * @todo add asText instead of "print"?
+ * @todo add basic operations (especialy intersects/intersects3D)
+ */
+class SFCGAL_API Envelope {
+public:
+ /**
+ * default constructor (empty bounding box)
+ */
+ Envelope() ;
+ /**
+ * 2D box constructor with min,max values
+ */
+ Envelope(
+ const double& xmin, const double& xmax,
+ const double& ymin, const double& ymax
+ ) ;
+ /**
+ * 3D box constructor with min,max values
+ */
+ Envelope(
+ const double& xmin, const double& xmax,
+ const double& ymin, const double& ymax,
+ const double& zmin, const double& zmax
+ ) ;
+ /**
+ * default constructor (empty bounding box)
+ */
+ Envelope( const Coordinate& p ) ;
+ /**
+ * default constructor (empty bounding box)
+ */
+ Envelope( const Coordinate& p1, const Coordinate& p2 ) ;
+ /**
+ * copy constructor
+ */
+ Envelope( const Envelope& other ) ;
+ /**
+ * assign operator
+ */
+ Envelope& operator = ( const Envelope& other ) ;
+ /**
+ * destructor
+ */
+ ~Envelope() ;
+
+ /**
+ * indicates if the bounding box is empty
+ */
+ bool isEmpty() const ;
+ /**
+ * indicates if the bounding box has a 3D component
+ */
+ bool is3D() const ;
+
+ /**
+ * expand the box to include coordinate
+ */
+ void expandToInclude( const Coordinate& coordinate ) ;
+
+
+ inline const double& xMin() const {
+ return _bounds[0].lower();
+ }
+ inline const double& yMin() const {
+ return _bounds[1].lower();
+ }
+ inline const double& zMin() const {
+ return _bounds[2].lower();
+ }
+
+ inline const double& xMax() const {
+ return _bounds[0].upper();
+ }
+ inline const double& yMax() const {
+ return _bounds[1].upper();
+ }
+ inline const double& zMax() const {
+ return _bounds[2].upper();
+ }
+
+ /**
+ * returns the n-th bound
+ */
+ inline detail::Interval& boundsN( const size_t& n ) {
+ BOOST_ASSERT( n < 3 );
+ return _bounds[n] ;
+ }
+ /**
+ * returns the n-th bound
+ */
+ inline const detail::Interval& boundsN( const size_t& n ) const {
+ BOOST_ASSERT( n < 3 );
+ return _bounds[n] ;
+ }
+
+
+ /**
+ * Convenience function. Convert to CGAL::BBox_2
+ */
+ inline CGAL::Bbox_2 toBbox_2() const {
+ BOOST_ASSERT( ! isEmpty() );
+
+ return CGAL::Bbox_2(
+ _bounds[0].lower(), _bounds[1].lower(),
+ _bounds[0].upper(), _bounds[1].upper()
+ );
+ }
+
+ /**
+ * Convenience function. Convert to CGAL::BBox_3
+ */
+ inline CGAL::Bbox_3 toBbox_3() const {
+ if ( is3D() ) {
+ return CGAL::Bbox_3(
+ _bounds[0].lower(), _bounds[1].lower(), _bounds[2].lower(),
+ _bounds[0].upper(), _bounds[1].upper(), _bounds[2].upper()
+ );
+ }
+
+ return CGAL::Bbox_3(
+ _bounds[0].lower(), _bounds[1].lower(), 0.0,
+ _bounds[0].upper(), _bounds[1].upper(), 0.0
+ );
+ }
+
+
+
+ /**
+ * Global binary operator on Envelopes. Test if A's bounding box contains B's
+ * FIXME: consider moving that outside of the class
+ */
+ static bool contains( const Envelope& a, const Envelope& b );
+
+ /**
+ * Global binary operator on Envelopes. Test if A's bounding box overlaps B's
+ */
+ static bool overlaps( const Envelope& a, const Envelope& b );
+
+
+ //-- helpers
+
+ /**
+ * @brief convenience method to convert to 2D Polygon ring
+ * @warning empty LineString for empty Envelope, may be X or Y collapsed
+ */
+ std::auto_ptr< LineString > toRing() const ;
+ /**
+ * @brief convenience method to convert to 2D Polygon
+ * @warning empty Polygon for empty Envelope, may be X or Y collapsed
+ */
+ std::auto_ptr< Polygon > toPolygon() const ;
+
+ /**
+ * @brief convenience method to convert to 3D Shell
+ * @warning empty Solid for empty or non 3D Envelope, may be X, Y or Z collapsed
+ */
+ std::auto_ptr< PolyhedralSurface > toShell() const ;
+ /**
+ * @brief convenience method to convert to 3D Solid
+ * @warning empty Solid for empty or non 3D Envelope, may be X, Y or Z collapsed
+ */
+ std::auto_ptr< Solid > toSolid() const ;
+
+
+ /*
+ * Display method
+ */
+ std::ostream& print( std::ostream& ) const;
+
+private:
+ /**
+ * bounds of the interval ((xmin,xmax),(ymin,ymax),(zmin,zmax))
+ */
+ detail::Interval _bounds[3] ;
+};
+
+/**
+ * Global comparison operator on Envelope
+ */
+SFCGAL_API bool operator==( const Envelope&, const Envelope& );
+
+}//SFCGAL
+
+#endif
diff --git a/src/Exception.cpp b/src/Exception.cpp
new file mode 100644
index 0000000..545bd56
--- /dev/null
+++ b/src/Exception.cpp
@@ -0,0 +1,73 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/Exception.h>
+
+
+namespace SFCGAL {
+
+///
+///
+///
+Exception::Exception() throw():
+ _message( "unknown exception" )
+{
+
+}
+
+
+///
+///
+///
+Exception::Exception( std::string const& message ) throw():
+ _message( message )
+{
+
+}
+
+///
+///
+///
+Exception::~Exception() throw()
+{
+
+}
+
+///
+///
+///
+const char* Exception::what() const throw()
+{
+ return _message.c_str() ;
+}
+
+///
+///
+///
+std::string Exception::diagnostic() const throw()
+{
+ return boost::diagnostic_information( *this ) ;
+}
+
+
+}//SFCGAL
+
+
+
diff --git a/src/Exception.h b/src/Exception.h
new file mode 100644
index 0000000..cf3178a
--- /dev/null
+++ b/src/Exception.h
@@ -0,0 +1,117 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _IGN_EXCEPTION_H_
+#define _IGN_EXCEPTION_H_
+
+#include <SFCGAL/config.h>
+
+#include <string>
+
+#include <boost/exception/all.hpp>
+#include <boost/format.hpp>
+
+namespace SFCGAL {
+
+/**
+ * Base SFCGAL Exception
+ *
+ * \code
+ * BOOST_THROW_EXCEPTION( Exception("invalid geometry") );
+ * \endcode
+ */
+class SFCGAL_API Exception : public virtual boost::exception, public virtual std::exception {
+public:
+ Exception() throw();
+ Exception( std::string const& message ) throw();
+ virtual ~Exception() throw();
+
+ /**
+ * returns the exception message
+ */
+ virtual const char* what() const throw();
+ /**
+ * returns diagnostic informations (file, line, etc.)
+ */
+ std::string diagnostic() const throw();
+protected:
+ std::string _message;
+};
+
+/**
+ * SFCGAL Exception thrown when invalid geometries are found before entering an algo
+ */
+class SFCGAL_API GeometryInvalidityException : public Exception {
+public:
+ GeometryInvalidityException( std::string const& message ):
+ Exception( message ) {
+ }
+
+};
+
+/**
+ * SFCGAL Exception thrown when a function is not implemented
+ */
+class SFCGAL_API NotImplementedException : public Exception {
+public:
+ NotImplementedException( std::string const& message ):
+ Exception( message ) {
+ }
+
+};
+
+/**
+ * SFCGAL Exception thrown when geometry is inapropriate for a function
+ */
+class SFCGAL_API InappropriateGeometryException : public Exception {
+public:
+ InappropriateGeometryException( std::string const& message ):
+ Exception( message ) {
+ }
+
+};
+
+/**
+ * SFCGAL Exception thrown when non finite value is found
+ */
+class SFCGAL_API NonFiniteValueException : public Exception {
+public:
+ NonFiniteValueException( std::string const& message ):
+ Exception( message ) {
+ }
+
+};
+
+/**
+ * SFCGAL Exception thrown when parsing WKT
+ */
+class SFCGAL_API WktParseException : public Exception {
+public:
+ WktParseException( std::string const& message ):
+ Exception( message ) {
+ }
+
+};
+
+} // namespace SFCGAL
+
+#endif
+
+
diff --git a/src/Geometry.cpp b/src/Geometry.cpp
new file mode 100644
index 0000000..c635708
--- /dev/null
+++ b/src/Geometry.cpp
@@ -0,0 +1,204 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/Geometry.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/GeometryVisitor.h>
+#include <SFCGAL/detail/io/WktWriter.h>
+#include <SFCGAL/detail/GetPointsVisitor.h>
+
+#include <SFCGAL/algorithm/BoundaryVisitor.h>
+#include <SFCGAL/algorithm/distance.h>
+#include <SFCGAL/algorithm/distance3d.h>
+
+#include <SFCGAL/detail/EnvelopeVisitor.h>
+
+#include <SFCGAL/detail/transform/RoundTransform.h>
+
+#include <SFCGAL/Kernel.h>
+
+namespace SFCGAL {
+
+///
+///
+///
+Geometry::~Geometry()
+{
+
+}
+
+
+///
+///
+///
+std::string Geometry::asText( const int& numDecimals ) const
+{
+ std::ostringstream oss;
+
+ if ( numDecimals >= 0 ) {
+ oss << std::fixed ;
+ oss.precision( numDecimals );
+ }
+
+ detail::io::WktWriter writer( oss );
+ bool exact = false;
+
+ if ( numDecimals == -1 ) {
+ exact = true;
+ }
+
+ writer.write( *this, exact );
+ return oss.str();
+}
+
+///
+///
+///
+Envelope Geometry::envelope() const
+{
+ Envelope box ;
+ detail::EnvelopeVisitor envelopeVisitor( box );
+ accept( envelopeVisitor );
+ return box ;
+}
+
+///
+///
+///
+std::auto_ptr< Geometry > Geometry::boundary() const
+{
+ algorithm::BoundaryVisitor visitor ;
+ accept( visitor );
+ return std::auto_ptr< Geometry >( visitor.releaseBoundary() ) ;
+}
+
+
+///
+///
+///
+double Geometry::distance( const Geometry& other ) const
+{
+ return algorithm::distance( *this, other ) ;
+}
+
+///
+///
+///
+double Geometry::distance3D( const Geometry& other ) const
+{
+ return algorithm::distance3D( *this, other ) ;
+}
+
+///
+///
+///
+void Geometry::round( const long& scale )
+{
+ transform::RoundTransform roundTransform( scale );
+ accept( roundTransform ) ;
+}
+
+///
+///
+///
+size_t Geometry::numGeometries() const
+{
+ return 1 ;
+}
+
+///
+///
+///
+const Geometry& Geometry::geometryN( size_t const& n ) const
+{
+ BOOST_ASSERT( n == 0 );
+ ( void )n;
+ return *this ;
+}
+
+///
+///
+///
+Geometry& Geometry::geometryN( size_t const& n )
+{
+ BOOST_ASSERT( n == 0 );
+ ( void )n;
+ return *this ;
+}
+
+
+///
+///
+///
+Geometry::Geometry()
+{
+
+}
+
+///
+///
+///
+Geometry::Geometry( Geometry const& )
+{
+
+}
+
+///
+/// Function used to compare geometries
+/// FIXME
+/// Since we do not have (yet) a real "equals" operator, we only compare points coordinates
+bool operator == ( const Geometry& ga, const Geometry& gb )
+{
+ if ( ga.geometryTypeId() != gb.geometryTypeId() ) {
+ return false;
+ }
+
+ detail::GetPointsVisitor get_points_a, get_points_b;
+ ga.accept( get_points_a );
+ gb.accept( get_points_b );
+
+ if ( get_points_a.points.size() != get_points_b.points.size() ) {
+ return false;
+ }
+
+ for ( size_t i = 0; i < get_points_a.points.size(); ++i ) {
+ bool found = false;
+
+ for ( size_t j = 0; j < get_points_b.points.size(); ++j ) {
+ const Point& pta = *( get_points_a.points[i] );
+ const Point& ptb = *( get_points_b.points[j] );
+
+ if ( pta == ptb ) {
+ found = true;
+ break;
+ }
+ }
+
+ if ( ! found ) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+}//SFCGAL
+
diff --git a/src/Geometry.h b/src/Geometry.h
new file mode 100644
index 0000000..86c7846
--- /dev/null
+++ b/src/Geometry.h
@@ -0,0 +1,286 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_GEOMETRY_H_
+#define _SFCGAL_GEOMETRY_H_
+
+#include <SFCGAL/config.h>
+
+#include <boost/shared_ptr.hpp>
+
+#include <memory>
+#include <string>
+#include <sstream>
+
+#include <boost/assert.hpp>
+
+namespace CGAL {
+class Object;
+}
+
+namespace SFCGAL {
+class Geometry ;
+class Point ;
+class LineString ;
+class Polygon ;
+class GeometryCollection ;
+class MultiPoint ;
+class MultiLineString ;
+class MultiPolygon ;
+
+class Triangle ;
+class TriangulatedSurface ;
+class PolyhedralSurface ;
+
+//not SFA, appears in GML/CityGML
+class Solid ;
+//not SFA, appears in GML/CityGML
+class MultiSolid ;
+//not SFA, appears in GML/CityGML
+class Grid ;
+
+class Envelope ;
+
+class GeometryVisitor ;
+class ConstGeometryVisitor ;
+}
+
+namespace SFCGAL {
+
+/**
+ * [OGC/SFA]8.2.3 "A common list of codes for geometric types"
+ *
+ * @todo solid and triangles as non OGC/SFA geometric types?
+ * @warning codes for abstract classes and unimplemented classes are hidden
+ * @warning code values have are important for WKB
+ *
+ * @ingroup public_api
+ */
+enum GeometryType {
+// TYPE_GEOMETRY = 0, //abstract
+ TYPE_POINT = 1,
+ TYPE_LINESTRING = 2,
+ TYPE_POLYGON = 3,
+ TYPE_MULTIPOINT = 4,
+ TYPE_MULTILINESTRING = 5,
+ TYPE_MULTIPOLYGON = 6,
+ TYPE_GEOMETRYCOLLECTION = 7,
+// TYPE_CIRCULARSTRING = 8, // not yet supported
+// TYPE_COMPOUNDCURVE = 9, // not yet supported
+// TYPE_CURVEPOLYGON = 10, // not yet supported
+// TYPE_MULTICURVE = 11, //abstract
+// TYPE_MULTISURFACE = 12, //abstract
+// TYPE_CURVE = 13, //abstract
+// TYPE_SURFACE = 14, //abstract
+ TYPE_POLYHEDRALSURFACE = 15,
+ TYPE_TRIANGULATEDSURFACE = 16,
+
+ //-- not official codes
+ TYPE_TRIANGLE = 100, //17 in Wikipedia???
+ TYPE_SOLID = 101,
+ TYPE_MULTISOLID = 102
+};
+
+
+/**
+ * @brief coordinate types (XY, XYZ, XYM, etc.)
+ * @see SFA 2.8.3 LineStringZ = 1003 ( coordinateType + geometryType)
+ * @ingroup public_api
+ */
+typedef enum {
+ COORDINATE_XY = 0 ,
+ COORDINATE_XYZ = 1000,
+ COORDINATE_XYM = 2000,
+ COORDINATE_XYZM = 3000
+} CoordinateType ;
+
+/**
+ * @brief OGC/SFA based Geometry abstract class
+ *
+ * @ingroup public_api
+ */
+class SFCGAL_API Geometry {
+public:
+ virtual ~Geometry();
+
+ /**
+ * @brief Get a deep copy of the geometry
+ */
+ virtual Geometry* clone() const = 0 ;
+
+ /**
+ * @brief [OGC/SFA]returns the geometry type
+ * @warning use CamelCase (LineString, not LINESTRING)
+ */
+ virtual std::string geometryType() const = 0 ;
+ /**
+ * @brief Returns a code corresponding to the type
+ * @warning not standard
+ */
+ virtual GeometryType geometryTypeId() const = 0 ;
+
+ /**
+ * [OGC/SFA]Dimension of the Geometry ( 0 : punctual, 1 : curve, ...)
+ * @warning empty geometries provide the dimension corresponding to the object
+ */
+ virtual int dimension() const = 0 ;
+ /**
+ * [OGC/SFA]returns the dimension of the coordinates
+ * @pre suppose no mix of 2D/3D coordinates
+ */
+ virtual int coordinateDimension() const = 0 ;
+ /**
+ * [OGC/SFA]test if geometry is empty
+ */
+ virtual bool isEmpty() const = 0 ;
+
+ /**
+ * [OGC/SFA]test if geometry is 3d
+ * @pre suppose no mix of 2D/3D coordinates
+ */
+ virtual bool is3D() const = 0 ;
+ /**
+ * [OGC/SFA]test if geometry is measured (has an m)
+ * @pre suppose no mix of M/!M points
+ */
+ virtual bool isMeasured() const = 0 ;
+
+ //virtual bool isSimple() const = 0 ;
+
+ /**
+ * [OGC/SFA]returns the WKT string
+ * @param numDecimals extension specify fix precision output
+ */
+ std::string asText( const int& numDecimals = -1 ) const ;
+
+ /**
+ * [OGC/SFA]Returns a polygon representing the BBOX of the geometry
+ * @todo In order to adapt to 3D, would be better to define an "Envelope type",
+ * otherway would lead to Polygon and PolyhedralSurface
+ */
+ //std::auto_ptr< Geometry > envelope() const = 0 ;
+ Envelope envelope() const ;
+
+ /**
+ * @brief [OGC/SFA]Returns the boundary of the geometry
+ */
+ virtual std::auto_ptr< Geometry > boundary() const ;
+
+ /**
+ * @brief Computes the distance to an other geometry
+ */
+ double distance( const Geometry& other ) const ;
+ /**
+ * @brief Computes the 3D distance to an other geometry
+ */
+ double distance3D( const Geometry& other ) const ;
+
+
+ //-- helpers
+
+ /**
+ * @brief round the geometry with a corresponding scale factor
+ * @param scale the scale factor (1 corresponds to the nearest integer, 1000 to a 0.001 tolerance)
+ */
+ void round( const long& scale = 1 ) ;
+
+
+ /**
+ * @brief [OGC/SFA]Gets the number of geometries in a collection of geometries
+ * @warning 1 for Point, LineString, Polygon, Triangle
+ */
+ virtual size_t numGeometries() const ;
+ /**
+ * @brief [OGC/SFA]Returns the n-th geometry
+ * @warning *this for Point, LineString, Polygon, Triangle
+ */
+ virtual const Geometry& geometryN( size_t const& n ) const ;
+ /**
+ * @brief [OGC/SFA]Returns the n-th geometry
+ * @warning *this for Point, LineString, Polygon, Triangle
+ */
+ virtual Geometry& geometryN( size_t const& n ) ;
+
+
+ /**
+ * @brief Tests if geometry is of "Derived" type given as template parameter
+ * @warning not optimized (slow with dynamic_cast)
+ */
+ template < typename Derived >
+ inline bool is() const {
+ return dynamic_cast< Derived const* >( this ) != NULL ;
+ }
+
+
+ /**
+ * @brief Downcast to a "Derived" class
+ * @warning performs check if boost assertions are enabled
+ * @pre The cast must be doable
+ */
+ template < typename Derived >
+ inline const Derived& as() const {
+ BOOST_ASSERT( is< Derived >() );
+ return *static_cast< Derived const* >( this );
+ }
+ /**
+ * @brief Downcast to a "Derived" class
+ * @warning performs check if boost assertions are enabled
+ * @pre The cast must be doable
+ */
+ template < typename Derived >
+ inline Derived& as() {
+ BOOST_ASSERT( is< Derived >() );
+ return *static_cast< Derived* >( this );
+ }
+
+ /**
+ * @brief [visitor]dispatch visitor
+ * @ingroup detail
+ */
+ virtual void accept( GeometryVisitor& visitor ) = 0 ;
+ /**
+ * @brief [visitor]dispatch visitor
+ * @ingroup detail
+ */
+ virtual void accept( ConstGeometryVisitor& visitor ) const = 0 ;
+
+ /**
+ * Serializer
+ * @ingroup detail
+ */
+ template <class Archive>
+ void serialize( Archive& /*ar*/, const unsigned int /*version*/ ) {
+ }
+protected:
+ Geometry();
+ Geometry( const Geometry& );
+ const Geometry& operator=( const Geometry& );
+};
+
+/**
+ * Equality operator
+ * @todo only compare coordinate points
+ * @pre the two geometries must be valid
+ */
+SFCGAL_API bool operator==( const Geometry&, const Geometry& );
+
+} // namespace SFCGAL
+
+#endif
diff --git a/src/GeometryCollection.cpp b/src/GeometryCollection.cpp
new file mode 100644
index 0000000..da02f65
--- /dev/null
+++ b/src/GeometryCollection.cpp
@@ -0,0 +1,221 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/GeometryVisitor.h>
+
+#include <SFCGAL/Exception.h>
+
+
+
+namespace SFCGAL {
+
+///
+///
+///
+GeometryCollection::GeometryCollection():
+ _geometries()
+{
+
+}
+
+///
+///
+///
+GeometryCollection::GeometryCollection( GeometryCollection const& other ):
+ Geometry()
+{
+ for ( size_t i = 0; i < other.numGeometries(); i++ ) {
+ addGeometry( other.geometryN( i ).clone() );
+ }
+}
+
+///
+///
+///
+GeometryCollection& GeometryCollection::operator = ( GeometryCollection other )
+{
+ swap( other );
+ return *this ;
+}
+
+///
+///
+///
+GeometryCollection::~GeometryCollection()
+{
+
+}
+
+///
+///
+///
+GeometryCollection* GeometryCollection::clone() const
+{
+ return new GeometryCollection( *this );
+}
+
+///
+///
+///
+std::string GeometryCollection::geometryType() const
+{
+ return "GeometryCollection";
+}
+
+///
+///
+///
+GeometryType GeometryCollection::geometryTypeId() const
+{
+ return TYPE_GEOMETRYCOLLECTION ;
+}
+
+///
+///
+///
+int GeometryCollection::dimension() const
+{
+ int maxDimension = 0 ;
+
+ for ( boost::ptr_vector< Geometry >::const_iterator it = _geometries.begin(); it != _geometries.end(); ++it ) {
+ maxDimension = std::max( maxDimension, it->dimension() );
+ }
+
+ return maxDimension ;
+}
+
+///
+///
+///
+int GeometryCollection::coordinateDimension() const
+{
+ if ( isEmpty() ) {
+ return 0 ;
+ }
+ else {
+ return _geometries.front().coordinateDimension() ;
+ }
+}
+
+///
+///
+///
+bool GeometryCollection::isEmpty() const
+{
+ return _geometries.empty() ;
+}
+
+///
+///
+///
+bool GeometryCollection::is3D() const
+{
+ return ! isEmpty() && _geometries.front().is3D() ;
+}
+
+///
+///
+///
+bool GeometryCollection::isMeasured() const
+{
+ return ! isEmpty() && _geometries.front().isMeasured() ;
+}
+
+///
+///
+///
+size_t GeometryCollection::numGeometries() const
+{
+ return _geometries.size();
+}
+
+///
+///
+///
+const Geometry& GeometryCollection::geometryN( size_t const& n ) const
+{
+ return _geometries[n];
+}
+
+///
+///
+///
+Geometry& GeometryCollection::geometryN( size_t const& n )
+{
+ return _geometries[n];
+}
+
+
+///
+///
+///
+void GeometryCollection::addGeometry( Geometry* geometry )
+{
+ BOOST_ASSERT( geometry != NULL );
+
+ if ( ! isAllowed( *geometry ) ) {
+ std::ostringstream oss;
+ oss << "try a add a '" << geometry->geometryType() << "' in a '" << geometryType() << "'";
+ delete geometry; // we are responsible for the resource here
+ BOOST_THROW_EXCEPTION( std::runtime_error( oss.str() ) );
+ }
+
+ _geometries.push_back( geometry );
+}
+
+///
+///
+///
+void GeometryCollection::addGeometry( Geometry const& geometry )
+{
+ addGeometry( geometry.clone() );
+}
+
+///
+///
+///
+bool GeometryCollection::isAllowed( Geometry const& )
+{
+ //GeometryCollection accepts all subtypes
+ return true ;
+}
+
+///
+///
+///
+void GeometryCollection::accept( GeometryVisitor& visitor )
+{
+ return visitor.visit( *this );
+}
+
+///
+///
+///
+void GeometryCollection::accept( ConstGeometryVisitor& visitor ) const
+{
+ return visitor.visit( *this );
+}
+
+
+
+
+}//SFCGAL
+
diff --git a/src/GeometryCollection.h b/src/GeometryCollection.h
new file mode 100644
index 0000000..1139d6a
--- /dev/null
+++ b/src/GeometryCollection.h
@@ -0,0 +1,146 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_GEOMETRYCOLLECTION_H_
+#define _SFCGAL_GEOMETRYCOLLECTION_H_
+
+#include <vector>
+#include <boost/assert.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <boost/serialization/base_object.hpp>
+#include <boost/ptr_container/serialize_ptr_vector.hpp>
+
+#include <SFCGAL/Geometry.h>
+
+namespace SFCGAL {
+
+/**
+ * A GeometryCollection in SFA.
+ * @ingroup public_api
+ */
+class SFCGAL_API GeometryCollection : public Geometry {
+public:
+ typedef boost::ptr_vector< Geometry >::iterator iterator ;
+ typedef boost::ptr_vector< Geometry >::const_iterator const_iterator ;
+
+ /**
+ * Empty GeometryCollection constructor
+ */
+ GeometryCollection() ;
+ /**
+ * Copy constructor
+ */
+ GeometryCollection( const GeometryCollection& other ) ;
+ /**
+ * assign operator
+ */
+ GeometryCollection& operator = ( GeometryCollection other ) ;
+ /**
+ * destructor
+ */
+ virtual ~GeometryCollection() ;
+
+ //-- SFCGAL::Geometry
+ virtual GeometryCollection* clone() const ;
+
+ //-- SFCGAL::Geometry
+ virtual std::string geometryType() const ;
+ //-- SFCGAL::Geometry
+ virtual GeometryType geometryTypeId() const ;
+ //-- SFCGAL::Geometry
+ virtual int dimension() const ;
+ //-- SFCGAL::Geometry
+ virtual int coordinateDimension() const ;
+ //-- SFCGAL::Geometry
+ virtual bool isEmpty() const ;
+ //-- SFCGAL::Geometry
+ virtual bool is3D() const ;
+ //-- SFCGAL::Geometry
+ virtual bool isMeasured() const ;
+
+ //-- SFCGAL::Geometry
+ virtual size_t numGeometries() const ;
+ //-- SFCGAL::Geometry
+ virtual const Geometry& geometryN( size_t const& n ) const ;
+ //-- SFCGAL::Geometry
+ virtual Geometry& geometryN( size_t const& n ) ;
+
+ /**
+ * [SFA/OGC]add a geometry to the collection (takes ownership)
+ */
+ void addGeometry( Geometry* geometry ) ;
+ /**
+ * [SFA/OGC]add a geometry to the collection (clone instance)
+ */
+ void addGeometry( Geometry const& geometry ) ;
+
+ //-- iterators
+
+ inline iterator begin() {
+ return _geometries.begin() ;
+ }
+ inline const_iterator begin() const {
+ return _geometries.begin() ;
+ }
+
+ inline iterator end() {
+ return _geometries.end() ;
+ }
+ inline const_iterator end() const {
+ return _geometries.end() ;
+ }
+
+ //-- visitors
+
+ //-- SFCGAL::Geometry
+ virtual void accept( GeometryVisitor& visitor ) ;
+ //-- SFCGAL::Geometry
+ virtual void accept( ConstGeometryVisitor& visitor ) const ;
+
+ /**
+ * Serializer
+ */
+ template <class Archive>
+ void serialize( Archive& ar, const unsigned int /*version*/ ) {
+ ar& boost::serialization::base_object<Geometry>( *this );
+ ar& _geometries;
+ }
+private:
+ boost::ptr_vector< Geometry > _geometries ;
+
+protected:
+ /**
+ * Test if a geometry in the collection
+ */
+ virtual bool isAllowed( Geometry const& g ) ;
+
+
+ /**
+ * Swap
+ */
+ void swap( GeometryCollection& other ) {
+ _geometries.swap( other._geometries );
+ }
+};
+
+
+}
+
+#endif
diff --git a/src/GeometryVisitor.cpp b/src/GeometryVisitor.cpp
new file mode 100644
index 0000000..5a75173
--- /dev/null
+++ b/src/GeometryVisitor.cpp
@@ -0,0 +1,203 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/GeometryVisitor.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+namespace SFCGAL {
+
+///
+///
+///
+GeometryVisitor::~GeometryVisitor()
+{
+
+}
+
+///
+///
+///
+void GeometryVisitor::visit( Geometry& g )
+{
+ g.accept( *this );
+}
+//
+/////
+/////
+/////
+//void GeometryVisitor::visit( MultiPoint & g )
+//{
+// for ( size_t i = 0; i < g.numGeometries(); i++ ){
+// visit( g.geometryN(i).as< Point >() );
+// }
+//}
+//
+/////
+/////
+/////
+//void GeometryVisitor::visit( MultiLineString & g )
+//{
+// for ( size_t i = 0; i < g.numGeometries(); i++ ){
+// visit( g.geometryN(i).as< LineString >() );
+// }
+//}
+//
+/////
+/////
+/////
+//void GeometryVisitor::visit( MultiPolygon & g )
+//{
+// for ( size_t i = 0; i < g.numGeometries(); i++ ){
+// visit( g.geometryN(i).as< Polygon >() );
+// }
+//}
+//
+//
+/////
+/////
+/////
+//void GeometryVisitor::visit( GeometryCollection & g )
+//{
+// for ( size_t i = 0; i < g.numGeometries(); i++ ){
+// visit( g.geometryN(i) );
+// }
+//}
+//
+/////
+/////
+/////
+//void GeometryVisitor::visit( PolyhedralSurface & g )
+//{
+// for ( size_t i = 0; i < g.numPolygons(); i++ ){
+// visit( g.polygonN(i) );
+// }
+//}
+//
+/////
+/////
+/////
+//void GeometryVisitor::visit( TriangulatedSurface & g )
+//{
+// for ( size_t i = 0; i < g.numTriangles(); i++ ){
+// visit( g.triangleN(i) );
+// }
+//}
+
+
+//---------------- ConstGeometryVisitor
+
+
+
+///
+///
+///
+ConstGeometryVisitor::~ConstGeometryVisitor()
+{
+
+}
+
+///
+///
+///
+void ConstGeometryVisitor::visit( const Geometry& g )
+{
+ g.accept( *this );
+}
+//
+/////
+/////
+/////
+//void ConstGeometryVisitor::visit( const MultiPoint & g )
+//{
+// for ( size_t i = 0; i < g.numGeometries(); i++ ){
+// visit( g.geometryN(i).as< Point >() );
+// }
+//}
+//
+/////
+/////
+/////
+//void ConstGeometryVisitor::visit( const MultiLineString & g )
+//{
+// for ( size_t i = 0; i < g.numGeometries(); i++ ){
+// visit( g.geometryN(i).as< LineString >() );
+// }
+//}
+//
+/////
+/////
+/////
+//void ConstGeometryVisitor::visit( const MultiPolygon & g )
+//{
+// for ( size_t i = 0; i < g.numGeometries(); i++ ){
+// visit( g.geometryN(i).as< Polygon >() );
+// }
+//}
+//
+//
+/////
+/////
+/////
+//void ConstGeometryVisitor::visit( const GeometryCollection & g )
+//{
+// for ( size_t i = 0; i < g.numGeometries(); i++ ){
+// visit( g.geometryN(i) );
+// }
+//}
+//
+/////
+/////
+/////
+//void ConstGeometryVisitor::visit( const PolyhedralSurface & g )
+//{
+// for ( size_t i = 0; i < g.numPolygons(); i++ ){
+// visit( g.polygonN(i) );
+// }
+//}
+//
+/////
+/////
+/////
+//void ConstGeometryVisitor::visit( const TriangulatedSurface & g )
+//{
+// for ( size_t i = 0; i < g.numTriangles(); i++ ){
+// visit( g.triangleN(i) );
+// }
+//}
+//
+
+
+
+
+
+}//SFCGAL
+
diff --git a/src/GeometryVisitor.h b/src/GeometryVisitor.h
new file mode 100644
index 0000000..a41201f
--- /dev/null
+++ b/src/GeometryVisitor.h
@@ -0,0 +1,85 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_GEOMETRYVISITOR_H_
+#define _SFCGAL_GEOMETRYVISITOR_H_
+
+#include <SFCGAL/Geometry.h>
+
+namespace SFCGAL {
+
+/**
+ * GeometryVisitor
+ */
+class SFCGAL_API GeometryVisitor {
+public:
+ virtual ~GeometryVisitor() ;
+
+ /**
+ * apply visitor
+ */
+ virtual void visit( Geometry& g ) ;
+
+ virtual void visit( Point& g ) = 0 ;
+ virtual void visit( LineString& g ) = 0 ;
+ virtual void visit( Polygon& g ) = 0 ;
+ virtual void visit( Triangle& g ) = 0 ;
+ virtual void visit( Solid& g ) = 0 ;
+ virtual void visit( MultiPoint& g ) = 0 ;
+ virtual void visit( MultiLineString& g ) = 0 ;
+ virtual void visit( MultiPolygon& g ) = 0 ;
+ virtual void visit( MultiSolid& g ) = 0 ;
+ virtual void visit( GeometryCollection& g ) = 0 ;
+ virtual void visit( PolyhedralSurface& g ) = 0 ;
+ virtual void visit( TriangulatedSurface& g ) = 0 ;
+};
+
+
+/**
+ * Visitor for const geometries
+ */
+class SFCGAL_API ConstGeometryVisitor {
+public:
+ virtual ~ConstGeometryVisitor() ;
+
+ /**
+ * apply visitor
+ */
+ virtual void visit( const Geometry& g ) ;
+
+ virtual void visit( const Point& g ) = 0 ;
+ virtual void visit( const LineString& g ) = 0 ;
+ virtual void visit( const Polygon& g ) = 0 ;
+ virtual void visit( const Triangle& g ) = 0 ;
+ virtual void visit( const Solid& g ) = 0 ;
+ virtual void visit( const MultiPoint& g ) = 0 ;
+ virtual void visit( const MultiLineString& g ) = 0 ;
+ virtual void visit( const MultiPolygon& g ) = 0 ;
+ virtual void visit( const MultiSolid& g ) = 0 ;
+ virtual void visit( const GeometryCollection& g ) = 0 ;
+ virtual void visit( const PolyhedralSurface& g ) = 0 ;
+ virtual void visit( const TriangulatedSurface& g ) = 0 ;
+};
+
+
+}//SFCGAL
+
+
+#endif
diff --git a/src/Grid.cpp b/src/Grid.cpp
new file mode 100644
index 0000000..ec98b20
--- /dev/null
+++ b/src/Grid.cpp
@@ -0,0 +1,138 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/Grid.h>
+
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/TriangulatedSurface.h>
+
+using namespace SFCGAL::detail;
+
+namespace SFCGAL {
+
+///
+///
+///
+Grid::Grid():
+ _data(),
+ _limits( Envelope( 0.0,1.0,0.0,1.0 ) ),
+ _pixelConvention( PIXEL_IS_POINT )
+{
+
+}
+
+///
+///
+///
+Grid::Grid(
+ const size_t& nrows,
+ const size_t& ncols,
+ const double& fillValue,
+ const Envelope& limits,
+ const PixelConvention& pixelType
+):
+ _data( ublas::scalar_matrix< double >( nrows, ncols, fillValue ) ),
+ _limits( limits ),
+ _pixelConvention( pixelType )
+{
+
+}
+
+
+///
+///
+///
+Grid::Grid(
+ const ublas::matrix< double >& data,
+ const Envelope& limits,
+ const PixelConvention& pixelType
+):
+ _data( data ),
+ _limits( limits ),
+ _pixelConvention( pixelType )
+{
+
+}
+
+///
+///
+///
+Grid::Grid( const Grid& other )
+{
+ ( *this ) = other ;
+}
+
+///
+///
+///
+Grid& Grid::operator = ( const Grid& other )
+{
+ _data = other._data ;
+ _limits = other._limits ;
+ _pixelConvention = other._pixelConvention ;
+ return *this ;
+}
+
+///
+///
+///
+Grid::~Grid()
+{
+
+}
+
+
+///
+///
+///
+std::auto_ptr< TriangulatedSurface > Grid::toTrianguledSurface() const
+{
+ std::auto_ptr< TriangulatedSurface > result( new TriangulatedSurface() ) ;
+
+ if ( nrows() <= 1 || ncols() <= 1 ) {
+ return result ;
+ }
+
+ for ( size_t i = 0; i < nrows() - 1; i++ ) {
+ for ( size_t j = 0; j < ncols() - 1; j++ ) {
+ /*
+ * a b
+ *
+ * d c
+ */
+ Point a = point( i,j );
+ Point b = point( i,j+1 );
+ Point c = point( i+1,j+1 );
+ Point d = point( i+1,j );
+
+ if ( d.isMeasured() && c.isMeasured() && b.isMeasured() ) {
+ result->addTriangle( new Triangle( d, c, b ) );
+ }
+
+ if ( d.isMeasured() && b.isMeasured() && a.isMeasured() ) {
+ result->addTriangle( new Triangle( d, b, a ) );
+ }
+ }
+ }
+
+ return result ;
+}
+
+} // namespace SFCGAL
diff --git a/src/Grid.h b/src/Grid.h
new file mode 100644
index 0000000..299e2bb
--- /dev/null
+++ b/src/Grid.h
@@ -0,0 +1,239 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_GRID_H_
+#define _SFCGAL_GRID_H_
+
+#include <SFCGAL/detail/ublas.h>
+
+#include <SFCGAL/Envelope.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/TriangulatedSurface.h>
+
+namespace SFCGAL {
+
+/**
+ * @brief represents a pixel convention for Grid data
+ *
+ * PIXEL_IS_POINT : Each value represents a point of the grid
+ * PIXEL_IS_AREA : Each value corresponds to an area
+ *
+ */
+typedef enum {
+ PIXEL_IS_POINT,
+ PIXEL_IS_AREA
+} PixelConvention ;
+
+/**
+ * @brief represents a Grid.
+ *
+ * left-right, top-down orientation :
+ * i
+ * +----------------------->
+ * |
+ * |
+ * |
+ * |
+ * v j
+ *
+ *
+ * NaN represents undefined values
+ */
+class SFCGAL_API Grid {
+public:
+
+ /**
+ * @brief default constructor
+ */
+ Grid();
+ /**
+ * @brief default constructor
+ */
+ Grid(
+ const size_t& nrows,
+ const size_t& ncols,
+ const double& fillValue = NaN(),
+ const Envelope& limits = Envelope( 0.0,1.0,0.0,1.0 ),
+ const PixelConvention& pixelType = PIXEL_IS_POINT
+ );
+ /**
+ * @brief copy constructor
+ */
+ Grid(
+ const detail::ublas::matrix< double >& data,
+ const Envelope& limits = Envelope( 0.0,1.0,0.0,1.0 ),
+ const PixelConvention& pixelType = PIXEL_IS_POINT
+ );
+ /**
+ * @brief copy constructor
+ */
+ Grid( const Grid& other );
+ /**
+ * @brief copy constructor
+ */
+ Grid& operator = ( const Grid& other );
+ /**
+ * @brief destructor
+ */
+ ~Grid();
+
+
+ /**
+ * @brief test if the grid is empty
+ */
+ inline bool isEmpty() const {
+ return ( _data.size1() == 0U ) || ( _data.size2() == 0U ) ;
+ }
+
+ /**
+ * @brief get a point at a specific location
+ */
+ inline Point point( const size_t& row, const size_t& col ) const {
+ if ( _pixelConvention == PIXEL_IS_POINT ) {
+ Point p(
+ _limits.xMin() + col * dx(),
+ _limits.yMax() - row * dy() );
+ p.setM( _data( row,col ) );
+ return p;
+ }
+ else {
+ Point p(
+ _limits.xMin() + ( 0.5 + col ) * dx(),
+ _limits.yMax() - ( 0.5 + row ) * dy() );
+ p.setM( _data( row,col ) );
+ return p;
+ }
+ }
+
+ /**
+ * @brief get the width of a pixel
+ */
+ inline double dx() const {
+ if ( _pixelConvention == PIXEL_IS_POINT ) {
+ return _limits.boundsN( 0 ).width() / ( _data.size2() - 1 ) ;
+ }
+ else {
+ return _limits.boundsN( 0 ).width() / ( _data.size2() ) ;
+ }
+ }
+
+ /**
+ * @brief get the height of a pixel
+ */
+ inline double dy() const {
+ if ( _pixelConvention == PIXEL_IS_POINT ) {
+ return _limits.boundsN( 1 ).width() / ( _data.size1() - 1 ) ;
+ }
+ else {
+ return _limits.boundsN( 1 ).width() / ( _data.size1() ) ;
+ }
+ }
+
+ /**
+ * @brief get Z for a given location
+ */
+ inline const double& z( const size_t& row, const size_t& col ) const {
+ return _data( row,col ) ;
+ }
+ /**
+ * @brief get Z for a given location
+ */
+ inline double& z( const size_t& row, const size_t& col ) {
+ return _data( row,col ) ;
+ }
+
+
+ /**
+ * @brief gets the height of the grid
+ */
+ inline size_t nrows() const {
+ return _data.size1() ;
+ }
+ /**
+ * @brief gets the width of the grid
+ */
+ inline size_t ncols() const {
+ return _data.size2() ;
+ }
+
+ /**
+ * @brief access to grid limits
+ */
+ inline const Envelope& limits() const {
+ return _limits ;
+ }
+ /**
+ * @brief Sets the limits
+ */
+ inline void setLimits( const Envelope& limits ) {
+ _limits = limits ;
+ }
+
+ /**
+ * @brief get pixel type
+ */
+ inline const PixelConvention& pixelConvention() const {
+ return _pixelConvention ;
+ }
+ /**
+ * @brief set the pixel type
+ */
+ inline void setPixelConvention( const PixelConvention& pixelConvention ) {
+ _pixelConvention = pixelConvention ;
+ }
+
+ /**
+ * @brief [advanced]access to grid data
+ */
+ inline detail::ublas::matrix< double >& data() {
+ return _data ;
+ }
+ /**
+ * @brief [advanced]access to grid data
+ */
+ inline const detail::ublas::matrix< double >& data() const {
+ return _data ;
+ }
+
+
+ /**
+ * @brief converts the Grid to a TriangulatedSurface
+ */
+ std::auto_ptr< TriangulatedSurface > toTrianguledSurface() const ;
+
+
+private:
+ /**
+ * @brief grid data
+ */
+ detail::ublas::matrix< double > _data ;
+ /**
+ * @brief grid extent
+ */
+ Envelope _limits ;
+ /**
+ * @brief pixel type
+ */
+ PixelConvention _pixelConvention ;
+};
+
+} // namespace SFCGAL
+
+#endif
diff --git a/src/Kernel.h b/src/Kernel.h
new file mode 100644
index 0000000..cf299b3
--- /dev/null
+++ b/src/Kernel.h
@@ -0,0 +1,41 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_KERNEL_H_
+#define _SFCGAL_KERNEL_H_
+
+#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+
+namespace SFCGAL {
+
+/**
+ * default Kernel
+ */
+typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel ;
+
+
+/**
+ * Quotient type
+ */
+typedef CGAL::Gmpq QT;
+
+}//namespace SFCGAL
+
+#endif
diff --git a/src/LineString.cpp b/src/LineString.cpp
new file mode 100644
index 0000000..a5d08af
--- /dev/null
+++ b/src/LineString.cpp
@@ -0,0 +1,256 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/GeometryVisitor.h>
+
+namespace SFCGAL {
+
+///
+///
+///
+LineString::LineString():
+ Geometry(),
+ _points()
+{
+
+}
+
+///
+///
+///
+LineString::LineString( const std::vector< Point >& points ):
+ Geometry(),
+ _points()
+{
+ for ( size_t i = 0; i < points.size(); i++ ) {
+ _points.push_back( points[i].clone() ) ;
+ }
+}
+
+///
+///
+///
+LineString::LineString( const Point& startPoint, const Point& endPoint ):
+ Geometry(),
+ _points()
+{
+ _points.push_back( startPoint.clone() );
+ _points.push_back( endPoint.clone() );
+}
+
+///
+///
+///
+LineString::LineString( const LineString& other ):
+ Geometry()
+{
+ for ( size_t i = 0; i < other.numPoints(); i++ ) {
+ _points.push_back( other.pointN( i ).clone() ) ;
+ }
+}
+
+///
+///
+///
+LineString& LineString::operator = ( LineString other )
+{
+ swap( other );
+ return *this ;
+}
+
+///
+///
+///
+LineString::~LineString()
+{
+
+}
+
+///
+///
+///
+LineString* LineString::clone() const
+{
+ return new LineString( *this );
+}
+
+
+///
+///
+///
+GeometryType LineString::geometryTypeId() const
+{
+ return TYPE_LINESTRING ;
+}
+
+///
+///
+///
+std::string LineString::geometryType() const
+{
+ return "LineString" ;
+}
+
+///
+///
+///
+int LineString::dimension() const
+{
+ return 1 ;
+}
+
+///
+///
+int LineString::coordinateDimension() const
+{
+ return isEmpty() ? 0 : _points[0].coordinateDimension() ;
+}
+
+///
+///
+///
+bool LineString::isEmpty() const
+{
+ return _points.empty() ;
+}
+
+///
+///
+///
+bool LineString::is3D() const
+{
+ return ! isEmpty() && startPoint().is3D() ;
+}
+
+///
+///
+///
+bool LineString::isMeasured() const
+{
+ return ! isEmpty() && startPoint().isMeasured() ;
+}
+
+///
+///
+///
+void LineString::clear()
+{
+ _points.clear();
+}
+
+///
+///
+///
+void LineString::reverse()
+{
+ std::reverse( _points.begin(), _points.end() );
+}
+
+///
+///
+///
+size_t LineString::numSegments() const
+{
+ if ( _points.empty() ) {
+ return 0 ;
+ }
+ else {
+ return _points.size() - 1 ;
+ }
+}
+
+///
+///
+///
+bool LineString::isClosed() const
+{
+ return ( ! isEmpty() ) && ( startPoint() == endPoint() ) ;
+}
+
+///
+///
+///
+void LineString::reserve( const size_t& n )
+{
+ _points.reserve( n ) ;
+}
+
+
+///
+///
+///
+void LineString::accept( GeometryVisitor& visitor )
+{
+ return visitor.visit( *this );
+}
+
+///
+///
+///
+void LineString::accept( ConstGeometryVisitor& visitor ) const
+{
+ return visitor.visit( *this );
+}
+
+///
+///
+///
+CGAL::Polygon_2< Kernel > LineString::toPolygon_2( bool fixOrientation ) const
+{
+ if ( isEmpty() ) {
+ return CGAL::Polygon_2< Kernel >();
+ }
+
+ Point_2_const_iterator pend = points_2_end();
+ // skip the last point
+ pend--;
+
+ // skip double points
+ // TODO: what to do with cycles ?
+ std::list<Kernel::Point_2> points;
+ Kernel::Point_2 lastP;
+
+ for ( Point_2_const_iterator pit = points_2_begin(); pit != pend; ++pit ) {
+ if ( pit == points_2_begin() ) {
+ lastP = *pit;
+ points.push_back( *pit );
+ continue;
+ }
+
+ if ( lastP != *pit ) {
+ points.push_back( *pit );
+ }
+
+ lastP = *pit;
+ }
+
+ CGAL::Polygon_2< Kernel > result( points.begin(), points.end() );
+
+ if ( fixOrientation && result.orientation() == CGAL::CLOCKWISE ) {
+ result.reverse_orientation() ;
+ }
+
+ return result ;
+}
+
+
+}//SFCGAL
+
diff --git a/src/LineString.h b/src/LineString.h
new file mode 100644
index 0000000..e65eecc
--- /dev/null
+++ b/src/LineString.h
@@ -0,0 +1,319 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_LINESTRING_H_
+#define _SFCGAL_LINESTRING_H_
+
+#include <vector>
+
+#include <boost/assert.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <boost/serialization/base_object.hpp>
+#include <boost/ptr_container/serialize_ptr_vector.hpp>
+
+#include <SFCGAL/Point.h>
+
+#include <CGAL/Polygon_2.h>
+
+namespace SFCGAL {
+
+/**
+ * A LineString in SFA
+ * @ingroup public_api
+ */
+class SFCGAL_API LineString : public Geometry {
+public:
+ typedef boost::ptr_vector< Point >::iterator iterator ;
+ typedef boost::ptr_vector< Point >::const_iterator const_iterator ;
+
+ /**
+ * Empty LineString constructor
+ */
+ LineString() ;
+ /**
+ * Constructor with a point vector
+ */
+ LineString( const std::vector< Point >& points ) ;
+ /**
+ * LineString constructor
+ */
+ LineString( const Point& startPoint, const Point& endPoint ) ;
+ /**
+ * Copy constructor
+ */
+ LineString( LineString const& other ) ;
+
+ /**
+ * assign operator
+ */
+ LineString& operator = ( LineString other ) ;
+
+ /**
+ * destructor
+ */
+ ~LineString() ;
+
+ //-- SFCGAL::Geometry
+ virtual LineString* clone() const ;
+
+ //-- SFCGAL::Geometry
+ virtual std::string geometryType() const ;
+ //-- SFCGAL::Geometry
+ virtual GeometryType geometryTypeId() const ;
+ //-- SFCGAL::Geometry
+ virtual int dimension() const ;
+ //-- SFCGAL::Geometry
+ virtual int coordinateDimension() const ;
+ //-- SFCGAL::Geometry
+ virtual bool isEmpty() const ;
+ //-- SFCGAL::Geometry
+ virtual bool is3D() const ;
+ //-- SFCGAL::Geometry
+ virtual bool isMeasured() const ;
+
+ /**
+ * remove all points from the LineString
+ */
+ void clear() ;
+
+ /**
+ * reverse LineString orientation
+ */
+ void reverse() ;
+
+ /**
+ * [SFA/OGC]Returns the number of points
+ */
+ inline size_t numPoints() const {
+ return _points.size();
+ }
+ /**
+ * Returns the number of segments
+ * @warning not standard, returns zero if LineString contains only one point
+ */
+ size_t numSegments() const ;
+
+
+ /**
+ * [SFA/OGC]Returns the n-th point
+ */
+ inline const Point& pointN( size_t const& n ) const {
+ BOOST_ASSERT( n < numPoints() ) ;
+ return _points[n];
+ }
+ /**
+ * [SFA/OGC]Returns the n-th point
+ */
+ inline Point& pointN( size_t const& n ) {
+ BOOST_ASSERT( n < numPoints() ) ;
+ return _points[n];
+ }
+
+
+ /**
+ * [SFA/OGC]Returns the first point
+ */
+ inline const Point& startPoint() const {
+ return _points.front();
+ }
+ /**
+ * [SFA/OGC]Returns the first point
+ */
+ inline Point& startPoint() {
+ return _points.front();
+ }
+
+
+ /**
+ * [SFA/OGC]Returns the first point
+ */
+ inline const Point& endPoint() const {
+ return _points.back();
+ }
+ /**
+ * [SFA/OGC]Returns the first point
+ */
+ inline Point& endPoint() {
+ return _points.back();
+ }
+
+
+ /**
+ * append a Point to the LineString
+ */
+ inline void addPoint( const Point& p ) {
+ _points.push_back( p.clone() ) ;
+ }
+ /**
+ * append a Point to the LineString and takes ownership
+ */
+ inline void addPoint( Point* p ) {
+ _points.push_back( p ) ;
+ }
+
+
+ //-- methods
+
+ /**
+ * test if the LineString is closed
+ */
+ bool isClosed() const ;
+
+
+ //-- iterators
+
+ inline iterator begin() {
+ return _points.begin() ;
+ }
+ inline const_iterator begin() const {
+ return _points.begin() ;
+ }
+
+ inline iterator end() {
+ return _points.end() ;
+ }
+ inline const_iterator end() const {
+ return _points.end() ;
+ }
+
+ //-- optimization
+
+ void reserve( const size_t& n ) ;
+
+
+ /**
+ * Const iterator to 2D points
+ * TODO: replace by boost::tranform_iterator ?
+ */
+ class Point_2_const_iterator :
+ public boost::iterator_facade<
+ Point_2_const_iterator,
+ Kernel::Point_2 const,
+ boost::bidirectional_traversal_tag > {
+ public:
+ Point_2_const_iterator() {}
+ explicit Point_2_const_iterator( const_iterator it ) : it_( it ) {}
+ //Point_2_const_iterator( const Point_2_const_iterator<K>& other ) : it_(other.it_) {}
+ private:
+ friend class boost::iterator_core_access;
+ void increment() {
+ it_++;
+ }
+ void decrement() {
+ it_--;
+ }
+ bool equal( const Point_2_const_iterator& other ) const {
+ return this->it_ == other.it_;
+ }
+ const Kernel::Point_2& dereference() const {
+ p_ = it_->toPoint_2();
+ return p_;
+ }
+ mutable Kernel::Point_2 p_;
+ const_iterator it_;
+ };
+ Point_2_const_iterator points_2_begin() const {
+ return Point_2_const_iterator( begin() );
+ }
+ Point_2_const_iterator points_2_end() const {
+ return Point_2_const_iterator( end() );
+ }
+ std::pair< Point_2_const_iterator, Point_2_const_iterator > points_2() const {
+ return std::make_pair( points_2_begin(), points_2_end() );
+ }
+
+
+ /**
+ * Const iterator to 3D points
+ * TODO: replace by boost::tranform_iterator ?
+ */
+ class Point_3_const_iterator :
+ public boost::iterator_facade<
+ Point_3_const_iterator,
+ Kernel::Point_3 const,
+ boost::bidirectional_traversal_tag > {
+ public:
+ Point_3_const_iterator() {}
+ explicit Point_3_const_iterator( const_iterator it ) : it_( it ) {}
+ Point_3_const_iterator( const Point_3_const_iterator& other ) : it_( other.it_ ) {}
+ private:
+ friend class boost::iterator_core_access;
+ void increment() {
+ it_++;
+ }
+ void decrement() {
+ it_--;
+ }
+ bool equal( const Point_3_const_iterator& other ) const {
+ return this->it_ == other.it_;
+ }
+ const Kernel::Point_3& dereference() const {
+ p_ = it_->toPoint_3();
+ return p_;
+ }
+ mutable Kernel::Point_3 p_;
+ const_iterator it_;
+ };
+
+ Point_3_const_iterator points_3_begin() const {
+ return Point_3_const_iterator( begin() );
+ }
+ Point_3_const_iterator points_3_end() const {
+ return Point_3_const_iterator( end() );
+ }
+ std::pair< Point_3_const_iterator, Point_3_const_iterator > points_3() const {
+ return std::make_pair( points_3_begin(), points_3_end() );
+ }
+
+ /*
+ * @brief Convert to CGAL::Polygon_2
+ * @param forceCounterClocksize force exterior ring orientation (counter clocksize)
+ */
+ CGAL::Polygon_2< Kernel > toPolygon_2( bool fixOrientation = true ) const;
+
+ //-- visitors
+
+ //-- SFCGAL::Geometry
+ virtual void accept( GeometryVisitor& visitor ) ;
+ //-- SFCGAL::Geometry
+ virtual void accept( ConstGeometryVisitor& visitor ) const ;
+
+ /**
+ * Serializer
+ */
+ template <class Archive>
+ void serialize( Archive& ar, const unsigned int /*version*/ ) {
+ ar& boost::serialization::base_object<Geometry>( *this );
+ ar& _points;
+ }
+private:
+ boost::ptr_vector< Point > _points ;
+
+ void swap( LineString& other ) {
+ std::swap( _points, other._points );
+ }
+};
+
+
+}
+
+
+
+#endif
diff --git a/src/MultiLineString.cpp b/src/MultiLineString.cpp
new file mode 100644
index 0000000..f5025fe
--- /dev/null
+++ b/src/MultiLineString.cpp
@@ -0,0 +1,110 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/GeometryVisitor.h>
+
+namespace SFCGAL {
+
+///
+///
+///
+MultiLineString::MultiLineString():
+ GeometryCollection()
+{
+
+}
+
+///
+///
+///
+MultiLineString::MultiLineString( MultiLineString const& other ):
+ GeometryCollection( other )
+{
+
+}
+
+///
+///
+///
+MultiLineString& MultiLineString::operator = ( MultiLineString other )
+{
+ swap( other ) ;
+ return *this ;
+}
+
+///
+///
+///
+MultiLineString::~MultiLineString()
+{
+
+}
+
+///
+///
+///
+MultiLineString* MultiLineString::clone() const
+{
+ return new MultiLineString( *this );
+}
+
+///
+///
+///
+std::string MultiLineString::geometryType() const
+{
+ return "MultiLineString" ;
+}
+
+///
+///
+///
+GeometryType MultiLineString::geometryTypeId() const
+{
+ return TYPE_MULTILINESTRING ;
+}
+
+///
+///
+///
+bool MultiLineString::isAllowed( Geometry const& g )
+{
+ return g.geometryTypeId() == TYPE_LINESTRING ;
+}
+
+///
+///
+///
+void MultiLineString::accept( GeometryVisitor& visitor )
+{
+ return visitor.visit( *this );
+}
+
+///
+///
+///
+void MultiLineString::accept( ConstGeometryVisitor& visitor ) const
+{
+ return visitor.visit( *this );
+}
+
+}//SFCGAL
+
diff --git a/src/MultiLineString.h b/src/MultiLineString.h
new file mode 100644
index 0000000..94f9467
--- /dev/null
+++ b/src/MultiLineString.h
@@ -0,0 +1,101 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_MULTILINESTRING_H_
+#define _SFCGAL_MULTILINESTRING_H_
+
+#include <vector>
+#include <boost/assert.hpp>
+
+#include <boost/serialization/base_object.hpp>
+
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/GeometryCollection.h>
+
+namespace SFCGAL {
+
+/**
+ * A MultiLineString in SFA.
+ * @ingroup public_api
+ */
+class SFCGAL_API MultiLineString : public GeometryCollection {
+public:
+ /**
+ * Empty MultiLineString constructor
+ */
+ MultiLineString() ;
+ /**
+ * Copy constructor
+ */
+ MultiLineString( const MultiLineString& other ) ;
+ /**
+ * assign operator
+ */
+ MultiLineString& operator = ( MultiLineString other ) ;
+ /**
+ * destructor
+ */
+ virtual ~MultiLineString() ;
+
+ //-- SFCGAL::Geometry
+ virtual MultiLineString* clone() const ;
+
+ //-- SFCGAL::Geometry
+ virtual std::string geometryType() const ;
+ //-- SFCGAL::Geometry
+ virtual GeometryType geometryTypeId() const ;
+
+ /**
+ * returns the n-th Geometry as a Polygon
+ */
+ inline LineString& lineStringN( const size_t& n ) {
+ return geometryN( n ).as< LineString >() ;
+ }
+ /**
+ * returns the n-th Geometry as a Polygon
+ */
+ inline const LineString& lineStringN( const size_t& n ) const {
+ return geometryN( n ).as< LineString >() ;
+ }
+
+ //-- visitors
+
+ //-- SFCGAL::Geometry
+ virtual void accept( GeometryVisitor& visitor ) ;
+ //-- SFCGAL::Geometry
+ virtual void accept( ConstGeometryVisitor& visitor ) const ;
+
+ /**
+ * Serializer
+ */
+ template <class Archive>
+ void serialize( Archive& ar, const unsigned int /*version*/ ) {
+ ar& boost::serialization::base_object<GeometryCollection>( *this );
+
+ }
+protected:
+ //-- SFCGAL::GeometryCollection
+ virtual bool isAllowed( Geometry const& g ) ;
+};
+
+
+}
+
+#endif
diff --git a/src/MultiPoint.cpp b/src/MultiPoint.cpp
new file mode 100644
index 0000000..4c9162a
--- /dev/null
+++ b/src/MultiPoint.cpp
@@ -0,0 +1,113 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/GeometryVisitor.h>
+
+
+namespace SFCGAL {
+
+///
+///
+///
+MultiPoint::MultiPoint():
+ GeometryCollection()
+{
+
+}
+
+///
+///
+///
+MultiPoint::MultiPoint( MultiPoint const& other ):
+ GeometryCollection( other )
+{
+
+}
+
+///
+///
+///
+MultiPoint& MultiPoint::operator = ( MultiPoint other )
+{
+ swap( other ) ;
+ return *this ;
+}
+
+///
+///
+///
+MultiPoint::~MultiPoint()
+{
+
+}
+
+///
+///
+///
+MultiPoint* MultiPoint::clone() const
+{
+ return new MultiPoint( *this );
+}
+
+///
+///
+///
+std::string MultiPoint::geometryType() const
+{
+ return "MultiPoint" ;
+}
+
+///
+///
+///
+GeometryType MultiPoint::geometryTypeId() const
+{
+ return TYPE_MULTIPOINT ;
+}
+
+///
+///
+///
+bool MultiPoint::isAllowed( Geometry const& g )
+{
+ return g.geometryTypeId() == TYPE_POINT ;
+}
+
+
+
+///
+///
+///
+void MultiPoint::accept( GeometryVisitor& visitor )
+{
+ return visitor.visit( *this );
+}
+
+///
+///
+///
+void MultiPoint::accept( ConstGeometryVisitor& visitor ) const
+{
+ return visitor.visit( *this );
+}
+
+}//SFCGAL
+
diff --git a/src/MultiPoint.h b/src/MultiPoint.h
new file mode 100644
index 0000000..bc4c8f8
--- /dev/null
+++ b/src/MultiPoint.h
@@ -0,0 +1,105 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_MULTIPOINT_H_
+#define _SFCGAL_MULTIPOINT_H_
+
+#include <vector>
+#include <boost/assert.hpp>
+
+#include <boost/serialization/base_object.hpp>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/GeometryCollection.h>
+
+namespace SFCGAL {
+
+/**
+ * A MultiPoint in SFA.
+ * @ingroup public_api
+ */
+class SFCGAL_API MultiPoint : public GeometryCollection {
+public:
+ /**
+ * Empty MultiPoint constructor
+ */
+ MultiPoint() ;
+ /**
+ * Copy constructor
+ */
+ MultiPoint( const MultiPoint& other ) ;
+ /**
+ * assign operator
+ */
+ MultiPoint& operator = ( MultiPoint other ) ;
+ /**
+ * destructor
+ */
+ virtual ~MultiPoint() ;
+
+ //-- SFCGAL::Geometry
+ virtual MultiPoint* clone() const ;
+
+ //-- SFCGAL::Geometry
+ virtual std::string geometryType() const ;
+ //-- SFCGAL::Geometry
+ virtual GeometryType geometryTypeId() const ;
+
+
+ /**
+ * returns the n-th Geometry as a Point
+ */
+ inline Point& pointN( const size_t& n ) {
+ return geometryN( n ).as< Point >() ;
+ }
+ /**
+ * returns the n-th Geometry as a Point
+ */
+ inline const Point& pointN( const size_t& n ) const {
+ return geometryN( n ).as< Point >() ;
+ }
+
+
+
+
+ //-- visitors
+
+ //-- SFCGAL::Geometry
+ virtual void accept( GeometryVisitor& visitor ) ;
+ //-- SFCGAL::Geometry
+ virtual void accept( ConstGeometryVisitor& visitor ) const ;
+
+ /**
+ * Serializer
+ */
+ template <class Archive>
+ void serialize( Archive& ar, const unsigned int /*version*/ ) {
+ ar& boost::serialization::base_object<GeometryCollection>( *this );
+
+ }
+protected:
+ //-- SFCGAL::GeometryCollection
+ virtual bool isAllowed( Geometry const& g ) ;
+};
+
+
+}
+
+#endif
diff --git a/src/MultiPolygon.cpp b/src/MultiPolygon.cpp
new file mode 100644
index 0000000..1508a2a
--- /dev/null
+++ b/src/MultiPolygon.cpp
@@ -0,0 +1,110 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/GeometryVisitor.h>
+
+namespace SFCGAL {
+
+///
+///
+///
+MultiPolygon::MultiPolygon():
+ GeometryCollection()
+{
+
+}
+
+///
+///
+///
+MultiPolygon::MultiPolygon( MultiPolygon const& other ):
+ GeometryCollection( other )
+{
+
+}
+
+///
+///
+///
+MultiPolygon& MultiPolygon::operator = ( MultiPolygon other )
+{
+ swap( other ) ;
+ return *this ;
+}
+
+///
+///
+///
+MultiPolygon::~MultiPolygon()
+{
+
+}
+
+///
+///
+///
+MultiPolygon* MultiPolygon::clone() const
+{
+ return new MultiPolygon( *this );
+}
+
+///
+///
+///
+std::string MultiPolygon::geometryType() const
+{
+ return "MultiPolygon" ;
+}
+
+///
+///
+///
+GeometryType MultiPolygon::geometryTypeId() const
+{
+ return TYPE_MULTIPOLYGON ;
+}
+
+///
+///
+///
+bool MultiPolygon::isAllowed( Geometry const& g )
+{
+ return g.geometryTypeId() == TYPE_POLYGON ;
+}
+
+///
+///
+///
+void MultiPolygon::accept( GeometryVisitor& visitor )
+{
+ return visitor.visit( *this );
+}
+
+///
+///
+///
+void MultiPolygon::accept( ConstGeometryVisitor& visitor ) const
+{
+ return visitor.visit( *this );
+}
+
+}//SFCGAL
+
diff --git a/src/MultiPolygon.h b/src/MultiPolygon.h
new file mode 100644
index 0000000..caa6094
--- /dev/null
+++ b/src/MultiPolygon.h
@@ -0,0 +1,103 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_MULTIPOLYGON_H_
+#define _SFCGAL_MULTIPOLYGON_H_
+
+#include <vector>
+#include <boost/assert.hpp>
+
+#include <boost/serialization/base_object.hpp>
+
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/GeometryCollection.h>
+
+namespace SFCGAL {
+
+/**
+ * A MultiPolygon in SFA.
+ * @ingroup public_api
+ * @ŧodo add polygon() etc.
+ */
+class SFCGAL_API MultiPolygon : public GeometryCollection {
+public:
+ /**
+ * Empty MultiPolygon constructor
+ */
+ MultiPolygon() ;
+ /**
+ * Copy constructor
+ */
+ MultiPolygon( MultiPolygon const& other ) ;
+ /**
+ * assign operator
+ */
+ MultiPolygon& operator = ( MultiPolygon other ) ;
+ /**
+ * destructor
+ */
+ virtual ~MultiPolygon() ;
+
+ //-- SFCGAL::Geometry
+ virtual MultiPolygon* clone() const ;
+
+ //-- SFCGAL::Geometry
+ virtual std::string geometryType() const ;
+ //-- SFCGAL::Geometry
+ virtual GeometryType geometryTypeId() const ;
+
+ /**
+ * returns the n-th Geometry as a Polygon
+ */
+ inline Polygon& polygonN( const size_t& n ) {
+ return geometryN( n ).as< Polygon >() ;
+ }
+ /**
+ * returns the n-th Geometry as a Polygon
+ */
+ inline const Polygon& polygonN( const size_t& n ) const {
+ return geometryN( n ).as< Polygon >() ;
+ }
+
+
+ //-- visitors
+
+ //-- SFCGAL::Geometry
+ virtual void accept( GeometryVisitor& visitor ) ;
+ //-- SFCGAL::Geometry
+ virtual void accept( ConstGeometryVisitor& visitor ) const ;
+
+ /**
+ * Serializer
+ */
+ template <class Archive>
+ void serialize( Archive& ar, const unsigned int /*version*/ ) {
+ ar& boost::serialization::base_object<GeometryCollection>( *this );
+
+ }
+protected:
+ //-- SFCGAL::GeometryCollection
+ virtual bool isAllowed( Geometry const& g ) ;
+};
+
+
+}
+
+#endif
diff --git a/src/MultiSolid.cpp b/src/MultiSolid.cpp
new file mode 100644
index 0000000..35ee080
--- /dev/null
+++ b/src/MultiSolid.cpp
@@ -0,0 +1,110 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/GeometryVisitor.h>
+
+namespace SFCGAL {
+
+///
+///
+///
+MultiSolid::MultiSolid():
+ GeometryCollection()
+{
+
+}
+
+///
+///
+///
+MultiSolid::MultiSolid( MultiSolid const& other ):
+ GeometryCollection( other )
+{
+
+}
+
+///
+///
+///
+MultiSolid& MultiSolid::operator = ( MultiSolid other )
+{
+ swap( other ) ;
+ return *this ;
+}
+
+///
+///
+///
+MultiSolid::~MultiSolid()
+{
+
+}
+
+///
+///
+///
+MultiSolid* MultiSolid::clone() const
+{
+ return new MultiSolid( *this );
+}
+
+///
+///
+///
+std::string MultiSolid::geometryType() const
+{
+ return "MultiSolid" ;
+}
+
+///
+///
+///
+GeometryType MultiSolid::geometryTypeId() const
+{
+ return TYPE_MULTISOLID ;
+}
+
+///
+///
+///
+bool MultiSolid::isAllowed( Geometry const& g )
+{
+ return g.geometryTypeId() == TYPE_SOLID ;
+}
+
+///
+///
+///
+void MultiSolid::accept( GeometryVisitor& visitor )
+{
+ return visitor.visit( *this );
+}
+
+///
+///
+///
+void MultiSolid::accept( ConstGeometryVisitor& visitor ) const
+{
+ return visitor.visit( *this );
+}
+
+}//SFCGAL
+
diff --git a/src/MultiSolid.h b/src/MultiSolid.h
new file mode 100644
index 0000000..de12780
--- /dev/null
+++ b/src/MultiSolid.h
@@ -0,0 +1,102 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_MULTISOLID_H_
+#define _SFCGAL_MULTISOLID_H_
+
+#include <vector>
+#include <boost/assert.hpp>
+
+#include <boost/serialization/base_object.hpp>
+
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+
+namespace SFCGAL {
+
+/**
+ * A MultiSolid
+ * @ingroup public_api
+ */
+class SFCGAL_API MultiSolid : public GeometryCollection {
+public:
+ /**
+ * Empty MultiSolid constructor
+ */
+ MultiSolid() ;
+ /**
+ * Copy constructor
+ */
+ MultiSolid( const MultiSolid& other ) ;
+ /**
+ * assign operator
+ */
+ MultiSolid& operator = ( MultiSolid other ) ;
+ /**
+ * destructor
+ */
+ virtual ~MultiSolid() ;
+
+ //-- SFCGAL::Geometry
+ virtual MultiSolid* clone() const ;
+
+ //-- SFCGAL::Geometry
+ virtual std::string geometryType() const ;
+ //-- SFCGAL::Geometry
+ virtual GeometryType geometryTypeId() const ;
+
+ /**
+ * returns the n-th Geometry as a Solid
+ */
+ inline Solid& solidN( const size_t& n ) {
+ return geometryN( n ).as< Solid >() ;
+ }
+ /**
+ * returns the n-th Geometry as a Solid
+ */
+ inline const Solid& solidN( const size_t& n ) const {
+ return geometryN( n ).as< Solid >() ;
+ }
+
+
+ //-- visitors
+
+ //-- SFCGAL::Geometry
+ virtual void accept( GeometryVisitor& visitor ) ;
+ //-- SFCGAL::Geometry
+ virtual void accept( ConstGeometryVisitor& visitor ) const ;
+
+ /**
+ * Serializer
+ */
+ template <class Archive>
+ void serialize( Archive& ar, const unsigned int /*version*/ ) {
+ ar& boost::serialization::base_object<GeometryCollection>( *this );
+
+ }
+protected:
+ //-- SFCGAL::GeometryCollection
+ virtual bool isAllowed( Geometry const& g ) ;
+};
+
+
+}
+
+#endif
diff --git a/src/Point.cpp b/src/Point.cpp
new file mode 100644
index 0000000..6357e33
--- /dev/null
+++ b/src/Point.cpp
@@ -0,0 +1,287 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/GeometryVisitor.h>
+
+#include <SFCGAL/Exception.h>
+
+using namespace SFCGAL::detail;
+
+namespace SFCGAL {
+
+///
+///
+///
+Point::Point():
+ Geometry(),
+ _coordinate(),
+ _m( NaN() )
+{
+}
+
+///
+///
+///
+Point::Point( const Coordinate& coordinate ):
+ _coordinate( coordinate ),
+ _m( NaN() )
+{
+
+}
+
+///
+///
+///
+Point::Point( const Kernel::FT& x, const Kernel::FT& y ):
+ _coordinate( x,y ),
+ _m( NaN() )
+{
+
+}
+
+///
+///
+///
+Point::Point( const Kernel::FT& x, const Kernel::FT& y, const Kernel::FT& z, const double& m ):
+ _coordinate( x,y,z ),
+ _m( m )
+{
+
+}
+
+///
+///
+///
+Point::Point( const double& x, const double& y ):
+ Geometry(),
+ _coordinate( x,y ),
+ _m( NaN() )
+{
+
+}
+
+///
+///
+///
+Point::Point( const double& x, const double& y, const double& z ):
+ Geometry(),
+ _coordinate( x,y,z ),
+ _m( NaN() )
+{
+
+}
+
+///
+///
+///
+Point::Point( const double& x, const double& y, const double& z, const double& m ):
+ Geometry(),
+ _coordinate( x,y,z ),
+ _m( m )
+{
+
+}
+
+///
+///
+///
+Point::Point( const Kernel::Point_2& other ):
+ _coordinate( other ),
+ _m( NaN() )
+{
+
+}
+
+///
+///
+///
+Point::Point( const Kernel::Point_3& other ):
+ _coordinate( other ),
+ _m( NaN() )
+{
+
+}
+
+
+///
+///
+///
+Point::Point( const Point& other ):
+ Geometry(),
+ _coordinate( other._coordinate ),
+ _m( other._m )
+{
+
+}
+
+///
+///
+///
+Point& Point::operator = ( const Point& other )
+{
+ _coordinate = other._coordinate ;
+ _m = other._m ;
+ return *this ;
+}
+
+///
+///
+///
+Point::~Point()
+{
+
+}
+
+
+///
+///
+///
+Point* Point::clone() const
+{
+ return new Point( *this );
+}
+
+///
+///
+///
+std::string Point::geometryType() const
+{
+ return "Point";
+}
+
+///
+///
+///
+GeometryType Point::geometryTypeId() const
+{
+ return TYPE_POINT ;
+}
+
+///
+///
+///
+int Point::dimension() const
+{
+ return 0 ;
+}
+
+///
+///
+///
+int Point::coordinateDimension() const
+{
+ return _coordinate.coordinateDimension() + ( isMeasured() ? 1 : 0 ) ;
+}
+
+
+///
+///
+///
+bool Point::isEmpty() const
+{
+ return _coordinate.isEmpty() ;
+}
+
+///
+///
+///
+bool Point::is3D() const
+{
+ return _coordinate.is3D() ;
+}
+
+///
+///
+///
+bool Point::isMeasured() const
+{
+ return ! isNaN( _m ) ;
+}
+
+///
+///
+///
+void Point::accept( GeometryVisitor& visitor )
+{
+ return visitor.visit( *this );
+}
+
+///
+///
+///
+void Point::accept( ConstGeometryVisitor& visitor ) const
+{
+ return visitor.visit( *this );
+}
+
+///
+///
+///
+bool Point::operator < ( const Point& other ) const
+{
+ return _coordinate < other._coordinate ;
+}
+
+///
+///
+///
+bool Point::operator == ( const Point& other ) const
+{
+ return _coordinate == other._coordinate ;
+}
+
+///
+///
+///
+bool Point::operator != ( const Point& other ) const
+{
+ return _coordinate != other._coordinate ;
+}
+
+
+///
+/// Private structures used to implement partial function specialization
+template <int D>
+struct do_toPoint_d {
+ static CGAL::Point_2<Kernel> toPoint( const Point* p ) {
+ return p->toPoint_2();
+ }
+};
+
+template <>
+struct do_toPoint_d<3> {
+ static CGAL::Point_3<Kernel> toPoint( const Point* p ) {
+ return p->toPoint_3();
+ }
+};
+
+template <int Dim>
+typename TypeForDimension<Dim>::Point Point::toPoint_d() const
+{
+ return do_toPoint_d<Dim>::toPoint( this );
+}
+// template instanciations
+template CGAL::Point_2<Kernel> Point::toPoint_d<2>() const;
+template CGAL::Point_3<Kernel> Point::toPoint_d<3>() const;
+
+
+}//SFCGAL
+
diff --git a/src/Point.h b/src/Point.h
new file mode 100644
index 0000000..85dc86b
--- /dev/null
+++ b/src/Point.h
@@ -0,0 +1,231 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_POINT_H_
+#define _SFCGAL_POINT_H_
+
+#include <SFCGAL/Coordinate.h>
+
+#include <SFCGAL/Geometry.h>
+#include <SFCGAL/detail/TypeForDimension.h>
+
+#include <boost/serialization/base_object.hpp>
+
+namespace SFCGAL {
+
+/**
+ * A point in SFA.
+ * @ingroup public_api
+ * The x(),y(),z() interface is based on CGAL kernel requirements, taken
+ * from examples/Kernel_23/MyPointC2.h
+ * @todo strong typing on coordinate dimension?
+ */
+class SFCGAL_API Point : public Geometry {
+public:
+ /**
+ * Empty point constructor
+ */
+ Point() ;
+ /**
+ * Constructor with Coordinate
+ */
+ Point( const Coordinate& coordinate ) ;
+ /**
+ * XY Constructor with exact coordinates
+ */
+ Point( const Kernel::FT& x, const Kernel::FT& y ) ;
+ /**
+ * XY Constructor with exact coordinates
+ */
+ Point( const Kernel::FT& x, const Kernel::FT& y, const Kernel::FT& z, const double& m = NaN() ) ;
+ /**
+ * XY constructor
+ */
+ Point( const double& x, const double& y ) ;
+
+ /**
+ * XYZ constructor
+ */
+ Point( const double& x, const double& y, const double& z ) ;
+
+ /**
+ * XYZM constructor
+ */
+ Point( const double& x, const double& y, const double& z, const double& m ) ;
+
+ /**
+ * Constructor from CGAL::Point_2<K>
+ */
+ Point( const Kernel::Point_2& other ) ;
+ /**
+ * Constructor from CGAL::Point_3<K>
+ */
+ Point( const Kernel::Point_3& other ) ;
+
+
+ /**
+ * copy constructor
+ */
+ Point( const Point& other ) ;
+ /**
+ * assign operator
+ */
+ Point& operator = ( const Point& other ) ;
+ /**
+ * destructor
+ */
+ ~Point() ;
+
+ //-- SFCGAL::Geometry
+ virtual Point* clone() const ;
+
+ //-- SFCGAL::Geometry
+ virtual std::string geometryType() const ;
+ //-- SFCGAL::Geometry
+ virtual GeometryType geometryTypeId() const ;
+ //-- SFCGAL::Geometry
+ virtual int dimension() const ;
+ //-- SFCGAL::Geometry
+ virtual int coordinateDimension() const ;
+ //-- SFCGAL::Geometry
+ virtual bool isEmpty() const ;
+ //-- SFCGAL::Geometry
+ virtual bool is3D() const ;
+ //-- SFCGAL::Geometry
+ virtual bool isMeasured() const ;
+ //--- accessors
+
+ /**
+ * Returns the x value as a double throw for empty Point
+ */
+ inline Kernel::RT x() const {
+ return _coordinate.x() ;
+ }
+ /**
+ * Returns the y value as a double throw for empty Point
+ */
+ inline Kernel::RT y() const {
+ return _coordinate.y() ;
+ }
+ /**
+ * Returns the z value (zero for 2D) throw for empty Point
+ */
+ inline Kernel::RT z() const {
+ return _coordinate.z() ;
+ }
+
+ /**
+ * Returns the m value (NaN is not defined)
+ */
+ inline double m() const {
+ return _m ;
+ }
+ /**
+ * Sets the m value
+ */
+ inline void setM( const double& m ) {
+ _m = m ;
+ }
+
+
+ /**
+ * compare two points
+ */
+ bool operator < ( const Point& other ) const ;
+
+ /**
+ * compare with an other point
+ */
+ bool operator == ( const Point& other ) const ;
+ /**
+ * compare with an other point
+ */
+ bool operator != ( const Point& other ) const ;
+
+ //-- visitors
+
+ //-- SFCGAL::Geometry
+ virtual void accept( GeometryVisitor& visitor ) ;
+ //-- SFCGAL::Geometry
+ virtual void accept( ConstGeometryVisitor& visitor ) const ;
+
+
+
+ /**
+ * @see Coordinate::toVector_2()
+ */
+ inline Kernel::Vector_2 toVector_2() const {
+ return _coordinate.toVector_2();
+ }
+
+ /**
+ * @see Coordinate::toVector_3()
+ */
+ inline Kernel::Vector_3 toVector_3() const {
+ return _coordinate.toVector_3();
+ }
+
+ /**
+ * @see Coordinate::toPoint_2()
+ */
+ inline Kernel::Point_2 toPoint_2() const {
+ return _coordinate.toPoint_2();
+ }
+
+ /**
+ * @see Coordinate::toPoint_3()
+ */
+ inline Kernel::Point_3 toPoint_3() const {
+ return _coordinate.toPoint_3();
+ }
+
+ /**
+ * @brief Converts to CGAL::Point_2 or CGAL::Point_3
+ */
+ template <int D>
+ typename detail::TypeForDimension<D>::Point toPoint_d() const;
+
+ inline Coordinate& coordinate() {
+ return _coordinate;
+ }
+ inline const Coordinate& coordinate() const {
+ return _coordinate;
+ }
+
+ /**
+ * Serializer
+ */
+ template <class Archive>
+ void serialize( Archive& ar, const unsigned int /*version*/ ) {
+ ar& boost::serialization::base_object<Geometry>( *this );
+ ar& _coordinate;
+ }
+private:
+ Coordinate _coordinate ;
+ /**
+ * @brief m coordinates (NaN if not defined)
+ */
+ double _m ;
+};
+
+
+}
+
+#endif
diff --git a/src/Polygon.cpp b/src/Polygon.cpp
new file mode 100644
index 0000000..8e2de32
--- /dev/null
+++ b/src/Polygon.cpp
@@ -0,0 +1,281 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/GeometryVisitor.h>
+
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/algorithm/orientation.h>
+
+namespace SFCGAL {
+
+///
+///
+///
+Polygon::Polygon():
+ Surface()
+{
+ _rings.push_back( new LineString() );
+}
+
+///
+///
+///
+Polygon::Polygon( const std::vector< LineString >& rings ):
+ Surface()
+{
+ if ( rings.empty() ) {
+ _rings.resize( 1, new LineString() );
+ }
+ else {
+ for ( size_t i = 0; i < rings.size(); i++ ) {
+ _rings.push_back( rings[i].clone() ) ;
+ }
+ }
+}
+
+///
+///
+///
+Polygon::Polygon( const LineString& exteriorRing ):
+ Surface()
+{
+ _rings.push_back( exteriorRing.clone() );
+}
+
+///
+///
+///
+Polygon::Polygon( LineString* exteriorRing ):
+ Surface()
+{
+ _rings.push_back( exteriorRing );
+}
+
+///
+///
+///
+Polygon::Polygon( const Triangle& triangle ):
+ Surface()
+{
+ _rings.push_back( new LineString() );
+
+ if ( ! triangle.isEmpty() ) {
+ for ( size_t i = 0; i < 4; i++ ) {
+ exteriorRing().addPoint( triangle.vertex( i ) );
+ }
+ }
+}
+
+///
+///
+///
+Polygon::Polygon( const Polygon& other ):
+ Surface( other )
+{
+ for ( size_t i = 0; i < other.numRings(); i++ ) {
+ _rings.push_back( other.ringN( i ).clone() );
+ }
+}
+
+///
+///
+///
+Polygon::Polygon( const CGAL::Polygon_2< Kernel >& other )
+{
+ _rings.push_back( new LineString() );
+ CGAL::Polygon_2<Kernel>::Edge_const_iterator ei;
+
+ for ( ei = other.edges_begin(); ei != other.edges_end(); ++ei ) {
+ _rings.back().addPoint( ei->source() );
+ }
+}
+
+
+///
+///
+///
+Polygon::Polygon( const CGAL::Polygon_with_holes_2< Kernel >& poly )
+{
+ _rings.push_back( new LineString() );
+ CGAL::Polygon_2<Kernel> outer = poly.outer_boundary();
+ CGAL::Polygon_2<Kernel>::Edge_const_iterator ei;
+
+ for ( ei = outer.edges_begin(); ei != outer.edges_end(); ++ei ) {
+ _rings.back().addPoint( ei->source() );
+ }
+
+ _rings.back().addPoint( _rings.back().startPoint() );
+
+ for ( CGAL::Polygon_with_holes_2<Kernel>::Hole_const_iterator hit = poly.holes_begin(); hit != poly.holes_end(); ++hit ) {
+ _rings.push_back( new LineString() );
+ CGAL::Polygon_2<Kernel>::Edge_const_iterator ei;
+
+ for ( ei = hit->edges_begin(); ei != hit->edges_end(); ++ei ) {
+ _rings.back().addPoint( ei->source() );
+ }
+
+ _rings.back().addPoint( _rings.back().startPoint() );
+ }
+}
+
+///
+///
+///
+Polygon& Polygon::operator = ( Polygon other )
+{
+ swap( other );
+ return *this ;
+}
+
+///
+///
+///
+Polygon::~Polygon()
+{
+
+}
+
+///
+///
+///
+int Polygon::coordinateDimension() const
+{
+ return _rings[0].coordinateDimension() ;
+}
+
+
+///
+///
+///
+std::string Polygon::geometryType() const
+{
+ return "Polygon" ;
+}
+
+///
+///
+///
+GeometryType Polygon::geometryTypeId() const
+{
+ return TYPE_POLYGON ;
+}
+
+///
+///
+///
+Polygon* Polygon::clone() const
+{
+ return new Polygon( *this );
+}
+
+///
+///
+///
+bool Polygon::isEmpty() const
+{
+ return exteriorRing().isEmpty() ;
+}
+
+///
+///
+///
+bool Polygon::is3D() const
+{
+ return exteriorRing().is3D() ;
+}
+
+///
+///
+///
+bool Polygon::isMeasured() const
+{
+ return exteriorRing().isMeasured() ;
+}
+
+///
+///
+///
+void Polygon::reverse()
+{
+ for ( size_t i = 0; i < numRings(); i++ ) {
+ ringN( i ).reverse();
+ }
+}
+
+
+///
+///
+///
+void Polygon::accept( GeometryVisitor& visitor )
+{
+ return visitor.visit( *this );
+}
+
+///
+///
+///
+void Polygon::accept( ConstGeometryVisitor& visitor ) const
+{
+ return visitor.visit( *this );
+}
+
+///
+///
+///
+bool Polygon::isCounterClockWiseOriented() const
+{
+ return algorithm::isCounterClockWiseOriented( *this );
+}
+
+///
+///
+///
+CGAL::Polygon_2<Kernel> Polygon::toPolygon_2( bool fixOrientation ) const
+{
+ return exteriorRing().toPolygon_2( fixOrientation );
+}
+
+///
+///
+///
+CGAL::Polygon_with_holes_2<Kernel> Polygon::toPolygon_with_holes_2( bool fixOrientation ) const
+{
+ std::list<CGAL::Polygon_2<Kernel> > holes;
+
+ for ( size_t i = 0; i < numInteriorRings(); ++i ) {
+ // note that the orientation is fixed here to avoid double reverse for interior rings
+ CGAL::Polygon_2<Kernel> inner = interiorRingN( i ).toPolygon_2( false );
+
+ if ( fixOrientation && inner.orientation() == CGAL::COUNTERCLOCKWISE ) {
+ inner.reverse_orientation();
+ }
+
+ holes.push_back( inner );
+ }
+
+ CGAL::Polygon_2<Kernel> outer = exteriorRing().toPolygon_2( fixOrientation );
+ return CGAL::Polygon_with_holes_2<Kernel>( outer,
+ holes.begin(),
+ holes.end() );
+}
+
+}//SFCGAL
+
diff --git a/src/Polygon.h b/src/Polygon.h
new file mode 100644
index 0000000..5c1de47
--- /dev/null
+++ b/src/Polygon.h
@@ -0,0 +1,283 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_POLYGON_H_
+#define _SFCGAL_POLYGON_H_
+
+#include <vector>
+#include <boost/assert.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <boost/serialization/base_object.hpp>
+#include <boost/ptr_container/serialize_ptr_vector.hpp>
+
+#include <CGAL/Polygon_with_holes_2.h>
+
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Surface.h>
+#include <SFCGAL/Kernel.h>
+
+namespace SFCGAL {
+
+/**
+ * A Polygon in SFA with holes
+ * @ingroup public_api
+ */
+class SFCGAL_API Polygon : public Surface {
+public:
+ typedef boost::ptr_vector< LineString >::iterator iterator ;
+ typedef boost::ptr_vector< LineString >::const_iterator const_iterator ;
+
+ /**
+ * Empty Polygon constructor
+ */
+ Polygon() ;
+ /**
+ * Constructor with an exterior ring
+ */
+ Polygon( const std::vector< LineString >& rings ) ;
+ /**
+ * Constructor with an exterior ring
+ */
+ Polygon( const LineString& exteriorRing ) ;
+ /**
+ * Constructor with an exterior ring (takes ownership)
+ */
+ Polygon( LineString* exteriorRing ) ;
+ /**
+ * Constructor with a Triangle
+ */
+ Polygon( const Triangle& triangle ) ;
+ /**
+ * Copy constructor
+ */
+ Polygon( const Polygon& other ) ;
+
+ /**
+ * Constructor from CGAL::Polygon_with_holes_2<K>
+ */
+ Polygon( const CGAL::Polygon_2< Kernel >& other );
+ /**
+ * Constructor from CGAL::Polygon_with_holes_2<K>
+ */
+ Polygon( const CGAL::Polygon_with_holes_2< Kernel >& other );
+
+ /**
+ * assign operator
+ */
+ Polygon& operator = ( Polygon other ) ;
+
+ /**
+ * destructor
+ */
+ ~Polygon() ;
+
+ //-- SFCGAL::Geometry
+ virtual Polygon* clone() const ;
+
+ //-- SFCGAL::Geometry
+ virtual std::string geometryType() const ;
+ //-- SFCGAL::Geometry
+ virtual GeometryType geometryTypeId() const ;
+ //-- SFCGAL::Geometry
+ virtual int coordinateDimension() const ;
+ //-- SFCGAL::Geometry
+ virtual bool isEmpty() const ;
+ //-- SFCGAL::Geometry
+ virtual bool is3D() const ;
+ //-- SFCGAL::Geometry
+ virtual bool isMeasured() const ;
+
+ /**
+ * Check whether the 2D polygon is pointing up
+ */
+ bool isCounterClockWiseOriented() const;
+
+ /**
+ * reverse Polygon orientation
+ */
+ void reverse() ;
+
+
+ /**
+ * [OGC/SFA]returns the exterior ring
+ */
+ inline const LineString& exteriorRing() const {
+ return _rings.front();
+ }
+ /**
+ * [OGC/SFA]returns the exterior ring
+ */
+ inline LineString& exteriorRing() {
+ return _rings.front();
+ }
+ /**
+ * Sets the exterior ring
+ */
+ inline void setExteriorRing( const LineString& ring ) {
+ _rings.front() = ring ;
+ }
+ /**
+ * Sets the exterior ring (takes ownership)
+ */
+ inline void setExteriorRing( LineString* ring ) {
+ _rings.replace( 0, ring );
+ }
+
+ /**
+ * Test if the polygon has interior rings
+ */
+ inline bool hasInteriorRings() const {
+ return _rings.size() > 1 ;
+ }
+
+ /**
+ * [OGC/SFA]returns the exterior ring
+ */
+ inline size_t numInteriorRings() const {
+ return _rings.size() - 1 ;
+ }
+ /**
+ * [OGC/SFA]returns the exterior ring
+ */
+ inline const LineString& interiorRingN( const size_t& n ) const {
+ return _rings[n+1];
+ }
+ /**
+ * [OGC/SFA]returns the exterior ring
+ */
+ inline LineString& interiorRingN( const size_t& n ) {
+ return _rings[n+1];
+ }
+
+ /**
+ * Returns the number of rings
+ */
+ inline size_t numRings() const {
+ return _rings.size() ;
+ }
+ /**
+ * Returns the n-th ring, 0 is exteriorRing
+ * @warning not standard, avoid conditionnal to access rings
+ */
+ inline const LineString& ringN( const size_t& n ) const {
+ BOOST_ASSERT( n < _rings.size() );
+ return _rings[n];
+ }
+ /**
+ * Returns the n-th ring, 0 is exteriorRing
+ * @warning not standard, avoid conditionnal to access rings
+ */
+ inline LineString& ringN( const size_t& n ) {
+ BOOST_ASSERT( n < _rings.size() );
+ return _rings[n];
+ }
+
+ /**
+ * append a ring to the Polygon
+ */
+ inline void addInteriorRing( const LineString& ls ) {
+ _rings.push_back( ls.clone() ) ;
+ }
+ /**
+ * append a ring to the Polygon (take ownership)
+ */
+ inline void addInteriorRing( LineString* ls ) {
+ BOOST_ASSERT( ls != NULL );
+ _rings.push_back( ls ) ;
+ }
+
+ /**
+ * append a ring to the Polygon
+ * @deprecated addInteriorRing
+ */
+ inline void addRing( const LineString& ls ) {
+ _rings.push_back( ls.clone() ) ;
+ }
+ /**
+ * append a ring to the Polygon (take ownership)
+ * @deprecated addInteriorRing
+ */
+ inline void addRing( LineString* ls ) {
+ BOOST_ASSERT( ls != NULL );
+ _rings.push_back( ls ) ;
+ }
+
+ inline iterator begin() {
+ return _rings.begin() ;
+ }
+ inline const_iterator begin() const {
+ return _rings.begin() ;
+ }
+
+ inline iterator end() {
+ return _rings.end() ;
+ }
+ inline const_iterator end() const {
+ return _rings.end() ;
+ }
+
+
+ /*
+ * @brief Convert to CGAL::Polygon_2. Does not consider holes, if any
+ * @param forceCounterClocksize force exterior ring orientation to counter clocksize
+ */
+ CGAL::Polygon_2<Kernel> toPolygon_2( bool fixOrientation = true ) const;
+
+ /*
+ * @brief Convert to CGAL::Polygon_with_holes_2.
+ * @param forceCounterClocksize force exterior ring orientation to counter clocksize and
+ * interior ring to clocksize.
+ */
+ CGAL::Polygon_with_holes_2<Kernel> toPolygon_with_holes_2( bool fixOrientation = true ) const;
+
+ //-- visitors
+
+ //-- SFCGAL::Geometry
+ virtual void accept( GeometryVisitor& visitor ) ;
+ //-- SFCGAL::Geometry
+ virtual void accept( ConstGeometryVisitor& visitor ) const ;
+
+ /**
+ * Serializer
+ */
+ template <class Archive>
+ void serialize( Archive& ar, const unsigned int /*version*/ ) {
+ ar& boost::serialization::base_object<Geometry>( *this );
+ ar& _rings;
+ }
+private:
+ /**
+ * rings forming the polygon (size() >= 1)
+ *
+ * _ring[0] is the interior ring
+ *
+ * @warning never empty, empty LineString as exteriorRing for empty Polygon
+ */
+ boost::ptr_vector< LineString > _rings ;
+
+ void swap( Polygon& other ) {
+ std::swap( _rings, other._rings );
+ }
+};
+
+
+}
+
+#endif
diff --git a/src/PolyhedralSurface.cpp b/src/PolyhedralSurface.cpp
new file mode 100644
index 0000000..49631ea
--- /dev/null
+++ b/src/PolyhedralSurface.cpp
@@ -0,0 +1,260 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/GeometryVisitor.h>
+
+using namespace SFCGAL::detail;
+
+namespace SFCGAL {
+
+///
+///
+///
+PolyhedralSurface::PolyhedralSurface():
+ Surface(),
+ _polygons()
+{
+
+}
+
+///
+///
+///
+PolyhedralSurface::PolyhedralSurface( const std::vector< Polygon >& polygons ) :
+ Surface()
+{
+ for ( size_t i = 0; i < polygons.size(); i++ ) {
+ _polygons.push_back( polygons[i].clone() ) ;
+ }
+}
+
+///
+///
+///
+PolyhedralSurface::PolyhedralSurface( const PolyhedralSurface& other ) :
+ Surface(),
+ _polygons( other._polygons )
+{
+
+}
+
+///
+///
+///
+PolyhedralSurface::PolyhedralSurface( const MarkedPolyhedron& poly ) :
+ Surface()
+{
+ for ( MarkedPolyhedron::Facet_const_iterator fit = poly.facets_begin(); fit != poly.facets_end(); ++fit ) {
+ LineString* face = new LineString();
+ MarkedPolyhedron::Halfedge_around_facet_const_circulator hit = fit->facet_begin();
+
+ do {
+ face->addPoint( hit->vertex()->point() );
+ ++hit;
+ }
+ while ( hit != fit->facet_begin() );
+
+ // close the ring
+ face->addPoint( hit->vertex()->point() );
+ _polygons.push_back( new Polygon( face ) );
+ }
+}
+
+///
+///
+///
+PolyhedralSurface& PolyhedralSurface::operator = ( PolyhedralSurface other )
+{
+ swap( other );
+ return *this ;
+}
+
+
+///
+///
+///
+PolyhedralSurface::~PolyhedralSurface()
+{
+
+}
+
+///
+///
+///
+PolyhedralSurface* PolyhedralSurface::clone() const
+{
+ return new PolyhedralSurface( *this );
+}
+
+///
+///
+///
+std::string PolyhedralSurface::geometryType() const
+{
+ return "PolyhedralSurface" ;
+}
+
+///
+///
+///
+GeometryType PolyhedralSurface::geometryTypeId() const
+{
+ return TYPE_POLYHEDRALSURFACE ;
+}
+
+///
+///
+///
+int PolyhedralSurface::dimension() const
+{
+ return 2 ;
+}
+
+///
+///
+///
+int PolyhedralSurface::coordinateDimension() const
+{
+ if ( isEmpty() ) {
+ return 0 ;
+ }
+ else {
+ return _polygons.front().coordinateDimension() ;
+ }
+}
+
+///
+///
+///
+bool PolyhedralSurface::isEmpty() const
+{
+ return _polygons.empty();
+}
+
+///
+///
+///
+bool PolyhedralSurface::is3D() const
+{
+ if ( isEmpty() ) {
+ return false ;
+ }
+ else {
+ return _polygons.front().is3D() ;
+ }
+}
+
+///
+///
+///
+bool PolyhedralSurface::isMeasured() const
+{
+ if ( isEmpty() ) {
+ return false ;
+ }
+ else {
+ return _polygons.front().isMeasured() ;
+ }
+}
+
+
+
+///
+///
+///
+TriangulatedSurface PolyhedralSurface::toTriangulatedSurface() const
+{
+ TriangulatedSurface result ;
+ triangulate::triangulatePolygon3D( *this, result );
+ return result ;
+}
+
+///
+///
+///
+void PolyhedralSurface::addPolygon( const Polygon& polygon )
+{
+ addPolygon( polygon.clone() );
+}
+
+///
+///
+///
+void PolyhedralSurface::addPolygon( Polygon* polygon )
+{
+ BOOST_ASSERT( polygon != NULL );
+ _polygons.push_back( polygon );
+}
+
+///
+///
+///
+void PolyhedralSurface::addPolygons( const PolyhedralSurface& polyhedralSurface )
+{
+ for ( size_t i = 0; i < polyhedralSurface.numPolygons(); i++ ) {
+ addPolygon( polyhedralSurface.polygonN( i ) );
+ }
+}
+
+///
+///
+///
+size_t PolyhedralSurface::numGeometries() const
+{
+ return _polygons.size() ;
+}
+
+
+///
+///
+///
+const Polygon& PolyhedralSurface::geometryN( size_t const& n ) const
+{
+ return _polygons[n] ;
+}
+
+///
+///
+///
+Polygon& PolyhedralSurface::geometryN( size_t const& n )
+{
+ return _polygons[n];
+}
+
+///
+///
+///
+void PolyhedralSurface::accept( GeometryVisitor& visitor )
+{
+ return visitor.visit( *this );
+}
+
+///
+///
+///
+void PolyhedralSurface::accept( ConstGeometryVisitor& visitor ) const
+{
+ return visitor.visit( *this );
+}
+}//SFCGAL
+
+
+
diff --git a/src/PolyhedralSurface.h b/src/PolyhedralSurface.h
new file mode 100644
index 0000000..d8bd165
--- /dev/null
+++ b/src/PolyhedralSurface.h
@@ -0,0 +1,192 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_POLYHEDRALSURFACE_H_
+#define _SFCGAL_POLYHEDRALSURFACE_H_
+
+#include <vector>
+#include <boost/assert.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <boost/serialization/base_object.hpp>
+#include <boost/ptr_container/serialize_ptr_vector.hpp>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/triangulate/triangulatePolygon.h>
+
+#include <CGAL/Polyhedron_3.h>
+
+namespace SFCGAL {
+
+/**
+ * A PolyhedralSurface in SFA modeled as a Polygon soup
+ * @ingroup public_api
+ * @todo do better than a "polygon soup" or add topological view?
+ */
+class SFCGAL_API PolyhedralSurface : public Surface {
+public:
+ typedef boost::ptr_vector< Polygon >::iterator iterator ;
+ typedef boost::ptr_vector< Polygon >::const_iterator const_iterator ;
+
+ /**
+ * Empty PolyhedralSurface constructor
+ */
+ PolyhedralSurface() ;
+ /**
+ * Constructor with a vector of polygons
+ */
+ PolyhedralSurface( const std::vector< Polygon >& polygons ) ;
+ /**
+ * Constructor from a CGAL::Polyhedron_3
+ */
+ PolyhedralSurface( const detail::MarkedPolyhedron& poly );
+ /**
+ * Copy constructor
+ */
+ PolyhedralSurface( const PolyhedralSurface& other ) ;
+ /**
+ * assign operator
+ */
+ PolyhedralSurface& operator = ( PolyhedralSurface other ) ;
+ /**
+ * destructor
+ */
+ ~PolyhedralSurface() ;
+
+ //-- SFCGAL::Geometry
+ virtual PolyhedralSurface* clone() const ;
+
+ //-- SFCGAL::Geometry
+ virtual std::string geometryType() const ;
+ //-- SFCGAL::Geometry
+ virtual GeometryType geometryTypeId() const ;
+ //-- SFCGAL::Geometry
+ virtual int dimension() const ;
+ //-- SFCGAL::Geometry
+ virtual int coordinateDimension() const ;
+ //-- SFCGAL::Geometry
+ virtual bool isEmpty() const ;
+ //-- SFCGAL::Geometry
+ virtual bool is3D() const ;
+ //-- SFCGAL::Geometry
+ virtual bool isMeasured() const ;
+
+ /**
+ * Convert PolyhedralSurface to TriangulatedSurface
+ */
+ TriangulatedSurface toTriangulatedSurface() const ;
+
+
+ /**
+ * [SFA/OGC]Returns the number of points
+ * @deprecated see numGeometries
+ */
+ inline size_t numPolygons() const {
+ return _polygons.size();
+ }
+ /**
+ * [SFA/OGC]Returns the n-th point
+ * @deprecated see geometryN()
+ */
+ inline const Polygon& polygonN( size_t const& n ) const {
+ BOOST_ASSERT( n < _polygons.size() );
+ return _polygons[n];
+ }
+ /**
+ * [SFA/OGC]Returns the n-th point
+ * @deprecated see geometryN()
+ */
+ inline Polygon& polygonN( size_t const& n ) {
+ BOOST_ASSERT( n < _polygons.size() );
+ return _polygons[n];
+ }
+ /**
+ * add a polygon to the PolyhedralSurface
+ */
+ void addPolygon( const Polygon& polygon ) ;
+ /**
+ * add a polygon to the PolyhedralSurface
+ */
+ void addPolygon( Polygon* polygon ) ;
+ /**
+ * add polygons from an other PolyhedralSurface
+ */
+ void addPolygons( const PolyhedralSurface& polyhedralSurface ) ;
+
+ //-- SFCGAL::Geometry
+ virtual size_t numGeometries() const ;
+ //-- SFCGAL::Geometry
+ virtual const Polygon& geometryN( size_t const& n ) const ;
+ //-- SFCGAL::Geometry
+ virtual Polygon& geometryN( size_t const& n ) ;
+
+ /**
+ * Convert to CGAL::Polyhedron_3
+ */
+ template < typename K, typename Polyhedron >
+ std::auto_ptr<Polyhedron> toPolyhedron_3() const {
+ TriangulatedSurface tri;
+ triangulate::triangulatePolygon3D( *this, tri );
+ return tri.toPolyhedron_3<K, Polyhedron>();
+ }
+
+
+ //-- iterators
+
+ inline iterator begin() {
+ return _polygons.begin() ;
+ }
+ inline const_iterator begin() const {
+ return _polygons.begin() ;
+ }
+
+ inline iterator end() {
+ return _polygons.end() ;
+ }
+ inline const_iterator end() const {
+ return _polygons.end() ;
+ }
+
+ //-- visitors
+
+ //-- SFCGAL::Geometry
+ virtual void accept( GeometryVisitor& visitor ) ;
+ //-- SFCGAL::Geometry
+ virtual void accept( ConstGeometryVisitor& visitor ) const ;
+
+ /**
+ * Serializer
+ */
+ template <class Archive>
+ void serialize( Archive& ar, const unsigned int /*version*/ ) {
+ ar& boost::serialization::base_object<Geometry>( *this );
+ ar& _polygons;
+ }
+private:
+ boost::ptr_vector< Polygon > _polygons ;
+
+ void swap( PolyhedralSurface& other ) {
+ std::swap( _polygons, other._polygons );
+ }
+};
+}
+
+#endif
diff --git a/src/PreparedGeometry.cpp b/src/PreparedGeometry.cpp
new file mode 100644
index 0000000..23e116a
--- /dev/null
+++ b/src/PreparedGeometry.cpp
@@ -0,0 +1,102 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/PreparedGeometry.h>
+
+#include <SFCGAL/detail/io/WktWriter.h>
+
+namespace SFCGAL {
+PreparedGeometry::PreparedGeometry() :
+ _srid( 0 )
+{
+}
+
+PreparedGeometry::PreparedGeometry( std::auto_ptr<Geometry> geometry, srid_t srid ) :
+ _geometry( geometry ),
+ _srid( srid )
+{
+}
+
+PreparedGeometry::PreparedGeometry( Geometry* geometry, srid_t srid ) :
+ _geometry( geometry ),
+ _srid( srid )
+{
+}
+
+PreparedGeometry::~PreparedGeometry()
+{
+}
+
+const Geometry& PreparedGeometry::geometry() const
+{
+ BOOST_ASSERT( _geometry.get() );
+ return *_geometry;
+}
+
+Geometry& PreparedGeometry::geometry()
+{
+ BOOST_ASSERT( _geometry.get() );
+ return *_geometry;
+}
+
+void PreparedGeometry::resetGeometry( Geometry* geom )
+{
+ _geometry.reset( geom );
+ invalidateCache();
+}
+
+const Envelope& PreparedGeometry::envelope() const
+{
+ if ( ! _envelope ) {
+ _envelope.reset( _geometry->envelope() );
+ }
+
+ return *_envelope;
+}
+
+void PreparedGeometry::invalidateCache()
+{
+ _envelope.reset();
+}
+
+std::string PreparedGeometry::asEWKT( const int& numDecimals ) const
+{
+ std::ostringstream oss;
+
+ if ( numDecimals >= 0 ) {
+ oss << std::fixed ;
+ oss.precision( numDecimals );
+ }
+
+ if ( _srid != 0 ) {
+ oss << "SRID=" << _srid << ";";
+ }
+
+ detail::io::WktWriter writer( oss );
+ bool exactWrite = false;
+
+ if ( numDecimals == -1 ) {
+ exactWrite = true;
+ }
+
+ writer.write( *_geometry, exactWrite );
+ return oss.str();
+}
+}
diff --git a/src/PreparedGeometry.h b/src/PreparedGeometry.h
new file mode 100644
index 0000000..db42a61
--- /dev/null
+++ b/src/PreparedGeometry.h
@@ -0,0 +1,145 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_PREPARED_GEOMETRY_H_
+#define _SFCGAL_PREPARED_GEOMETRY_H_
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Envelope.h>
+
+#include <boost/serialization/split_member.hpp>
+#include <boost/optional.hpp>
+#include <boost/noncopyable.hpp>
+
+#include <stdint.h> // uint32_t
+
+namespace SFCGAL {
+
+class Geometry;
+
+typedef uint32_t srid_t;
+
+/**
+ * A PreparedGeometry is a shell around a SFCGAL::Geometry.
+ * It is used to store annex data, like SRID or cached computations
+ *
+ * It is noncopyable since it stores a std::auto_ptr<SFCGAL::Geometry>
+ *
+ */
+class SFCGAL_API PreparedGeometry : public boost::noncopyable {
+public:
+ /**
+ * Default constructor
+ */
+ PreparedGeometry();
+
+ /**
+ * Constructor
+ * @param geometry pointer to the underlying SFCGAL::Geometry. Takes ownership
+ */
+ PreparedGeometry( std::auto_ptr<Geometry> geometry, srid_t srid = 0 );
+
+ /**
+ * Constructor
+ * @param geometry pointer to the underlying SFCGAL::Geometry. Takes ownership
+ */
+ PreparedGeometry( Geometry* geometry, srid_t srid = 0 );
+
+ virtual ~PreparedGeometry();
+
+ /**
+ * Geometry accessors
+ */
+ const Geometry& geometry() const;
+ Geometry& geometry();
+
+ /**
+ * Geometry setter
+ */
+ void resetGeometry( Geometry* geom );
+
+ /**
+ * SRID read only accessor
+ */
+ const srid_t& SRID() const {
+ return _srid;
+ }
+
+ /**
+ * SRID accessor
+ */
+ srid_t& SRID() {
+ return _srid;
+ }
+
+ /**
+ * Envelope accessor (using cache)
+ */
+ const Envelope& envelope() const;
+
+ /**
+ * Resets the cache
+ */
+ void invalidateCache();
+
+ /**
+ * Convert to an extended WKT (with SRID)
+ * @param numDecimals: number of decimals, -1 for keeping the exact rational representation, if possible
+ */
+ std::string asEWKT( const int& numDecimals = - 1 ) const;
+
+ /**
+ * Serializer
+ */
+ template <class Archive>
+ void save( Archive& ar, const unsigned int /*version*/ ) const {
+ ar& _srid;
+ const Geometry* pgeom = _geometry.get();
+ ar& pgeom;
+ }
+
+ template <class Archive>
+ void load( Archive& ar, const unsigned int /*version*/ ) {
+ ar& _srid;
+ Geometry* pgeom;
+ ar& pgeom;
+ _geometry.reset( pgeom );
+ }
+
+ template <class Archive>
+ void serialize( Archive& ar, const unsigned int version ) {
+ boost::serialization::split_member( ar, *this, version );
+ }
+
+protected:
+ // Pointer to underlying Geometry
+ std::auto_ptr<Geometry> _geometry;
+
+ // SRID of the geometry
+ srid_t _srid;
+
+ // bbox of the geometry
+ mutable boost::optional<Envelope> _envelope;
+};
+
+}
+
+#endif
diff --git a/src/Solid.cpp b/src/Solid.cpp
new file mode 100644
index 0000000..dc34b5b
--- /dev/null
+++ b/src/Solid.cpp
@@ -0,0 +1,179 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryVisitor.h>
+
+namespace SFCGAL {
+
+///
+///
+///
+Solid::Solid()
+{
+ _shells.push_back( new PolyhedralSurface() );
+}
+
+///
+///
+///
+Solid::Solid( const PolyhedralSurface& exteriorShell )
+{
+ _shells.push_back( exteriorShell.clone() );
+}
+
+///
+///
+///
+Solid::Solid( PolyhedralSurface* exteriorShell )
+{
+ _shells.push_back( exteriorShell );
+}
+
+///
+///
+///
+Solid::Solid( const std::vector< PolyhedralSurface >& shells )
+{
+ if ( shells.empty() ) {
+ _shells.resize( 1, new PolyhedralSurface() );
+ }
+ else {
+ for ( size_t i = 0; i < shells.size(); i++ ) {
+ _shells.push_back( shells[i].clone() ) ;
+ }
+ }
+}
+
+///
+///
+///
+Solid::Solid( const Solid& other ):
+ Geometry( other )
+{
+ for ( size_t i = 0; i < other.numShells(); i++ ) {
+ _shells.push_back( other.shellN( i ).clone() );
+ }
+}
+
+///
+///
+///
+Solid& Solid::operator = ( Solid other )
+{
+ swap( other );
+ return *this ;
+}
+
+///
+///
+///
+Solid::~Solid()
+{
+
+}
+
+///
+///
+///
+Solid* Solid::clone() const
+{
+ return new Solid( *this );
+}
+
+
+
+
+///
+///
+///
+std::string Solid::geometryType() const
+{
+ return "Solid" ;
+}
+
+///
+///
+///
+GeometryType Solid::geometryTypeId() const
+{
+ return TYPE_SOLID ;
+}
+
+///
+///
+///
+int Solid::dimension() const
+{
+ return 3 ;
+}
+
+///
+///
+///
+int Solid::coordinateDimension() const
+{
+ return exteriorShell().coordinateDimension() ;
+}
+
+///
+///
+///
+bool Solid::isEmpty() const
+{
+ return exteriorShell().isEmpty();
+}
+
+///
+///
+///
+bool Solid::is3D() const
+{
+ return exteriorShell().is3D();
+}
+
+///
+///
+///
+bool Solid::isMeasured() const
+{
+ return exteriorShell().isMeasured();
+}
+
+///
+///
+///
+void Solid::accept( GeometryVisitor& visitor )
+{
+ return visitor.visit( *this );
+}
+
+///
+///
+///
+void Solid::accept( ConstGeometryVisitor& visitor ) const
+{
+ return visitor.visit( *this );
+}
+
+}//SFCGAL
+
+
+
diff --git a/src/Solid.h b/src/Solid.h
new file mode 100644
index 0000000..b52652d
--- /dev/null
+++ b/src/Solid.h
@@ -0,0 +1,207 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_SOLID_H_
+#define _SFCGAL_SOLID_H_
+
+#include <vector>
+#include <boost/assert.hpp>
+
+#include <boost/ptr_container/ptr_vector.hpp>
+
+#include <boost/serialization/base_object.hpp>
+#include <boost/serialization/vector.hpp>
+
+#include <SFCGAL/PolyhedralSurface.h>
+
+#include <CGAL/Nef_polyhedron_3.h>
+
+namespace SFCGAL {
+
+/**
+ * A Solid modeled with an exteriorShell and interiorShells materialized by PolyhedralSurface.
+ * @ingroup public_api
+ * @note A shell is supposed to be closed.
+ * @warning GM_Solid, from ISO 19107 is defined in CityGML, but not in SFA. Without Solid concept,
+ * @note Volume concept is missing.
+ */
+class SFCGAL_API Solid : public Geometry {
+public:
+ typedef boost::ptr_vector< PolyhedralSurface >::iterator iterator ;
+ typedef boost::ptr_vector< PolyhedralSurface >::const_iterator const_iterator ;
+
+ /**
+ * Empty Solid constructor
+ */
+ Solid() ;
+ /**
+ * Constructor with an exterior shell
+ */
+ Solid( const PolyhedralSurface& exteriorShell ) ;
+ /**
+ * Constructor with an exterior shell (takes ownership)
+ */
+ Solid( PolyhedralSurface* exteriorShell ) ;
+ /**
+ * Constructor with a vector of shells (PolyhedralSurface)
+ */
+ Solid( const std::vector< PolyhedralSurface >& shells ) ;
+ /**
+ * Copy constructor
+ */
+ Solid( const Solid& other ) ;
+ /**
+ * assign operator
+ */
+ Solid& operator = ( Solid other ) ;
+ /**
+ * destructor
+ */
+ ~Solid() ;
+
+ //-- SFCGAL::Geometry
+ virtual Solid* clone() const ;
+
+ //-- SFCGAL::Geometry
+ virtual std::string geometryType() const ;
+ //-- SFCGAL::Geometry
+ virtual GeometryType geometryTypeId() const ;
+ //-- SFCGAL::Geometry
+ virtual int dimension() const ;
+ //-- SFCGAL::Geometry
+ virtual int coordinateDimension() const ;
+ //-- SFCGAL::Geometry
+ virtual bool isEmpty() const ;
+ //-- SFCGAL::Geometry
+ virtual bool is3D() const ;
+ //-- SFCGAL::Geometry
+ virtual bool isMeasured() const ;
+
+ /**
+ * Returns the exterior shell
+ */
+ inline const PolyhedralSurface& exteriorShell() const {
+ return _shells[0] ;
+ }
+ /**
+ * Returns the exterior shell
+ */
+ inline PolyhedralSurface& exteriorShell() {
+ return _shells[0] ;
+ }
+
+ /**
+ * Returns the number of interior shells
+ */
+ inline size_t numInteriorShells() const {
+ return _shells.size() - 1 ;
+ }
+ /**
+ * Returns the n-th interior shell
+ */
+ inline const PolyhedralSurface& interiorShellN( size_t const& n ) const {
+ return _shells[n+1];
+ }
+ /**
+ * Returns the n-th interior shell
+ */
+ inline PolyhedralSurface& interiorShellN( size_t const& n ) {
+ return _shells[n+1];
+ }
+ /**
+ * add a polygon to the PolyhedralSurface
+ */
+ inline void addInteriorShell( const PolyhedralSurface& shell ) {
+ _shells.push_back( shell.clone() );
+ }
+ /**
+ * add a polygon to the PolyhedralSurface
+ */
+ inline void addInteriorShell( PolyhedralSurface* shell ) {
+ BOOST_ASSERT( shell != NULL );
+ _shells.push_back( shell );
+ }
+
+ /**
+ * Returns the number of shells
+ */
+ inline size_t numShells() const {
+ return _shells.size() ;
+ }
+ /**
+ * Returns the n-th shell, 0 is exteriorShell
+ * @warning not standard, avoid conditionnal to access rings
+ */
+ inline const PolyhedralSurface& shellN( const size_t& n ) const {
+ BOOST_ASSERT( n < numShells() );
+ return _shells[n];
+ }
+ /**
+ * Returns the n-th shell, 0 is exteriorShell
+ * @warning not standard, avoid conditionnal to access rings
+ */
+ inline PolyhedralSurface& shellN( const size_t& n ) {
+ BOOST_ASSERT( n < numShells() );
+ return _shells[n];
+ }
+
+ //-- iterators
+
+ inline iterator begin() {
+ return _shells.begin() ;
+ }
+ inline const_iterator begin() const {
+ return _shells.begin() ;
+ }
+
+ inline iterator end() {
+ return _shells.end() ;
+ }
+ inline const_iterator end() const {
+ return _shells.end() ;
+ }
+
+ //-- visitors
+
+ //-- SFCGAL::Geometry
+ virtual void accept( GeometryVisitor& visitor ) ;
+ //-- SFCGAL::Geometry
+ virtual void accept( ConstGeometryVisitor& visitor ) const ;
+
+ /**
+ * Serializer
+ */
+ template <class Archive>
+ void serialize( Archive& ar, const unsigned int /*version*/ ) {
+ ar& boost::serialization::base_object<Geometry>( *this );
+ ar& _shells;
+ }
+private:
+ boost::ptr_vector< PolyhedralSurface > _shells ;
+
+ void swap( Solid& other ) {
+ _shells.swap( other._shells );
+ }
+};
+
+
+}
+
+#endif
diff --git a/src/Surface.cpp b/src/Surface.cpp
new file mode 100644
index 0000000..ed4e858
--- /dev/null
+++ b/src/Surface.cpp
@@ -0,0 +1,79 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/Surface.h>
+#include <SFCGAL/GeometryVisitor.h>
+
+namespace SFCGAL {
+
+///
+///
+///
+Surface::~Surface()
+{
+
+}
+
+///
+///
+///
+int Surface::dimension() const
+{
+ return 2 ;
+}
+
+///
+///
+///
+Surface::Surface() :
+ Geometry()
+{
+
+}
+
+///
+///
+///
+Surface::Surface( Surface const& other ) :
+ Geometry( other )
+{
+
+}
+
+/**
+ * [OGC/SFS]"The area of this Surface, as measured in the spatial reference system of this Surface"
+ */
+//virtual double area() const = 0 ;
+/**
+ * [OGC/SFS]"The mathematical centroid for this Surface as a Point. The result in not guaranteed to
+ * be on this Surface"
+ */
+//virtual Point centroid() const = 0 ;
+/**
+ * [OGC/SFS]"A Point guaranteed to be on this Surface"
+ * @warning empty point is isEmpty()
+ */
+//virtual Point pointOnSurface() const = 0 ;
+
+
+}//SFCGAL
+
+
+
diff --git a/src/Surface.h b/src/Surface.h
new file mode 100644
index 0000000..efe8717
--- /dev/null
+++ b/src/Surface.h
@@ -0,0 +1,69 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_SURFACE_H_
+#define _SFCGAL_SURFACE_H_
+
+#include <SFCGAL/Geometry.h>
+
+namespace SFCGAL {
+
+/**
+ * Abstract Surface class
+ */
+class SFCGAL_API Surface : public Geometry {
+public:
+ /**
+ * destructor
+ */
+ virtual ~Surface() ;
+
+ //-- SFCGAL::Geometry
+ virtual int dimension() const ;
+
+ /**
+ * [OGC/SFS]"The area of this Surface, as measured in the spatial reference system of this Surface"
+ */
+ //virtual double area() const = 0 ;
+ /**
+ * [OGC/SFS]"The mathematical centroid for this Surface as a Point. The result in not guaranteed to
+ * be on this Surface"
+ */
+ //virtual Point centroid() const = 0 ;
+ /**
+ * [OGC/SFS]"A Point guaranteed to be on this Surface"
+ * @warning empty point is isEmpty()
+ */
+ //virtual Point pointOnSurface() const = 0 ;
+protected:
+ /**
+ * no default constructor
+ */
+ Surface() ;
+ /**
+ * no copy constructor
+ */
+ Surface( Surface const& other ) ;
+};
+
+
+}
+
+#endif
diff --git a/src/Transform.cpp b/src/Transform.cpp
new file mode 100644
index 0000000..42f4d88
--- /dev/null
+++ b/src/Transform.cpp
@@ -0,0 +1,174 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/Transform.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+namespace SFCGAL {
+
+///
+///
+///
+Transform::~Transform()
+{
+
+}
+
+
+///
+///
+///
+void Transform::visit( Point& g )
+{
+ transform( g );
+}
+
+///
+///
+///
+void Transform::visit( LineString& g )
+{
+ for ( size_t i = 0; i < g.numPoints(); i++ ) {
+ visit( g.pointN( i ) );
+ }
+}
+
+///
+///
+///
+void Transform::visit( Polygon& g )
+{
+ for ( size_t i = 0; i < g.numRings(); i++ ) {
+ visit( g.ringN( i ) );
+ }
+}
+
+///
+///
+///
+void Transform::visit( Triangle& g )
+{
+ visit( g.vertex( 0 ) );
+ visit( g.vertex( 1 ) );
+ visit( g.vertex( 2 ) );
+}
+
+///
+///
+///
+void Transform::visit( Solid& g )
+{
+ for ( size_t i = 0; i < g.numShells(); i++ ) {
+ visit( g.shellN( i ) );
+ }
+}
+
+///
+///
+///
+void Transform::visit( MultiPoint& g )
+{
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ visit( g.pointN( i ) );
+ }
+}
+
+///
+///
+///
+void Transform::visit( MultiLineString& g )
+{
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ visit( g.lineStringN( i ) );
+ }
+}
+
+
+///
+///
+///
+void Transform::visit( MultiPolygon& g )
+{
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ visit( g.polygonN( i ) );
+ }
+}
+
+///
+///
+///
+void Transform::visit( MultiSolid& g )
+{
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ visit( g.solidN( i ) );
+ }
+}
+
+
+///
+///
+///
+void Transform::visit( GeometryCollection& g )
+{
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ GeometryVisitor::visit( g.geometryN( i ) );
+ }
+}
+
+
+///
+///
+///
+void Transform::visit( PolyhedralSurface& g )
+{
+ for ( size_t i = 0; i < g.numPolygons(); i++ ) {
+ visit( g.polygonN( i ) );
+ }
+}
+
+
+///
+///
+///
+void Transform::visit( TriangulatedSurface& g )
+{
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ visit( g.geometryN( i ) ) ;
+ }
+}
+
+
+
+
+
+}//SFCGAL
+
diff --git a/src/Transform.h b/src/Transform.h
new file mode 100644
index 0000000..13a6e14
--- /dev/null
+++ b/src/Transform.h
@@ -0,0 +1,59 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_TRANSFORM_H_
+#define _SFCGAL_TRANSFORM_H_
+
+#include <SFCGAL/Geometry.h>
+#include <SFCGAL/GeometryVisitor.h>
+
+
+namespace SFCGAL {
+
+/**
+ * Represents a coordinate transform
+ */
+class SFCGAL_API Transform : public GeometryVisitor {
+public:
+ virtual ~Transform() ;
+ /**
+ * apply transform to a geometry
+ */
+ virtual void transform( Point& p ) = 0 ;
+
+ virtual void visit( Point& g ) ;
+ virtual void visit( LineString& g ) ;
+ virtual void visit( Polygon& g ) ;
+ virtual void visit( Triangle& g ) ;
+ virtual void visit( Solid& g ) ;
+ virtual void visit( MultiPoint& g );
+ virtual void visit( MultiLineString& g ) ;
+ virtual void visit( MultiPolygon& g );
+ virtual void visit( MultiSolid& g );
+ virtual void visit( GeometryCollection& g ) ;
+ virtual void visit( PolyhedralSurface& g ) ;
+ virtual void visit( TriangulatedSurface& g ) ;
+};
+
+
+}//SFCGAL
+
+
+#endif
diff --git a/src/Triangle.cpp b/src/Triangle.cpp
new file mode 100644
index 0000000..695cecb
--- /dev/null
+++ b/src/Triangle.cpp
@@ -0,0 +1,214 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/GeometryVisitor.h>
+
+#include <SFCGAL/Polygon.h>
+
+namespace SFCGAL {
+
+///
+///
+///
+Triangle::Triangle() :
+ Surface()
+{
+ _vertices[0] = Point();
+ _vertices[1] = Point();
+ _vertices[2] = Point();
+}
+
+///
+///
+///
+Triangle::Triangle( const Kernel::Triangle_2& triangle )
+{
+ for ( int i = 0; i < 3; i++ ) {
+ _vertices[i] = triangle.vertex( i ) ;
+ }
+}
+
+
+///
+///
+///
+Triangle::Triangle( const Kernel::Triangle_3& triangle )
+{
+ for ( int i = 0; i < 3; i++ ) {
+ _vertices[i] = triangle.vertex( i ) ;
+ }
+}
+
+///
+///
+///
+Triangle::Triangle( const Point& p, const Point& q, const Point& r ) :
+ Surface()
+{
+ _vertices[0] = p ;
+ _vertices[1] = q ;
+ _vertices[2] = r ;
+}
+
+
+///
+///
+///
+Triangle::Triangle( const Triangle& other )
+ : Surface()
+{
+ _vertices[0] = other._vertices[0] ;
+ _vertices[1] = other._vertices[1] ;
+ _vertices[2] = other._vertices[2] ;
+}
+
+
+
+
+///
+///
+///
+Triangle& Triangle::operator = ( const Triangle& other )
+{
+ _vertices[0] = other._vertices[0] ;
+ _vertices[1] = other._vertices[1] ;
+ _vertices[2] = other._vertices[2] ;
+ return *this ;
+}
+
+///
+///
+///
+Triangle::~Triangle()
+{
+
+}
+
+
+
+///
+///
+///
+Triangle* Triangle::clone() const
+{
+ return new Triangle( *this );
+}
+
+
+///
+///
+///
+std::string Triangle::geometryType() const
+{
+ return "Triangle" ;
+}
+
+
+///
+///
+///
+GeometryType Triangle::geometryTypeId() const
+{
+ return TYPE_TRIANGLE ;
+}
+
+
+///
+///
+///
+int Triangle::coordinateDimension() const
+{
+ return _vertices[0].coordinateDimension() ;
+}
+
+
+///
+///
+///
+bool Triangle::isEmpty() const
+{
+ return _vertices[0].isEmpty();
+}
+
+
+///
+///
+///
+bool Triangle::is3D() const
+{
+ return _vertices[0].is3D() ;
+}
+
+///
+///
+///
+bool Triangle::isMeasured() const
+{
+ return _vertices[0].isMeasured() ;
+}
+
+///
+///
+///
+void Triangle::reverse()
+{
+ //note : first point kept to simplify testing
+ std::swap( _vertices[1], _vertices[2] );
+}
+
+
+///
+///
+///
+Polygon Triangle::toPolygon() const
+{
+ if ( isEmpty() ) {
+ return Polygon() ;
+ }
+
+ std::vector< Point > points ;
+
+ for ( size_t i = 0; i < 4; i++ ) {
+ points.push_back( vertex( i ) );
+ }
+
+ return Polygon( LineString( points ) );
+}
+
+///
+///
+///
+void Triangle::accept( GeometryVisitor& visitor )
+{
+ return visitor.visit( *this );
+}
+
+///
+///
+///
+void Triangle::accept( ConstGeometryVisitor& visitor ) const
+{
+ return visitor.visit( *this );
+}
+
+}//SFCGAL
+
+
diff --git a/src/Triangle.h b/src/Triangle.h
new file mode 100644
index 0000000..fd4859b
--- /dev/null
+++ b/src/Triangle.h
@@ -0,0 +1,164 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_TRIANGLE_H_
+#define _SFCGAL_TRIANGLE_H_
+
+#include <boost/shared_ptr.hpp>
+
+#include <boost/serialization/base_object.hpp>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/Surface.h>
+#include <SFCGAL/detail/TypeForDimension.h>
+
+#include <CGAL/Triangle_2.h>
+#include <CGAL/Triangle_3.h>
+
+namespace SFCGAL {
+
+/**
+ * [OGC/SFA]Triangle
+ * @ingroup public_api
+ *
+ * @warning According to SFA, a Triangle should be inherited from a Polygon. That means
+ * that a triangle "is a" Polygon with hole. This inheritance is removed in order to
+ * keep CGAL modeling.
+ *
+ * @warning An empty triangle has empty points
+ */
+class SFCGAL_API Triangle : public Surface {
+public:
+ /**
+ * empty Triangle constructor
+ */
+ Triangle();
+ /**
+ * Constructor with a CGAL triangle
+ */
+ Triangle( const Kernel::Triangle_2& triangle ) ;
+ /**
+ * Constructor with a CGAL triangle
+ */
+ Triangle( const Kernel::Triangle_3& triangle ) ;
+ /**
+ * constructor with 3 points
+ */
+ Triangle( const Point& p, const Point& q, const Point& r );
+ /**
+ * copy constructor
+ */
+ Triangle( const Triangle& other );
+ /**
+ * assign operator
+ */
+ Triangle& operator = ( const Triangle& other );
+ /**
+ * destructor
+ */
+ ~Triangle();
+
+ //-- SFCGAL::Geometry
+ virtual Triangle* clone() const ;
+
+ //-- SFCGAL::Geometry
+ virtual std::string geometryType() const ;
+ //-- SFCGAL::Geometry
+ virtual GeometryType geometryTypeId() const ;
+ //-- SFCGAL::Geometry
+ virtual int coordinateDimension() const ;
+ //-- SFCGAL::Geometry
+ virtual bool isEmpty() const ;
+ //-- SFCGAL::Geometry
+ virtual bool is3D() const ;
+ //-- SFCGAL::Geometry
+ virtual bool isMeasured() const ;
+
+ /**
+ * reverse Triangle orientation
+ */
+ void reverse() ;
+
+
+ /**
+ * convert a triangle to a polygon
+ */
+ Polygon toPolygon() const ;
+
+ /**
+ * returns the i-th vertex
+ */
+ inline const Point& vertex( const int& i ) const {
+ return _vertices[ i % 3 ];
+ }
+ /**
+ * returns the i-th vertex
+ */
+ inline Point& vertex( const int& i ) {
+ return _vertices[ i % 3 ];
+ }
+
+ /**
+ * Convert to CGAL::Triangle_2
+ */
+ inline Kernel::Triangle_2 toTriangle_2() const {
+ return Kernel::Triangle_2( vertex( 0 ).toPoint_2(), vertex( 1 ).toPoint_2(), vertex( 2 ).toPoint_2() );
+ }
+
+ /**
+ * Convert to CGAL::Triangle_3
+ */
+ inline Kernel::Triangle_3 toTriangle_3() const {
+ return Kernel::Triangle_3( vertex( 0 ).toPoint_3(), vertex( 1 ).toPoint_3(), vertex( 2 ).toPoint_3() );
+ }
+
+ /**
+ * Convert to CGAL::Triangle_2 or CGAL::Triangle_2
+ */
+ template < int D >
+ inline typename detail::TypeForDimension<D>::Triangle toTriangle_d() const {
+ return typename detail::TypeForDimension<D>::Triangle( vertex( 0 ).toPoint_d<D>(), vertex( 1 ).toPoint_d<D>(), vertex( 2 ).toPoint_d<D>() );
+ }
+
+ //-- visitors
+
+ //-- SFCGAL::Geometry
+ virtual void accept( GeometryVisitor& visitor ) ;
+ //-- SFCGAL::Geometry
+ virtual void accept( ConstGeometryVisitor& visitor ) const ;
+
+ /**
+ * Serializer
+ */
+ template <class Archive>
+ void serialize( Archive& ar, const unsigned int /*version*/ ) {
+ ar& boost::serialization::base_object<Geometry>( *this );
+ ar& _vertices[0] & _vertices[1] & _vertices[2];
+ }
+private:
+ /**
+ * point forming the triangle
+ */
+ Point _vertices[3];
+};
+
+}
+
+#endif
diff --git a/src/TriangulatedSurface.cpp b/src/TriangulatedSurface.cpp
new file mode 100644
index 0000000..7aeb2b4
--- /dev/null
+++ b/src/TriangulatedSurface.cpp
@@ -0,0 +1,309 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/GeometryVisitor.h>
+
+namespace SFCGAL {
+
+///
+///
+///
+TriangulatedSurface::TriangulatedSurface():
+ Surface(),
+ _triangles()
+{
+
+}
+
+///
+///
+///
+TriangulatedSurface::TriangulatedSurface( const std::vector< Triangle >& triangles ):
+ Surface()
+{
+ for ( size_t i = 0; i < triangles.size(); i++ ) {
+ _triangles.push_back( triangles[i].clone() ) ;
+ }
+}
+
+///
+///
+///
+TriangulatedSurface::TriangulatedSurface( const TriangulatedSurface& other ):
+ Surface(),
+ _triangles( other._triangles )
+{
+
+}
+
+///
+///
+///
+TriangulatedSurface& TriangulatedSurface::operator = ( TriangulatedSurface other )
+{
+ swap( other );
+ return *this ;
+}
+
+///
+///
+///
+TriangulatedSurface::~TriangulatedSurface()
+{
+
+}
+
+///
+///
+///
+TriangulatedSurface* TriangulatedSurface::clone() const
+{
+ return new TriangulatedSurface( *this );
+}
+
+///
+///
+///
+std::string TriangulatedSurface::geometryType() const
+{
+ return "TriangulatedSurface" ;
+}
+
+///
+///
+///
+GeometryType TriangulatedSurface::geometryTypeId() const
+{
+ return TYPE_TRIANGULATEDSURFACE ;
+}
+
+///
+///
+///
+int TriangulatedSurface::dimension() const
+{
+ //surface
+ return 2 ;
+}
+
+///
+///
+///
+int TriangulatedSurface::coordinateDimension() const
+{
+ if ( _triangles.empty() ) {
+ return 0 ;
+ }
+ else {
+ return _triangles[0].coordinateDimension() ;
+ }
+}
+
+///
+///
+///
+bool TriangulatedSurface::isEmpty() const
+{
+ return _triangles.empty() ;
+}
+
+///
+///
+///
+bool TriangulatedSurface::is3D() const
+{
+ return ! _triangles.empty() && _triangles.front().is3D() ;
+}
+
+///
+///
+///
+bool TriangulatedSurface::isMeasured() const
+{
+ return ! _triangles.empty() && _triangles.front().isMeasured() ;
+}
+
+
+///
+///
+///
+void TriangulatedSurface::addTriangles( const TriangulatedSurface& other )
+{
+ for ( TriangulatedSurface::const_iterator it = other.begin(); it != other.end(); ++it ) {
+ addTriangle( *it ) ;
+ }
+}
+
+
+///
+///
+///
+size_t TriangulatedSurface::numGeometries() const
+{
+ return _triangles.size();
+}
+
+///
+///
+///
+const Triangle& TriangulatedSurface::geometryN( size_t const& n ) const
+{
+ BOOST_ASSERT( n < numGeometries() );
+ return _triangles[n];
+}
+
+///
+///
+///
+Triangle& TriangulatedSurface::geometryN( size_t const& n )
+{
+ BOOST_ASSERT( n < numGeometries() );
+ return _triangles[n];
+}
+
+///
+///
+///
+void TriangulatedSurface::reserve( const size_t& n )
+{
+ _triangles.reserve( n );
+}
+
+///
+///
+///
+void TriangulatedSurface::accept( GeometryVisitor& visitor )
+{
+ return visitor.visit( *this );
+}
+
+///
+///
+///
+void TriangulatedSurface::accept( ConstGeometryVisitor& visitor ) const
+{
+ return visitor.visit( *this );
+}
+
+
+// Private class
+// A modifier creating triangles from a TriangulatedSurface with the incremental builder.
+template <class HDS>
+class Triangulated2Polyhedron : public CGAL::Modifier_base<HDS> {
+public:
+ Triangulated2Polyhedron( const TriangulatedSurface& surf ) : surf( surf ) {}
+
+ typedef typename HDS::Vertex Vertex;
+ typedef typename Vertex::Point Point;
+ typedef typename HDS::Traits K;
+ typedef std::map<Point, size_t> PointMap;
+ typedef std::set< std::pair<Point, Point> > HalfedgeSet;
+
+ void operator()( HDS& hds ) {
+ // Postcondition: `hds' is a valid polyhedral surface.
+ CGAL::Polyhedron_incremental_builder_3<HDS> B( hds, true );
+ B.begin_surface( /* vertices */ surf.numGeometries() * 3,
+ /* facets */ surf.numGeometries(),
+ /* halfedges */ surf.numGeometries() * 3 );
+
+ size_t vertex_idx = 0;
+
+ // first pass: insert vertices, only if they are not shared between faces
+ // thanks to a binary tree (PointMap)
+ for ( size_t i = 0; i < surf.numGeometries(); i++ ) {
+ for ( size_t j = 0; j < 3; j++ ) {
+ Point p = surf.geometryN( i ).vertex( j ).toPoint_3();
+
+ if ( points.find( p ) == points.end() ) {
+ B.add_vertex( p );
+ points[p] = vertex_idx++;
+ }
+ }
+ }
+
+ // second pass: adjacent triangles must be built with compliant orientations
+ // the two halfedges of a shared edge must be of opposite orientation
+
+ // Extract from CGAL's documentation
+ // "The convention is that the halfedges are oriented counterclockwise
+ // around facets as seen from the outside of the polyhedron"
+
+ for ( size_t i = 0; i < surf.numGeometries(); i++ ) {
+ B.begin_facet();
+ CGAL::Triangle_3<K> tri( surf.geometryN( i ).toTriangle_3() );
+ CGAL::Point_3<K> pa( tri[0] );
+ CGAL::Point_3<K> pb( tri[1] );
+ CGAL::Point_3<K> pc( tri[2] );
+
+ if ( edges.find( std::make_pair( pa, pb ) ) != edges.end() ||
+ edges.find( std::make_pair( pb, pc ) ) != edges.end() ||
+ edges.find( std::make_pair( pc, pa ) ) != edges.end() ) {
+ BOOST_THROW_EXCEPTION( Exception( "When trying to build a CGAL::Polyhedron_3 from a TriangulatedSurface: bad orientation for "
+ + surf.geometryN( i ).asText()
+ + " consider using ConsistentOrientationBuilder first" ) );
+ }
+
+ B.add_vertex_to_facet( points[pa] );
+ B.add_vertex_to_facet( points[pb] );
+ B.add_vertex_to_facet( points[pc] );
+ edges.insert( std::make_pair( pa, pb ) );
+ edges.insert( std::make_pair( pb, pc ) );
+ edges.insert( std::make_pair( pc, pa ) );
+ B.end_facet();
+ }
+
+ B.end_surface();
+ }
+private:
+ const TriangulatedSurface& surf;
+ PointMap points;
+ HalfedgeSet edges;
+};
+
+template <typename Polyhedron>
+struct Plane_from_facet {
+ typename Polyhedron::Plane_3 operator()( typename Polyhedron::Facet& f ) {
+ typename Polyhedron::Halfedge_handle h = f.halfedge();
+ return typename Polyhedron::Plane_3( h->vertex()->point(),
+ h->next()->vertex()->point(),
+ h->opposite()->vertex()->point() );
+ }
+};
+
+template < typename K, typename Polyhedron >
+std::auto_ptr<Polyhedron> TriangulatedSurface::toPolyhedron_3() const
+{
+ Polyhedron* poly = new Polyhedron();
+ Triangulated2Polyhedron<typename Polyhedron::HalfedgeDS> converter( *this );
+ poly->delegate( converter );
+
+ // compute planes
+ std::transform( poly->facets_begin(), poly->facets_end(), poly->planes_begin(), Plane_from_facet<Polyhedron>() );
+
+ return std::auto_ptr<Polyhedron>( poly );
+}
+
+template SFCGAL_API std::auto_ptr< detail::MarkedPolyhedron > TriangulatedSurface::toPolyhedron_3<Kernel, detail::MarkedPolyhedron >() const;
+template SFCGAL_API std::auto_ptr< CGAL::Polyhedron_3<Kernel> > TriangulatedSurface::toPolyhedron_3<Kernel, CGAL::Polyhedron_3<Kernel> >() const;
+
+}//SFCGAL
+
+
diff --git a/src/TriangulatedSurface.h b/src/TriangulatedSurface.h
new file mode 100644
index 0000000..2d488f3
--- /dev/null
+++ b/src/TriangulatedSurface.h
@@ -0,0 +1,193 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_TRIANGULATED_SURFACE_H_
+#define _SFCGAL_TRIANGULATED_SURFACE_H_
+
+#include <vector>
+#include <set>
+#include <boost/assert.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <boost/serialization/base_object.hpp>
+#include <boost/ptr_container/serialize_ptr_vector.hpp>
+
+
+#include <CGAL/Polyhedron_3.h>
+#include <CGAL/Polyhedron_incremental_builder_3.h>
+
+#include <SFCGAL/Exception.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/Triangle.h>
+
+
+namespace SFCGAL {
+
+/**
+ * A TriangulatedSurface in SFA modeled as a Triangle soup
+ * @ingroup public_api
+ * @todo do better than a "triangle soup" or add topological view?
+ */
+class SFCGAL_API TriangulatedSurface : public Surface {
+public:
+ typedef boost::ptr_vector< Triangle >::iterator iterator ;
+ typedef boost::ptr_vector< Triangle >::const_iterator const_iterator ;
+
+ /**
+ * Empty TriangulatedSurface constructor
+ */
+ TriangulatedSurface() ;
+ /**
+ * Constructor with a vector of triangles
+ */
+ TriangulatedSurface( const std::vector< Triangle >& triangle ) ;
+ /**
+ * Copy constructor
+ */
+ TriangulatedSurface( const TriangulatedSurface& other ) ;
+ /**
+ * assign operator
+ */
+ TriangulatedSurface& operator = ( TriangulatedSurface other ) ;
+ /**
+ * destructor
+ */
+ ~TriangulatedSurface() ;
+
+ //-- SFCGAL::Geometry
+ virtual TriangulatedSurface* clone() const ;
+
+ //-- SFCGAL::Geometry
+ virtual std::string geometryType() const ;
+ //-- SFCGAL::Geometry
+ virtual GeometryType geometryTypeId() const ;
+ //-- SFCGAL::Geometry
+ virtual int dimension() const ;
+ //-- SFCGAL::Geometry
+ virtual int coordinateDimension() const ;
+ //-- SFCGAL::Geometry
+ virtual bool isEmpty() const ;
+ //-- SFCGAL::Geometry
+ virtual bool is3D() const ;
+ //-- SFCGAL::Geometry
+ virtual bool isMeasured() const ;
+
+ /**
+ * [SFA/OGC]Returns the number of points
+ * @deprecated see numGeometries()
+ */
+ inline size_t numTriangles() const {
+ return _triangles.size();
+ }
+ /**
+ * [SFA/OGC]Returns the n-th point
+ * @deprecated see geometryN()
+ */
+ inline const Triangle& triangleN( size_t const& n ) const {
+ BOOST_ASSERT( n < _triangles.size() );
+ return _triangles[n];
+ }
+ /**
+ * [SFA/OGC]Returns the n-th point
+ * @deprecated see geometryN()
+ */
+ inline Triangle& triangleN( size_t const& n ) {
+ BOOST_ASSERT( n < _triangles.size() );
+ return _triangles[n];
+ }
+ /**
+ * add a Triangle to the TriangulatedSurface
+ */
+ inline void addTriangle( const Triangle& triangle ) {
+ addTriangle( triangle.clone() );
+ }
+ /**
+ * add a Triangle to the TriangulatedSurface
+ */
+ inline void addTriangle( Triangle* triangle ) {
+ _triangles.push_back( triangle );
+ }
+ /**
+ * add triangles from an other TriangulatedSurface
+ */
+ void addTriangles( const TriangulatedSurface& other ) ;
+
+
+ //-- SFCGAL::Geometry
+ virtual size_t numGeometries() const ;
+ //-- SFCGAL::Geometry
+ virtual const Triangle& geometryN( size_t const& n ) const ;
+ //-- SFCGAL::Geometry
+ virtual Triangle& geometryN( size_t const& n ) ;
+
+
+ //-- optimization
+
+ void reserve( const size_t& n ) ;
+
+ //-- iterators
+
+ inline iterator begin() {
+ return _triangles.begin() ;
+ }
+ inline const_iterator begin() const {
+ return _triangles.begin() ;
+ }
+
+ inline iterator end() {
+ return _triangles.end() ;
+ }
+ inline const_iterator end() const {
+ return _triangles.end() ;
+ }
+
+ //-- visitors
+
+ //-- SFCGAL::Geometry
+ virtual void accept( GeometryVisitor& visitor ) ;
+ //-- SFCGAL::Geometry
+ virtual void accept( ConstGeometryVisitor& visitor ) const ;
+
+
+ //-- helpers
+
+ /**
+ * @brief Converts a TriangulatedSurface to a CGAL::Polyhedron_3
+ */
+ template < typename K, typename Polyhedron >
+ std::auto_ptr<Polyhedron> toPolyhedron_3() const;
+
+ /**
+ * Serializer
+ */
+ template <class Archive>
+ void serialize( Archive& ar, const unsigned int /*version*/ ) {
+ ar& boost::serialization::base_object<Geometry>( *this );
+ ar& _triangles;
+ }
+private:
+ boost::ptr_vector< Triangle > _triangles ;
+
+ void swap( TriangulatedSurface& other ) {
+ std::swap( _triangles, other._triangles );
+ }
+};
+}
+
+#endif
diff --git a/src/Validity.h b/src/Validity.h
new file mode 100644
index 0000000..6dd145e
--- /dev/null
+++ b/src/Validity.h
@@ -0,0 +1,63 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _SFCGAL_VALIDITY_H_
+#define _SFCGAL_VALIDITY_H_
+
+namespace SFCGAL {
+
+/**
+ * @brief the class, convertible to bool, that stores the reason why a geom is invalid
+ */
+struct Validity {
+ /**
+ * @note the class has private ctor to force the use of functions valid() and invalid(reason) that are clearer in the code than to remember that "Valid constructed with a reason is invalid"
+ */
+ static const Validity valid() {
+ return Validity();
+ }
+ static const Validity invalid( const std::string& reason ) {
+ return Validity( reason );
+ }
+ operator bool() const {
+ return _valid;
+ }
+ const std::string& reason() const {
+ return _reason;
+ }
+private:
+ bool _valid; // not const to allow default copy
+ std::string _reason;
+ /**
+ * @brief default ctor for valid
+ */
+ Validity():_valid( true ) {}
+ /**
+ * @brief if we construct with a reason, the class is invalid
+ */
+ Validity( const std::string& reason ):
+ _valid( false ),
+ _reason( reason ) {
+ }
+};
+
+}
+#endif
diff --git a/src/algorithm/BoundaryVisitor.cpp b/src/algorithm/BoundaryVisitor.cpp
new file mode 100644
index 0000000..078beac
--- /dev/null
+++ b/src/algorithm/BoundaryVisitor.cpp
@@ -0,0 +1,321 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/BoundaryVisitor.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+#include <map>
+#include <complex>
+#include <SFCGAL/detail/ComplexComparator.h>
+
+namespace SFCGAL {
+namespace algorithm {
+
+///
+///
+///
+void BoundaryVisitor::visit( const Point& )
+{
+ _boundary.reset();
+}
+
+///
+///
+///
+void BoundaryVisitor::visit( const LineString& g )
+{
+ if ( g.isEmpty() ) {
+ _boundary.reset();
+ return ;
+ }
+
+ if ( g.startPoint().coordinate() == g.endPoint().coordinate() ) {
+ _boundary.reset() ;
+ }
+ else {
+ std::auto_ptr< MultiPoint > boundary( new MultiPoint );
+ boundary->addGeometry( g.startPoint() );
+ boundary->addGeometry( g.endPoint() );
+ _boundary.reset( boundary.release() );
+ }
+}
+
+///
+///
+///
+void BoundaryVisitor::visit( const Polygon& g )
+{
+ if ( g.isEmpty() ) {
+ _boundary.reset();
+ return ;
+ }
+
+ if ( ! g.hasInteriorRings() ) {
+ _boundary.reset( g.exteriorRing().clone() );
+ }
+ else {
+ std::auto_ptr< MultiLineString > boundary( new MultiLineString );
+
+ for ( size_t i = 0; i < g.numRings(); i++ ) {
+ boundary->addGeometry( g.ringN( i ) );
+ }
+
+ _boundary.reset( boundary.release() );
+ }
+}
+
+///
+///
+///
+void BoundaryVisitor::visit( const Triangle& g )
+{
+ if ( g.isEmpty() ) {
+ _boundary.reset();
+ return ;
+ }
+
+ std::auto_ptr< LineString > boundary( new LineString );
+
+ for ( size_t i = 0; i < 4; i++ ) {
+ boundary->addPoint( g.vertex( i ) );
+ }
+
+ _boundary.reset( boundary.release() );
+}
+
+///
+///
+///
+void BoundaryVisitor::visit( const Solid& g )
+{
+ BOOST_THROW_EXCEPTION( Exception(
+ ( boost::format( "unsupported type %1% in boundary operation" ) % g.geometryType() ).str()
+ ) );
+}
+
+///
+///
+///
+void BoundaryVisitor::visit( const MultiPoint& )
+{
+ _boundary.reset();
+}
+
+///
+///
+///
+void BoundaryVisitor::visit( const MultiLineString& g )
+{
+ if ( g.isEmpty() ) {
+ _boundary.reset();
+ return ;
+ }
+
+ /*
+ * create a GeometryGraph and rely on vertex degree (1 means boundary)
+ */
+ graph::GeometryGraph graph ;
+ graph::GeometryGraphBuilder graphBuilder( graph ) ;
+
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ graphBuilder.addLineString( g.lineStringN( i ) );
+ }
+
+ getBoundaryFromLineStrings( graph ) ;
+}
+
+///
+///
+///
+void BoundaryVisitor::visit( const MultiPolygon& g )
+{
+ graph::GeometryGraph graph ;
+ graph::GeometryGraphBuilder graphBuilder( graph ) ;
+
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ graphBuilder.addPolygon( g.polygonN( i ) );
+ }
+
+ getBoundaryFromPolygons( graph ) ;
+}
+
+///
+///
+///
+void BoundaryVisitor::visit( const MultiSolid& g )
+{
+ BOOST_THROW_EXCEPTION( Exception(
+ ( boost::format( "unsupported type %1% in boundary operation" ) % g.geometryType() ).str()
+ ) );
+}
+
+///
+///
+///
+void BoundaryVisitor::visit( const GeometryCollection& g )
+{
+ BOOST_THROW_EXCEPTION( Exception(
+ ( boost::format( "unsupported type %1% in boundary operation" ) % g.geometryType() ).str()
+ ) );
+}
+
+///
+///
+///
+void BoundaryVisitor::visit( const PolyhedralSurface& g )
+{
+ graph::GeometryGraph graph ;
+ graph::GeometryGraphBuilder graphBuilder( graph ) ;
+
+ graphBuilder.addPolyhedralSurface( g );
+ getBoundaryFromPolygons( graph ) ;
+}
+
+///
+///
+///
+void BoundaryVisitor::visit( const TriangulatedSurface& g )
+{
+ graph::GeometryGraph graph ;
+ graph::GeometryGraphBuilder graphBuilder( graph ) ;
+
+ graphBuilder.addTriangulatedSurface( g );
+ getBoundaryFromPolygons( graph ) ;
+}
+
+
+///
+///
+///
+Geometry* BoundaryVisitor::releaseBoundary()
+{
+ if ( _boundary.get() ) {
+ return _boundary.release() ;
+ }
+ else {
+ return new GeometryCollection() ;
+ }
+}
+
+
+///
+///
+///
+void BoundaryVisitor::getBoundaryFromLineStrings( const graph::GeometryGraph& graph )
+{
+ typedef graph::GeometryGraph::vertex_descriptor vertex_descriptor ;
+ typedef graph::GeometryGraph::vertex_iterator vertex_iterator ;
+
+
+ std::vector< vertex_descriptor > vertices ;
+
+ vertex_iterator it,end ;
+
+ for ( boost::tie( it,end ) = graph.vertices(); it != end; ++it ) {
+ vertex_descriptor vertex = *it ;
+
+ if ( graph.degree( vertex ) == 1 ) {
+ vertices.push_back( vertex );
+ }
+ }
+
+ if ( vertices.empty() ) {
+ _boundary.reset() ;
+ }
+ else if ( vertices.size() == 1 ) {
+ _boundary.reset( new Point( graph[ vertices[0] ].coordinate ) );
+ }
+ else {
+ std::auto_ptr< MultiPoint > boundary( new MultiPoint );
+
+ for ( size_t i = 0; i < vertices.size(); i++ ) {
+ boundary->addGeometry( new Point( graph[ vertices[i] ].coordinate ) ) ;
+ }
+
+ _boundary.reset( boundary.release() );
+ }
+}
+
+
+///
+///
+///
+void BoundaryVisitor::getBoundaryFromPolygons( const graph::GeometryGraph& g )
+{
+ typedef graph::GeometryGraph::vertex_descriptor vertex_descriptor ;
+ //typedef graph::GeometryGraph::vertex_iterator vertex_iterator ;
+ typedef graph::GeometryGraph::edge_descriptor edge_descriptor ;
+ typedef graph::GeometryGraph::edge_iterator edge_iterator ;
+
+
+ std::vector< edge_descriptor > boundaryEdges ;
+
+ edge_iterator it, end ;
+
+ for ( boost::tie( it, end ) = g.edges(); it != end ; ++it ) {
+ if ( g.edges( g.source( *it ), g.target( *it ) ).size() == 1U ) {
+ boundaryEdges.push_back( *it ) ;
+ }
+ }
+
+ if ( boundaryEdges.empty() ) {
+ _boundary.reset() ;
+ }
+ else {
+ //TODO merge Line Segments into LineString
+ std::auto_ptr< MultiLineString > boundary( new MultiLineString );
+
+ for ( size_t i = 0; i < boundaryEdges.size(); i++ ) {
+ const edge_descriptor& edge = boundaryEdges[i] ;
+
+ vertex_descriptor source = g.source( edge );
+ vertex_descriptor target = g.target( edge );
+
+ boundary->addGeometry(
+ new LineString(
+ Point( g[ source ].coordinate ),
+ Point( g[ target ].coordinate )
+ )
+ ) ;
+ }
+
+ _boundary.reset( boundary.release() );
+ }
+}
+
+
+
+
+
+}//algorithm
+}//SFCGAL
+
diff --git a/src/algorithm/BoundaryVisitor.h b/src/algorithm/BoundaryVisitor.h
new file mode 100644
index 0000000..30dd4c7
--- /dev/null
+++ b/src/algorithm/BoundaryVisitor.h
@@ -0,0 +1,101 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_ALGORITHM_BOUNDARYVISITOR_H_
+#define _SFCGAL_ALGORITHM_BOUNDARYVISITOR_H_
+
+#include <SFCGAL/GeometryVisitor.h>
+
+#include <SFCGAL/detail/graph/GeometryGraph.h>
+#include <SFCGAL/detail/graph/GeometryGraphBuilder.h>
+
+
+namespace SFCGAL {
+namespace algorithm {
+
+
+/**
+ * Compute the boundary for a Geometry
+ *
+ * boundary( Point ) : GEOMETRYCOLLECTION EMPTY
+ * boundary( LineString ) : either GEOMETRYCOLLECTION EMPTY is the LineString is closed, or MULTIPOINT(2)
+ * boundary( Polygon ) : LINESTRING | MULTILINESTRING (polygon rings)
+ * boundary( Triangle ) : either GEOMETRYCOLLECTION EMPTY is the LineString is closed, or MULTIPOINT(2)
+ *
+ * boundary( MultiPoint ) : GEOMETRYCOLLECTION EMPTY
+ * boundary( MultiLineString ) : either GEOMETRYCOLLECTION EMPTY or single occurance points
+ *
+ * @warning GeometryCollection are not supported in the general case
+ *
+ * @ŧodo Solid
+ *
+ * @todo MultiPolygon, PolyhedralSurface, TriangulatedSurface (same graph algorithm, edges without parallel or opposite)
+ *
+ *
+ * @todo GeometryCollection : complex for heterogeneous collection (not supported in GEOS)
+ * @todo MultiSolid : faced elimination
+ * @ingroup detail
+ *
+ */
+class SFCGAL_API BoundaryVisitor : public ConstGeometryVisitor {
+public:
+
+ virtual void visit( const Point& g ) ;
+ virtual void visit( const LineString& g ) ;
+ virtual void visit( const Polygon& g ) ;
+ virtual void visit( const Triangle& g ) ;
+ virtual void visit( const Solid& g ) ;
+ virtual void visit( const MultiPoint& g ) ;
+ virtual void visit( const MultiLineString& g ) ;
+ virtual void visit( const MultiPolygon& g ) ;
+ virtual void visit( const MultiSolid& g ) ;
+ virtual void visit( const GeometryCollection& g ) ;
+ virtual void visit( const PolyhedralSurface& g ) ;
+ virtual void visit( const TriangulatedSurface& g ) ;
+
+ /**
+ * get the boundary
+ */
+ Geometry* releaseBoundary() ;
+
+protected:
+
+ /**
+ * get the boundary vertices for a set of LineString in a GeometryGraph
+ */
+ void getBoundaryFromLineStrings( const graph::GeometryGraph& g );
+ /**
+ * get the boundary edges for a set of Polygons in a GeometryGraph
+ * @warning not optimal (edges could be counted using complex< vertex_descriptor >)
+ * @todo merge resulting edges
+ */
+ void getBoundaryFromPolygons( const graph::GeometryGraph& g );
+
+private:
+ std::auto_ptr< Geometry > _boundary ;
+};
+
+
+
+}//algorithm
+}//SFCGAL
+
+
+#endif
diff --git a/src/algorithm/ConsistentOrientationBuilder.cpp b/src/algorithm/ConsistentOrientationBuilder.cpp
new file mode 100644
index 0000000..0af2835
--- /dev/null
+++ b/src/algorithm/ConsistentOrientationBuilder.cpp
@@ -0,0 +1,232 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/ConsistentOrientationBuilder.h>
+#include <SFCGAL/detail/graph/algorithm/orientation.h>
+
+namespace SFCGAL {
+namespace algorithm {
+
+///
+///
+///
+ConsistentOrientationBuilder::ConsistentOrientationBuilder():
+ _graph(),
+ _graphBuilder( _graph ),
+ _triangles()
+{
+
+}
+
+///
+///
+///
+void ConsistentOrientationBuilder::addTriangle( const Triangle& triangle )
+{
+ _triangles.push_back( _graphBuilder.addTriangle( triangle, graph::Edge( _triangles.size() ) ) ) ;
+}
+
+///
+///
+///
+void ConsistentOrientationBuilder::addTriangulatedSurface( const TriangulatedSurface& triangulatedSurface )
+{
+ for ( size_t i = 0; i < triangulatedSurface.numGeometries(); i++ ) {
+ addTriangle( triangulatedSurface.geometryN( i ) ) ;
+ }
+}
+
+///
+///
+///
+TriangulatedSurface ConsistentOrientationBuilder::buildTriangulatedSurface()
+{
+ _makeOrientationConsistent() ;
+ TriangulatedSurface triangulatedSurface ;
+
+ for ( size_t i = 0; i < numTriangles(); i++ ) {
+ triangulatedSurface.addTriangle( triangleN( i ) );
+ }
+
+ return triangulatedSurface ;
+}
+
+///
+///
+///
+Triangle ConsistentOrientationBuilder::triangleN( const size_t& n ) const
+{
+ const edge_descriptor& ab = _triangles[n][0] ;
+ const edge_descriptor& bc = _triangles[n][1] ;
+ const edge_descriptor& ca = _triangles[n][2] ;
+
+ return Triangle(
+ Point( _graph[ _graph.source( ab ) ].coordinate ),
+ Point( _graph[ _graph.source( bc ) ].coordinate ),
+ Point( _graph[ _graph.source( ca ) ].coordinate )
+ );
+}
+
+
+///
+///
+///
+void ConsistentOrientationBuilder::_makeOrientationConsistent()
+{
+ if ( _triangles.empty() ) {
+ return ;
+ }
+
+ /*
+ * mark all triangles as not oriented and not visited
+ */
+ _visited.resize( numTriangles() ) ;
+ _oriented.resize( numTriangles() ) ;
+
+ for ( size_t i = 0; i < numTriangles(); i++ ) {
+ _visited[i] = false ;
+ _oriented[i] = false ;
+ }
+
+ _computeNeighbors();
+
+ // mark first one as oriented (reference)
+ int currentTriangle = -1 ;
+
+ while ( ( currentTriangle = _findNextTriangle() ) != -1 ) {
+ //mark triangle as visited
+ _visited[ currentTriangle ] = true ;
+
+ //orient neighbors
+ const std::set< size_t >& neighbors = _neighbors[ currentTriangle ] ;
+
+ for ( std::set< size_t >::const_iterator it = neighbors.begin(); it != neighbors.end(); ++it ) {
+ bool hasOppositeEdge, hasParallelEdge ;
+ graph::algorithm::studyOrientation(
+ _graph,
+ _triangles[ currentTriangle ],
+ _triangles[ ( *it ) ],
+ hasOppositeEdge,
+ hasParallelEdge
+ );
+
+ // orientation is consistent
+ if ( ! hasParallelEdge ) {
+ _oriented[ *it ] = true ;
+ continue ;
+ }
+
+ // orientation can't be consistent
+ if ( hasOppositeEdge && hasParallelEdge ) {
+ BOOST_THROW_EXCEPTION( Exception(
+ "can't build consistent orientation from triangle set"
+ ) );
+ }
+
+ // orientation has already been fixed (moebius)
+ if ( hasParallelEdge && _oriented[ *it ] ) {
+ BOOST_THROW_EXCEPTION( Exception(
+ "can't build consistent orientation from triangle set, inconsistent orientation for triangle"
+ ) );
+ }
+
+ //here, neighbor triangle should be reversed
+ _graph.reverse( _triangles[ ( *it ) ] );
+ _oriented[ *it ] = true ;
+ }
+ }
+}
+
+///
+///
+///
+void ConsistentOrientationBuilder::_computeNeighbors()
+{
+ _neighbors.clear() ;
+ _neighbors.resize( numTriangles() );
+
+ for ( size_t i = 0; i < _triangles.size(); i++ ) {
+ const std::vector< edge_descriptor >& triangle = _triangles[i] ;
+
+ for ( size_t j = 0; j < triangle.size(); j++ ) {
+ vertex_descriptor source = _graph.source( triangle[j] ) ;
+ vertex_descriptor target = _graph.target( triangle[j] ) ;
+
+ //get neighbor edges
+ std::vector< directed_edge_descriptor > neighborEdges = _graph.edges( source, target );
+
+ //use marker to fill neighborGraph
+ for ( size_t k = 0; k < neighborEdges.size(); k++ ) {
+ size_t idOtherTriangle = ( size_t )_graph[ neighborEdges[k].first ].face;
+
+ if ( idOtherTriangle == i ) {
+ continue ;
+ }
+
+ _neighbors[i].insert( idOtherTriangle );
+ }
+ }
+ }
+}
+
+///
+///
+///
+int ConsistentOrientationBuilder::_findNextTriangle()
+{
+ int result = -1 ;
+
+ /*
+ * find an oriented triangle (reached) and not visited
+ */
+ for ( size_t i = 0; i < numTriangles(); i++ ) {
+ if ( ! _oriented[i] || _visited[i] ) {
+ continue ;
+ }
+
+ result = i ;
+ break ;
+ }
+
+ //triangle found
+ if ( result != -1 ) {
+ return result ;
+ }
+
+ /*
+ * here, a new connected part begins
+ */
+ for ( size_t i = 0; i < numTriangles(); i++ ) {
+ if ( ! _oriented[i] ) {
+ _oriented[i] = true ;
+ return i ;
+ }
+ }
+
+ BOOST_ASSERT( result == -1 );
+ return result ;
+}
+
+
+
+
+}//algorithm
+}//SFCGAL
+
diff --git a/src/algorithm/ConsistentOrientationBuilder.h b/src/algorithm/ConsistentOrientationBuilder.h
new file mode 100644
index 0000000..a1b4241
--- /dev/null
+++ b/src/algorithm/ConsistentOrientationBuilder.h
@@ -0,0 +1,114 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_ALGORITHM_CONSISTENTORIENTATIONBUILDER_H_
+#define _SFCGAL_ALGORITHM_CONSISTENTORIENTATIONBUILDER_H_
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Geometry.h>
+
+#include <SFCGAL/detail/graph/GeometryGraph.h>
+#include <SFCGAL/detail/graph/GeometryGraphBuilder.h>
+
+namespace SFCGAL {
+namespace algorithm {
+
+/**
+ * Make orientation consistent in a triangle set
+ * @ingroup detail
+ */
+class SFCGAL_API ConsistentOrientationBuilder {
+public:
+ typedef graph::GeometryGraph::vertex_descriptor vertex_descriptor ;
+ typedef graph::GeometryGraph::edge_descriptor edge_descriptor ;
+ typedef graph::GeometryGraph::directed_edge_descriptor directed_edge_descriptor ;
+
+ /**
+ * default constructor
+ */
+ ConsistentOrientationBuilder() ;
+
+ /**
+ * add a Triangle
+ */
+ void addTriangle( const Triangle& triangle ) ;
+ /**
+ * add a TriangulatedSurface
+ */
+ void addTriangulatedSurface( const TriangulatedSurface& triangulatedSurface ) ;
+
+ /**
+ * get the resulting TriangulatedSurface where each connected part
+ * has consistent orientation.
+ *
+ * @throw SFCGAL::Exception if such a TriangulatedSurface can't be built
+ */
+ TriangulatedSurface buildTriangulatedSurface() ;
+
+ /**
+ * returns the number of triangles
+ */
+ inline size_t numTriangles() const {
+ return _triangles.size();
+ }
+ /**
+ * returns the n-th triangle
+ */
+ Triangle triangleN( const size_t& n ) const ;
+
+
+ /**
+ * [advanced]use after buildTriangulatedSurface
+ */
+ const std::set< size_t >& neighbors( const size_t& n ) const ;
+private:
+ graph::GeometryGraph _graph ;
+ graph::GeometryGraphBuilder _graphBuilder ;
+ std::vector< std::vector< edge_descriptor > > _triangles ;
+
+ std::vector< bool > _visited ;
+ std::vector< bool > _oriented ;
+ std::vector< std::set< size_t > > _neighbors ;
+
+
+ /**
+ * make triangle orientation consistent
+ */
+ void _makeOrientationConsistent() ;
+
+ /**
+ * compute neighbors for each triangles
+ */
+ void _computeNeighbors() ;
+
+ /**
+ * find the next triangle to visit (may select a new reference triangle)
+ */
+ int _findNextTriangle() ;
+
+};
+
+
+}//algorithm
+}//SFCGAL
+
+
+#endif
diff --git a/src/algorithm/Intersection2D.cpp b/src/algorithm/Intersection2D.cpp
new file mode 100644
index 0000000..5ba2c8a
--- /dev/null
+++ b/src/algorithm/Intersection2D.cpp
@@ -0,0 +1,164 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <CGAL/Segment_2.h>
+#include <CGAL/Triangle_2.h>
+
+#include <CGAL/Boolean_set_operations_2.h>
+#include <CGAL/intersections.h>
+
+#include <SFCGAL/Exception.h>
+#include <SFCGAL/detail/GeometrySet.h>
+#include <SFCGAL/algorithm/intersects.h>
+#include <SFCGAL/algorithm/intersection.h>
+#include <SFCGAL/detail/triangulate/triangulateInGeometrySet.h>
+
+using namespace SFCGAL::detail;
+
+namespace SFCGAL {
+namespace algorithm {
+
+// local function : get the number of intersection points between rings of a polygon
+int numIntersectionPoints( const CGAL::Polygon_with_holes_2<Kernel>& poly )
+{
+ int numIntersectionPoints = 0;
+ CGAL::Polygon_with_holes_2<Kernel>::Hole_const_iterator hit = poly.holes_begin();
+
+ for ( int i = 0; i == 0 || hit != poly.holes_end(); ++i ) {
+ GeometrySet<2> ringI;
+
+ if ( i == 0 ) {
+ ringI.addSegments( poly.outer_boundary().edges_begin(), poly.outer_boundary().edges_end() );
+ }
+ else {
+ ringI.addSegments( hit->edges_begin(), hit->edges_end() );
+ hit++;
+ }
+
+ for ( CGAL::Polygon_with_holes_2<Kernel>::Hole_const_iterator hjt = hit;
+ hjt != poly.holes_end();
+ ++hjt ) {
+ GeometrySet<2> ringJ, inter;
+ ringJ.addSegments( hjt->edges_begin(), hjt->edges_end() );
+
+ algorithm::intersection( ringI, ringJ, inter );
+ numIntersectionPoints += inter.points().size();
+ }
+ }
+
+ return numIntersectionPoints;
+}
+
+//
+// must be called with pa's dimension larger than pb's
+void intersection( const PrimitiveHandle<2>& pa, const PrimitiveHandle<2>& pb,
+ GeometrySet<2>& output, dim_t<2> )
+{
+ // everything vs a point
+ if ( pb.handle.which() == PrimitivePoint ) {
+ if ( algorithm::intersects( pa, pb ) ) {
+ output.addPrimitive( *pb.as<CGAL::Point_2<Kernel> >() );
+ }
+ }
+ else if ( pa.handle.which() == PrimitiveSurface && pb.handle.which() == PrimitiveSurface ) {
+ const CGAL::Polygon_with_holes_2<Kernel>* poly1 = pa.as<CGAL::Polygon_with_holes_2<Kernel> >();
+ const CGAL::Polygon_with_holes_2<Kernel>* poly2 = pb.as<CGAL::Polygon_with_holes_2<Kernel> >();
+
+ // shortcut for triangles
+ if ( poly1->holes_begin() == poly1->holes_end() &&
+ poly1->outer_boundary().size() == 3 &&
+ poly2->holes_begin() == poly2->holes_end() &&
+ poly2->outer_boundary().size() == 3 ) {
+ CGAL::Polygon_2<Kernel>::Vertex_iterator vit1 = poly1->outer_boundary().vertices_begin();
+ CGAL::Point_2<Kernel> pa1 = *vit1++;
+ CGAL::Point_2<Kernel> pa2 = *vit1++;
+ CGAL::Point_2<Kernel> pa3 = *vit1;
+ CGAL::Triangle_2<Kernel> tri1( pa1, pa2, pa3 );
+
+ CGAL::Polygon_2<Kernel>::Vertex_iterator vit2 = poly2->outer_boundary().vertices_begin();
+ CGAL::Point_2<Kernel> pb1 = *vit2++;
+ CGAL::Point_2<Kernel> pb2 = *vit2++;
+ CGAL::Point_2<Kernel> pb3 = *vit2;
+ CGAL::Triangle_2<Kernel> tri2( pb1, pb2, pb3 );
+
+ CGAL::Object interObj = CGAL::intersection( tri1, tri2 );
+ output.addPrimitive( interObj, /* pointsAsRing */ true );
+ return;
+ }
+
+ // CGAL::intersection does not work when the intersection is a point or a segment
+ // We have to call intersection on boundaries first
+
+ GeometrySet<2> gpoly1, gpoly2;
+ gpoly1.addBoundary( *poly1 );
+ gpoly2.addBoundary( *poly2 );
+
+ algorithm::intersection( gpoly1, gpoly2, output );
+
+ // CGAL::intersection does not work when rings intersect themselves
+ // However, touching by a single point is valid for OGC
+ // FIXME: not implemented yet
+ if ( numIntersectionPoints( *poly1 ) > 0 ) {
+ BOOST_THROW_EXCEPTION( NotImplementedException( "Intersection does not support polygon with connected rings" ) );
+ }
+
+ if ( numIntersectionPoints( *poly2 ) > 0 ) {
+ BOOST_THROW_EXCEPTION( NotImplementedException( "Intersection does not support polygon with connected rings" ) );
+ }
+
+ // now call on polygon's interiors
+ CGAL::intersection( *poly1,
+ *poly2,
+ std::back_inserter( output.surfaces() ) );
+ }
+ else if ( pa.handle.which() == PrimitiveSegment && pb.handle.which() == PrimitiveSegment ) {
+ const CGAL::Segment_2<Kernel>* seg1 = pa.as<CGAL::Segment_2<Kernel> >();
+ const CGAL::Segment_2<Kernel>* seg2 = pb.as<CGAL::Segment_2<Kernel> >();
+ CGAL::Object interObj = CGAL::intersection( *seg1, *seg2 );
+ output.addPrimitive( interObj );
+ }
+ else if ( pa.handle.which() == PrimitiveSurface && pb.handle.which() == PrimitiveSegment ) {
+ const CGAL::Polygon_with_holes_2<Kernel>* poly = pa.as<CGAL::Polygon_with_holes_2<Kernel> >();
+ const CGAL::Segment_2<Kernel>* seg = pb.as<CGAL::Segment_2<Kernel> >();
+
+ // shortcut for triangle
+ if ( poly->holes_begin() == poly->holes_end() && poly->outer_boundary().size() == 3 ) {
+ // no holes and 3 vertices => it is a triangle
+ CGAL::Polygon_2<Kernel>::Vertex_iterator vit = poly->outer_boundary().vertices_begin();
+ CGAL::Point_2<Kernel> p1( *vit++ );
+ CGAL::Point_2<Kernel> p2( *vit++ );
+ CGAL::Point_2<Kernel> p3( *vit++ );
+ CGAL::Triangle_2<Kernel> tri( p1, p2, p3 );
+ CGAL::Object interObj = CGAL::intersection( tri, *seg );
+ output.addPrimitive( interObj );
+ return;
+ }
+
+ // if it s a regulat polygon, triangulate it and recurse call
+ GeometrySet<2> triangles, g;
+ triangulate::triangulate( *poly, triangles );
+ g.addPrimitive( pb );
+
+ // recurse call
+ algorithm::intersection( triangles, g, output );
+ }
+}
+} // algorithm
+} // SFCGAL
diff --git a/src/algorithm/Intersection3D.cpp b/src/algorithm/Intersection3D.cpp
new file mode 100644
index 0000000..2481eb7
--- /dev/null
+++ b/src/algorithm/Intersection3D.cpp
@@ -0,0 +1,350 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <CGAL/intersections.h>
+
+#include <CGAL/intersection_of_Polyhedra_3.h>
+#include <CGAL/intersection_of_Polyhedra_3_refinement_visitor.h>
+#include <CGAL/corefinement_operations.h>
+
+#include <SFCGAL/detail/GeometrySet.h>
+#include <SFCGAL/algorithm/intersects.h>
+#include <SFCGAL/algorithm/intersection.h>
+#include <SFCGAL/detail/triangulate/triangulateInGeometrySet.h>
+
+#include <CGAL/IO/Polyhedron_iostream.h>
+
+#include <CGAL/Point_inside_polyhedron_3.h>
+
+using namespace SFCGAL::detail;
+
+namespace SFCGAL {
+namespace algorithm {
+
+void _intersection_solid_segment( const PrimitiveHandle<3>& pa, const PrimitiveHandle<3>& pb, GeometrySet<3>& output )
+{
+ //typedef CGAL::Polyhedral_mesh_domain_3<MarkedPolyhedron, Kernel> Mesh_domain;
+
+ const MarkedPolyhedron* ext_poly = pa.as<MarkedPolyhedron>();
+ BOOST_ASSERT( ext_poly->is_closed() );
+ const CGAL::Segment_3<Kernel>* segment = pb.as<CGAL::Segment_3<Kernel> >();
+
+ MarkedPolyhedron* ext_poly_nc = const_cast<MarkedPolyhedron*>( ext_poly );
+ CGAL::Point_inside_polyhedron_3<MarkedPolyhedron, Kernel> is_in_ext( *ext_poly_nc );
+
+ GeometrySet<3> triangles;
+ GeometrySet<3> spoint( segment->source() );
+ GeometrySet<3> tpoint( segment->target() );
+ triangulate::triangulate( *ext_poly, triangles );
+
+ bool source_inside = ( is_in_ext( segment->source() ) != CGAL::ON_UNBOUNDED_SIDE ) || intersects( triangles, spoint );
+ bool target_inside = ( is_in_ext( segment->target() ) != CGAL::ON_UNBOUNDED_SIDE ) || intersects( triangles, tpoint );
+
+ if ( source_inside && target_inside ) {
+ // the entire segment intersects the volume, return the segment
+ output.addPrimitive( pb );
+ }
+ else {
+ GeometrySet<3> triangles, g;
+ triangulate::triangulate( *ext_poly, triangles );
+ g.addPrimitive( pb );
+ GeometrySet<3> inter;
+
+ // call recursively on triangulated polyhedron
+ intersection( g, triangles, inter );
+
+ if ( ! inter.points().empty() ) {
+ // the intersection is a point, build a segment from that point to the other end
+ if ( !source_inside && target_inside ) {
+ CGAL::Segment_3<Kernel> interSeg( inter.points().begin()->primitive(),
+ segment->target() );
+
+ if ( interSeg.source() == interSeg.target() ) {
+ output.addPrimitive( segment->target() );
+ }
+ else {
+ output.addPrimitive( interSeg );
+ }
+ }
+ else if ( source_inside && !target_inside ) {
+ CGAL::Segment_3<Kernel> interSeg( segment->source(),
+ inter.points().begin()->primitive() );
+
+ if ( interSeg.source() == interSeg.target() ) {
+ output.addPrimitive( segment->source() );
+ }
+ else {
+ output.addPrimitive( interSeg );
+ }
+ }
+ else { // !source_inside && !target_inside => intersection on a point
+ output.addPrimitive( inter.points().begin()->primitive() );
+ }
+ }
+
+ if ( ! inter.segments().empty() ) {
+ // the intersection is a segment
+ output.addPrimitive( inter.segments().begin()->primitive() );
+ }
+ }
+}
+
+
+#if CGAL_VERSION_NR < 1040301000 // version 4.3
+// Before 4.3, we pass CGAL::Tag_true to mark boundary halfedges
+typedef CGAL::Node_visitor_refine_polyhedra<MarkedPolyhedron, Kernel, CGAL::Tag_true> Split_visitor;
+#else
+// Starting with 4.3, we must now pass a property_map
+template<class Polyhedron>
+struct Edge_mark_property_map {
+ typedef bool value_type;
+ typedef value_type reference;
+ typedef std::pair<typename Polyhedron::Halfedge_handle,Polyhedron*> key_type;
+ typedef boost::read_write_property_map_tag category;
+
+ friend reference get( Edge_mark_property_map,const key_type& key ) {
+ return key.first->mark;
+ }
+ friend void put( Edge_mark_property_map,key_type key,value_type v ) {
+ key.first->mark=v;
+ }
+};
+typedef CGAL::Node_visitor_refine_polyhedra<MarkedPolyhedron,Kernel,Edge_mark_property_map<MarkedPolyhedron> > Split_visitor;
+#endif
+
+typedef std::vector<Kernel::Point_3> Polyline_3;
+
+struct Is_not_marked {
+ bool operator()( MarkedPolyhedron::Halfedge_const_handle h ) const {
+ return !h->mark;
+ }
+};
+
+void _intersection_solid_triangle( const MarkedPolyhedron& pa, const CGAL::Triangle_3<Kernel>& tri, GeometrySet<3>& output )
+{
+ BOOST_ASSERT( pa.is_closed() );
+ Split_visitor visitor( NULL, true );
+
+ MarkedPolyhedron polyb;
+ polyb.make_triangle( tri.vertex( 0 ), tri.vertex( 1 ), tri.vertex( 2 ) );
+
+ MarkedPolyhedron& polya = const_cast<MarkedPolyhedron&>( pa );
+ std::list<Polyline_3> polylines;
+ CGAL::Intersection_of_Polyhedra_3<MarkedPolyhedron,Kernel, Split_visitor> intersect_polys( visitor );
+ intersect_polys( polya, polyb, std::back_inserter( polylines ) );
+
+ CGAL::Point_inside_polyhedron_3<MarkedPolyhedron, Kernel> point_inside_q( polya );
+
+ if ( polylines.size() == 0 ) {
+ // no surface intersection
+ // if one of the point of the triangle is inside the polyhedron,
+ // the triangle is inside
+ if ( point_inside_q( tri.vertex( 0 ) ) != CGAL::ON_UNBOUNDED_SIDE ) {
+ output.addPrimitive( tri );
+ return;
+ }
+
+ return;
+ }
+
+ // triangle decomposition
+ std::list<MarkedPolyhedron> decomposition;
+ Is_not_marked criterion;
+ CGAL::internal::extract_connected_components( polyb, criterion, std::back_inserter( decomposition ) );
+
+ bool hasSurface = false;
+
+ for ( std::list<MarkedPolyhedron>::iterator it = decomposition.begin(); it != decomposition.end(); ++it ) {
+ // char fname[256];
+ // sprintf(fname, "decompo%d.off", k++);
+ // std::ofstream decompo(fname);
+ // decompo << *it;
+
+ // take a point on the component and tests if its inside the other polyhedron
+ //
+ CGAL::Point_3<Kernel> test_point;
+
+ if ( it->size_of_facets() == 1 ) {
+ //
+ // If we only have a facet, take the centroid (cannot take a point on the intersection)
+ CGAL::Point_3<Kernel> q[3];
+ MarkedPolyhedron::Point_iterator pit = it->points_begin();
+
+ for ( size_t i = 0; i < 3; ++i, ++pit ) {
+ q[i] = *pit;
+ }
+
+ test_point = CGAL::centroid( q[0], q[1], q[2] );
+ }
+ else {
+ //
+ // Take a point not an the border
+ for ( MarkedPolyhedron::Halfedge_iterator hit = it->halfedges_begin(); hit != it->halfedges_end(); ++hit ) {
+ if ( !hit->is_border_edge() ) {
+ // take the center of the edge
+ test_point = CGAL::midpoint( hit->vertex()->point(), hit->prev()->vertex()->point() );
+ break;
+ }
+ }
+ }
+
+ // point inside volume or on surface
+ bool point_is_inside = false;
+ // on surface test
+ {
+ // triangulate the polyhedron
+ GeometrySet<3> triangles;
+ GeometrySet<3> point( test_point );
+
+ triangulate::triangulate( polya, triangles );
+ bool point_on_surface = intersects( triangles, point );
+
+ if ( point_on_surface ) {
+ point_is_inside = true;
+ }
+ else {
+ // strictly inside test
+ bool point_inside_volume = point_inside_q( test_point ) != CGAL::ON_UNBOUNDED_SIDE;
+
+ if ( point_inside_volume ) {
+ point_is_inside = true;
+ }
+ }
+ }
+
+ if ( point_is_inside ) {
+ // we know it is a planar intersection
+ hasSurface = true;
+ output.addPrimitive( *it, FLAG_IS_PLANAR );
+ }
+ }
+
+ if ( hasSurface ) {
+ return;
+ }
+
+ for ( std::list<Polyline_3>::const_iterator lit = polylines.begin(); lit != polylines.end(); ++lit ) {
+ if ( lit->size() == 1 ) {
+ // it's a point
+ output.addPrimitive( ( *lit )[0] );
+ }
+ else {
+ for ( size_t k = 1; k < lit->size(); ++k ) {
+ CGAL::Segment_3<Kernel> seg( ( *lit )[k-1], ( *lit )[k] );
+ output.addPrimitive( seg );
+ }
+ }
+ }
+}
+
+void _intersection_solid_solid( const MarkedPolyhedron& pa, const MarkedPolyhedron& pb, GeometrySet<3>& output )
+{
+ // 1. find intersections on surfaces
+ // CGAL corefinement or polyhedra_intersection do not return polygon intersections between two solids
+ // they only return points, lines and volumes (but no surfaces ...)
+ {
+ // call CGAL::intersection on triangles
+ GeometrySet<3> gsa, gsb;
+ // convert polyhedra to geometry sets
+ // (no actual triangulation is done if the polyhedra are pure_triangle()
+ triangulate::triangulate( pa, gsa );
+ triangulate::triangulate( pb, gsb );
+ // "recurse" call on triangles
+ algorithm::intersection( gsa, gsb, output );
+ }
+
+ // 2. find intersections in volumes
+ {
+ typedef CGAL::Polyhedron_corefinement<MarkedPolyhedron> Corefinement;
+ MarkedPolyhedron& polya = const_cast<MarkedPolyhedron&>( pa );
+ MarkedPolyhedron& polyb = const_cast<MarkedPolyhedron&>( pb );
+
+ Corefinement coref;
+ CGAL::Emptyset_iterator no_polylines;
+ // vector of <Polyhedron, tag>
+ typedef std::vector<std::pair<MarkedPolyhedron*, int> > Decomposition;
+ Decomposition result;
+ coref( polya, polyb, no_polylines, std::back_inserter( result ), Corefinement::Intersection_tag );
+
+ // empty intersection
+ if ( result.size() == 0 ) {
+ return ;
+ }
+
+ // else, we have an intersection
+ MarkedPolyhedron* res_poly = result[0].first;
+ output.addPrimitive( *res_poly );
+ delete res_poly;
+ }
+}
+
+//
+// must be called with pa's dimension larger than pb's
+void intersection( const PrimitiveHandle<3>& pa, const PrimitiveHandle<3>& pb,
+ GeometrySet<3>& output, dim_t<3> )
+{
+ // everything vs a point
+ if ( pb.handle.which() == PrimitivePoint ) {
+ if ( algorithm::intersects( pa, pb ) ) {
+ output.addPrimitive( *boost::get<const TypeForDimension<3>::Point*>( pb.handle ) );
+ }
+ }
+ else if ( pa.handle.which() == PrimitiveSegment && pb.handle.which() == PrimitiveSegment ) {
+ const CGAL::Segment_3<Kernel>* seg1 = pa.as<CGAL::Segment_3<Kernel> >();
+ const CGAL::Segment_3<Kernel>* seg2 = pb.as<CGAL::Segment_3<Kernel> >();
+ CGAL::Object interObj = CGAL::intersection( *seg1, *seg2 );
+ output.addPrimitive( interObj );
+ }
+ else if ( pa.handle.which() == PrimitiveSurface ) {
+ const CGAL::Triangle_3<Kernel>* tri1 = pa.as<CGAL::Triangle_3<Kernel> >();
+
+ if ( pb.handle.which() == PrimitiveSegment ) {
+ const CGAL::Segment_3<Kernel>* seg2 = pb.as<CGAL::Segment_3<Kernel> >();
+ CGAL::Object interObj = CGAL::intersection( *tri1, *seg2 );
+ output.addPrimitive( interObj );
+ }
+ else if ( pb.handle.which() == PrimitiveSurface ) {
+ const CGAL::Triangle_3<Kernel>* tri2 = pb.as<CGAL::Triangle_3<Kernel> >();
+ CGAL::Object interObj = CGAL::intersection( *tri1, *tri2 );
+ output.addPrimitive( interObj, /* pointsAsRing */ true );
+ }
+ }
+ else if ( pa.handle.which() == PrimitiveVolume ) {
+ if ( pb.handle.which() == PrimitiveSegment ) {
+ _intersection_solid_segment( pa, pb, output );
+ }
+ else if ( pb.handle.which() == PrimitiveSurface ) {
+ _intersection_solid_triangle( *pa.as<MarkedPolyhedron>(),
+ *pb.as<CGAL::Triangle_3<Kernel> >(),
+ output );
+ }
+ else if ( pb.handle.which() == PrimitiveVolume ) {
+ const MarkedPolyhedron& sa = *pa.as<MarkedPolyhedron>();
+ const MarkedPolyhedron& sb = *pb.as<MarkedPolyhedron>();
+ BOOST_ASSERT( sa.is_closed() );
+ BOOST_ASSERT( sb.is_closed() );
+ _intersection_solid_solid( sa, sb, output );
+ }
+ }
+}
+
+} // algorithm
+} // SFCGAL
diff --git a/src/algorithm/area.cpp b/src/algorithm/area.cpp
new file mode 100644
index 0000000..29cd42d
--- /dev/null
+++ b/src/algorithm/area.cpp
@@ -0,0 +1,359 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/area.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+
+#include <SFCGAL/algorithm/plane.h>
+#include <SFCGAL/algorithm/isValid.h>
+
+#include <CGAL/Point_2.h>
+#include <CGAL/Triangle_2.h>
+#include <CGAL/Polygon_2.h>
+
+#include <CGAL/Point_3.h>
+#include <CGAL/Triangle_3.h>
+#include <CGAL/Plane_3.h>
+
+#include <SFCGAL/Exception.h>
+#include <boost/format.hpp>
+
+namespace SFCGAL {
+namespace algorithm {
+
+typedef CGAL::Point_2< SFCGAL::Kernel > Point_2 ;
+typedef CGAL::Triangle_2< SFCGAL::Kernel > Triangle_2 ;
+typedef CGAL::Polygon_2< SFCGAL::Kernel > Polygon_2 ;
+
+typedef CGAL::Point_3< SFCGAL::Kernel > Point_3 ;
+typedef CGAL::Triangle_3< SFCGAL::Kernel > Triangle_3 ;
+typedef CGAL::Plane_3< SFCGAL::Kernel > Plane_3 ;
+
+
+///
+///
+///
+double area( const Geometry& g, NoValidityCheck )
+{
+ switch ( g.geometryTypeId() ) {
+ case TYPE_POINT:
+ case TYPE_LINESTRING:
+ return 0 ;
+
+ case TYPE_POLYGON:
+ return area( g.as< Polygon >() ) ;
+
+ case TYPE_TRIANGLE:
+ return area( g.as< Triangle >() ) ;
+
+ case TYPE_MULTIPOINT:
+ case TYPE_MULTILINESTRING:
+ case TYPE_MULTIPOLYGON:
+ case TYPE_GEOMETRYCOLLECTION:
+ return area( g.as< GeometryCollection >() ) ;
+
+ case TYPE_TRIANGULATEDSURFACE:
+ return area( g.as< TriangulatedSurface >() ) ;
+
+ case TYPE_POLYHEDRALSURFACE:
+ return area( g.as< PolyhedralSurface >() ) ;
+
+ case TYPE_SOLID:
+ case TYPE_MULTISOLID:
+ return 0 ;
+ }
+
+ BOOST_THROW_EXCEPTION( Exception(
+ ( boost::format( "Unexpected geometry type (%s) in SFCGAL::algorithm::area" ) % g.geometryType() ).str()
+ ) );
+}
+
+double area( const Geometry& g )
+{
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_2D( g );
+ return area( g, NoValidityCheck() );
+}
+
+///
+///
+///
+Kernel::FT signedArea( const Triangle& g )
+{
+ Triangle_2 triangle = g.toTriangle_2() ;
+ return triangle.area() ;
+}
+
+///
+///
+///
+Kernel::FT signedArea( const LineString& g )
+{
+ return g.toPolygon_2( false ).area() ;
+}
+
+///
+///
+///
+double area( const Triangle& g )
+{
+ return CGAL::to_double( CGAL::abs( signedArea( g ) ) ) ;
+}
+
+///
+///
+///
+double area( const Polygon& g )
+{
+ Kernel::RT result = 0.0 ;
+
+ for ( size_t i = 0; i < g.numRings(); i++ ) {
+ Kernel::FT ringArea = CGAL::abs( signedArea( g.ringN( i ) ) ) ;
+
+ if ( i == 0 ) {
+ //exterior ring
+ result += CGAL::abs( ringArea );
+ }
+ else {
+ //interior ring
+ result -= CGAL::abs( ringArea );
+ }
+ }
+
+ return CGAL::to_double( result ) ;
+}
+
+
+///
+///
+///
+double area( const GeometryCollection& g )
+{
+ double result = 0.0 ;
+
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ result += area( g.geometryN( i ) ) ;
+ }
+
+ return result ;
+}
+
+///
+///
+///
+double area( const TriangulatedSurface& g )
+{
+ double result = 0.0 ;
+
+ for ( size_t i = 0; i < g.numTriangles(); i++ ) {
+ result += area( g.triangleN( i ) ) ;
+ }
+
+ return result ;
+}
+
+///
+///
+///
+double area( const PolyhedralSurface& g )
+{
+ double result = 0.0 ;
+
+ for ( size_t i = 0; i < g.numPolygons(); i++ ) {
+ result += area( g.polygonN( i ) ) ;
+ }
+
+ return result ;
+}
+
+
+///----------------------------------------------------------------------------------
+/// -- area3D
+///----------------------------------------------------------------------------------
+
+
+///
+///
+///
+double area3D( const Geometry& g, NoValidityCheck )
+{
+ switch ( g.geometryTypeId() ) {
+ case TYPE_POINT:
+ case TYPE_LINESTRING:
+ return 0 ;
+
+ case TYPE_POLYGON:
+ return area3D( g.as< Polygon >() );
+
+ case TYPE_TRIANGLE:
+ return area3D( g.as< Triangle >() );
+
+ case TYPE_MULTIPOINT:
+ case TYPE_MULTILINESTRING:
+ case TYPE_MULTIPOLYGON:
+ case TYPE_GEOMETRYCOLLECTION:
+ return area3D( g.as< GeometryCollection >() );
+
+ case TYPE_TRIANGULATEDSURFACE:
+ return area3D( g.as< TriangulatedSurface >() );
+
+ case TYPE_POLYHEDRALSURFACE:
+ return area3D( g.as< PolyhedralSurface >() );
+
+ case TYPE_SOLID:
+ case TYPE_MULTISOLID:
+ return 0 ;
+ }
+
+ BOOST_THROW_EXCEPTION( Exception( "missing case in SFCGAL::algorithm::area3D" ) );
+}
+
+double area3D( const Geometry& g )
+{
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_3D( g );
+ return area3D( g, NoValidityCheck() );
+}
+///
+///
+///
+double area3D( const Polygon& g )
+{
+ double result = 0.0 ;
+
+ if ( g.isEmpty() ) {
+ return result ;
+ }
+
+ CGAL::Point_3< Kernel > a, b, c ;
+ algorithm::plane3D< Kernel >( g, a, b, c );
+
+ /*
+ * compute polygon basis (CGAL doesn't build an orthonormal basis so that computing
+ * the 2D area in this basis would lead to scale effects)
+ * ux = bc
+ * uz = bc^ba
+ * uy = uz^ux
+ *
+ * Note that the basis is rounded to double (CGAL::sqrt)
+ */
+ CGAL::Vector_3< Kernel > ux = c - b ;
+ CGAL::Vector_3< Kernel > uz = CGAL::cross_product( ux, a - b ) ;
+ ux = ux / CGAL::sqrt( CGAL::to_double( ux.squared_length() ) ) ;
+ uz = uz / CGAL::sqrt( CGAL::to_double( uz.squared_length() ) ) ;
+ CGAL::Vector_3< Kernel > uy = CGAL::cross_product( uz, ux );
+
+ /*
+ * compute the area for each ring in the local basis
+ */
+ for ( size_t i = 0; i < g.numRings(); i++ ) {
+ const LineString& ring = g.ringN( i );
+
+ CGAL::Polygon_2< Kernel > projectedPolygon;
+
+ for ( size_t j = 0; j < ring.numPoints() - 1 ; j++ ) {
+ CGAL::Point_3< Kernel > point = ring.pointN( j ).toPoint_3();
+ CGAL::Point_2< Kernel > projectedPoint(
+ ( point - b ) * ux,
+ ( point - b ) * uy
+ );
+ projectedPolygon.push_back( projectedPoint );
+ }
+
+ if ( i == 0 ) {
+ //exterior ring
+ result += CGAL::to_double( CGAL::abs( projectedPolygon.area() ) ) ;
+ }
+ else {
+ //interior ring
+ result -= CGAL::to_double( CGAL::abs( projectedPolygon.area() ) ) ;
+ }
+ }
+
+ return result ;
+}
+
+///
+///
+///
+double area3D( const Triangle& g )
+{
+ CGAL::Triangle_3< Kernel > triangle(
+ g.vertex( 0 ).toPoint_3(),
+ g.vertex( 1 ).toPoint_3(),
+ g.vertex( 2 ).toPoint_3()
+ );
+ return sqrt( CGAL::to_double( triangle.squared_area() ) ) ;
+}
+
+
+///
+///
+///
+double area3D( const GeometryCollection& g )
+{
+ double result = 0.0 ;
+
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ result += area3D( g.geometryN( i ) ) ;
+ }
+
+ return result ;
+}
+
+///
+///
+///
+double area3D( const PolyhedralSurface& g )
+{
+ double area = 0.0 ;
+
+ for ( size_t i = 0; i < g.numPolygons(); i++ ) {
+ area += area3D( g.polygonN( i ) ) ;
+ }
+
+ return area ;
+}
+
+///
+///
+///
+double area3D( const TriangulatedSurface& g )
+{
+ double result = 0.0 ;
+
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ result += area3D( g.geometryN( i ) ) ;
+ }
+
+ return result ;
+}
+
+
+}//algorithm
+}//SFCGAL
+
+
diff --git a/src/algorithm/area.h b/src/algorithm/area.h
new file mode 100644
index 0000000..b2aceac
--- /dev/null
+++ b/src/algorithm/area.h
@@ -0,0 +1,142 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_ALGORITHM_AREA_H_
+#define _SFCGAL_ALGORITHM_AREA_H_
+
+#include <SFCGAL/Geometry.h>
+#include <SFCGAL/Kernel.h>
+
+namespace SFCGAL {
+namespace algorithm {
+struct NoValidityCheck;
+
+/**
+ * @brief Compute the 2D area for a Geometry
+ * @ingroup public_api
+ * @warning Z component is ignored, there is no 2D projection for 3D geometries
+ * @ingroup public_api
+ * @pre g is a valid geometry
+ */
+SFCGAL_API double area( const Geometry& g ) ;
+
+/**
+ * @brief Compute the 2D area for a Geometry
+ *
+ * @warning Z component is ignored, there is no 2D projection for 3D geometries
+ * @ingroup detail
+ * @pre g is a valid geometry
+ * @warning No actual validity check is done
+ */
+SFCGAL_API double area( const Geometry& g, NoValidityCheck ) ;
+
+/**
+ * @brief Compute the 2D signed area for a Triangle
+ * @ingroup detail
+ */
+SFCGAL_API Kernel::FT signedArea( const Triangle& g );
+/**
+ * @brief Compute the 2D signed area for a closed LineString
+ * @ingroup detail
+ */
+SFCGAL_API Kernel::FT signedArea( const LineString& g );
+
+/**
+ * Returns Compute the 2D area for a Triangle
+ * @ingroup detail
+ */
+SFCGAL_API double area( const Triangle& g ) ;
+/**
+ * Returns Compute the 2D area for a Polygon
+ * @ingroup detail
+ */
+SFCGAL_API double area( const Polygon& g ) ;
+/**
+ * Returns the 2D area for a GeometryCollection
+ * @ingroup detail
+ */
+SFCGAL_API double area( const GeometryCollection& g ) ;
+/**
+ * Returns the 2D area for a TriangulatedSurface
+ * @ingroup detail
+ */
+SFCGAL_API double area( const TriangulatedSurface& g ) ;
+/**
+ * Returns the 2D area for a TriangulatedSurface
+ * @ingroup detail
+ */
+SFCGAL_API double area( const PolyhedralSurface& g ) ;
+
+
+/**
+ * Returns 3D area for a Geometry
+ * @ingroup public_api
+ * @warning Solid area is set to 0 (might be defined as the area of the surface)
+ * @ingroup public_api
+ * @pre g is a valid geometry
+ */
+SFCGAL_API double area3D( const Geometry& g ) ;
+
+/**
+ * Returns 3D area for a Geometry
+ *
+ * @warning Solid area is set to 0 (might be defined as the area of the surface)
+ * @ingroup detail
+ * @pre g is a valid geometry
+ * @warning No actual validity check is done
+ */
+SFCGAL_API double area3D( const Geometry& g, NoValidityCheck ) ;
+
+/**
+ * Returns 3D area for a Polygon
+ * @ingroup detail
+ */
+SFCGAL_API double area3D( const Polygon& g ) ;
+/**
+ * Returns the 3D area for a MultiPolygon
+ * @ingroup detail
+ */
+SFCGAL_API double area3D( const GeometryCollection& g ) ;
+
+/**
+ * Returns the 3D area for a PolyhedralSurface
+ * @ingroup detail
+ */
+SFCGAL_API double area3D( const PolyhedralSurface& g ) ;
+
+/**
+ * Returns the 3D area for a Triangle
+ * @ingroup detail
+ */
+SFCGAL_API double area3D( const Triangle& g ) ;
+
+/**
+ * Returns the 3D area for a TriangulatedSurface
+ * @ingroup detail
+ */
+SFCGAL_API double area3D( const TriangulatedSurface& g ) ;
+
+
+
+}//algorithm
+}//SFCGAL
+
+
+#endif
diff --git a/src/algorithm/collect.cpp b/src/algorithm/collect.cpp
new file mode 100644
index 0000000..764a380
--- /dev/null
+++ b/src/algorithm/collect.cpp
@@ -0,0 +1,67 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/collect.h>
+
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+namespace SFCGAL {
+namespace algorithm {
+std::auto_ptr<Geometry> collect( const Geometry& ga, const Geometry& gb )
+{
+ if ( ga.geometryTypeId() == gb.geometryTypeId() ) {
+ if ( ga.geometryTypeId() == TYPE_POINT ) {
+ MultiPoint* mp = new MultiPoint;
+ mp->addGeometry( ga );
+ mp->addGeometry( gb );
+ return std::auto_ptr<Geometry>( mp );
+ }
+ else if ( ga.geometryTypeId() == TYPE_LINESTRING ) {
+ MultiLineString* mls = new MultiLineString();
+ mls->addGeometry( ga );
+ mls->addGeometry( gb );
+ return std::auto_ptr<Geometry>( mls );
+ }
+ else if ( ga.geometryTypeId() == TYPE_POLYGON ) {
+ MultiPolygon* mp = new MultiPolygon();
+ mp->addGeometry( ga );
+ mp->addGeometry( gb );
+ return std::auto_ptr<Geometry>( mp );
+ }
+ else if ( ga.geometryTypeId() == TYPE_SOLID ) {
+ MultiSolid* mp = new MultiSolid();
+ mp->addGeometry( ga );
+ mp->addGeometry( gb );
+ return std::auto_ptr<Geometry>( mp );
+ }
+ }
+
+ // else
+ GeometryCollection* coll = new GeometryCollection();
+ coll->addGeometry( ga );
+ coll->addGeometry( gb );
+ return std::auto_ptr<Geometry>( coll );
+}
+}
+}
diff --git a/src/algorithm/collect.h b/src/algorithm/collect.h
new file mode 100644
index 0000000..d428d68
--- /dev/null
+++ b/src/algorithm/collect.h
@@ -0,0 +1,57 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SFCGAL_COLLECT_ALGORITHM
+#define SFCGAL_COLLECT_ALGORITHM
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Geometry.h>
+#include <SFCGAL/GeometryCollection.h>
+
+namespace SFCGAL {
+namespace algorithm {
+/**
+ * Returns an aggregate of ga and gb
+ * @ingroup detail
+ */
+SFCGAL_API std::auto_ptr<Geometry> collect( const Geometry& ga, const Geometry& gb );
+
+/**
+ * Returns an aggregate of a list of geometries
+ * @ingroup detail
+ */
+template <typename GeometryIterator>
+std::auto_ptr<Geometry> collect( GeometryIterator begin, GeometryIterator end )
+{
+ GeometryIterator it;
+ // FIXME: optimize type. For instance, if all the given geometries are points, return a MultiPoint instead of a GeometryCollection
+ GeometryCollection* coll = new GeometryCollection();
+
+ for ( it = begin; it != end; ++it ) {
+ coll->addGeometry( *it );
+ }
+
+ return std::auto_ptr<Geometry>( coll );
+}
+}
+}
+
+#endif
diff --git a/src/algorithm/collectionExtract.cpp b/src/algorithm/collectionExtract.cpp
new file mode 100644
index 0000000..1af8146
--- /dev/null
+++ b/src/algorithm/collectionExtract.cpp
@@ -0,0 +1,91 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/collectionExtract.h>
+
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+#include <SFCGAL/detail/transform/ForceZ.h>
+
+namespace SFCGAL {
+namespace algorithm {
+
+// Use of auto_ptr :
+// If nothing has to be built, g will be moved to the result without copy and new allocation.
+// Otherwise, a new geometry is built and the old one is deleted
+std::auto_ptr<Geometry> collectionExtractPolygons( std::auto_ptr<Geometry> g )
+{
+ if ( ! g->is<GeometryCollection>() ) {
+ // not a collection, nothing to do
+ return g;
+ }
+
+ const GeometryCollection& coll = g->as<GeometryCollection>();
+
+ // if it is empty, do not do anything
+ if ( coll.isEmpty() ) {
+ return g;
+ }
+
+ MultiPolygon* ret_geo = new MultiPolygon;
+
+ // copy each geometry
+ for ( size_t i = 0; i < coll.numGeometries(); ++i ) {
+
+ Geometry* gi = coll.geometryN( i ).clone();
+
+ switch ( gi->geometryTypeId() ) {
+ case TYPE_TRIANGLE:
+ ret_geo->addGeometry( Polygon( gi->as<Triangle>() ) );
+ break;
+
+ case TYPE_TRIANGULATEDSURFACE: {
+ for ( size_t j = 0; j < gi->numGeometries(); ++j ) {
+ ret_geo->addGeometry( Polygon( gi->geometryN( j ).as<Triangle>() ) );
+ }
+ }
+ break;
+
+ case TYPE_POLYHEDRALSURFACE: {
+ for ( size_t j = 0; j < gi->numGeometries(); ++j ) {
+ ret_geo->addGeometry( gi->geometryN( j ) );
+ }
+ }
+ break;
+
+ case TYPE_POLYGON:
+ ret_geo->addGeometry( *gi );
+ break;
+
+ default:
+ // nothing
+ break;
+ }
+ }
+
+ return std::auto_ptr<Geometry>( ret_geo );
+}
+
+}
+}
diff --git a/src/algorithm/collectionExtract.h b/src/algorithm/collectionExtract.h
new file mode 100644
index 0000000..6fba9e8
--- /dev/null
+++ b/src/algorithm/collectionExtract.h
@@ -0,0 +1,42 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SFCGAL_COLLECTION_EXTRACT_ALGORITHM
+#define SFCGAL_COLLECTION_EXTRACT_ALGORITHM
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Geometry.h>
+#include <SFCGAL/GeometryCollection.h>
+
+namespace SFCGAL {
+namespace algorithm {
+/*
+ * Given a geometry collection
+ * returns a MultiPolygon from triangles, polygons, polyhedral and polygons
+ *
+ * @warning Ownership is taken from the parameter
+ * @ingroup detail
+ */
+SFCGAL_API std::auto_ptr<Geometry> collectionExtractPolygons( std::auto_ptr<Geometry> coll );
+}
+}
+
+#endif
diff --git a/src/algorithm/collectionHomogenize.cpp b/src/algorithm/collectionHomogenize.cpp
new file mode 100644
index 0000000..8b5acd2
--- /dev/null
+++ b/src/algorithm/collectionHomogenize.cpp
@@ -0,0 +1,95 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/collectionHomogenize.h>
+
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+namespace SFCGAL {
+namespace algorithm {
+
+// Use of auto_ptr :
+// If nothing has to be built, g will be moved to the result without copy and new allocation.
+// Otherwise, a new geometry is built and the old one is deleted
+std::auto_ptr<Geometry> collectionHomogenize( std::auto_ptr<Geometry> g )
+{
+ // unknown type
+ int common_type = 0;
+
+ if ( ! g->is<GeometryCollection>() ) {
+ // not a collection, nothing to do
+ return g;
+ }
+
+ const GeometryCollection& coll = g->as<GeometryCollection>();
+
+ // test if it is a singleton
+ if ( coll.numGeometries() == 1 ) {
+ return std::auto_ptr<Geometry>( coll.geometryN( 0 ).clone() );
+ }
+
+ for ( size_t i = 0; i < coll.numGeometries(); ++i ) {
+ const Geometry& gi = coll.geometryN( i );
+
+ if ( common_type == 0 ) {
+ common_type = gi.geometryTypeId();
+ continue;
+ }
+
+ if ( gi.geometryTypeId() != common_type ) {
+ common_type = 0;
+ break;
+ }
+ }
+
+ if ( common_type == 0 ) {
+ // not an homogeneous collection, give back
+ return g;
+ }
+
+ GeometryCollection* ret_geo = 0;
+
+ if ( common_type == TYPE_POINT ) {
+ ret_geo = new MultiPoint;
+ }
+ else if ( common_type == TYPE_LINESTRING ) {
+ ret_geo = new MultiLineString;
+ }
+ else if ( common_type == TYPE_POLYGON ) {
+ ret_geo = new MultiPolygon;
+ }
+ else if ( common_type == TYPE_SOLID ) {
+ ret_geo = new MultiSolid;
+ }
+
+ // copy each geometry
+ for ( size_t i = 0; i < coll.numGeometries(); ++i ) {
+ ret_geo->addGeometry( coll.geometryN( i ) );
+ }
+
+ return std::auto_ptr<Geometry>( ret_geo );
+}
+
+}
+}
diff --git a/src/algorithm/collectionHomogenize.h b/src/algorithm/collectionHomogenize.h
new file mode 100644
index 0000000..9851723
--- /dev/null
+++ b/src/algorithm/collectionHomogenize.h
@@ -0,0 +1,45 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SFCGAL_COLLECTION_HOMOGENIZE_ALGORITHM
+#define SFCGAL_COLLECTION_HOMOGENIZE_ALGORITHM
+
+#include <SFCGAL/config.h>
+
+#include <memory>
+
+#include <SFCGAL/Geometry.h>
+#include <SFCGAL/GeometryCollection.h>
+
+namespace SFCGAL {
+namespace algorithm {
+/**
+ * Given a geometry collection, returns the "simplest" representation of the contents.
+ * Singletons will be returned as singletons.
+ * Collections that are homogeneous will be returned as the appropriate multi-type.
+ *
+ * @warning Ownership is taken from the parameter
+ * @ingroup detail
+ */
+SFCGAL_API std::auto_ptr<Geometry> collectionHomogenize( std::auto_ptr<Geometry> coll );
+}
+}
+
+#endif
diff --git a/src/algorithm/collectionToMulti.cpp b/src/algorithm/collectionToMulti.cpp
new file mode 100644
index 0000000..80b5feb
--- /dev/null
+++ b/src/algorithm/collectionToMulti.cpp
@@ -0,0 +1,123 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/collectionToMulti.h>
+
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+#include <SFCGAL/detail/transform/ForceZ.h>
+
+namespace SFCGAL {
+namespace algorithm {
+
+// Use of auto_ptr :
+// If nothing has to be built, g will be moved to the result without copy and new allocation.
+// Otherwise, a new geometry is built and the old one is deleted
+std::auto_ptr<Geometry> collectionToMulti( std::auto_ptr<Geometry> g )
+{
+ if ( ! g->is<GeometryCollection>() ) {
+ // not a collection, nothing to do
+ return g;
+ }
+
+ const GeometryCollection& coll = g->as<GeometryCollection>();
+
+ // if it is empty, do not do anything
+ if ( coll.isEmpty() ) {
+ return g;
+ }
+
+ bool has2d = false;
+ bool has3d = false;
+
+ for ( size_t i = 0; i < coll.numGeometries(); ++i ) {
+ const Geometry& gi = coll.geometryN( i );
+
+ if ( !has3d && gi.is3D() ) {
+ has3d = true;
+ }
+
+ if ( !has2d && !gi.is3D() ) {
+ has2d = true;
+ }
+
+ if ( !gi.isEmpty() && ( gi.geometryTypeId() != TYPE_POLYGON ) &&
+ ( gi.geometryTypeId() != TYPE_TRIANGLE ) &&
+ ( gi.geometryTypeId() != TYPE_POLYHEDRALSURFACE ) &&
+ ( gi.geometryTypeId() != TYPE_TRIANGULATEDSURFACE ) ) {
+ // it contains a bad type, abort
+ return g;
+ }
+ }
+
+ bool force3d = has2d && has3d;
+
+ MultiPolygon* ret_geo = new MultiPolygon;
+
+ // copy each geometry
+ for ( size_t i = 0; i < coll.numGeometries(); ++i ) {
+
+ Geometry* gi = coll.geometryN( i ).clone();
+
+ if ( force3d && !gi->is3D() ) {
+ transform::ForceZ forceZ;
+ gi->accept( forceZ );
+ }
+
+ switch ( gi->geometryTypeId() ) {
+ case TYPE_TRIANGLE:
+ ret_geo->addGeometry( Polygon( gi->as<Triangle>() ) );
+ break;
+
+ case TYPE_TRIANGULATEDSURFACE: {
+ for ( size_t j = 0; j < gi->numGeometries(); ++j ) {
+ ret_geo->addGeometry( Polygon( gi->geometryN( j ).as<Triangle>() ) );
+ }
+ }
+ break;
+
+ case TYPE_POLYHEDRALSURFACE: {
+ for ( size_t j = 0; j < gi->numGeometries(); ++j ) {
+ ret_geo->addGeometry( gi->geometryN( j ) );
+ }
+ }
+ break;
+
+ case TYPE_GEOMETRYCOLLECTION:
+
+ // do not include empty geometrycollection
+ if ( gi->isEmpty() ) {
+ continue;
+ }
+
+ default:
+ ret_geo->addGeometry( *gi );
+ }
+ }
+
+ return std::auto_ptr<Geometry>( ret_geo );
+}
+
+}
+}
diff --git a/src/algorithm/collectionToMulti.h b/src/algorithm/collectionToMulti.h
new file mode 100644
index 0000000..53a4d74
--- /dev/null
+++ b/src/algorithm/collectionToMulti.h
@@ -0,0 +1,42 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SFCGAL_COLLECTION_TO_MULTI_ALGORITHM
+#define SFCGAL_COLLECTION_TO_MULTI_ALGORITHM
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Geometry.h>
+#include <SFCGAL/GeometryCollection.h>
+
+namespace SFCGAL {
+namespace algorithm {
+/**
+ * Given a geometry collection of triangles, TINs and polygons
+ * returns a MultiPolygon
+ *
+ * @warning Ownership is taken from the parameter
+ * @ingroup
+ */
+SFCGAL_API std::auto_ptr<Geometry> collectionToMulti( std::auto_ptr<Geometry> coll );
+}
+}
+
+#endif
diff --git a/src/algorithm/connection.cpp b/src/algorithm/connection.cpp
new file mode 100644
index 0000000..559e5de
--- /dev/null
+++ b/src/algorithm/connection.cpp
@@ -0,0 +1,164 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <SFCGAL/algorithm/connection.h>
+
+#include <SFCGAL/Coordinate.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+
+namespace SFCGAL {
+namespace algorithm {
+
+void SurfaceGraph::addRing( const LineString& ring, FaceIndex faceIndex )
+{
+ const size_t numSegments = ring.numSegments() ;
+
+ for ( size_t s = 0; s != numSegments; ++s ) { // for each segment
+ const Coordinate startCoord = ring.pointN( s ).coordinate() ;
+ const Coordinate endCoord = ring.pointN( ( s + 1 ) % numSegments ).coordinate() ; // possible optimization: store the index of ring start point instead of finding it
+ const CoordinateMap::const_iterator startFound = _coordinateMap.find( startCoord ) ;
+ const CoordinateMap::const_iterator endFound = _coordinateMap.find( endCoord ) ;
+ BOOST_ASSERT( s + 1 != numSegments || endFound != _coordinateMap.end() ); // ring not closed
+
+ if ( startFound != _coordinateMap.end() && endFound != _coordinateMap.end() ) {
+ // found both end, we look for the edge
+ const VertexIndex startIndex = startFound->second ;
+ const VertexIndex endIndex = endFound->second ;
+ const std::pair< VertexIndex, VertexIndex > edge( startIndex, endIndex );
+ const EdgeMap::const_iterator foundEdgeWithBadOrientation = _edgeMap.find( edge );
+
+ if ( foundEdgeWithBadOrientation != _edgeMap.end() ) {
+ _isValid = Validity::invalid(
+ ( boost::format( "inconsistant orientation of PolyhedralSurface detected at edge %d (%d-%d) of polygon %d" ) % s % edge.first % edge.second % faceIndex ).str()
+ );
+ }
+
+ const std::pair< VertexIndex, VertexIndex > reversedEdge( endIndex, startIndex );
+
+ const EdgeMap::iterator foundEdge = _edgeMap.find( reversedEdge );
+
+ if ( foundEdge != _edgeMap.end() ) {
+ // edit edge
+ foundEdge->second.second = faceIndex;
+ // we have two faces connected, this is an edge of the graph
+ boost::add_edge( foundEdge->second.first, foundEdge->second.second, _graph );
+ //std::cerr << "face " << foundEdge->second.first << "->" << foundEdge->second.second << "\n";
+ }
+ else {
+ // create edge
+ _edgeMap.insert( std::make_pair( edge, std::make_pair( faceIndex, INVALID_INDEX ) ) );
+ //std::cerr << "face " << faceIndex << " edge " << edge.first << "-" << edge.second << "\n";
+ }
+ }
+ else {
+ // one end at least is missing, create the edge
+ VertexIndex startIndex ;
+
+ if ( startFound == _coordinateMap.end() ) {
+ _coordinateMap.insert( std::make_pair( startCoord, _numVertices ) ) ;
+ startIndex = _numVertices;
+ ++_numVertices ;
+ }
+ else {
+ startIndex = startFound->second;
+ }
+
+ VertexIndex endIndex ;
+
+ if ( endFound == _coordinateMap.end() ) {
+ _coordinateMap.insert( std::make_pair( endCoord, _numVertices ) ) ;
+ endIndex = _numVertices;
+ ++_numVertices ;
+ }
+ else {
+ endIndex = endFound-> second;
+ }
+
+ const std::pair< VertexIndex, VertexIndex > edge( startIndex, endIndex );
+
+ _edgeMap.insert( std::make_pair( edge, std::make_pair( faceIndex, INVALID_INDEX ) ) );
+
+ //std::cerr << "face " << faceIndex << " edge " << edge.first << "-" << edge.second << "\n";
+ }
+ }
+}
+
+SurfaceGraph::SurfaceGraph( const PolyhedralSurface& surf ) :
+ _numVertices( 0 ),
+ _isValid( Validity::valid() )
+{
+ const size_t numPolygons = surf.numPolygons() ;
+
+ for ( size_t p = 0; p != numPolygons; ++p ) { // for each polygon
+ const FaceIndex idx = boost::add_vertex( _graph );
+ BOOST_ASSERT( idx == p );
+ ( void )idx;
+ const Polygon& polygon = surf.polygonN( p ) ;
+ const size_t numRings = polygon.numRings() ;
+
+ for ( size_t r = 0; r != numRings; ++r ) { // for each ring
+ addRing( polygon.ringN( r ), p );
+ }
+ }
+}
+
+SurfaceGraph::SurfaceGraph( const TriangulatedSurface& tin ) :
+ _numVertices( 0 ),
+ _isValid( Validity::valid() )
+{
+ const size_t numTriangles = tin.numTriangles() ;
+
+ for ( size_t t = 0; t != numTriangles; ++t ) { // for each polygon
+ const FaceIndex idx = boost::add_vertex( _graph );
+ BOOST_ASSERT( idx == t );
+ ( void )idx;
+ const Triangle& triangle = tin.triangleN( t ) ;
+ addRing( triangle.toPolygon().exteriorRing(), t );
+ }
+}
+
+bool isConnected( const SurfaceGraph& graph )
+{
+ std::vector< SurfaceGraph::FaceIndex > component( boost::num_vertices( graph.faceGraph() ) );
+ const size_t numComponents = boost::connected_components( graph.faceGraph(), &component[0] );
+ return 1 == numComponents;
+}
+
+bool isClosed( const SurfaceGraph& graph )
+{
+ const SurfaceGraph::EdgeMap::const_iterator end = graph.edgeMap().end() ;
+
+ for ( SurfaceGraph::EdgeMap::const_iterator e= graph.edgeMap().begin(); e != end; ++e ) {
+ if ( e->second.second == SurfaceGraph::INVALID_INDEX ) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+}
+}
+
diff --git a/src/algorithm/connection.h b/src/algorithm/connection.h
new file mode 100644
index 0000000..ed9627c
--- /dev/null
+++ b/src/algorithm/connection.h
@@ -0,0 +1,104 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_GRAPH_ISCONNECTED_H_
+#define _SFCGAL_GRAPH_ISCONNECTED_H_
+
+#include <SFCGAL/Geometry.h>
+#include <SFCGAL/Coordinate.h>
+#include <SFCGAL/Validity.h>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/connected_components.hpp>
+#include <boost/noncopyable.hpp>
+#include <map>
+
+namespace SFCGAL {
+namespace algorithm {
+
+/**
+ * Represents a polyhedral surface as a graph where faces are nodes and egde are graph edges
+ * @pre the polygons are valid
+ * @todo unittest
+ * @ingroup detail
+ */
+
+class SFCGAL_API SurfaceGraph : boost::noncopyable {
+public:
+ typedef size_t VertexIndex;
+ typedef size_t FaceIndex;
+ typedef std::map< Coordinate, VertexIndex > CoordinateMap ;
+ static const size_t INVALID_INDEX = size_t( -1 ) ; // would use std::numeric_limits< size_t >::max() if it were constant, or SIZE_MAX if it were easier to find.
+ // an edge is inserted with vtx ordered by the first polygon we treat,
+ // we search the edge with reverse ordered vtx indexes.
+ // as a result, an inconsistent orientation between polygons can be spotted by
+ // finding the edge in the same order
+ // note that this situation may be caused if a face is duplicated
+ typedef std::map< std::pair < VertexIndex, VertexIndex > , std::pair< FaceIndex, FaceIndex > > EdgeMap ;
+ typedef boost::adjacency_list< boost::vecS, boost::vecS, boost::undirectedS > FaceGraph;
+ /*
+ * Construct from PolyHedralSurface
+ * @throw Exception if surface is not connected
+ */
+ SurfaceGraph( const PolyhedralSurface& s );
+
+ /*
+ * Construct from TriangulatedSurface
+ * @throw Exception if surface is not connected
+ */
+ SurfaceGraph( const TriangulatedSurface& tin ) ;
+
+ const EdgeMap& edgeMap() const {
+ return _edgeMap ;
+ }
+ const FaceGraph& faceGraph() const {
+ return _graph ;
+ }
+ //const CoordinateMap & coordMap() const { return _coordinateMap ; }
+ const Validity isValid() const {
+ return _isValid ;
+ }
+
+private:
+ CoordinateMap _coordinateMap ;
+ EdgeMap _edgeMap ;
+ FaceGraph _graph ;
+ VertexIndex _numVertices ;
+
+ Validity _isValid ;
+
+ void addRing( const LineString& ring, FaceIndex faceIndex ); // helper for ctor
+};
+
+/**
+ * test if a surface is connected, the graph should be build beforehand
+ * @ingroup detail
+ */
+SFCGAL_API bool isConnected( const SurfaceGraph& graph );
+
+/**
+ * test if a surface is closed, the graph should be build beforehand
+ * @note the surface may not be connected, eg. two spheres will yield a true result
+ * @ingroup detail
+ */
+SFCGAL_API bool isClosed( const SurfaceGraph& graph );
+
+}
+}
+#endif
diff --git a/src/algorithm/convexHull.cpp b/src/algorithm/convexHull.cpp
new file mode 100644
index 0000000..22151f0
--- /dev/null
+++ b/src/algorithm/convexHull.cpp
@@ -0,0 +1,184 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/convexHull.h>
+
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/GeometryCollection.h>
+
+#include <SFCGAL/detail/GetPointsVisitor.h>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Exception.h>
+#include <boost/format.hpp>
+
+#include <CGAL/point_generators_3.h>
+#include <CGAL/algorithm.h>
+#include <CGAL/Polyhedron_3.h>
+#include <CGAL/convex_hull_2.h>
+#include <CGAL/convex_hull_3.h>
+#include <vector>
+
+namespace SFCGAL {
+namespace algorithm {
+
+typedef CGAL::Point_3< Kernel > Point_3;
+typedef CGAL::Segment_3< Kernel > Segment_3;
+typedef CGAL::Triangle_3< Kernel > Triangle_3;
+typedef CGAL::Polyhedron_3< Kernel > Polyhedron_3;
+
+typedef CGAL::Point_2< Kernel > Point_2;
+
+///
+///
+///
+std::auto_ptr<Geometry> convexHull( const Geometry& g )
+{
+ using CGAL::object_cast ;
+
+ if ( g.isEmpty() ) {
+ return std::auto_ptr<Geometry>( g.clone() );
+ }
+
+ SFCGAL::detail::GetPointsVisitor getPointVisitor;
+ const_cast< Geometry& >( g ).accept( getPointVisitor );
+
+ // collect points
+
+ if ( getPointVisitor.points.size() == 0 ) {
+ return std::auto_ptr<Geometry>( new GeometryCollection() );
+ }
+
+ std::vector< Point_2 > points ;
+
+ for ( size_t i = 0; i < getPointVisitor.points.size(); i++ ) {
+ points.push_back( getPointVisitor.points[i]->toPoint_2() );
+ }
+
+ // resulting extreme points
+ std::list<Point_2> epoints;
+ CGAL::convex_hull_2( points.begin(), points.end(), std::back_inserter( epoints ) ) ;
+
+ if ( epoints.size() == 1 ) {
+ return std::auto_ptr<Geometry>( new Point( *epoints.begin() ) );
+ }
+ else if ( epoints.size() == 2 ) {
+ std::list<Point_2>::const_iterator it = epoints.begin();
+ return std::auto_ptr<Geometry>( new LineString( Point( *it++ ), Point( *it++ ) ) );
+ }
+ // GEOS does not seem to return triangles
+ else if ( epoints.size() == 3 ) {
+ std::list<Point_2>::const_iterator it = epoints.begin();
+ Point_2 p( *it++ );
+ Point_2 q( *it++ );
+ Point_2 r( *it++ );
+ return std::auto_ptr<Geometry>( new Triangle( p, q, r ) ) ;
+ }
+ else if ( epoints.size() > 3 ) {
+ Polygon* poly = new Polygon;
+
+ for ( std::list<Point_2>::const_iterator it = epoints.begin(); it != epoints.end(); ++it ) {
+ poly->exteriorRing().addPoint( *it );
+ }
+
+ // add back the first point to close the ring
+ poly->exteriorRing().addPoint( *epoints.begin() );
+ return std::auto_ptr<Geometry>( poly );
+ }
+ else {
+ BOOST_THROW_EXCEPTION( Exception( "unexpected CGAL output type in CGAL::convex_hull_2" ) );
+ }
+}
+
+///
+///
+///
+std::auto_ptr<Geometry> convexHull3D( const Geometry& g )
+{
+ using CGAL::object_cast ;
+
+ SFCGAL::detail::GetPointsVisitor getPointVisitor;
+ const_cast< Geometry& >( g ).accept( getPointVisitor );
+
+ // collect points
+
+ std::vector< Point_3 > points ;
+
+ for ( size_t i = 0; i < getPointVisitor.points.size(); i++ ) {
+ points.push_back( getPointVisitor.points[i]->toPoint_3() );
+ }
+
+ /*
+ * http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Convex_hull_3/Chapter_main.html
+ *
+ * handles all degenerate cases and returns a CGAL::Object,
+ * which may be a point, a segment, a triangle, or a polyhedron.
+ */
+ CGAL::Object hull;
+ CGAL::convex_hull_3( points.begin(), points.end(), hull ) ;
+
+ if ( hull.empty() ) {
+ return std::auto_ptr<Geometry>( new GeometryCollection() );
+ }
+ else if ( const Point_3* point = object_cast< Point_3 >( &hull ) ) {
+ return std::auto_ptr<Geometry>( new Point( *point ) );
+ }
+ else if ( const Segment_3* segment = object_cast< Segment_3 >( &hull ) ) {
+ return std::auto_ptr<Geometry>( new LineString( Point( segment->start() ), Point( segment->end() ) ) );
+ }
+ else if ( const Triangle_3* triangle = object_cast< Triangle_3 >( &hull ) ) {
+ return std::auto_ptr<Geometry>( new Triangle(
+ Point( triangle->vertex( 0 ) ),
+ Point( triangle->vertex( 1 ) ),
+ Point( triangle->vertex( 2 ) )
+ ) );
+ }
+ else if ( const Polyhedron_3* polyhedron = object_cast< Polyhedron_3 >( &hull ) ) {
+ std::auto_ptr< PolyhedralSurface > result( new PolyhedralSurface() );
+
+ for ( Polyhedron_3::Facet_const_iterator it_facet = polyhedron->facets_begin();
+ it_facet != polyhedron->facets_end(); ++it_facet ) {
+ Polyhedron_3::Halfedge_around_facet_const_circulator it = it_facet->facet_begin();
+
+ std::vector< Point > ring ;
+
+ do {
+ ring.push_back( Point( it->vertex()->point() ) );
+ }
+ while ( ++it != it_facet->facet_begin() );
+
+ ring.push_back( ring.front() );
+
+ result->addPolygon( Polygon( ring ) );
+ }
+
+ return std::auto_ptr<Geometry>( result.release() );
+ }
+ else {
+ BOOST_THROW_EXCEPTION( Exception( "unexpected CGAL output type in CGAL::convex_hull_3" ) );
+ }
+}
+
+
+}//algorithm
+}//SFCGAL
diff --git a/src/algorithm/convexHull.h b/src/algorithm/convexHull.h
new file mode 100644
index 0000000..991e7e9
--- /dev/null
+++ b/src/algorithm/convexHull.h
@@ -0,0 +1,49 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_ALGORITHM_CONVEXHULL_H_
+#define _SFCGAL_ALGORITHM_CONVEXHULL_H_
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Geometry.h>
+
+namespace SFCGAL {
+namespace algorithm {
+
+/**
+ * Compute the 2D convex hull for a geometry
+ * @ingroup public_api
+ */
+SFCGAL_API std::auto_ptr<Geometry> convexHull( const Geometry& g ) ;
+
+/**
+ * Compute the 3D convex hull for a geometry
+ * @todo improve to handle collinear points and coplanar points
+ * @ingroup public_api
+ */
+SFCGAL_API std::auto_ptr<Geometry> convexHull3D( const Geometry& g ) ;
+
+
+}//algorithm
+}//SFCGAL
+
+
+#endif
diff --git a/src/algorithm/covers.cpp b/src/algorithm/covers.cpp
new file mode 100644
index 0000000..9521b70
--- /dev/null
+++ b/src/algorithm/covers.cpp
@@ -0,0 +1,265 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <SFCGAL/algorithm/covers.h>
+#include <SFCGAL/Geometry.h>
+#include <SFCGAL/algorithm/intersects.h>
+#include <SFCGAL/algorithm/intersection.h>
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/detail/TypeForDimension.h>
+#include <SFCGAL/detail/GeometrySet.h>
+
+#include <CGAL/box_intersection_d.h>
+
+using namespace SFCGAL::detail;
+
+namespace SFCGAL {
+namespace algorithm {
+
+bool covers( const PrimitiveHandle<3>&, const PrimitiveHandle<3>& )
+{
+ return false;
+}
+
+template <int Dim>
+double segmentsLength( const GeometrySet<Dim>& gs )
+{
+ double result = 0.0;
+
+ for ( typename GeometrySet<Dim>::SegmentCollection::const_iterator it = gs.segments().begin();
+ it != gs.segments().end();
+ ++it ) {
+ result = result + sqrt( CGAL::to_double( it->primitive().squared_length() ) );
+ }
+
+ return result;
+}
+
+double solidsVolume( const GeometrySet<3>& gs, bool planarSurface = false )
+{
+ double result = 0.0;
+
+ for ( GeometrySet<3>::VolumeCollection::const_iterator it = gs.volumes().begin();
+ it != gs.volumes().end();
+ ++it ) {
+ // TODO : we use areas of surfaces here instead of volumes
+ const MarkedPolyhedron& poly = it->primitive();
+
+ if ( poly.is_closed() && planarSurface ) {
+ continue;
+ }
+
+ if ( ! poly.is_closed() && ! planarSurface ) {
+ continue;
+ }
+
+ BOOST_ASSERT( poly.is_pure_triangle() );
+
+ CGAL::Point_3<Kernel> p1, p2, p3;
+
+ for ( MarkedPolyhedron::Facet_const_iterator fit = poly.facets_begin();
+ fit != poly.facets_end();
+ ++fit ) {
+ MarkedPolyhedron::Halfedge_around_facet_const_circulator cit = fit->facet_begin();
+ p1 = cit->vertex()->point();
+ cit++;
+ p2 = cit->vertex()->point();
+ cit++;
+ p3 = cit->vertex()->point();
+ CGAL::Triangle_3<Kernel> tri( p1, p2, p3 );
+ result = result + sqrt( CGAL::to_double( tri.squared_area() ) );
+ }
+ }
+
+ return result;
+}
+
+double surfacesArea( const GeometrySet<2>& gs )
+{
+ Kernel::FT result = 0.0;
+
+ for ( GeometrySet<2>::SurfaceCollection::const_iterator it = gs.surfaces().begin();
+ it != gs.surfaces().end();
+ ++it ) {
+ const CGAL::Polygon_with_holes_2<Kernel>& polygon = it->primitive();
+ result = result + CGAL::abs( polygon.outer_boundary().area() );
+
+ for ( CGAL::Polygon_with_holes_2<Kernel>::Hole_const_iterator hit = polygon.holes_begin();
+ hit != polygon.holes_end();
+ ++hit ) {
+ result = result - CGAL::abs( hit->area() );
+ }
+ }
+
+ return CGAL::to_double( result );
+}
+
+double surfacesArea( const GeometrySet<3>& gs )
+{
+ double result = 0.0;
+
+ if ( gs.surfaces().empty() && !gs.volumes().empty() ) {
+ result = solidsVolume( gs, /* planarSurfaces = */ true );
+ }
+
+ for ( GeometrySet<3>::SurfaceCollection::const_iterator it = gs.surfaces().begin();
+ it != gs.surfaces().end();
+ ++it ) {
+ result = result + sqrt( CGAL::to_double( it->primitive().squared_area() ) );
+ }
+
+ return result;
+}
+
+double solidsVolume( const GeometrySet<2>& )
+{
+ return 0.0;
+}
+
+template <int Dim>
+bool equalLength( const GeometrySet<Dim>& a, const GeometrySet<Dim>& b, int dim )
+{
+ // compare 'length' of primitives in A with 'length' of primitives in B
+ // 'length' is :
+ // - number of elements for points
+ // - length for segments
+ // - area for surfaces
+ // - should be volume for volumes. We use area here
+
+ double tol = 1e-9;
+
+ switch ( dim ) {
+ case 0: {
+ if ( a.points().size() != b.points().size() ) {
+ return false;
+ }
+ }
+
+ case 1: {
+
+ //
+ // Compare lengths
+ double lengthA = segmentsLength( a );
+ double lengthB = segmentsLength( b );
+ double cmp = ( lengthA - lengthB ) * ( lengthA - lengthB );
+
+ if ( cmp > tol ) {
+ return false;
+ }
+ }
+
+ case 2: {
+ //
+ // Compare areas
+ double areaA = surfacesArea( a );
+ double areaB = surfacesArea( b );
+ double cmp = ( areaA - areaB ) * ( areaA - areaB );
+
+ if ( cmp > tol ) {
+ return false;
+ }
+ }
+
+ case 3: {
+ // Compare volumes
+ double volA = solidsVolume( a );
+ double volB = solidsVolume( b );
+ double cmp = ( volA - volB ) * ( volA - volB );
+
+ if ( cmp > tol ) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+template <int Dim>
+bool covers( const GeometrySet<Dim>& a, const GeometrySet<Dim>& b )
+{
+ int dimA = a.dimension();
+ int dimB = b.dimension();
+
+ if ( dimA == -1 || dimB == -1 ) {
+ return false;
+ }
+
+ if ( dimB > dimA ) {
+ return false;
+ }
+
+ //
+ // This is a very naive (not efficient) implementation of covers() !
+ //
+ // covers(A,B) <=> A inter B == B
+ // '==' is here implemented with comparison of length, area and volumes
+ // TODO use only predicates if possible
+ GeometrySet<Dim> inter;
+ algorithm::intersection( a, b, inter );
+
+ if ( b.hasPoints() && ! equalLength( b, inter, 0 ) ) {
+ return false;
+ }
+
+ if ( b.hasSegments() && ! equalLength( b, inter, 1 ) ) {
+ return false;
+ }
+
+ if ( b.hasSurfaces() && ! equalLength( b, inter, 2 ) ) {
+ return false;
+ }
+
+ if ( b.hasVolumes() && ! equalLength( b, inter, 3 ) ) {
+ return false;
+ }
+
+ return true;
+}
+
+template bool covers<2>( const GeometrySet<2>& a, const GeometrySet<2>& b );
+template bool covers<3>( const GeometrySet<3>& a, const GeometrySet<3>& b );
+
+bool covers( const Geometry& ga, const Geometry& gb )
+{
+ if ( ga.isEmpty() || gb.isEmpty() ) {
+ return false;
+ }
+
+ GeometrySet<2> gsa( ga );
+ GeometrySet<2> gsb( gb );
+
+ return covers( gsa, gsb );
+}
+
+bool covers3D( const Geometry& ga, const Geometry& gb )
+{
+ if ( ga.isEmpty() || gb.isEmpty() ) {
+ return false;
+ }
+
+ GeometrySet<3> gsa( ga );
+ GeometrySet<3> gsb( gb );
+
+ return covers( gsa, gsb );
+}
+}
+}
diff --git a/src/algorithm/covers.h b/src/algorithm/covers.h
new file mode 100644
index 0000000..71038da
--- /dev/null
+++ b/src/algorithm/covers.h
@@ -0,0 +1,63 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SFCGAL_COVERS_ALGORITHM
+#define SFCGAL_COVERS_ALGORITHM
+
+#include <SFCGAL/config.h>
+
+#include <vector>
+
+namespace SFCGAL {
+class Geometry;
+class Solid;
+class Point;
+namespace detail {
+template <int Dim> class GeometrySet;
+template <int Dim> class PrimitiveHandle;
+}
+
+namespace algorithm {
+/**
+ * Cover test on 2D geometries. Checks if gA covers gB. Force projection to z=0 if needed
+ * @ingroup@ detail
+ */
+SFCGAL_API bool covers( const Geometry& ga, const Geometry& gb );
+
+/**
+ * Cover test on 3D geometries. Checks if gA covers gB. Assume z = 0 if needed
+ */
+SFCGAL_API bool covers3D( const Geometry& ga, const Geometry& gb );
+
+/**
+ * @ingroup@ detail
+ */
+template <int Dim>
+bool covers( const detail::GeometrySet<Dim>& a, const detail::GeometrySet<Dim>& b );
+
+/**
+ * @ingroup@ detail
+ */
+template <int Dim>
+bool covers( const detail::PrimitiveHandle<Dim>& a, const detail::PrimitiveHandle<Dim>& b );
+}
+}
+
+#endif
diff --git a/src/algorithm/difference.cpp b/src/algorithm/difference.cpp
new file mode 100644
index 0000000..aaadac9
--- /dev/null
+++ b/src/algorithm/difference.cpp
@@ -0,0 +1,431 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/differencePrimitives.h>
+#include <SFCGAL/algorithm/difference.h>
+#include <SFCGAL/Exception.h>
+#include <SFCGAL/detail/GeometrySet.h>
+#include <SFCGAL/algorithm/isValid.h>
+#include <SFCGAL/triangulate/triangulatePolygon.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/TriangulatedSurface.h>
+
+#include <CGAL/Boolean_set_operations_2.h>
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+#include <CGAL/box_intersection_d.h>
+#include <CGAL/corefinement_operations.h>
+#include <CGAL/Point_inside_polyhedron_3.h>
+
+//
+// Intersection kernel
+
+using namespace SFCGAL::detail;
+
+namespace SFCGAL {
+
+namespace algorithm {
+
+template <int Dim>
+struct CollisionMapper {
+ typedef std::vector< PrimitiveHandle<Dim>* > PrimitiveHandleSet;
+ typedef std::map< PrimitiveHandle<Dim>*, PrimitiveHandleSet > Map;
+ CollisionMapper( Map& map ) : _map( map ) {};
+ void operator()( const typename PrimitiveBox<Dim>::Type& a,
+ const typename PrimitiveBox<Dim>::Type& b ) {
+ _map[a.handle()].push_back( b.handle() );
+ }
+
+private:
+ Map& _map;
+};
+
+template < typename OutputIteratorType >
+OutputIteratorType difference( const Point_2& primitive, const PrimitiveHandle<2>& pb, OutputIteratorType out )
+{
+ switch ( pb.handle.which() ) {
+ case PrimitivePoint:
+ difference( primitive, *pb.as< Point_2 >(), out );
+ break;
+
+ case PrimitiveSegment:
+ difference( primitive, *pb.as< Segment_2 >(), out );
+ break;
+
+ case PrimitiveSurface:
+ difference( primitive, *pb.as< PolygonWH_2 >(), out );
+ break;
+ }
+
+ return out;
+}
+
+
+template < typename OutputIteratorType >
+OutputIteratorType difference( const Segment_2& primitive, const PrimitiveHandle<2>& pb, OutputIteratorType out )
+{
+ switch ( pb.handle.which() ) {
+ case PrimitivePoint:
+ *out++ = primitive;
+ break;
+
+ case PrimitiveSegment:
+ difference( primitive, *pb.as< Segment_2 >(), out );
+ break;
+
+ case PrimitiveSurface:
+ difference( primitive, *pb.as< PolygonWH_2 >(), out );
+ break;
+ }
+
+ return out;
+}
+
+template < typename OutputIteratorType >
+OutputIteratorType difference( const PolygonWH_2& primitive, const PrimitiveHandle<2>& pb, OutputIteratorType out )
+{
+ switch ( pb.handle.which() ) {
+ case PrimitivePoint:
+ *out++ = primitive;
+ break;
+
+ case PrimitiveSegment:
+ *out++ = primitive;
+ break;
+
+ case PrimitiveSurface:
+ difference( primitive, *pb.as< PolygonWH_2 >(), out );
+ break;
+ }
+
+ return out;
+}
+
+template < typename OutputIteratorType >
+OutputIteratorType difference( const Point_3& primitive, const PrimitiveHandle<3>& pb, OutputIteratorType out )
+{
+ switch ( pb.handle.which() ) {
+ case PrimitivePoint:
+ difference( primitive, *pb.as< Point_3 >(), out );
+ break;
+
+ case PrimitiveSegment:
+ difference( primitive, *pb.as< Segment_3 >(), out );
+ break;
+
+ case PrimitiveSurface:
+ difference( primitive, *pb.as< Triangle_3 >(), out );
+ break;
+
+ case PrimitiveVolume:
+ difference( primitive, *pb.as< MarkedPolyhedron >(), out );
+ break;
+ }
+
+ return out;
+}
+
+template < typename OutputIteratorType >
+OutputIteratorType difference( const Segment_3& primitive, const PrimitiveHandle<3>& pb, OutputIteratorType out )
+{
+ switch ( pb.handle.which() ) {
+ case PrimitivePoint:
+ *out++ = primitive;
+ break;
+
+ case PrimitiveSegment:
+ difference( primitive, *pb.as< Segment_3 >(), out );
+ break;
+
+ case PrimitiveSurface:
+ difference( primitive, *pb.as< Triangle_3 >(), out );
+ break;
+
+ case PrimitiveVolume:
+ difference( primitive, *pb.as< MarkedPolyhedron >(), out );
+ break;
+ }
+
+ return out;
+}
+
+template < typename OutputIteratorType >
+OutputIteratorType difference( const Triangle_3& primitive, const PrimitiveHandle<3>& pb, OutputIteratorType out )
+{
+ switch ( pb.handle.which() ) {
+ case PrimitivePoint:
+ *out++ = primitive;
+ break;
+
+ case PrimitiveSegment:
+ *out++ = primitive;
+ break;
+
+ case PrimitiveSurface:
+ difference( primitive, *pb.as< Triangle_3 >(), out );
+ break;
+
+ case PrimitiveVolume:
+ difference( primitive, *pb.as< MarkedPolyhedron >(), out );
+ break;
+ }
+
+ return out;
+}
+
+template < typename OutputIteratorType >
+OutputIteratorType difference( const MarkedPolyhedron& primitive, const PrimitiveHandle<3>& pb, OutputIteratorType out )
+{
+ switch ( pb.handle.which() ) {
+ case PrimitivePoint:
+ *out++ = primitive;
+ break;
+
+ case PrimitiveSegment:
+ *out++ = primitive;
+ break;
+
+ case PrimitiveSurface:
+ *out++ = primitive;
+ break;
+
+ case PrimitiveVolume:
+ difference( primitive, *pb.as< MarkedPolyhedron >(), out );
+ break;
+ }
+
+ return out;
+}
+
+
+template <typename Primitive, typename PrimitiveHandleConstIterator>
+std::vector< Primitive >
+difference( const Primitive& primitive, PrimitiveHandleConstIterator begin, PrimitiveHandleConstIterator end )
+{
+ std::vector< Primitive > primitives;
+ primitives.push_back( primitive );
+
+ for ( PrimitiveHandleConstIterator b = begin; b != end; ++b ) {
+ std::vector< Primitive > new_primitives;
+
+ for ( typename std::vector< Primitive >::const_iterator a = primitives.begin();
+ a != primitives.end(); ++a ) {
+ difference( *a, *( *b ), std::back_inserter( new_primitives ) );
+ }
+
+ primitives.swap( new_primitives );
+ }
+
+ return primitives;
+}
+
+
+// just performs the type switch for the primitive to substract from
+//
+void appendDifference( const PrimitiveHandle<2>& pa,
+ CollisionMapper<2>::PrimitiveHandleSet::const_iterator begin,
+ CollisionMapper<2>::PrimitiveHandleSet::const_iterator end,
+ GeometrySet<2>& output )
+{
+ switch ( pa.handle.which() ) {
+ case PrimitivePoint: {
+ std::vector< Point_2 > res = difference(
+ *pa.as< Point_2 >(), begin, end );
+ output.addPoints( res.begin(), res.end() );
+ return;
+ }
+
+ case PrimitiveSegment: {
+ std::vector< Segment_2 > res = difference(
+ *pa.as< Segment_2 >(), begin, end );
+ output.addSegments( res.begin(), res.end() );
+ return;
+ }
+
+ case PrimitiveSurface: {
+ std::vector< PolygonWH_2 > res = difference( *pa.as< PolygonWH_2 >(), begin, end );
+ output.addSurfaces( res.begin(), res.end() );
+ return;
+ }
+ }
+}
+
+void appendDifference( const PrimitiveHandle<3>& pa,
+ CollisionMapper<3>::PrimitiveHandleSet::const_iterator begin,
+ CollisionMapper<3>::PrimitiveHandleSet::const_iterator end,
+ GeometrySet<3>& output )
+{
+ switch ( pa.handle.which() ) {
+ case PrimitivePoint: {
+ std::vector< Point_3 > res = difference( *pa.as< Point_3 >(), begin, end );
+ output.addPoints( res.begin(), res.end() );
+ return;
+ }
+
+ case PrimitiveSegment: {
+ std::vector< Segment_3 > res = difference( *pa.as< Segment_3 >(), begin, end );
+ output.addSegments( res.begin(), res.end() );
+ break;
+ }
+
+ case PrimitiveSurface: {
+ std::vector< Triangle_3 > res = difference( *pa.as< Triangle_3 >(), begin, end );
+ output.addSurfaces( res.begin(), res.end() );
+ break;
+ }
+
+ case PrimitiveVolume: {
+ std::vector< MarkedPolyhedron > res = difference( *pa.as< MarkedPolyhedron >(), begin, end );
+ output.addVolumes( res.begin(), res.end() );
+ break;
+ }
+ }
+}
+
+/**
+ * difference post processing
+ */
+void post_difference( const GeometrySet<2>& input, GeometrySet<2>& output )
+{
+ //
+ // reverse orientation of polygons if needed
+ for ( GeometrySet<2>::SurfaceCollection::const_iterator it = input.surfaces().begin();
+ it != input.surfaces().end();
+ ++it ) {
+ const PolygonWH_2& p = it->primitive();
+ Polygon_2 outer = p.outer_boundary();
+
+ if ( outer.orientation() == CGAL::CLOCKWISE ) {
+ outer.reverse_orientation();
+ }
+
+ std::list<CGAL::Polygon_2<Kernel> > rings;
+
+ for ( CGAL::Polygon_with_holes_2<Kernel>::Hole_const_iterator hit = p.holes_begin();
+ hit != p.holes_end();
+ ++hit ) {
+ rings.push_back( *hit );
+
+ if ( hit->orientation() == CGAL::COUNTERCLOCKWISE ) {
+ rings.back().reverse_orientation();
+ }
+ }
+
+ output.surfaces().push_back( PolygonWH_2( outer, rings.begin(), rings.end() ) );
+ }
+
+ output.points() = input.points();
+ output.segments() = input.segments();
+ output.volumes() = input.volumes();
+}
+
+void post_difference( const GeometrySet<3>& input, GeometrySet<3>& output )
+{
+ // nothing special to do
+ output = input;
+}
+
+template <int Dim>
+void difference( const GeometrySet<Dim>& a, const GeometrySet<Dim>& b, GeometrySet<Dim>& output )
+{
+ typedef typename SFCGAL::detail::BoxCollection<Dim>::Type BoxCollection;
+ typename SFCGAL::detail::HandleCollection<Dim>::Type ahandles, bhandles;
+ BoxCollection aboxes, bboxes;
+ a.computeBoundingBoxes( ahandles, aboxes );
+ b.computeBoundingBoxes( bhandles, bboxes );
+
+ // here we use box_intersection_d to build the list of operations
+ // that actually need to be performed
+ GeometrySet<Dim> temp, temp2;
+ typename CollisionMapper<Dim>::Map map;
+ CollisionMapper<Dim> cb( map );
+ CGAL::box_intersection_d( aboxes.begin(), aboxes.end(),
+ bboxes.begin(), bboxes.end(),
+ cb );
+
+ // now we have in cb a map of operations to perform
+ // we can put in the result right away all the primitives
+ // that are not keys in this map
+ {
+ typename BoxCollection::const_iterator ait = aboxes.begin();
+ const typename BoxCollection::const_iterator end = aboxes.end();
+
+ for ( ; ait != end; ++ait ) {
+ if ( map.find( ait->handle() ) == map.end() ) {
+ temp.addPrimitive( *ait->handle() );
+ }
+ }
+ }
+
+ // then we delegate the operations according to type
+ {
+ typename CollisionMapper<Dim>::Map::const_iterator cbit = map.begin();
+ const typename CollisionMapper<Dim>::Map::const_iterator end = map.end();
+
+ for ( ; cbit != end; ++cbit ) {
+ appendDifference( *cbit->first, cbit->second.begin(), cbit->second.end(), temp );
+ }
+ }
+
+ post_difference( temp, temp2 );
+ output.merge( temp2 );
+}
+
+template void difference<2>( const GeometrySet<2>& a, const GeometrySet<2>& b, GeometrySet<2>& );
+template void difference<3>( const GeometrySet<3>& a, const GeometrySet<3>& b, GeometrySet<3>& );
+
+std::auto_ptr<Geometry> difference( const Geometry& ga, const Geometry& gb, NoValidityCheck )
+{
+ GeometrySet<2> gsa( ga ), gsb( gb ), output;
+ algorithm::difference( gsa, gsb, output );
+
+ GeometrySet<2> filtered;
+ output.filterCovered( filtered );
+ return filtered.recompose();
+}
+
+std::auto_ptr<Geometry> difference( const Geometry& ga, const Geometry& gb )
+{
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_2D( ga );
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_2D( gb );
+
+ return difference( ga, gb, NoValidityCheck() );
+}
+
+std::auto_ptr<Geometry> difference3D( const Geometry& ga, const Geometry& gb, NoValidityCheck )
+{
+ GeometrySet<3> gsa( ga ), gsb( gb ), output;
+ algorithm::difference( gsa, gsb, output );
+
+ GeometrySet<3> filtered;
+ output.filterCovered( filtered );
+
+ return filtered.recompose();
+}
+
+std::auto_ptr<Geometry> difference3D( const Geometry& ga, const Geometry& gb )
+{
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_3D( ga );
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_3D( gb );
+
+ return difference3D( ga, gb, NoValidityCheck() );
+}
+}
+}
diff --git a/src/algorithm/difference.h b/src/algorithm/difference.h
new file mode 100644
index 0000000..af0b6b9
--- /dev/null
+++ b/src/algorithm/difference.h
@@ -0,0 +1,77 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SFCGAL_DIFFERENCE_ALGORITHM
+#define SFCGAL_DIFFERENCE_ALGORITHM
+
+#include <SFCGAL/config.h>
+
+#include <memory>
+
+namespace SFCGAL {
+class Geometry;
+namespace detail {
+template <int Dim> class GeometrySet;
+template <int Dim> class PrimitiveHandle;
+}
+
+namespace algorithm {
+struct NoValidityCheck;
+
+/**
+ * Difference on 2D geometries.
+ * @pre ga and gb are valid geometries
+ * @ingroup public_api
+ */
+SFCGAL_API std::auto_ptr<Geometry> difference( const Geometry& ga, const Geometry& gb );
+
+/**
+ * Diffrence on 2D geometries. No validity check variant
+ * @pre ga and gb are valid geometries
+ * @ingroup detail
+ * @warning No actual validity check is done.
+ */
+SFCGAL_API std::auto_ptr<Geometry> difference( const Geometry& ga, const Geometry& gb,NoValidityCheck );
+
+/**
+ * Difference on 3D geometries. Assume z = 0 if needed
+ * @pre ga and gb are valid geometries
+ * @ingroup public_api
+ */
+SFCGAL_API std::auto_ptr<Geometry> difference3D( const Geometry& ga, const Geometry& gb );
+
+/**
+ * Difference on 3D geometries. Assume z = 0 if needed
+ * @pre ga and gb are valid geometries
+ * @ingroup detail
+ * @warning@ No actual validity check is done
+ */
+SFCGAL_API std::auto_ptr<Geometry> difference3D( const Geometry& ga, const Geometry& gb, NoValidityCheck );
+
+/**
+ * @ingroup detail
+ */
+template <int Dim>
+void difference( const detail::GeometrySet<Dim>& a, const detail::GeometrySet<Dim>& b, detail::GeometrySet<Dim>& );
+
+}
+}
+
+#endif
diff --git a/src/algorithm/differencePrimitives.cpp b/src/algorithm/differencePrimitives.cpp
new file mode 100644
index 0000000..87578ad
--- /dev/null
+++ b/src/algorithm/differencePrimitives.cpp
@@ -0,0 +1,32 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/Triangle.h>
+// GOTCHA do not include the header, this is a trick to avoid ambiguous def in CGAL
+
+namespace SFCGAL {
+namespace algorithm {
+CGAL::Object intersection( const CGAL::Triangle_3<Kernel>& a, const CGAL::Triangle_3<Kernel>& b )
+{
+ return CGAL::intersection( a, b );
+}
+}
+}
+
diff --git a/src/algorithm/differencePrimitives.h b/src/algorithm/differencePrimitives.h
new file mode 100644
index 0000000..c1ae977
--- /dev/null
+++ b/src/algorithm/differencePrimitives.h
@@ -0,0 +1,809 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_ALGORITHM_DIFFERENCEPRIMITIVES_H_
+#define _SFCGAL_ALGORITHM_DIFFERENCEPRIMITIVES_H_
+
+#include <SFCGAL/Exception.h>
+#include <SFCGAL/triangulate/triangulatePolygon.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/detail/GeometrySet.h>
+
+#include <CGAL/Boolean_set_operations_2.h>
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+#include <CGAL/box_intersection_d.h>
+#include <CGAL/corefinement_operations.h>
+#include <CGAL/Point_inside_polyhedron_3.h>
+
+
+
+namespace SFCGAL {
+
+namespace algorithm {
+
+typedef CGAL::Vector_2<Kernel> Vector_2;
+typedef CGAL::Point_2<Kernel> Point_2;
+typedef CGAL::Segment_2<Kernel> Segment_2;
+typedef CGAL::Triangle_2<Kernel> Triangle_2;
+typedef CGAL::Polygon_2<Kernel> Polygon_2;
+typedef CGAL::Polygon_with_holes_2<Kernel> PolygonWH_2;
+typedef detail::NoVolume NoVolume;
+
+typedef CGAL::Vector_3<Kernel> Vector_3;
+typedef CGAL::Point_3<Kernel> Point_3;
+typedef CGAL::Segment_3<Kernel> Segment_3;
+typedef CGAL::Triangle_3<Kernel> Triangle_3;
+typedef CGAL::Plane_3<Kernel> Plane_3;
+typedef detail::MarkedPolyhedron MarkedPolyhedron;
+
+CGAL::Object intersection( const CGAL::Triangle_3<Kernel>& a, const CGAL::Triangle_3<Kernel>& b );
+
+inline
+bool do_intersect( const Point_2& point, const PolygonWH_2& polygon )
+{
+ // point intersects if it's inside the ext ring and outside all holes
+
+ if ( CGAL::bounded_side_2( polygon.outer_boundary().vertices_begin(),
+ polygon.outer_boundary().vertices_end(), point, Kernel() )
+ == CGAL::ON_UNBOUNDED_SIDE ) {
+ return false;
+ }
+
+ for ( PolygonWH_2::Hole_const_iterator hit = polygon.holes_begin();
+ hit != polygon.holes_end();
+ ++hit ) {
+ if ( CGAL::bounded_side_2( hit->vertices_begin(),
+ hit->vertices_end(), point, Kernel() )
+ != CGAL::ON_UNBOUNDED_SIDE ) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+
+template < typename PointOutputIteratorType>
+PointOutputIteratorType difference( const Point_2& a, const Point_2& b, PointOutputIteratorType out )
+{
+ if ( a != b ) {
+ *out++ = a;
+ }
+
+ return out;
+}
+
+template < typename PointOutputIteratorType>
+PointOutputIteratorType difference( const Point_2& a, const Segment_2& b, PointOutputIteratorType out )
+{
+ if ( ! CGAL::do_intersect( a, b ) ) {
+ *out++ = a;
+ }
+
+ return out;
+}
+
+template < typename PointOutputIteratorType>
+PointOutputIteratorType difference( const Point_2& a, const PolygonWH_2& b, PointOutputIteratorType out )
+{
+ if ( ! do_intersect( a, b ) ) {
+ *out++ = a;
+ }
+
+ return out;
+}
+
+template < typename PointOutputIteratorType>
+PointOutputIteratorType difference( const Point_2&, const NoVolume& , PointOutputIteratorType out )
+{
+ BOOST_ASSERT( false );
+ return out;
+}
+
+template < typename SegmentOutputIteratorType>
+SegmentOutputIteratorType difference( const Segment_2&, const NoVolume& , SegmentOutputIteratorType out )
+{
+ BOOST_ASSERT( false );
+ return out;
+}
+
+template < typename SurfaceOutputIteratorType>
+SurfaceOutputIteratorType difference( const PolygonWH_2&, const NoVolume& , SurfaceOutputIteratorType out )
+{
+ BOOST_ASSERT( false );
+ return out;
+}
+
+
+template < typename PointOutputIteratorType>
+PointOutputIteratorType difference( const Point_3& a, const Point_3& b, PointOutputIteratorType out )
+{
+ if ( a != b ) {
+ *out++ = a;
+ }
+
+ return out;
+}
+
+template < typename PointOutputIteratorType>
+PointOutputIteratorType difference( const Point_3& a, const Segment_3& b, PointOutputIteratorType out )
+{
+ if ( ! b.has_on( a ) ) {
+ *out++ = a;
+ }
+
+ return out;
+}
+
+template < typename PointOutputIteratorType>
+PointOutputIteratorType difference( const Point_3& a, const Triangle_3& b, PointOutputIteratorType out )
+{
+ if ( ! b.has_on( a ) ) {
+ *out++ = a;
+ }
+
+ return out;
+}
+
+template < typename PointOutputIteratorType>
+PointOutputIteratorType difference( const Point_3& a, const MarkedPolyhedron& b, PointOutputIteratorType out )
+{
+ CGAL::Point_inside_polyhedron_3<MarkedPolyhedron, Kernel> is_in_poly( b );
+
+ if ( CGAL::ON_UNBOUNDED_SIDE == is_in_poly( a ) ) {
+ *out++ = a;
+ }
+
+ return out;
+}
+
+
+template < typename SegmentType , typename SegmentOrSurfaceType, typename SegmentOutputIteratorType>
+SegmentOutputIteratorType difference( const SegmentType& a, const SegmentOrSurfaceType& b, SegmentOutputIteratorType out )
+{
+ CGAL::Object inter = CGAL::intersection( a, b );
+ const SegmentType* s = CGAL::object_cast< SegmentType >( &inter );
+
+ if ( s ) { // there maybe zero, one or two segments as a result
+ if ( CGAL::squared_distance( a.source(), s->source() ) < CGAL::squared_distance( a.source(), s->target() ) ) {
+ if ( a.source() != s->source() ) {
+ *out++ = SegmentType( a.source(), s->source() );
+ }
+
+ if ( s->target() != a.target() ) {
+ *out++ = SegmentType( s->target(), a.target() );
+ }
+ }
+ else {
+ if ( a.source() != s->target() ) {
+ *out++ = SegmentType( a.source(), s->target() );
+ }
+
+ if ( s->source() != a.target() ) {
+ *out++ = SegmentType( s->source(), a.target() );
+ }
+ }
+ }
+ else { // intersection is a point or nothing, leave a unchanged
+ *out++ = a;
+ }
+
+ return out;
+}
+
+template<typename PointType>
+struct Nearer {
+ Nearer( const PointType& reference ) :_ref( reference ) {}
+ bool operator()( const PointType& lhs, const PointType& rhs ) const {
+ return CGAL::squared_distance( _ref, lhs ) < CGAL::squared_distance( _ref, rhs );
+ }
+private:
+ const PointType _ref;
+};
+
+template < typename SegmentOutputIteratorType>
+SegmentOutputIteratorType difference( const Segment_2& segment, const PolygonWH_2& polygon, SegmentOutputIteratorType out )
+{
+ // we could triangulate the polygon and substract each triangle
+ //
+ // we could also cut the line by polygon contours and test if the middle of the segment is inside
+ // but if the segment lies on the contour it's a special case
+ // we first substract the contours to take care of this
+ // special case, we obtain a vector of segments,
+ // for each segment of this vector, we subdivide it with the intersection
+ // points with the rings
+ // once done, we check, for each subdivision that has distinct end-points
+ // if the middle is in or out.
+
+ std::vector< Segment_2 > result( 1, segment );
+ std::vector< Polygon_2 > rings( 1, polygon.outer_boundary() );
+ rings.insert( rings.end(), polygon.holes_begin(), polygon.holes_end() );
+
+ for ( std::vector< Polygon_2 >::iterator ring = rings.begin(); ring != rings.end(); ++ring ) {
+ for ( Polygon_2::Vertex_const_iterator target = ring->vertices_begin();
+ target != ring->vertices_end(); ++target ) {
+ const Segment_2 sc( target == ring->vertices_begin()
+ ? *( ring->vertices_end() - 1 )
+ : *( target - 1 )
+ ,
+ *target );
+ std::vector< Segment_2 > tmp;
+
+ for ( std::vector< Segment_2 >::const_iterator s = result.begin(); s != result.end(); ++s ) {
+ difference( *s, sc, std::back_inserter( tmp ) );
+ }
+
+ tmp.swap( result );
+ }
+ }
+
+ for ( std::vector< Segment_2 >::const_iterator s = result.begin(); s != result.end(); ++s ) {
+ std::vector< Point_2 > points( 1, s->source() );
+
+ for ( std::vector< Polygon_2 >::iterator ring = rings.begin(); ring != rings.end(); ++ring ) {
+ for ( Polygon_2::Vertex_const_iterator target = ring->vertices_begin();
+ target != ring->vertices_end(); ++target ) {
+ Segment_2 sc( target == ring->vertices_begin()
+ ? *( ring->vertices_end() - 1 )
+ : *( target - 1 )
+ ,
+ *target );
+ CGAL::Object inter = CGAL::intersection( *s, sc );
+ const Point_2* p = CGAL::object_cast< Point_2 >( &inter );
+
+ if ( p ) {
+ points.push_back( *p );
+ }
+ }
+ }
+
+ points.push_back( s->target() );
+ // order point according to the distance from source
+ const Nearer<Point_2> nearer( s->source() );
+ std::sort( points.begin()+1, points.end()-1, nearer );
+
+ // append segments that has length and wich midpoint is outside polygon to result
+ for ( std::vector< Point_2 >::const_iterator p = points.begin(); p != points.end()-1; ++p ) {
+ std::vector< Point_2 >::const_iterator q = p+1;
+
+ if ( *p != *q && !do_intersect( CGAL::midpoint( *p,*q ), polygon ) ) {
+ *out++ = Segment_2( *p, *q );
+ }
+ }
+ }
+
+ return out;
+}
+
+// assuming two disjoint (except at a point) polygon, test if the first a hole of the second
+inline
+bool isHoleOf( const Polygon_2& hole, const Polygon_2& poly )
+{
+ return CGAL::bounded_side_2( poly.vertices_begin(),
+ poly.vertices_end(), *hole.vertices_begin(), Kernel() )
+ == CGAL::ON_BOUNDED_SIDE ||
+ CGAL::bounded_side_2( poly.vertices_begin(),
+ poly.vertices_end(), *( hole.vertices_begin()+1 ), Kernel() )
+ == CGAL::ON_BOUNDED_SIDE ;
+
+}
+
+template < typename PolygonOutputIteratorType>
+PolygonOutputIteratorType fix_cgal_valid_polygon( const PolygonWH_2& p, PolygonOutputIteratorType out )
+{
+ const Polygon_2& outer = p.outer_boundary();
+
+ //std::cerr << "in fix outer " << outer << "\n";
+ if ( !outer.is_simple() ) {
+ // the holes are simple, so we need to find the intersection points, then split
+ // the outer ring into simple components and put holes in the right one
+ // note that the hole may touch the outer boundary at a point,
+ // so if the tested hole point falls on the boundary, we test the next
+
+ std::vector< Polygon_2 > boundaries;
+ std::vector< std::vector<Point_2> > stack( 1 );
+
+ for ( Polygon_2::Vertex_const_iterator v = outer.vertices_begin();
+ v != outer.vertices_end(); ++v ) {
+ if ( stack.back().size() && stack.back()[0] == *v ) { // closing ring
+ boundaries.push_back( Polygon_2( stack.back().begin(), stack.back().end() ) );
+ stack.pop_back();
+ }
+ else if ( std::find( v+1, outer.vertices_end(), *v ) != outer.vertices_end() ) { //split point
+ stack.back().push_back( *v );
+ stack.resize( stack.size() + 1 );
+ stack.back().push_back( *v );
+ }
+ else {
+ stack.back().push_back( *v );
+ }
+ }
+
+ if ( stack.size() ) {
+ boundaries.push_back( Polygon_2( stack.back().begin(), stack.back().end() ) );
+ }
+
+ //std::cerr << "in fix boundaries " << boundaries.size() << "\n";
+
+ std::vector<Polygon_2> holes( p.holes_begin(), p.holes_end() );
+
+ // one of the boundaries may be a hole
+ std::vector< Polygon_2 > cw;
+ std::vector< Polygon_2 > ccw;
+
+ for ( std::vector< Polygon_2 >::const_iterator b = boundaries.begin();
+ b != boundaries.end(); ++b ) {
+ if ( b->orientation() == CGAL::CLOCKWISE ) {
+ cw.push_back( *b );
+ }
+ else {
+ ccw.push_back( *b );
+ }
+ }
+
+ //std::cerr << "in fix " << ccw.size() << " ccw and " << cw.size() << " cw\n";
+
+ // if we have holes, check the orientation of the first hole to see
+ // what is a hole orientation
+ // if we don't have holes, we test if the first ccw is a hole of any
+ // of the cw, if not, then the other are holes
+ bool holesAreCCW = false;
+
+ if ( !cw.size() ) {
+ holesAreCCW = false;
+ }
+ else if ( !ccw.size() ) {
+ holesAreCCW = true;
+ }
+ else if ( holes.size() ) {
+ holesAreCCW = holes[0].orientation() != CGAL::CLOCKWISE;
+ }
+ else {
+ for ( std::vector< Polygon_2 >::const_iterator b = cw.begin();
+ b != boundaries.end(); ++b ) {
+ if ( isHoleOf( ccw[0], *b ) ) {
+ holesAreCCW = true;
+ break;
+ }
+ }
+ }
+
+ if ( holesAreCCW ) {
+ holes.insert( holes.end(), ccw.begin(), ccw.end() );
+ boundaries.swap( cw );
+ }
+ else {
+ holes.insert( holes.end(), cw.begin(), cw.end() );
+ boundaries.swap( ccw );
+ }
+
+ std::vector< std::vector< Polygon_2 > > sortedHoles( boundaries.size() ); // 1/1 with boudaries
+
+ unsigned nbHoles = 0;
+
+ for ( std::vector< Polygon_2 >::const_iterator h = holes.begin(); h != holes.end(); ++h ) {
+ ++nbHoles;
+
+ for ( std::vector< Polygon_2 >::const_iterator b = boundaries.begin();
+ b != boundaries.end(); ++b ) {
+ if ( isHoleOf( *h, *b ) ) {
+ sortedHoles[ b - boundaries.begin() ].push_back( *h );
+ }
+ }
+ }
+
+ for ( unsigned i = 0; i < boundaries.size(); i++ ) {
+ *out++ = PolygonWH_2( boundaries[i], sortedHoles[i].begin(), sortedHoles[i].end() );
+ }
+
+ //std::cerr << "extracted " << boundaries.size() << " boundaries, dispatched " << nbHoles << " holes \n";
+ }
+ else {
+ *out++ = p;
+ }
+
+ return out;
+}
+
+inline
+PolygonWH_2
+fix_sfs_valid_polygon( const PolygonWH_2& p )
+{
+ CGAL::Gps_segment_traits_2<Kernel> traits;
+
+ if ( are_holes_and_boundary_pairwise_disjoint( p, traits ) ) {
+ return p;
+ }
+
+ // a polygon is valid for sfs and invalid for CGAL when two rings intersect
+ // on a point that is not a ring vertex
+ // we add this vertex to fix the polygon
+ // for each ring segment
+ // for every other ring point
+ // add point to segment
+
+ // put all rings in a vector to avoid distinction between outer and holes
+ std::vector< Polygon_2 > rings( 1, p.outer_boundary() );
+ rings.insert( rings.end(), p.holes_begin(), p.holes_end() );
+
+ std::vector< Polygon_2 > out;
+
+ for ( std::vector< Polygon_2 >::iterator ring = rings.begin(); ring != rings.end(); ++ring ) {
+ out.push_back( Polygon_2() );
+
+ for ( Polygon_2::Vertex_const_iterator target = ring->vertices_begin(); target != ring->vertices_end(); ++target ) {
+ Segment_2 segment(
+ target == ring->vertices_begin()
+ ? *( ring->vertices_end() - 1 )
+ : *( target - 1 )
+ ,
+ *target );
+
+ // for every other ring
+ for ( std::vector< Polygon_2 >::const_iterator other = rings.begin(); other != rings.end(); ++other ) {
+ if ( ring == other ) {
+ continue;
+ }
+
+ for ( Polygon_2::Vertex_const_iterator vertex = other->vertices_begin();
+ vertex != other->vertices_end(); ++vertex ) {
+ if ( CGAL::do_intersect( *vertex, segment ) ) {
+ out.back().push_back( *vertex );
+ }
+ }
+ }
+
+ out.back().push_back( *target );
+ }
+ }
+
+ return PolygonWH_2( out[0], out.begin()+1, out.end() );
+}
+
+template < typename OutputIteratorType >
+OutputIteratorType difference( const Triangle_3& p, const Triangle_3& q, OutputIteratorType out )
+{
+
+ const Plane_3 plane = p.supporting_plane();
+
+ if ( plane != q.supporting_plane() || !CGAL::do_intersect( p,q ) ) {
+ *out++ = p;
+ }
+ else {
+ // project on plane
+ // difference between polygons
+ // triangulate the result
+
+ PolygonWH_2 pProj, qProj;
+
+ for ( unsigned i=0; i<3; i++ ) {
+ pProj.outer_boundary().push_back( plane.to_2d( p.vertex( i ) ) );
+ qProj.outer_boundary().push_back( plane.to_2d( q.vertex( i ) ) );
+ }
+
+ std::vector< PolygonWH_2 > res;
+ difference( pProj, qProj, std::back_inserter( res ) );
+
+
+ for ( std::vector< PolygonWH_2 >::const_iterator i = res.begin(); i != res.end(); ++i ) {
+ const Polygon poly( *i );
+ TriangulatedSurface ts;
+ triangulate::triangulatePolygon3D( poly, ts );
+
+ for ( TriangulatedSurface::iterator t = ts.begin(); t != ts.end(); ++t ) {
+ *out++ = Triangle_3( plane.to_3d( t->vertex( 0 ).toPoint_2() ),
+ plane.to_3d( t->vertex( 1 ).toPoint_2() ),
+ plane.to_3d( t->vertex( 2 ).toPoint_2() ) ) ;
+ }
+ }
+ }
+
+ return out;
+}
+
+template < typename VolumeOutputIteratorType>
+VolumeOutputIteratorType difference( const MarkedPolyhedron& a, const MarkedPolyhedron& b, VolumeOutputIteratorType out )
+{
+ MarkedPolyhedron& p = const_cast<MarkedPolyhedron&>( a );
+ MarkedPolyhedron& q = const_cast<MarkedPolyhedron&>( b );
+ typedef CGAL::Polyhedron_corefinement<MarkedPolyhedron> Corefinement;
+ Corefinement coref;
+ CGAL::Emptyset_iterator no_polylines;
+ typedef std::vector<std::pair<MarkedPolyhedron*, int> > ResultType;
+ ResultType result;
+ coref( p, q, no_polylines, std::back_inserter( result ), Corefinement::P_minus_Q_tag );
+
+ for ( ResultType::iterator it = result.begin(); it != result.end(); it++ ) {
+ *out++ = *it->first;
+ delete it->first;
+ }
+
+ return out;
+}
+
+typedef CGAL::Box_intersection_d::Box_with_handle_d<double,3,MarkedPolyhedron::Halfedge_around_facet_const_circulator> FaceBboxBase;
+
+
+struct FaceBbox: FaceBboxBase {
+ struct Bbox: CGAL::Bbox_3 {
+ Bbox( MarkedPolyhedron::Halfedge_around_facet_const_circulator handle )
+ : CGAL::Bbox_3( handle->vertex()->point().bbox() ) {
+ const MarkedPolyhedron::Halfedge_around_facet_const_circulator end = handle;
+
+ do {
+ // @note with CGAL 4.5 you would write simply
+ // *this += (++handle)->vertex()->point().bbox();
+ this->CGAL::Bbox_3::operator=( *this + ( ++handle )->vertex()->point().bbox() );
+ }
+ while ( handle != end );
+ }
+ };
+
+ FaceBbox( const MarkedPolyhedron::Facet& facet )
+ : FaceBboxBase( Bbox( facet.facet_begin() ), facet.facet_begin() ) {
+ }
+};
+
+struct FaceSegmentCollide {
+ typedef std::vector< MarkedPolyhedron::Halfedge_around_facet_const_circulator > CollisionVector;
+ FaceSegmentCollide( CollisionVector& list ): _list( list ) {}
+ void operator()( const FaceBboxBase&, const FaceBboxBase& face ) {
+ _list.push_back( face.handle() );
+ }
+private:
+ CollisionVector& _list;
+};
+
+template < typename TriangleOutputIteratorType>
+TriangleOutputIteratorType collidingTriangles( const FaceSegmentCollide::CollisionVector& collisions, TriangleOutputIteratorType out )
+{
+ for ( FaceSegmentCollide::CollisionVector::const_iterator cit = collisions.begin();
+ cit != collisions.end(); ++cit ) {
+ MarkedPolyhedron::Halfedge_around_facet_const_circulator it = *cit;
+ std::vector< Point > points( 1, it->vertex()->point() );
+
+ do {
+ points.push_back( ( ++it )->vertex()->point() );
+ }
+ while ( it != *cit );
+
+ if ( points.size() == 3 ) {
+ *out++ = Triangle_3( points[0].toPoint_3(), points[1].toPoint_3(), points[2].toPoint_3() ) ;
+ }
+ else {
+ const Polygon poly( points );
+ TriangulatedSurface ts;
+ triangulate::triangulatePolygon3D( poly, ts );
+
+ for ( TriangulatedSurface::iterator t = ts.begin(); t != ts.end(); ++t ) {
+ *out++ = Triangle_3( t->vertex( 0 ).toPoint_3(),
+ t->vertex( 1 ).toPoint_3(),
+ t->vertex( 2 ).toPoint_3() );
+ }
+ }
+ }
+
+ return out;
+}
+
+
+template < typename SegmentOutputIteratorType>
+SegmentOutputIteratorType difference( const Segment_3& segment, const MarkedPolyhedron& polyhedron, SegmentOutputIteratorType out )
+{
+ // this is a bit of a pain
+ // the algo should follow the same lines as the Segment_2 - PolygonWH_2
+ // namely, remove the pieces of the segment were it touches facets,
+ // then compute the intersections with facets to cut the segments and
+ // create segments for output were the middle point is inside
+ //
+ // to speed thing up we put facets in AABB-Tree
+
+ std::vector< FaceBbox > bboxes( polyhedron.facets_begin(), polyhedron.facets_end() );
+ std::vector< FaceBboxBase > bbox( 1, FaceBboxBase( segment.bbox(),polyhedron.facets_begin()->facet_begin() ) ); // nevermind the facet handle, it's not used anyway
+ FaceSegmentCollide::CollisionVector collisions;
+ FaceSegmentCollide cb( collisions );
+ CGAL::box_intersection_d( bbox.begin(), bbox.end(),
+ bboxes.begin(), bboxes.end(),
+ cb );
+
+ if ( !collisions.size() ) {
+ // completely in or out, we just test one point
+ CGAL::Point_inside_polyhedron_3<MarkedPolyhedron, Kernel> is_in_poly( polyhedron );
+
+ if ( CGAL::ON_UNBOUNDED_SIDE == is_in_poly( segment.source() ) ) {
+ *out++ = segment;
+ }
+ }
+ else {
+ std::vector< Triangle_3 > triangles;
+ collidingTriangles( collisions, std::back_inserter( triangles ) );
+
+ // first step, substract faces
+ std::vector< Segment_3 > res1( 1, segment );
+
+ for ( std::vector< Triangle_3 >::const_iterator tri=triangles.begin();
+ tri != triangles.end(); ++tri ) {
+ std::vector< Segment_3 > tmp;
+
+ for ( std::vector< Segment_3 >::const_iterator seg = res1.begin();
+ seg != res1.end(); ++seg ) {
+ difference( *seg, *tri, std::back_inserter( tmp ) );
+ }
+
+ res1.swap( tmp );
+ }
+
+ // second step, for each segment, add intersection points and test each middle point
+ // to know if it's in or out
+ for ( std::vector< Segment_3 >::const_iterator seg = res1.begin();
+ seg != res1.end(); ++seg ) {
+ std::vector< Point_3 > points( 1, seg->source() );
+
+ for ( std::vector< Triangle_3 >::const_iterator tri=triangles.begin();
+ tri != triangles.end(); ++tri ) {
+ CGAL::Object inter = CGAL::intersection( *seg, *tri );
+ const Point_3* p = CGAL::object_cast< Point_3 >( &inter );
+
+ if ( p ) {
+ points.push_back( *p );
+ }
+ }
+
+ points.push_back( seg->target() );
+ // order point according to the distance from source
+
+ const Nearer<Point_3> nearer( seg->source() );
+ std::sort( points.begin()+1, points.end()-1, nearer );
+
+ CGAL::Point_inside_polyhedron_3<MarkedPolyhedron, Kernel> is_in_poly( polyhedron );
+
+ // append segments that has length and wich midpoint is outside polyhedron to result
+ for ( std::vector< Point_3 >::const_iterator p = points.begin(); p != points.end()-1; ++p ) {
+ std::vector< Point_3 >::const_iterator q = p+1;
+
+ if ( *p != *q && CGAL::ON_UNBOUNDED_SIDE == is_in_poly( CGAL::midpoint( *p,*q ) ) ) {
+ *out++ = Segment_3( *p, *q );
+ }
+ }
+ }
+ }
+
+ return out;
+}
+
+// @TODO put that in a proper header
+void _intersection_solid_triangle( const MarkedPolyhedron& pa, const Triangle_3& tri, detail::GeometrySet<3>& output );
+
+
+template < typename TriangleOutputIteratorType>
+TriangleOutputIteratorType difference( const Triangle_3& triangle, const MarkedPolyhedron& polyhedron, TriangleOutputIteratorType out )
+{
+ std::vector< Triangle_3 > inter;
+ // call _intersection_solid_triangle
+ detail::GeometrySet<3> interSet;
+ _intersection_solid_triangle( polyhedron, triangle, interSet );
+
+ for ( detail::GeometrySet<3>::SurfaceCollection::const_iterator it = interSet.surfaces().begin();
+ it != interSet.surfaces().end(); ++it ) {
+ inter.push_back( it->primitive() );
+ }
+
+
+
+ std::vector< Triangle_3 > res( 1, triangle );
+
+ // GOTCHA for intersection points (volume touching triangle) , need to retriangulate
+ for ( detail::GeometrySet<3>::PointCollection::const_iterator it = interSet.points().begin();
+ it != interSet.points().end(); ++it ) {
+ std::vector< Triangle_3 > tmp;
+
+ for ( std::vector< Triangle_3 >::const_iterator tri = res.begin(); tri != res.end(); ++tri ) {
+ const Point_3 p( it->primitive() );
+
+ for ( int s = 0; s<3; s++ ) {
+ if ( p != tri->vertex( s ) && p != tri->vertex( ( s+1 )%3 )
+ && Segment_3( tri->vertex( s ), tri->vertex( ( s+1 )%3 ) ).has_on( p ) ) {
+ tmp.push_back( Triangle_3( tri->vertex( s ), p, tri->vertex( ( s+2 )%3 ) ) );
+ tmp.push_back( Triangle_3( p, tri->vertex( ( s+1 )%3 ), tri->vertex( ( s+2 )%3 ) ) );
+ }
+ }
+ }
+
+ tmp.swap( res );
+ }
+
+
+ for ( std::vector< Triangle_3 >::const_iterator it = inter.begin(); it != inter.end(); ++it ) {
+ std::vector< Triangle_3 > tmp;
+
+ for ( std::vector< Triangle_3 >::const_iterator tri = res.begin(); tri != res.end(); ++tri ) {
+ difference( *tri, *it, std::back_inserter( tmp ) );
+ }
+
+ tmp.swap( res );
+ }
+
+ for ( std::vector< Triangle_3 >::const_iterator tri = res.begin(); tri != res.end(); ++tri ) {
+ *out++ = *tri;
+ }
+
+ return out;
+
+ /*
+ std::vector< FaceBbox > bboxes(polyhedron.facets_begin(), polyhedron.facets_end() );
+ std::vector< FaceBboxBase > bbox( 1, FaceBboxBase(triangle.bbox(),polyhedron.facets_begin()->facet_begin()) ); // nevermind the facet handle, it's not used anyway
+ FaceSegmentCollide::CollisionVector collisions;
+ FaceSegmentCollide cb(collisions);
+ CGAL::box_intersection_d( bbox.begin(), bbox.end(),
+ bboxes.begin(), bboxes.end(),
+ cb );
+
+ if ( !collisions.size() ){
+ // completely in or out, we just test one point
+ CGAL::Point_inside_polyhedron_3<MarkedPolyhedron, Kernel> is_in_poly( polyhedron );
+ if ( CGAL::ON_UNBOUNDED_SIDE == is_in_poly( triangle.vertex(0) ) ) *out++ = triangle;
+ }
+ else {
+ // now we first transform bboxes colliding faces into triangles
+ // then we test for intersection and store resulting segments in a vector
+ // we also store resulting polygons as segments
+ //
+ // we need to convert the resulting segments to a multipolygon of sort
+ //
+ // finally we triangulate the result and substract those triangles
+ //
+ std::vector< Triangle_3 > interTriangles;
+ collidingTriangles( collisions, std::back_inserter( interTriangles ) );
+
+ std::vector< Segment_3 > intersectionCountours;
+
+ BOOST_THROW_EXCEPTION(NotImplementedException("Triangle_3 - Volume is not implemented") );
+ }
+ return out;
+ */
+}
+
+template < typename PolygonOutputIteratorType>
+PolygonOutputIteratorType difference( const PolygonWH_2& a, const PolygonWH_2& b, PolygonOutputIteratorType out )
+{
+ CGAL::Gps_segment_traits_2<Kernel> traits;
+
+ std::vector< PolygonWH_2 > temp;
+ CGAL::difference(
+ are_holes_and_boundary_pairwise_disjoint( a, traits ) ? a : fix_sfs_valid_polygon( a ),
+ are_holes_and_boundary_pairwise_disjoint( b, traits ) ? b : fix_sfs_valid_polygon( b ),
+ std::back_inserter( temp ) );
+
+ // polygon outer rings from difference can self intersect at points
+ // therefore we need to split the generated polygons so that they are valid for SFS
+ for ( std::vector< PolygonWH_2 >::const_iterator poly=temp.begin(); poly!=temp.end(); ++poly ) {
+ out = fix_cgal_valid_polygon( *poly, out );
+ }
+
+ return out;
+}
+
+
+}
+}
+#endif
diff --git a/src/algorithm/distance.cpp b/src/algorithm/distance.cpp
new file mode 100644
index 0000000..2dc5c7e
--- /dev/null
+++ b/src/algorithm/distance.cpp
@@ -0,0 +1,612 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/distance.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+
+#include <SFCGAL/algorithm/isValid.h>
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Exception.h>
+
+#include <CGAL/Polygon_with_holes_2.h>
+#include <CGAL/Polygon_2_algorithms.h>
+
+#include <SFCGAL/detail/transform/AffineTransform3.h>
+#include <SFCGAL/algorithm/intersects.h>
+#include <SFCGAL/detail/GetPointsVisitor.h>
+
+
+typedef SFCGAL::Kernel::Point_2 Point_2 ;
+typedef SFCGAL::Kernel::Vector_2 Vector_2 ;
+typedef SFCGAL::Kernel::Segment_2 Segment_2 ;
+
+typedef CGAL::Polygon_2< SFCGAL::Kernel > Polygon_2 ;
+typedef CGAL::Polygon_with_holes_2< SFCGAL::Kernel > Polygon_with_holes_2 ;
+
+
+
+namespace SFCGAL {
+namespace algorithm {
+
+///
+///
+///
+double distance( const Geometry& gA, const Geometry& gB, NoValidityCheck )
+{
+ switch ( gA.geometryTypeId() ) {
+ case TYPE_POINT:
+ return distancePointGeometry( gA.as< Point >(), gB ) ;
+
+ case TYPE_LINESTRING:
+ return distanceLineStringGeometry( gA.as< LineString >(), gB ) ;
+
+ case TYPE_POLYGON:
+ return distancePolygonGeometry( gA.as< Polygon >(), gB ) ;
+
+ case TYPE_TRIANGLE:
+ return distanceTriangleGeometry( gA.as< Triangle >(), gB ) ;
+
+ case TYPE_MULTIPOINT:
+ case TYPE_MULTILINESTRING:
+ case TYPE_MULTIPOLYGON:
+ case TYPE_MULTISOLID:
+ case TYPE_GEOMETRYCOLLECTION:
+ case TYPE_TRIANGULATEDSURFACE:
+ case TYPE_POLYHEDRALSURFACE:
+ return distanceGeometryCollectionToGeometry( gA, gB );
+
+ case TYPE_SOLID:
+ BOOST_THROW_EXCEPTION( NotImplementedException(
+ ( boost::format( "distance(%s,%s) is not implemented" ) % gA.geometryType() % gB.geometryType() ).str()
+ ) );
+ }
+
+ BOOST_ASSERT( false );
+ return 0;
+}
+
+double distance( const Geometry& gA, const Geometry& gB )
+{
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_2D( gA );
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_2D( gB );
+ return distance( gA, gB, NoValidityCheck() );
+}
+
+///
+///
+///
+double distancePointGeometry( const Point& gA, const Geometry& gB )
+{
+ switch ( gB.geometryTypeId() ) {
+ case TYPE_POINT:
+ return distancePointPoint( gA, gB.as< Point >() );
+
+ case TYPE_LINESTRING:
+ return distancePointLineString( gA, gB.as< LineString >() );
+
+ case TYPE_POLYGON:
+ return distancePointPolygon( gA, gB.as< Polygon >() );
+
+ case TYPE_TRIANGLE:
+ return distancePointTriangle( gA, gB.as< Triangle >() );
+
+ //collection dispatch
+ case TYPE_MULTIPOINT:
+ case TYPE_MULTILINESTRING:
+ case TYPE_MULTIPOLYGON:
+ case TYPE_MULTISOLID:
+ case TYPE_GEOMETRYCOLLECTION:
+ case TYPE_TRIANGULATEDSURFACE:
+ case TYPE_POLYHEDRALSURFACE:
+ return distanceGeometryCollectionToGeometry( gB, gA );
+
+ case TYPE_SOLID:
+ BOOST_THROW_EXCEPTION( NotImplementedException(
+ ( boost::format( "distance(%s,%s) is not implemented" ) % gA.geometryType() % gB.geometryType() ).str()
+ ) );
+ }
+
+ BOOST_ASSERT( false );
+ return 0;
+}
+
+///
+///
+///
+double distancePointPoint( const Point& gA, const Point& gB )
+{
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ return CGAL::sqrt(
+ CGAL::to_double(
+ CGAL::squared_distance( gA.toPoint_2(), gB.toPoint_2() )
+ )
+ );
+}
+
+///
+///
+///
+double distancePointLineString( const Point& gA, const LineString& gB )
+{
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ size_t numSegments = gB.numSegments() ;
+
+ double dMin = std::numeric_limits< double >::infinity() ;
+
+ for ( size_t i = 0; i < numSegments; i++ ) {
+ double d = distancePointSegment( gA, gB.pointN( i ), gB.pointN( i+1 ) );
+
+ if ( i == 0 || d < dMin ) {
+ dMin = d ;
+ }
+ }
+
+ return dMin ;
+}
+
+///
+///
+///
+double distancePointPolygon( const Point& gA, const Polygon& gB )
+{
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ if ( intersects( gA , gB, NoValidityCheck() ) ) {
+ return 0.0 ;
+ }
+
+ double dMin = 0.0 ;
+
+ //check if the point is in the polygon
+ for ( size_t i = 0; i < gB.numRings(); i++ ) {
+ double d = distancePointLineString( gA, gB.ringN( i ) );
+
+ if ( i == 0 || d < dMin ) {
+ dMin = d ;
+ }
+ }
+
+ return dMin ;
+}
+
+///
+///
+///
+double distancePointTriangle( const Point& gA, const Triangle& gB )
+{
+ return distancePointPolygon( gA, gB.toPolygon() );
+}
+
+
+
+///
+///
+///
+double distanceLineStringGeometry( const LineString& gA, const Geometry& gB )
+{
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ switch ( gB.geometryTypeId() ) {
+ case TYPE_POINT:
+ return distancePointLineString( gB.as< Point >(), gA ); //symetric
+
+ case TYPE_LINESTRING:
+ return distanceLineStringLineString( gA, gB.as< LineString >() );
+
+ case TYPE_POLYGON:
+ return distanceLineStringPolygon( gA, gB.as< Polygon >() );
+
+ case TYPE_TRIANGLE:
+ return distanceLineStringTriangle( gA, gB.as< Triangle >() );
+
+ //collection dispatch
+ case TYPE_MULTIPOINT:
+ case TYPE_MULTILINESTRING:
+ case TYPE_MULTIPOLYGON:
+ case TYPE_MULTISOLID:
+ case TYPE_GEOMETRYCOLLECTION:
+ case TYPE_TRIANGULATEDSURFACE:
+ case TYPE_POLYHEDRALSURFACE:
+ return distanceGeometryCollectionToGeometry( gB, gA );
+
+ case TYPE_SOLID:
+ BOOST_THROW_EXCEPTION( NotImplementedException(
+ ( boost::format( "distance(%s,%s) is not implemented" ) % gA.geometryType() % gB.geometryType() ).str()
+ ) );
+ }
+
+ BOOST_ASSERT( false );
+ return 0;
+}
+
+///
+///
+///
+double distanceLineStringLineString( const LineString& gA, const LineString& gB )
+{
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ size_t nsA = gA.numSegments() ;
+ size_t nsB = gB.numSegments() ;
+
+ double dMin = std::numeric_limits< double >::infinity() ;
+
+ for ( size_t i = 0; i < nsA; i++ ) {
+ for ( size_t j = 0; j < nsB; j++ ) {
+ dMin = std::min(
+ dMin,
+ distanceSegmentSegment(
+ gA.pointN( i ), gA.pointN( i+1 ),
+ gB.pointN( j ), gB.pointN( j+1 )
+ )
+ ) ;
+ }
+ }
+
+ return dMin ;
+}
+
+
+///
+///
+///
+double distanceLineStringPolygon( const LineString& gA, const Polygon& gB )
+{
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ if ( intersects( gA, gB, NoValidityCheck() ) ) {
+ return 0.0 ;
+ }
+
+ double dMin = std::numeric_limits< double >::infinity() ;
+
+ for ( size_t i = 0; i < gB.numRings(); i++ ) {
+ double d = distanceLineStringLineString( gA, gB.ringN( i ) );
+
+ if ( d < dMin ) {
+ dMin = d ;
+ }
+ }
+
+ return dMin ;
+}
+
+
+///
+///
+///
+double distanceLineStringTriangle( const LineString& gA, const Triangle& gB )
+{
+ return distanceLineStringPolygon( gA, gB.toPolygon() );
+}
+
+
+
+
+
+///
+///
+///
+double distancePolygonGeometry( const Polygon& gA, const Geometry& gB )
+{
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ switch ( gB.geometryTypeId() ) {
+ case TYPE_POINT:
+ return distancePointPolygon( gB.as< Point >(), gA ); //symetric
+
+ case TYPE_LINESTRING:
+ return distanceLineStringPolygon( gB.as< LineString >(), gA ); //symetric
+
+ case TYPE_POLYGON:
+ return distancePolygonPolygon( gA, gB.as< Polygon >() );
+
+ case TYPE_TRIANGLE:
+ return distancePolygonTriangle( gA, gB.as< Triangle >() );
+
+ //collection dispatch
+ case TYPE_MULTIPOINT:
+ case TYPE_MULTILINESTRING:
+ case TYPE_MULTIPOLYGON:
+ case TYPE_MULTISOLID:
+ case TYPE_GEOMETRYCOLLECTION:
+ case TYPE_TRIANGULATEDSURFACE:
+ case TYPE_POLYHEDRALSURFACE:
+ return distanceGeometryCollectionToGeometry( gB, gA );
+
+ case TYPE_SOLID:
+ BOOST_THROW_EXCEPTION( NotImplementedException(
+ ( boost::format( "distance(%s,%s) is not implemented" ) % gA.geometryType() % gB.geometryType() ).str()
+ ) );
+ }
+
+ BOOST_ASSERT( false );
+ return 0;
+}
+
+///
+///
+///
+double distancePolygonPolygon( const Polygon& gA, const Polygon& gB )
+{
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ if ( intersects( gA, gB, NoValidityCheck() ) ) {
+ return 0.0 ;
+ }
+
+ double dMin = std::numeric_limits< double >::infinity() ;
+
+ for ( size_t i = 0; i < gA.numRings(); i++ ) {
+ for ( size_t j = 0; j < gB.numRings(); j++ ) {
+ double d = distanceLineStringLineString( gA.ringN( i ), gB.ringN( j ) );
+
+ if ( d < dMin ) {
+ dMin = d ;
+ }
+ }
+ }
+
+ return dMin ;
+}
+
+///
+///
+///
+double distancePolygonTriangle( const Polygon& gA, const Triangle& gB )
+{
+ return distancePolygonPolygon( gA, gB.toPolygon() );
+}
+
+///
+///
+///
+double distanceTriangleGeometry( const Triangle& gA, const Geometry& gB )
+{
+ return distancePolygonGeometry( gA.toPolygon(), gB );
+}
+
+struct Circle {
+ Circle( const double& r, CGAL::Vector_2<Kernel>& c )
+ : _radius( r )
+ , _center( c )
+ , _empty( false ) {
+ }
+ Circle()
+ : _empty( true ) {
+ }
+ bool isEmpty() const {
+ return _empty;
+ }
+ double radius() const {
+ BOOST_ASSERT( !_empty );
+ return _radius;
+ }
+ const CGAL::Vector_2<Kernel>& center() const {
+ BOOST_ASSERT( !_empty );
+ return _center;
+ }
+private:
+ double _radius;
+ CGAL::Vector_2<Kernel> _center;
+ bool _empty;
+};
+
+const Circle boundingCircle( const Geometry& geom )
+{
+ if ( geom.isEmpty() ) {
+ return Circle();
+ }
+
+ using namespace SFCGAL::detail;
+ GetPointsVisitor v;
+ const_cast< Geometry& >( geom ).accept( v );
+
+ if( !v.points.size() ) {
+ return Circle();
+ }
+
+ typedef CGAL::Vector_2< Kernel > Vector_2 ;
+
+ const GetPointsVisitor::const_iterator end = v.points.end();
+
+ // centroid
+ Vector_2 c( 0,0 );
+ int numPoint = 0;
+
+ for ( GetPointsVisitor::const_iterator x = v.points.begin(); x != end; ++x ) {
+ c = c + ( *x )->toVector_2() ;
+ ++numPoint;
+ }
+
+ BOOST_ASSERT( numPoint );
+ c = c / numPoint;
+
+ // farest point from centroid
+ Vector_2 f = c ;
+ Kernel::FT maxDistanceSq = 0;
+
+ for ( GetPointsVisitor::const_iterator x = v.points.begin(); x != end; ++x ) {
+ const Vector_2 cx = ( *x )->toVector_2() - c ;
+ const Kernel::FT dSq = cx * cx ;
+
+ if ( dSq > maxDistanceSq ) {
+ f = ( *x )->toVector_2() ;
+ maxDistanceSq = dSq ;
+ }
+ }
+
+ return Circle( std::sqrt( CGAL::to_double( maxDistanceSq ) ), c );
+}
+
+///
+///
+///
+double distanceGeometryCollectionToGeometry( const Geometry& gA, const Geometry& gB )
+{
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ // if bounding spheres (BS) of gB and gAi don't intersect and
+ // if the closest point of BS(gAj) is further than the farest
+ // point of BS(gAi) there is no need to compute the distance(gAj, gB)
+ // since it will be greater than distance(gAi, gB)
+ //
+ // The aim is not to find the minimal bounding sphere, but a good enought sphere than
+ // encloses all points
+ std::set<size_t> noTest;
+
+ if ( 1 ) {
+ std::vector<Circle> bcA;
+
+ for ( size_t i = 0; i < gA.numGeometries(); i++ ) {
+ bcA.push_back( boundingCircle( gA.geometryN( i ) ) );
+ }
+
+ Circle bcB( boundingCircle( gB ) );
+
+ if ( bcB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ std::vector<size_t> noIntersect;
+
+ for ( size_t i = 0; i < gA.numGeometries(); i++ ) {
+ if ( bcA[i].isEmpty() ) {
+ continue;
+ }
+
+ const double l2 = CGAL::to_double( ( bcB.center() - bcA[i].center() ).squared_length() );
+
+ if ( std::pow( bcB.radius() + bcA[i].radius(), 2 ) < l2 ) {
+ noIntersect.push_back( i );
+ }
+ }
+
+ for ( size_t i = 0; i < noIntersect.size(); i++ ) {
+ const double li = std::sqrt( CGAL::to_double( ( bcA[noIntersect[i]].center() - bcB.center() ).squared_length() ) );
+
+ for ( size_t j = i; j < noIntersect.size(); j++ ) {
+ const double lj = std::sqrt( CGAL::to_double( ( bcA[noIntersect[j]].center() - bcB.center() ).squared_length() ) );
+
+ if ( li + bcA[noIntersect[i]].radius() < lj - bcA[noIntersect[j]].radius() ) {
+ noTest.insert( noIntersect[j] );
+ }
+ else if ( lj + bcA[noIntersect[j]].radius() < li - bcA[noIntersect[i]].radius() ) {
+ noTest.insert( noIntersect[i] );
+ }
+ }
+ }
+
+ //if (!noTest.empty()) std::cout << "pruning " << noTest.size() << "/" << gA.numGeometries() << "\n";
+ }
+
+ double dMin = std::numeric_limits< double >::infinity() ;
+
+ for ( size_t i = 0; i < gA.numGeometries(); i++ ) {
+ if ( noTest.end() != noTest.find( i ) ) {
+ continue;
+ }
+
+ dMin = std::min( dMin, distance( gA.geometryN( i ), gB ) );
+ }
+
+ return dMin ;
+}
+
+
+
+
+//--- private
+
+
+
+///
+///
+///
+double distancePointSegment( const Point& p, const Point& a, const Point& b )
+{
+ // empty already checked
+ BOOST_ASSERT( ! p.isEmpty() );
+ BOOST_ASSERT( ! a.isEmpty() );
+ BOOST_ASSERT( ! b.isEmpty() );
+
+ return CGAL::sqrt(
+ CGAL::to_double(
+ CGAL::squared_distance(
+ p.toPoint_2(),
+ Segment_2(
+ a.toPoint_2(),
+ b.toPoint_2()
+ )
+ )
+ )
+ );
+}
+
+///
+///
+///
+double distanceSegmentSegment( const Point& a, const Point& b, const Point& c, const Point& d )
+{
+ // empty already checked
+ BOOST_ASSERT( ! a.isEmpty() );
+ BOOST_ASSERT( ! b.isEmpty() );
+ BOOST_ASSERT( ! c.isEmpty() );
+ BOOST_ASSERT( ! d.isEmpty() );
+
+ return CGAL::sqrt( CGAL::to_double(
+ CGAL::squared_distance(
+ CGAL::Segment_2< Kernel >( a.toPoint_2(), b.toPoint_2() ),
+ CGAL::Segment_2< Kernel >( c.toPoint_2(), d.toPoint_2() )
+ )
+ ) );
+}
+
+
+}//namespace algorithm
+}//namespace SFCGAL
diff --git a/src/algorithm/distance.h b/src/algorithm/distance.h
new file mode 100644
index 0000000..6ad8538
--- /dev/null
+++ b/src/algorithm/distance.h
@@ -0,0 +1,142 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_ALGORITHM_DISTANCE_H_
+#define _SFCGAL_ALGORITHM_DISTANCE_H_
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Geometry.h>
+
+
+namespace SFCGAL {
+namespace algorithm {
+struct NoValidityCheck;
+
+/**
+ * Compute the distance between two Geometries
+ * @ingroup public_api
+ * @pre gA is a valid geometry
+ * @pre gB is a valid geometry
+ */
+SFCGAL_API double distance( const Geometry& gA, const Geometry& gB ) ;
+
+/**
+ * Compute the distance between two Geometries
+ * @ingroup detail
+ * @pre gA is a valid geometry
+ * @pre gB is a valid geometry
+ * @warning No actual validity check is done
+ */
+SFCGAL_API double distance( const Geometry& gA, const Geometry& gB, NoValidityCheck ) ;
+
+/**
+ * dispatch distance from Point to Geometry
+ * @ingroup detail
+ */
+SFCGAL_API double distancePointGeometry( const Point& gA, const Geometry& gB ) ;
+/**
+ * distance between two Points
+ * @ingroup detail
+ */
+SFCGAL_API double distancePointPoint( const Point& gA, const Point& gB ) ;
+/**
+ * distance between a Point and a LineString
+ * @ingroup detail
+ */
+SFCGAL_API double distancePointLineString( const Point& gA, const LineString& gB ) ;
+/**
+ * distance between a Point and a Polygon
+ * @ingroup detail
+ */
+SFCGAL_API double distancePointPolygon( const Point& gA, const Polygon& gB ) ;
+/**
+ * distance between a Point and a Triangle
+ * @ingroup detail
+ */
+SFCGAL_API double distancePointTriangle( const Point& gA, const Triangle& gB ) ;
+
+/**
+ * dispatch distance from LineString to Geometry
+ * @ingroup detail
+ */
+SFCGAL_API double distanceLineStringGeometry( const LineString& gA, const Geometry& gB ) ;
+/**
+ * distance between two LineStrings
+ * @ingroup detail
+ */
+SFCGAL_API double distanceLineStringLineString( const LineString& gA, const LineString& gB ) ;
+/**
+ * distance between a LineString and a Polygon
+ * @ingroup detail
+ */
+SFCGAL_API double distanceLineStringPolygon( const LineString& gA, const Polygon& gB ) ;
+/**
+ * distance between a LineString and a Triangle
+ * @ingroup detail
+ */
+SFCGAL_API double distanceLineStringTriangle( const LineString& gA, const Triangle& gB ) ;
+
+/**
+ * dispatch distance from Polygon to Geometry
+ * @ingroup detail
+ */
+SFCGAL_API double distancePolygonGeometry( const Polygon& gA, const Geometry& gB ) ;
+/**
+ * distance between two Polygons
+ * @ingroup detail
+ */
+SFCGAL_API double distancePolygonPolygon( const Polygon& gA, const Polygon& gB ) ;
+/**
+ * distance between a Polygon and a Triangle
+ * @ingroup detail
+ */
+SFCGAL_API double distancePolygonTriangle( const Polygon& gA, const Triangle& gB ) ;
+
+
+/**
+ * dispatch distance from a Triangle to a Geometry
+ * @ingroup detail
+ */
+SFCGAL_API double distanceTriangleGeometry( const Triangle& gA, const Geometry& gB ) ;
+
+
+/**
+ * dispatch distance from a collection of geometry (gA) to a Geometry (gB)
+ * @ingroup detail
+ */
+SFCGAL_API double distanceGeometryCollectionToGeometry( const Geometry& gA, const Geometry& gB ) ;
+
+
+
+/**
+ * @ingroup detail
+ */
+SFCGAL_API double distancePointSegment( const Point& p, const Point& a, const Point& b ) ;
+
+/**
+ * @ingroup detail
+ */
+SFCGAL_API double distanceSegmentSegment( const Point& a, const Point& b, const Point& c, const Point& d );
+
+}//namespace algorithm
+}//namespace SFCGAL
+
+#endif
diff --git a/src/algorithm/distance3d.cpp b/src/algorithm/distance3d.cpp
new file mode 100644
index 0000000..15e4d0d
--- /dev/null
+++ b/src/algorithm/distance3d.cpp
@@ -0,0 +1,877 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/distance3d.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+
+#include <SFCGAL/Exception.h>
+#include <SFCGAL/detail/tools/Log.h>
+
+#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+
+#include <SFCGAL/detail/transform/AffineTransform3.h>
+#include <SFCGAL/algorithm/intersects.h>
+#include <SFCGAL/algorithm/isValid.h>
+#include <SFCGAL/triangulate/triangulatePolygon.h>
+#include <SFCGAL/detail/GetPointsVisitor.h>
+
+
+typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel ;
+typedef Kernel::FT squared_distance_t ;
+
+typedef Kernel::Point_3 Point_3 ;
+typedef Kernel::Vector_3 Vector_3 ;
+typedef Kernel::Segment_3 Segment_3 ;
+typedef Kernel::Triangle_3 Triangle_3 ;
+typedef Kernel::Plane_3 Plane_3 ;
+
+namespace SFCGAL {
+namespace algorithm {
+
+///
+///
+///
+double distance3D( const Geometry& gA, const Geometry& gB, NoValidityCheck )
+{
+ //SFCGAL_DEBUG( boost::format("dispatch distance3D(%s,%s)") % gA.asText() % gB.asText() );
+
+ switch ( gA.geometryTypeId() ) {
+ case TYPE_POINT:
+ return distancePointGeometry3D( gA.as< Point >(), gB );
+
+ case TYPE_LINESTRING:
+ return distanceLineStringGeometry3D( gA.as< LineString >(), gB );
+
+ case TYPE_POLYGON:
+ //SFCGAL_DEBUG( boost::format("gA is a Polygon (%s)") % gA.geometryTypeId() );
+ return distancePolygonGeometry3D( gA.as< Polygon >(), gB );
+
+ case TYPE_TRIANGLE:
+ //SFCGAL_DEBUG( boost::format("gA is a Triangle (%s)") % gA.geometryTypeId() );
+ return distanceTriangleGeometry3D( gA.as< Triangle >(), gB );
+
+ case TYPE_SOLID:
+ return distanceSolidGeometry3D( gA.as< Solid >(), gB );
+
+ //collection dispatch
+ case TYPE_MULTIPOINT:
+ case TYPE_MULTILINESTRING:
+ case TYPE_MULTIPOLYGON:
+ case TYPE_MULTISOLID:
+ case TYPE_GEOMETRYCOLLECTION:
+ case TYPE_TRIANGULATEDSURFACE:
+ case TYPE_POLYHEDRALSURFACE:
+ return distanceGeometryCollectionToGeometry3D( gB, gA );
+ }
+
+ BOOST_THROW_EXCEPTION( Exception(
+ ( boost::format( "distance3D(%s,%s) is not implemented" ) % gA.geometryType() % gB.geometryType() ).str()
+ ) );
+}
+
+double distance3D( const Geometry& gA, const Geometry& gB )
+{
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_3D( gA );
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_3D( gB );
+
+ return distance3D( gA, gB, NoValidityCheck() );
+}
+///
+///
+///
+double distancePointGeometry3D( const Point& gA, const Geometry& gB )
+{
+ //SFCGAL_DEBUG( boost::format("dispatch distancePointGeometry3D(%s,%s)") % gA.asText() % gB.asText() );
+
+ switch ( gB.geometryTypeId() ) {
+ case TYPE_POINT:
+ return distancePointPoint3D( gA, gB.as< Point >() );
+
+ case TYPE_LINESTRING:
+ return distancePointLineString3D( gA, gB.as< LineString >() );
+
+ case TYPE_TRIANGLE:
+ return distancePointTriangle3D( gA, gB.as< Triangle >() );
+
+ case TYPE_POLYGON:
+ return distancePointPolygon3D( gA, gB.as< Polygon >() );
+
+ case TYPE_SOLID:
+ return distancePointSolid3D( gA, gB.as< Solid >() );
+
+ case TYPE_MULTIPOINT:
+ case TYPE_MULTILINESTRING:
+ case TYPE_MULTIPOLYGON:
+ case TYPE_MULTISOLID:
+ case TYPE_GEOMETRYCOLLECTION:
+ case TYPE_TRIANGULATEDSURFACE:
+ case TYPE_POLYHEDRALSURFACE:
+ return distanceGeometryCollectionToGeometry3D( gB, gA );
+ }
+
+ BOOST_THROW_EXCEPTION( Exception(
+ ( boost::format( "distance3D(%s,%s) is not implemented" ) % gA.geometryType() % gB.geometryType() ).str()
+ ) );
+}
+
+///
+///
+///
+double distancePointPoint3D( const Point& gA, const Point& gB )
+{
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ return CGAL::sqrt(
+ CGAL::to_double(
+ CGAL::squared_distance( gA.toPoint_3(), gB.toPoint_3() )
+ )
+ );
+}
+
+///
+///
+///
+double distancePointLineString3D( const Point& gA, const LineString& gB )
+{
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ double dMin = std::numeric_limits< double >::infinity() ;
+
+ for ( size_t i = 0; i < gB.numSegments(); i++ ) {
+ dMin = std::min( dMin, distancePointSegment3D( gA, gB.pointN( i ), gB.pointN( i+1 ) ) );
+ }
+
+ return dMin ;
+}
+
+
+///
+///
+///
+double distancePointTriangle3D( const Point& gA, const Triangle& gB )
+{
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ return distancePointTriangle3D( gA, gB.vertex( 0 ), gB.vertex( 1 ), gB.vertex( 2 ) );
+}
+
+
+///
+///
+///
+double distancePointPolygon3D( const Point& gA, const Polygon& gB )
+{
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ TriangulatedSurface triangulateSurfaceB ;
+ triangulate::triangulatePolygon3D( gB, triangulateSurfaceB ) ;
+ return distanceGeometryCollectionToGeometry3D( triangulateSurfaceB, gA );
+}
+
+
+
+///
+///
+///
+double distancePointSolid3D( const Point& gA, const Solid& gB )
+{
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ if ( intersects3D( gA, gB, NoValidityCheck() ) ) {
+ return 0.0 ;
+ }
+
+ double dMin = std::numeric_limits< double >::infinity() ;
+
+ for ( size_t i = 0; i < gB.numShells(); i++ ) {
+ dMin = std::min( dMin, distanceGeometryCollectionToGeometry3D( gB.shellN( i ), gA ) );
+ }
+
+ return dMin ;
+}
+
+
+
+
+
+///
+///
+///
+double distanceLineStringGeometry3D( const LineString& gA, const Geometry& gB )
+{
+ //SFCGAL_DEBUG( boost::format("dispatch distanceLineStringGeometry3D(%s,%s)") % gA.asText() % gB.asText() );
+
+ switch ( gB.geometryTypeId() ) {
+ case TYPE_POINT:
+ return distancePointLineString3D( gB.as< Point >(), gA ); //symetric
+
+ case TYPE_LINESTRING:
+ return distanceLineStringLineString3D( gA, gB.as< LineString >() );
+
+ case TYPE_TRIANGLE:
+ return distanceLineStringTriangle3D( gA, gB.as< Triangle >() );
+
+ case TYPE_POLYGON:
+ return distanceLineStringPolygon3D( gA, gB.as< Polygon >() );
+
+ case TYPE_SOLID:
+ return distanceLineStringSolid3D( gA, gB.as< Solid >() );
+
+ case TYPE_MULTIPOINT:
+ case TYPE_MULTILINESTRING:
+ case TYPE_MULTIPOLYGON:
+ case TYPE_MULTISOLID:
+ case TYPE_GEOMETRYCOLLECTION:
+ case TYPE_TRIANGULATEDSURFACE:
+ case TYPE_POLYHEDRALSURFACE:
+ return distanceGeometryCollectionToGeometry3D( gB, gA );
+ }
+
+ BOOST_THROW_EXCEPTION( Exception(
+ ( boost::format( "distance3D(%s,%s) is not implemented" ) % gA.geometryType() % gB.geometryType() ).str()
+ ) );
+}
+
+///
+///
+///
+double distanceLineStringLineString3D( const LineString& gA, const LineString& gB )
+{
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ size_t nsA = gA.numSegments() ;
+ size_t nsB = gB.numSegments() ;
+
+ double dMin = std::numeric_limits< double >::infinity() ;
+
+ for ( size_t i = 0; i < nsA; i++ ) {
+ for ( size_t j = 0; j < nsB; j++ ) {
+ dMin = std::min(
+ dMin,
+ distanceSegmentSegment3D(
+ gA.pointN( i ), gA.pointN( i+1 ),
+ gB.pointN( j ), gB.pointN( j+1 )
+ )
+ ) ;
+ }
+ }
+
+ return dMin ;
+}
+
+///
+///
+///
+double distanceLineStringTriangle3D( const LineString& gA, const Triangle& gB )
+{
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ double dMin = std::numeric_limits< double >::infinity() ;
+
+ const Point& tA = gB.vertex( 0 ) ;
+ const Point& tB = gB.vertex( 1 ) ;
+ const Point& tC = gB.vertex( 2 ) ;
+
+ for ( size_t i = 0; i < gA.numSegments(); i++ ) {
+ dMin = std::min( dMin, distanceSegmentTriangle3D( gA.pointN( i ), gA.pointN( i+1 ), tA, tB, tC ) );
+ }
+
+ return dMin ;
+}
+
+///
+///
+///
+double distanceLineStringPolygon3D( const LineString& gA, const Polygon& gB )
+{
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ TriangulatedSurface triangulateSurfaceB ;
+ triangulate::triangulatePolygon3D( gB, triangulateSurfaceB ) ;
+ return distanceGeometryCollectionToGeometry3D( triangulateSurfaceB, gA );
+}
+
+///
+///
+///
+double distanceLineStringSolid3D( const LineString& gA, const Solid& gB )
+{
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ if ( intersects( gA, gB, NoValidityCheck() ) ) {
+ return 0.0 ;
+ }
+
+ double dMin = std::numeric_limits< double >::infinity() ;
+
+ for ( size_t i = 0; i < gB.numShells(); i++ ) {
+ dMin = std::min( dMin, gB.shellN( i ).distance3D( gA ) );
+ }
+
+ return dMin ;
+}
+
+
+///
+///
+///
+double distanceTriangleGeometry3D( const Triangle& gA, const Geometry& gB )
+{
+ //SFCGAL_DEBUG( boost::format("dispatch distanceTriangleGeometry3D(%s,%s)") % gA.asText() % gB.asText() );
+
+ switch ( gB.geometryTypeId() ) {
+ case TYPE_POINT:
+ return distancePointTriangle3D( gB.as< Point >(), gA ); //symetric
+
+ case TYPE_LINESTRING:
+ return distanceLineStringTriangle3D( gB.as< LineString >(), gA ); //symetric
+
+ case TYPE_TRIANGLE:
+ return distanceTriangleTriangle3D( gA, gB.as< Triangle >() );
+
+ case TYPE_POLYGON:
+ return distancePolygonGeometry3D( gB.as< Polygon >(), gA );
+
+ case TYPE_SOLID:
+ return distanceTriangleSolid3D( gA, gB.as< Solid >() );
+
+ case TYPE_MULTIPOINT:
+ case TYPE_MULTILINESTRING:
+ case TYPE_MULTIPOLYGON:
+ case TYPE_MULTISOLID:
+ case TYPE_GEOMETRYCOLLECTION:
+ case TYPE_TRIANGULATEDSURFACE:
+ case TYPE_POLYHEDRALSURFACE:
+ return distanceGeometryCollectionToGeometry3D( gB, gA );
+ }
+
+ BOOST_THROW_EXCEPTION( Exception(
+ ( boost::format( "distance3D(%s,%s) is not implemented" ) % gA.geometryType() % gB.geometryType() ).str()
+ ) );
+}
+
+///
+///
+///
+double distanceTriangleSolid3D( const Triangle& gA, const Solid& gB )
+{
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ if ( intersects3D( gA, gB, NoValidityCheck() ) ) {
+ return 0.0 ;
+ }
+
+ double dMin = std::numeric_limits< double >::infinity() ;
+
+ for ( size_t i = 0; i < gB.numShells(); i++ ) {
+ dMin = std::min( dMin, gB.shellN( i ).distance3D( gA ) );
+ }
+
+ return dMin ;
+}
+
+
+
+///
+///
+///
+double distancePolygonGeometry3D( const Polygon& gA, const Geometry& gB )
+{
+ //SFCGAL_DEBUG( boost::format("dispatch distancePolygonGeometry3D(%s,%s)") % gA.asText() % gB.asText() );
+
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ TriangulatedSurface triangulateSurfaceA ;
+ triangulate::triangulatePolygon3D( gA, triangulateSurfaceA ) ;
+ return distanceGeometryCollectionToGeometry3D( triangulateSurfaceA, gB );
+}
+
+
+///
+///
+///
+double distanceSolidGeometry3D( const Solid& gA, const Geometry& gB )
+{
+ //SFCGAL_DEBUG( boost::format("dispatch distanceSolidGeometry3D(%s,%s)") % gA.asText() % gB.asText() );
+
+ switch ( gB.geometryTypeId() ) {
+ case TYPE_POINT:
+ return distancePointSolid3D( gB.as< Point >(), gA ); //symetric
+
+ case TYPE_LINESTRING:
+ return distanceLineStringSolid3D( gB.as< LineString >(), gA ); //symetric
+
+ case TYPE_TRIANGLE:
+ return distanceTriangleSolid3D( gB.as< Triangle >(), gA ); //symetric
+
+ case TYPE_POLYGON:
+ return distancePolygonGeometry3D( gB.as< Polygon >(), gA ); //symetric
+
+ case TYPE_SOLID:
+ return distanceSolidSolid3D( gA, gB.as< Solid >() );
+
+ case TYPE_MULTIPOINT:
+ case TYPE_MULTILINESTRING:
+ case TYPE_MULTIPOLYGON:
+ case TYPE_MULTISOLID:
+ case TYPE_GEOMETRYCOLLECTION:
+ case TYPE_TRIANGULATEDSURFACE:
+ case TYPE_POLYHEDRALSURFACE:
+ return distanceGeometryCollectionToGeometry3D( gB, gA );
+ }
+
+ BOOST_THROW_EXCEPTION( Exception(
+ ( boost::format( "distance3D(%s,%s) is not implemented" ) % gA.geometryType() % gB.geometryType() ).str()
+ ) );
+}
+
+///
+///
+///
+double distanceSolidSolid3D( const Solid& gA, const Solid& gB )
+{
+ //SFCGAL_DEBUG( boost::format("dispatch distancePolygonGeometry3D(%s,%s)") % gA.asText() % gB.asText() );
+
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ if ( intersects( gA, gB, NoValidityCheck() ) ) {
+ return 0.0 ;
+ }
+
+ double dMin = std::numeric_limits< double >::infinity() ;
+
+ for ( size_t i = 0; i < gA.numShells(); i++ ) {
+ for ( size_t j = 0; j < gB.numShells(); j++ ) {
+ dMin = std::min( dMin, gA.shellN( i ).distance3D( gB.shellN( j ) ) );
+ }
+ }
+
+ return dMin ;
+}
+
+struct Sphere {
+ Sphere( const double& r, CGAL::Vector_3<Kernel>& c )
+ : _radius( r )
+ , _center( c )
+ , _empty( false ) {
+ }
+ Sphere()
+ : _empty( true ) {
+ }
+ bool isEmpty() const {
+ return _empty;
+ }
+ double radius() const {
+ BOOST_ASSERT( !_empty );
+ return _radius;
+ }
+ const CGAL::Vector_3<Kernel>& center() const {
+ BOOST_ASSERT( !_empty );
+ return _center;
+ }
+private:
+ double _radius;
+ CGAL::Vector_3<Kernel> _center;
+ bool _empty;
+};
+
+const Sphere boundingSphere( const Geometry& geom )
+{
+ if ( geom.isEmpty() ) {
+ return Sphere();
+ }
+
+ using namespace SFCGAL::detail;
+ GetPointsVisitor v;
+ const_cast< Geometry& >( geom ).accept( v );
+
+ if( !v.points.size() ) {
+ return Sphere();
+ }
+
+ typedef CGAL::Vector_3< Kernel > Vector_3 ;
+
+ const GetPointsVisitor::const_iterator end = v.points.end();
+
+ // centroid
+ Vector_3 c( 0,0,0 );
+ int numPoint = 0;
+
+ for ( GetPointsVisitor::const_iterator x = v.points.begin(); x != end; ++x ) {
+ c = c + ( *x )->toVector_3() ;
+ ++numPoint;
+ }
+
+ BOOST_ASSERT( numPoint );
+ c = c / numPoint;
+
+ // farest point from centroid
+ Vector_3 f = c ;
+ Kernel::FT maxDistanceSq = 0;
+
+ for ( GetPointsVisitor::const_iterator x = v.points.begin(); x != end; ++x ) {
+ const Vector_3 cx = ( *x )->toVector_3() - c ;
+ const Kernel::FT dSq = cx * cx ;
+
+ if ( dSq > maxDistanceSq ) {
+ f = ( *x )->toVector_3() ;
+ maxDistanceSq = dSq ;
+ }
+ }
+
+ return Sphere( std::sqrt( CGAL::to_double( maxDistanceSq ) ), c );
+}
+
+///
+///
+///
+double distanceGeometryCollectionToGeometry3D( const Geometry& gA, const Geometry& gB )
+{
+ //SFCGAL_DEBUG( boost::format("dispatch distanceGeometryCollectionToGeometry3D(%s,%s)") % gA.asText() % gB.asText() );
+
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+
+ // if bounding spheres (BS) of gB and gAi don't intersect and
+ // if the closest point of BS(gAj) is further than the farest
+ // point of BS(gAi) there is no need to compute the distance(gAj, gB)
+ // since it will be greater than distance(gAi, gB)
+ //
+ // The aim is not to find the minimal bounding sphere, but a good enought sphere than
+ // encloses all points
+ std::set<size_t> noTest;
+
+ if ( 1 ) {
+ std::vector<Sphere> bsA;
+
+ for ( size_t i = 0; i < gA.numGeometries(); i++ ) {
+ bsA.push_back( boundingSphere( gA.geometryN( i ) ) );
+ }
+
+ Sphere bsB( boundingSphere( gB ) );
+
+ if ( bsB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ std::vector<size_t> noIntersect;
+
+ for ( size_t i = 0; i < gA.numGeometries(); i++ ) {
+ if ( bsA[i].isEmpty() ) {
+ continue;
+ }
+
+ const double l2 = CGAL::to_double( ( bsB.center() - bsA[i].center() ).squared_length() );
+
+ if ( std::pow( bsB.radius() + bsA[i].radius(), 2 ) < l2 ) {
+ noIntersect.push_back( i );
+ }
+ }
+
+ for ( size_t i = 0; i < noIntersect.size(); i++ ) {
+ const double li = std::sqrt( CGAL::to_double( ( bsA[noIntersect[i]].center() - bsB.center() ).squared_length() ) );
+
+ for ( size_t j = i; j < noIntersect.size(); j++ ) {
+ const double lj = std::sqrt( CGAL::to_double( ( bsA[noIntersect[j]].center() - bsB.center() ).squared_length() ) );
+
+ if ( li + bsA[noIntersect[i]].radius() < lj - bsA[noIntersect[j]].radius() ) {
+ noTest.insert( noIntersect[j] );
+ }
+ else if ( lj + bsA[noIntersect[j]].radius() < li - bsA[noIntersect[i]].radius() ) {
+ noTest.insert( noIntersect[i] );
+ }
+ }
+ }
+
+ //if (!noTest.empty()) std::cout << "pruning " << noTest.size() << "/" << gA.numGeometries() << "\n";
+ }
+
+ double dMin = std::numeric_limits< double >::infinity() ;
+
+ for ( size_t i = 0; i < gA.numGeometries(); i++ ) {
+ if ( noTest.end() != noTest.find( i ) ) {
+ continue;
+ }
+
+ dMin = std::min( dMin, distance3D( gA.geometryN( i ), gB ) );
+ }
+
+ return dMin ;
+}
+
+
+///
+///
+///
+double distancePointSegment3D( const Point& p, const Point& a, const Point& b )
+{
+ // empty already checked
+ BOOST_ASSERT( ! p.isEmpty() );
+ BOOST_ASSERT( ! a.isEmpty() );
+ BOOST_ASSERT( ! b.isEmpty() );
+
+ return CGAL::sqrt(
+ CGAL::to_double(
+ CGAL::squared_distance(
+ p.toPoint_3(),
+ Segment_3(
+ a.toPoint_3(),
+ b.toPoint_3()
+ )
+ )
+ )
+ );
+}
+
+/*
+ * missing in CGAL?
+ */
+squared_distance_t squaredDistancePointTriangle3D(
+ const Point_3& p,
+ const Triangle_3& abc
+)
+{
+ Point_3 a = abc.vertex( 0 );
+ Point_3 b = abc.vertex( 1 );
+ Point_3 c = abc.vertex( 2 );
+
+ /*
+ * project P on ABC plane as projP.
+ */
+ Point_3 projP = Plane_3( a, b, c ).projection( p );
+
+ squared_distance_t dMin ;
+
+ if ( abc.has_on( projP ) ) {
+ // Is projP is in the triangle, return distance from P to its projection
+ // on the plane
+ dMin = CGAL::squared_distance( p, projP ) ;
+ }
+ else {
+ // Else, the distance is the minimum from P to triangle sides
+ dMin = CGAL::squared_distance( p, Segment_3( a,b ) ) ;
+ dMin = std::min( dMin, CGAL::squared_distance( p, Segment_3( b,c ) ) );
+ dMin = std::min( dMin, CGAL::squared_distance( p, Segment_3( c,a ) ) );
+ }
+
+ return dMin ;
+}
+
+///
+///
+///
+double distancePointTriangle3D( const Point& p_, const Point& a_, const Point& b_, const Point& c_ )
+{
+ // empty already checked
+ BOOST_ASSERT( ! p_.isEmpty() );
+ BOOST_ASSERT( ! a_.isEmpty() );
+ BOOST_ASSERT( ! b_.isEmpty() );
+ BOOST_ASSERT( ! c_.isEmpty() );
+
+ Point_3 p = p_.toPoint_3();
+ Triangle_3 abc( a_.toPoint_3(), b_.toPoint_3(), c_.toPoint_3() ) ;
+
+ squared_distance_t dMin = squaredDistancePointTriangle3D( p, abc );
+ return CGAL::sqrt( CGAL::to_double( dMin ) ) ;
+}
+
+
+
+///
+///
+///
+double distanceSegmentSegment3D( const Point& a, const Point& b, const Point& c, const Point& d )
+{
+ // empty already checked
+ BOOST_ASSERT( ! a.isEmpty() );
+ BOOST_ASSERT( ! b.isEmpty() );
+ BOOST_ASSERT( ! c.isEmpty() );
+ BOOST_ASSERT( ! d.isEmpty() );
+
+ return CGAL::sqrt( CGAL::to_double(
+ CGAL::squared_distance(
+ CGAL::Segment_3< Kernel >( a.toPoint_3(), b.toPoint_3() ),
+ CGAL::Segment_3< Kernel >( c.toPoint_3(), d.toPoint_3() )
+ )
+ ) );
+}
+
+
+
+squared_distance_t squaredDistanceSegmentTriangle3D(
+ const Segment_3& sAB,
+ const Triangle_3& tABC
+)
+{
+ typedef Kernel::FT squared_distance_t ;
+
+ /*
+ * If [sAsB] intersects the triangle (tA,tB,tC), distance is 0.0
+ */
+ if ( ! CGAL::intersection( sAB, tABC ).empty() ) {
+ return 0.0 ;
+ }
+
+ /*
+ * else, distance is the min of the following values :
+ * - distance from sA to the Triangle
+ * - distance from sB to the Triangle
+ * - distance from sAB to the side of the Triangles
+ */
+ squared_distance_t dMin = squaredDistancePointTriangle3D( sAB.vertex( 0 ), tABC );
+ dMin = std::min( dMin, squaredDistancePointTriangle3D( sAB.vertex( 1 ), tABC ) );
+
+ for ( int i = 0; i < 3; i++ ) {
+ dMin = std::min( dMin, CGAL::squared_distance( sAB,
+ Segment_3( tABC.vertex( i ), tABC.vertex( i+1 ) ) )
+ ) ;
+ }
+
+ return dMin ;
+}
+
+
+///
+///
+///
+double distanceSegmentTriangle3D( const Point& sA_, const Point& sB_,
+ const Point& tA_, const Point& tB_, const Point& tC_
+ )
+{
+ // empty already checked
+ BOOST_ASSERT( ! sA_.isEmpty() );
+ BOOST_ASSERT( ! sB_.isEmpty() );
+ BOOST_ASSERT( ! tA_.isEmpty() );
+ BOOST_ASSERT( ! tB_.isEmpty() );
+ BOOST_ASSERT( ! tC_.isEmpty() );
+
+ Point_3 sA = sA_.toPoint_3();
+ Point_3 sB = sB_.toPoint_3();
+ Segment_3 sAB( sA, sB );
+
+ Point_3 tA = tA_.toPoint_3();
+ Point_3 tB = tB_.toPoint_3();
+ Point_3 tC = tC_.toPoint_3();
+ Triangle_3 tABC( tA, tB, tC );
+
+ squared_distance_t dMin = squaredDistanceSegmentTriangle3D( sAB, tABC );
+ return CGAL::sqrt( CGAL::to_double( dMin ) ) ;
+}
+
+/*
+ * missing in CGAL?
+ */
+squared_distance_t squaredDistanceTriangleTriangle3D(
+ const Triangle_3& triangleA,
+ const Triangle_3& triangleB
+)
+{
+ if ( ! CGAL::intersection( triangleA, triangleB ).empty() ) {
+ return squared_distance_t( 0 );
+ }
+
+ /*
+ * min of distance from A segments to B triangle and B segments to A triangle
+ */
+
+ squared_distance_t dMin = squaredDistanceSegmentTriangle3D(
+ Segment_3( triangleA.vertex( 0 ), triangleA.vertex( 1 ) ),
+ triangleB
+ );
+ dMin = std::min( dMin, squaredDistanceSegmentTriangle3D(
+ Segment_3( triangleA.vertex( 1 ), triangleA.vertex( 2 ) ),
+ triangleB
+ ) );
+ dMin = std::min( dMin, squaredDistanceSegmentTriangle3D(
+ Segment_3( triangleA.vertex( 2 ), triangleA.vertex( 0 ) ),
+ triangleB
+ ) );
+
+ dMin = std::min( dMin, squaredDistanceSegmentTriangle3D(
+ Segment_3( triangleB.vertex( 0 ), triangleB.vertex( 1 ) ),
+ triangleA
+ ) );
+ dMin = std::min( dMin, squaredDistanceSegmentTriangle3D(
+ Segment_3( triangleB.vertex( 1 ), triangleB.vertex( 2 ) ),
+ triangleA
+ ) );
+ dMin = std::min( dMin, squaredDistanceSegmentTriangle3D(
+ Segment_3( triangleB.vertex( 2 ), triangleB.vertex( 0 ) ),
+ triangleA
+ ) );
+
+ return dMin ;
+}
+
+
+///
+///
+///
+double distanceTriangleTriangle3D( const Triangle& gA, const Triangle& gB )
+{
+ if ( gA.isEmpty() || gB.isEmpty() ) {
+ return std::numeric_limits< double >::infinity() ;
+ }
+
+ Triangle_3 triangleA = gA.toTriangle_3() ;
+ Triangle_3 triangleB = gB.toTriangle_3() ;
+
+ squared_distance_t dMin = squaredDistanceTriangleTriangle3D( triangleA, triangleB );
+ return CGAL::sqrt( CGAL::to_double( dMin ) ) ;
+}
+
+
+
+}//namespace algorithm
+}//namespace SFCGAL
diff --git a/src/algorithm/distance3d.h b/src/algorithm/distance3d.h
new file mode 100644
index 0000000..9bc53c4
--- /dev/null
+++ b/src/algorithm/distance3d.h
@@ -0,0 +1,178 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_ALGORITHM_DISTANCE3D_H_
+#define _SFCGAL_ALGORITHM_DISTANCE3D_H_
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Geometry.h>
+
+namespace SFCGAL {
+namespace algorithm {
+struct NoValidityCheck;
+
+/**
+ * dispatch distance between two Geometries
+ * @todo complete with solid
+ * Compute distance between two 3D Geometries
+ * @ingroup public_api
+ * @pre gA is a valid geometry
+ * @pre gB is a valid geometry
+ */
+SFCGAL_API double distance3D( const Geometry& gA, const Geometry& gB ) ;
+
+/**
+ * Compute distance between two 3D Geometries
+ * @ingroup detail
+ * @pre gA is a valid geometry
+ * @pre gB is a valid geometry
+ * @warning No actual validity check is done
+ */
+SFCGAL_API double distance3D( const Geometry& gA, const Geometry& gB, NoValidityCheck ) ;
+
+/**
+ * dispatch distance from Point to Geometry
+ * @ingroup detail
+ */
+SFCGAL_API double distancePointGeometry3D( const Point& gA, const Geometry& gB ) ;
+/**
+ * distance between two Points
+ * @ingroup detail
+ */
+SFCGAL_API double distancePointPoint3D( const Point& gA, const Point& gB ) ;
+/**
+ * distance between a Point and a LineString
+ * @ingroup detail
+ */
+SFCGAL_API double distancePointLineString3D( const Point& gA, const LineString& gB ) ;
+/**
+ * distance between a Point and a Triangle
+ * @ingroup detail
+ */
+SFCGAL_API double distancePointTriangle3D( const Point& gA, const Triangle& gB ) ;
+/**
+ * distance between a Point and a Triangle
+ * @ingroup detail
+ */
+SFCGAL_API double distancePointPolygon3D( const Point& gA, const Polygon& gB ) ;
+/**
+ * distance between a Point and a Solid
+ * @ingroup detail
+ */
+SFCGAL_API double distancePointSolid3D( const Point& gA, const Solid& gB ) ;
+
+
+/**
+ * dispatch distance between a LineString and a Geometry
+ * @ingroup detail
+ */
+SFCGAL_API double distanceLineStringGeometry3D( const LineString& gA, const Geometry& gB ) ;
+/**
+ * distance between two LineStrings
+ * @ingroup detail
+ */
+SFCGAL_API double distanceLineStringLineString3D( const LineString& gA, const LineString& gB ) ;
+/**
+ * distance between a LineString and a Triangle
+ * @ingroup detail
+ */
+SFCGAL_API double distanceLineStringTriangle3D( const LineString& gA, const Triangle& gB ) ;
+/**
+ * distance between a LineString and a Polygon
+ * @todo same method than distancePointPolygon3D (unify if triangulate is available)
+ * @ingroup detail
+ */
+SFCGAL_API double distanceLineStringPolygon3D( const LineString& gA, const Polygon& gB ) ;
+/**
+ * distance between a LineString and a Solid
+ * @ingroup detail
+ */
+SFCGAL_API double distanceLineStringSolid3D( const LineString& gA, const Solid& gB ) ;
+
+/**
+ * dispatch distance between a Triangle and a Geometry
+ * @ingroup detail
+ */
+SFCGAL_API double distanceTriangleGeometry3D( const Triangle& gA, const Geometry& gB ) ;
+/**
+ * distance between a Triangle and a Solid
+ * @ingroup detail
+ */
+SFCGAL_API double distanceTriangleSolid3D( const Triangle& gA, const Solid& gB ) ;
+
+
+
+/**
+ * dispatch distance between a Polygon and a Geometry
+ * @ingroup detail
+ */
+SFCGAL_API double distancePolygonGeometry3D( const Polygon& gA, const Geometry& gB ) ;
+
+
+/**
+ * dispatch distance between a Solid and a Geometry
+ * @ingroup detail
+ */
+SFCGAL_API double distanceSolidGeometry3D( const Solid& gA, const Geometry& gB ) ;
+/**
+ * distance between two Solids
+ * @ingroup detail
+ */
+SFCGAL_API double distanceSolidSolid3D( const Solid& gA, const Solid& gB ) ;
+
+
+/**
+ * dispatch distance from a collection of geometry (gA) to a Geometry (gB)
+ * @ingroup detail
+ */
+SFCGAL_API double distanceGeometryCollectionToGeometry3D( const Geometry& gA, const Geometry& gB ) ;
+
+/**
+ * @ingroup detail
+ */
+SFCGAL_API double distancePointSegment3D( const Point& p, const Point& a, const Point& b ) ;
+/**
+ * @ingroup detail
+ */
+SFCGAL_API double distancePointTriangle3D( const Point& p, const Point& a, const Point& b, const Point& c ) ;
+/**
+ * @ingroup detail
+ */
+SFCGAL_API double distanceSegmentSegment3D( const Point& a, const Point& b, const Point& c, const Point& d );
+/**
+ * @ingroup detail
+ */
+SFCGAL_API double distanceSegmentTriangle3D(
+ const Point& sA, const Point& sB,
+ const Point& tA, const Point& tB, const Point& tC
+);
+/**
+ * distance between two Triangles
+ * @ingroup detail
+ */
+SFCGAL_API double distanceTriangleTriangle3D( const Triangle& gA, const Triangle& gB ) ;
+
+
+
+}//namespace algorithm
+}//namespace SFCGAL
+
+#endif
diff --git a/src/algorithm/extrude.cpp b/src/algorithm/extrude.cpp
new file mode 100644
index 0000000..b35aea1
--- /dev/null
+++ b/src/algorithm/extrude.cpp
@@ -0,0 +1,380 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/extrude.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+#include <SFCGAL/Exception.h>
+
+#include <SFCGAL/algorithm/normal.h>
+#include <SFCGAL/algorithm/translate.h>
+#include <SFCGAL/algorithm/force3D.h>
+#include <SFCGAL/algorithm/isValid.h>
+
+#include <SFCGAL/detail/tools/Log.h>
+
+
+namespace SFCGAL {
+namespace algorithm {
+
+//-- private interface
+
+LineString* extrude( const Point& g, const Kernel::Vector_3& v ) ;
+PolyhedralSurface* extrude( const LineString& g, const Kernel::Vector_3& v ) ;
+Solid* extrude( const Polygon& g, const Kernel::Vector_3& v ) ;
+Solid* extrude( const Triangle& g, const Kernel::Vector_3& v ) ;
+
+MultiLineString* extrude( const MultiPoint& g, const Kernel::Vector_3& v ) ;
+PolyhedralSurface* extrude( const MultiLineString& g, const Kernel::Vector_3& v ) ;
+MultiSolid* extrude( const MultiPolygon& g, const Kernel::Vector_3& v ) ;
+
+/**
+ * @warning suppose that the TriangulatedSurface is connected
+ * @todo take orientation in account
+ */
+Solid* extrude( const TriangulatedSurface& g, const Kernel::Vector_3& v ) ;
+/**
+ * @warning doesn't take orientation in account
+ * @todo take orientation in account
+ */
+Solid* extrude( const PolyhedralSurface& g, const Kernel::Vector_3& v ) ;
+
+/**
+ * extrude each geometry in a GeometryCollection
+ */
+GeometryCollection* extrude( const GeometryCollection& g, const Kernel::Vector_3& v ) ;
+
+
+///
+///
+///
+LineString* extrude( const Point& g, const Kernel::Vector_3& v )
+{
+ if( g.isEmpty() ) {
+ return new LineString() ;
+ }
+
+ Kernel::Point_3 a = g.toPoint_3() ;
+ Kernel::Point_3 b = a + v ;
+
+ return new LineString( Point( a ), Point( b ) );
+}
+
+///
+///
+///
+PolyhedralSurface* extrude( const LineString& g, const Kernel::Vector_3& v )
+{
+
+ std::auto_ptr< PolyhedralSurface > polyhedralSurface( new PolyhedralSurface() );
+
+ if ( g.isEmpty() ) {
+ return polyhedralSurface.release();
+ }
+
+ for ( size_t i = 0; i < g.numPoints() - 1; i++ ) {
+ std::auto_ptr< LineString > ring( new LineString ) ;
+
+ Kernel::Point_3 a = g.pointN( i ).toPoint_3() ;
+ Kernel::Point_3 b = g.pointN( i+1 ).toPoint_3() ;
+ ring->addPoint( new Point( a ) );
+ ring->addPoint( new Point( b ) );
+ ring->addPoint( new Point( b + v ) );
+ ring->addPoint( new Point( a + v ) );
+ ring->addPoint( new Point( a ) );
+
+ polyhedralSurface->addPolygon( new Polygon( ring.release() ) );
+ }
+
+ return polyhedralSurface.release() ;
+}
+
+///
+///
+///
+Solid* extrude( const Polygon& g, const Kernel::Vector_3& v )
+{
+ if ( g.isEmpty() ) {
+ return new Solid();
+ }
+
+ bool reverseOrientation = ( v * normal3D< Kernel >( g ) ) > 0 ;
+
+ //resulting shell
+ PolyhedralSurface polyhedralSurface ;
+
+ // "bottom"
+ Polygon bottom( g );
+ force3D( bottom ) ;
+
+ if ( reverseOrientation ) {
+ bottom.reverse();
+ }
+
+ polyhedralSurface.addPolygon( bottom );
+
+ // "top"
+ Polygon top( bottom );
+ top.reverse() ;
+ translate( top,v );
+ polyhedralSurface.addPolygon( top );
+
+ // exterior ring and interior rings extruded
+ for ( size_t i = 0; i < bottom.numRings(); i++ ) {
+ std::auto_ptr< PolyhedralSurface > boundaryExtruded( extrude( bottom.ringN( i ), v ) );
+
+ for ( size_t j = 0; j < boundaryExtruded->numPolygons(); j++ ) {
+ boundaryExtruded->polygonN( j ).reverse() ;
+ polyhedralSurface.addPolygon( boundaryExtruded->polygonN( j ) ) ;
+ }
+ }
+
+ return new Solid( polyhedralSurface );
+}
+
+
+///
+///
+///
+Solid* extrude( const Triangle& g, const Kernel::Vector_3& v )
+{
+ return extrude( g.toPolygon(), v );
+}
+
+///
+///
+///
+MultiLineString* extrude( const MultiPoint& g, const Kernel::Vector_3& v )
+{
+ std::auto_ptr< MultiLineString > result( new MultiLineString() );
+
+ if ( g.isEmpty() ) {
+ return result.release();
+ }
+
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ result->addGeometry( extrude( g.pointN( i ), v ) );
+ }
+
+ return result.release() ;
+}
+
+
+///
+///
+///
+PolyhedralSurface* extrude( const MultiLineString& g, const Kernel::Vector_3& v )
+{
+ std::auto_ptr< PolyhedralSurface > result( new PolyhedralSurface() );
+
+ if ( g.isEmpty() ) {
+ return result.release();
+ }
+
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ std::auto_ptr< PolyhedralSurface > extruded( extrude( g.lineStringN( i ), v ) );
+
+ for ( size_t j = 0; j < extruded->numPolygons(); j++ ) {
+ result->addPolygon( extruded->polygonN( j ) );
+ }
+ }
+
+ return result.release() ;
+}
+
+
+///
+///
+///
+MultiSolid* extrude( const MultiPolygon& g, const Kernel::Vector_3& v )
+{
+ std::auto_ptr< MultiSolid > result( new MultiSolid() );
+
+ if ( g.isEmpty() ) {
+ return result.release();
+ }
+
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ result->addGeometry( extrude( g.polygonN( i ), v ) );
+ }
+
+ return result.release() ;
+}
+
+
+///
+///
+///
+Solid* extrude( const TriangulatedSurface& g, const Kernel::Vector_3& v )
+{
+ std::auto_ptr< Solid > result( new Solid() );
+
+ if ( g.isEmpty() ) {
+ return result.release();
+ }
+
+ //bottom and top
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ Triangle bottomPart( g.geometryN( i ) );
+ force3D( bottomPart );
+ bottomPart.reverse() ;
+ result->exteriorShell().addPolygon( bottomPart );
+
+ Triangle topPart( g.geometryN( i ) );
+ force3D( topPart );
+ translate( topPart, v );
+ result->exteriorShell().addPolygon( topPart );
+ }
+
+ //boundary
+ std::auto_ptr< Geometry > boundary( g.boundary() ) ;
+ BOOST_ASSERT( boundary.get() != NULL );
+
+ // closed surface extruded
+ if ( ! boundary->isEmpty() ) {
+ std::auto_ptr< Geometry > extrudedBoundary( extrude( *boundary, v ) ) ;
+ BOOST_ASSERT( extrudedBoundary->is< PolyhedralSurface >() );
+ result->exteriorShell().addPolygons( extrudedBoundary->as< PolyhedralSurface >() );
+ }
+
+
+ return result.release() ;
+}
+
+///
+///
+///
+Solid* extrude( const PolyhedralSurface& g, const Kernel::Vector_3& v )
+{
+ if ( g.isEmpty() ) {
+ return new Solid();
+ }
+
+ TriangulatedSurface triangulatedSurface ;
+ triangulate::triangulatePolygon3D( g, triangulatedSurface );
+ return extrude( triangulatedSurface, v ) ;
+}
+
+///
+///
+///
+GeometryCollection* extrude( const GeometryCollection& g, const Kernel::Vector_3& v )
+{
+ std::auto_ptr< GeometryCollection > result( new GeometryCollection() ) ;
+
+ if ( g.isEmpty() ) {
+ return result.release();
+ }
+
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ result->addGeometry( extrude( g.geometryN( i ), v ).release() );
+ }
+
+ return result.release() ;
+}
+
+//-- public interface
+
+///
+///
+///
+std::auto_ptr< Geometry > extrude( const Geometry& g, const Kernel::Vector_3& v )
+{
+ switch ( g.geometryTypeId() ) {
+ case TYPE_POINT:
+ return std::auto_ptr< Geometry >( extrude( g.as< Point >(), v ) );
+
+ case TYPE_LINESTRING:
+ return std::auto_ptr< Geometry >( extrude( g.as< LineString >(), v ) );
+
+ case TYPE_POLYGON:
+ return std::auto_ptr< Geometry >( extrude( g.as< Polygon >(), v ) );
+
+ case TYPE_TRIANGLE:
+ return std::auto_ptr< Geometry >( extrude( g.as< Triangle >(), v ) );
+
+ case TYPE_GEOMETRYCOLLECTION:
+ return std::auto_ptr< Geometry >( extrude( g.as< GeometryCollection >(), v ) );
+
+ case TYPE_MULTIPOINT:
+ return std::auto_ptr< Geometry >( extrude( g.as< MultiPoint >(), v ) );
+
+ case TYPE_MULTILINESTRING:
+ return std::auto_ptr< Geometry >( extrude( g.as< MultiLineString >(), v ) );
+
+ case TYPE_MULTIPOLYGON:
+ return std::auto_ptr< Geometry >( extrude( g.as< MultiPolygon >(), v ) );
+
+ case TYPE_TRIANGULATEDSURFACE:
+ return std::auto_ptr< Geometry >( extrude( g.as< TriangulatedSurface >(), v ) );
+
+ case TYPE_POLYHEDRALSURFACE:
+ return std::auto_ptr< Geometry >( extrude( g.as< PolyhedralSurface >(), v ) );
+
+ case TYPE_SOLID:
+ case TYPE_MULTISOLID:
+ //extrusion not available
+ break;
+ }
+
+ BOOST_THROW_EXCEPTION( InappropriateGeometryException(
+ ( boost::format( "Extrusion of %s is not supported" ) % g.geometryType() ).str()
+ ) );
+}
+
+
+///
+///
+///
+std::auto_ptr< Geometry > extrude( const Geometry& g, Kernel::FT dx, Kernel::FT dy, Kernel::FT dz, NoValidityCheck )
+{
+ return extrude( g, Kernel::Vector_3( dx,dy,dz ) ) ;
+}
+
+std::auto_ptr< Geometry > extrude( const Geometry& g, Kernel::FT dx, Kernel::FT dy, Kernel::FT dz )
+{
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY( g );
+ return extrude( g, dx, dy, dz, NoValidityCheck() );
+}
+
+SFCGAL_API std::auto_ptr< Geometry > extrude( const Geometry& g, const double& dx, const double& dy, const double& dz )
+{
+ if ( !std::isfinite( dx ) || !std::isfinite( dy ) || !std::isfinite( dz ) ) {
+ BOOST_THROW_EXCEPTION( NonFiniteValueException( "trying to extrude with non finite value in direction" ) );
+ }
+
+ return extrude( g, Kernel::FT( dx ), Kernel::FT( dy ), Kernel::FT( dz ) );
+}
+
+
+}//algorithm
+}//SFCGAL
diff --git a/src/algorithm/extrude.h b/src/algorithm/extrude.h
new file mode 100644
index 0000000..2a85702
--- /dev/null
+++ b/src/algorithm/extrude.h
@@ -0,0 +1,68 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_ALGORITHM_EXTRUDE_H_
+#define _SFCGAL_ALGORITHM_EXTRUDE_H_
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Geometry.h>
+
+namespace SFCGAL {
+namespace algorithm {
+struct NoValidityCheck;
+
+/**
+ * extrude a Geometry with a direction
+ * @pre g is a valid geometry
+ * @ingroup public_api
+ */
+SFCGAL_API std::auto_ptr< Geometry > extrude( const Geometry& g, Kernel::FT dx, Kernel::FT dy, Kernel::FT dz ) ;
+
+/**
+ * extrude a Geometry with a direction
+ * @pre g is a valid geometry
+ * @ingroup detail
+ * @warning No actual validity check is done.
+ */
+SFCGAL_API std::auto_ptr< Geometry > extrude( const Geometry& g, Kernel::FT dx, Kernel::FT dy, Kernel::FT dz, NoValidityCheck ) ;
+
+/**
+ * extrude a Geometry with a direction
+ * @pre g is a valid geometry
+ * @pre dx, dy and dz are finite values
+ * @ingroup detail
+ * @warning No actual validity check is done.
+ */
+SFCGAL_API std::auto_ptr< Geometry > extrude( const Geometry& g, const double& dx, const double& dy, const double& dz );
+
+/**
+ * @brief extrude a Geometry by a given vector
+ * @todo Improve 3D surface extrude (Extrude only faces whose dot( v, normal ) > 0 and use Polyhedron union to
+ * get output geometries with a clean topology)
+ * @ingroup detail
+ */
+SFCGAL_API std::auto_ptr< Geometry > extrude( const Geometry& g, const Kernel::Vector_3& v ) ;
+
+}//algorithm
+}//SFCGAL
+
+#endif
diff --git a/src/algorithm/force2D.cpp b/src/algorithm/force2D.cpp
new file mode 100644
index 0000000..1b98e47
--- /dev/null
+++ b/src/algorithm/force2D.cpp
@@ -0,0 +1,38 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/force2D.h>
+#include <SFCGAL/detail/transform/Force2D.h>
+
+namespace SFCGAL {
+namespace algorithm {
+
+///
+///
+///
+void force2D( Geometry& g )
+{
+ transform::Force2D t ;
+ g.accept( t ) ;
+}
+
+} // namespace algorithm
+} // namespace SFCGAL
+
diff --git a/src/algorithm/force2D.h b/src/algorithm/force2D.h
new file mode 100644
index 0000000..80fbd47
--- /dev/null
+++ b/src/algorithm/force2D.h
@@ -0,0 +1,44 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_ALGORITHM_FORCE2D_H_
+#define _SFCGAL_ALGORITHM_FORCE2D_H_
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Kernel.h>
+
+namespace SFCGAL {
+class Geometry ;
+}
+
+namespace SFCGAL {
+namespace algorithm {
+
+/**
+ * @brief force a geometry to be 2D (project on O,x,y)
+ * @warning ignore empty geometries
+ */
+SFCGAL_API void force2D( Geometry& g );
+
+} // namespace algorithm
+} // namespace SFCGAL
+
+#endif
diff --git a/src/algorithm/force3D.cpp b/src/algorithm/force3D.cpp
new file mode 100644
index 0000000..00c3067
--- /dev/null
+++ b/src/algorithm/force3D.cpp
@@ -0,0 +1,38 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/force3D.h>
+#include <SFCGAL/detail/transform/ForceZ.h>
+
+namespace SFCGAL {
+namespace algorithm {
+
+///
+///
+///
+void force3D( Geometry& g, const Kernel::FT& defaultZ )
+{
+ transform::ForceZ t( defaultZ ) ;
+ g.accept( t ) ;
+}
+
+} // namespace algorithm
+} // namespace SFCGAL
+
diff --git a/src/algorithm/force3D.h b/src/algorithm/force3D.h
new file mode 100644
index 0000000..60288d5
--- /dev/null
+++ b/src/algorithm/force3D.h
@@ -0,0 +1,44 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_ALGORITHM_FORCE3D_H_
+#define _SFCGAL_ALGORITHM_FORCE3D_H_
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Kernel.h>
+
+namespace SFCGAL {
+class Geometry ;
+}
+
+namespace SFCGAL {
+namespace algorithm {
+
+/**
+ * @brief force a 2D geometry to be 3D (replace undefined Z by defaultZ, existing Z values remains unchanged)
+ * @warning ignore empty geometries
+ */
+SFCGAL_API void force3D( Geometry& g, const Kernel::FT& defaultZ = 0 ) ;
+
+} // namespace algorithm
+} // namespace SFCGAL
+
+#endif
diff --git a/src/algorithm/intersection.cpp b/src/algorithm/intersection.cpp
new file mode 100644
index 0000000..719945c
--- /dev/null
+++ b/src/algorithm/intersection.cpp
@@ -0,0 +1,190 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/intersection.h>
+#include <SFCGAL/Exception.h>
+#include <SFCGAL/algorithm/intersects.h>
+#include <SFCGAL/algorithm/collect.h>
+#include <SFCGAL/algorithm/collectionHomogenize.h>
+#include <SFCGAL/detail/tools/Registry.h>
+#include <SFCGAL/detail/GeometrySet.h>
+#include <SFCGAL/algorithm/isValid.h>
+
+#include <CGAL/Boolean_set_operations_2.h>
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+#include <CGAL/box_intersection_d.h>
+
+//
+// Intersection kernel
+
+using namespace SFCGAL::detail;
+
+namespace SFCGAL {
+
+typedef CGAL::Point_2<Kernel> Point_2;
+typedef CGAL::Segment_2<Kernel> Segment_2;
+typedef CGAL::Triangle_2<Kernel> Triangle_2;
+
+namespace algorithm {
+// see Intersection3D.cpp
+void intersection( const PrimitiveHandle<3>& pa, const PrimitiveHandle<3>& pb,
+ GeometrySet<3>& output, dim_t<3> );
+// see Intersection2D.cpp
+void intersection( const PrimitiveHandle<2>& pa, const PrimitiveHandle<2>& pb,
+ GeometrySet<2>& output, dim_t<2> );
+//
+// We deal here with symmetric call
+template <int Dim>
+void dispatch_intersection_sym( const PrimitiveHandle<Dim>& pa, const PrimitiveHandle<Dim>& pb,
+ GeometrySet<Dim>& output )
+{
+ // assume types are ordered by dimension within the boost::variant
+ if ( pa.handle.which() >= pb.handle.which() ) {
+ intersection( pa, pb, output, dim_t<Dim>() );
+ }
+ else {
+ intersection( pb, pa, output, dim_t<Dim>() );
+ }
+}
+
+template <int Dim>
+void intersection( const PrimitiveHandle<Dim>& pa, const PrimitiveHandle<Dim>& pb, GeometrySet<Dim>& output )
+{
+ dispatch_intersection_sym( pa, pb, output );
+}
+
+template void intersection<2>( const PrimitiveHandle<2>& a, const PrimitiveHandle<2>& b, GeometrySet<2>& );
+template void intersection<3>( const PrimitiveHandle<3>& a, const PrimitiveHandle<3>& b, GeometrySet<3>& );
+
+template <int Dim>
+struct intersection_cb {
+ intersection_cb( GeometrySet<Dim>& out ) : output( out ) {}
+
+ void operator()( const typename PrimitiveBox<Dim>::Type& a,
+ const typename PrimitiveBox<Dim>::Type& b ) {
+ dispatch_intersection_sym<Dim>( *a.handle(), *b.handle(), output );
+ }
+
+ GeometrySet<Dim>& output;
+};
+
+/**
+ * intersection post processing
+ */
+void post_intersection( const GeometrySet<2>& input, GeometrySet<2>& output )
+{
+ //
+ // reverse orientation of polygons if needed
+ for ( GeometrySet<2>::SurfaceCollection::const_iterator it = input.surfaces().begin();
+ it != input.surfaces().end();
+ ++it ) {
+ const CGAL::Polygon_with_holes_2<Kernel>& p = it->primitive();
+ CGAL::Polygon_2<Kernel> outer = p.outer_boundary();
+
+ if ( outer.orientation() == CGAL::CLOCKWISE ) {
+ outer.reverse_orientation();
+ }
+
+ std::list<CGAL::Polygon_2<Kernel> > rings;
+
+ for ( CGAL::Polygon_with_holes_2<Kernel>::Hole_const_iterator hit = p.holes_begin();
+ hit != p.holes_end();
+ ++hit ) {
+ rings.push_back( *hit );
+
+ if ( hit->orientation() == CGAL::COUNTERCLOCKWISE ) {
+ rings.back().reverse_orientation();
+ }
+ }
+
+ output.surfaces().push_back( CGAL::Polygon_with_holes_2<Kernel>( outer, rings.begin(), rings.end() ) );
+ }
+
+ output.points() = input.points();
+ output.segments() = input.segments();
+ output.volumes() = input.volumes();
+}
+
+void post_intersection( const GeometrySet<3>& input, GeometrySet<3>& output )
+{
+ // nothing special to do
+ output = input;
+}
+
+template <int Dim>
+void intersection( const GeometrySet<Dim>& a, const GeometrySet<Dim>& b, GeometrySet<Dim>& output )
+{
+ typename SFCGAL::detail::HandleCollection<Dim>::Type ahandles, bhandles;
+ typename SFCGAL::detail::BoxCollection<Dim>::Type aboxes, bboxes;
+ a.computeBoundingBoxes( ahandles, aboxes );
+ b.computeBoundingBoxes( bhandles, bboxes );
+
+ GeometrySet<Dim> temp, temp2;
+ intersection_cb<Dim> cb( temp );
+ CGAL::box_intersection_d( aboxes.begin(), aboxes.end(),
+ bboxes.begin(), bboxes.end(),
+ cb );
+
+ post_intersection( temp, temp2 );
+ output.merge( temp2 );
+}
+
+template void intersection<2>( const GeometrySet<2>& a, const GeometrySet<2>& b, GeometrySet<2>& );
+template void intersection<3>( const GeometrySet<3>& a, const GeometrySet<3>& b, GeometrySet<3>& );
+
+std::auto_ptr<Geometry> intersection( const Geometry& ga, const Geometry& gb, NoValidityCheck )
+{
+ GeometrySet<2> gsa( ga ), gsb( gb ), output;
+ algorithm::intersection( gsa, gsb, output );
+
+ GeometrySet<2> filtered;
+ output.filterCovered( filtered );
+ return filtered.recompose();
+}
+
+std::auto_ptr<Geometry> intersection( const Geometry& ga, const Geometry& gb )
+{
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_2D( ga );
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_2D( gb );
+
+ return intersection( ga, gb, NoValidityCheck() );
+}
+
+std::auto_ptr<Geometry> intersection3D( const Geometry& ga, const Geometry& gb, NoValidityCheck )
+{
+ GeometrySet<3> gsa( ga ), gsb( gb ), output;
+ algorithm::intersection( gsa, gsb, output );
+
+ GeometrySet<3> filtered;
+ output.filterCovered( filtered );
+
+ return filtered.recompose();
+}
+
+std::auto_ptr<Geometry> intersection3D( const Geometry& ga, const Geometry& gb )
+{
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_3D( ga );
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_3D( gb );
+
+ return intersection3D( ga, gb, NoValidityCheck() );
+}
+}
+}
diff --git a/src/algorithm/intersection.h b/src/algorithm/intersection.h
new file mode 100644
index 0000000..5a632fd
--- /dev/null
+++ b/src/algorithm/intersection.h
@@ -0,0 +1,83 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SFCGAL_INTERSECTION_ALGORITHM
+#define SFCGAL_INTERSECTION_ALGORITHM
+
+#include <SFCGAL/config.h>
+
+#include <memory>
+
+namespace SFCGAL {
+class Geometry;
+namespace detail {
+template <int Dim> class GeometrySet;
+template <int Dim> class PrimitiveHandle;
+}
+
+namespace algorithm {
+struct NoValidityCheck;
+
+/**
+ * Intersection on 2D geometries.
+ * @pre ga and gb are valid geometries
+ * @ingroup public_api
+ */
+SFCGAL_API std::auto_ptr<Geometry> intersection( const Geometry& ga, const Geometry& gb );
+
+/**
+ * Intersection on 2D geometries. No validity check variant
+ * @pre ga and gb are valid geometries
+ * @ingroup detail
+ * @warning No actual validity check is done.
+ */
+SFCGAL_API std::auto_ptr<Geometry> intersection( const Geometry& ga, const Geometry& gb,NoValidityCheck );
+
+/**
+ * Intersection on 3D geometries. Assume z = 0 if needed
+ * @pre ga and gb are valid geometries
+ * @ingroup public_api
+ */
+SFCGAL_API std::auto_ptr<Geometry> intersection3D( const Geometry& ga, const Geometry& gb );
+
+/**
+ * Intersection on 3D geometries. Assume z = 0 if needed
+ * @pre ga and gb are valid geometries
+ * @ingroup detail
+ * @warning@ No actual validity check is done
+ */
+SFCGAL_API std::auto_ptr<Geometry> intersection3D( const Geometry& ga, const Geometry& gb, NoValidityCheck );
+
+/**
+ * @ingroup detail
+ */
+template <int Dim>
+void intersection( const detail::GeometrySet<Dim>& a, const detail::GeometrySet<Dim>& b, detail::GeometrySet<Dim>& );
+
+/**
+ * @ingroup detail
+ */
+template <int Dim>
+void intersection( const detail::PrimitiveHandle<Dim>& a, const detail::PrimitiveHandle<Dim>& b, detail::GeometrySet<Dim>& );
+
+}
+}
+
+#endif
diff --git a/src/algorithm/intersects.cpp b/src/algorithm/intersects.cpp
new file mode 100644
index 0000000..55baa7f
--- /dev/null
+++ b/src/algorithm/intersects.cpp
@@ -0,0 +1,610 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <map>
+#include <sstream>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/algorithm/intersects.h>
+#include <SFCGAL/algorithm/intersection.h>
+#include <SFCGAL/algorithm/connection.h>
+#include <SFCGAL/algorithm/covers.h>
+#include <SFCGAL/algorithm/isValid.h>
+#include <SFCGAL/detail/triangulate/triangulateInGeometrySet.h>
+#include <SFCGAL/detail/GeometrySet.h>
+#include <SFCGAL/Envelope.h>
+#include <SFCGAL/Exception.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/PolyhedralSurface.h>
+
+#include <CGAL/box_intersection_d.h>
+
+#include <CGAL/Point_inside_polyhedron_3.h>
+
+using namespace SFCGAL::detail;
+
+namespace SFCGAL {
+namespace algorithm {
+//
+// Type of pa must be of larger dimension than type of pb
+bool _intersects( const PrimitiveHandle<2>& pa, const PrimitiveHandle<2>& pb )
+{
+ //
+ // Point vs. Point
+ //
+
+ if ( pa.handle.which() == PrimitivePoint && pb.handle.which() == PrimitivePoint ) {
+ return *boost::get<const CGAL::Point_2<Kernel>* >( pa.handle )
+ == *boost::get<const CGAL::Point_2<Kernel>* >( pb.handle );
+ }
+
+ //
+ // Segment vs. Point
+ //
+
+ else if ( pa.handle.which() == PrimitiveSegment && pb.handle.which() == PrimitivePoint ) {
+ const CGAL::Segment_2<Kernel>* seg = pa.as<CGAL::Segment_2<Kernel> >();
+ const CGAL::Point_2<Kernel>* pt = pb.as<CGAL::Point_2<Kernel> >();
+ return seg->has_on( *pt );
+ }
+
+ //
+ // Segment vs. Segment
+ //
+
+ else if ( pa.handle.which() == PrimitiveSegment && pb.handle.which() == PrimitiveSegment ) {
+ const CGAL::Segment_2<Kernel>* seg1 = pa.as<CGAL::Segment_2<Kernel> >();
+ const CGAL::Segment_2<Kernel>* seg2 = pb.as<CGAL::Segment_2<Kernel> >();
+ return CGAL::do_intersect( *seg1, *seg2 );
+ }
+
+ //
+ // Polygon vs. Point
+ //
+
+ else if ( pa.handle.which() == PrimitiveSurface && pb.handle.which() == PrimitivePoint ) {
+ // Polygon versus Point
+ const CGAL::Polygon_with_holes_2<Kernel>* poly = pa.as<CGAL::Polygon_with_holes_2<Kernel> >();
+ const CGAL::Point_2<Kernel>* pt = pb.as<CGAL::Point_2<Kernel> >();
+
+ int b1 = poly->outer_boundary().bounded_side( *pt );
+
+ if ( b1 == CGAL::ON_BOUNDARY ) {
+ return true;
+ }
+
+ if ( b1 == CGAL::ON_BOUNDED_SIDE ) {
+ CGAL::Polygon_with_holes_2<Kernel>::Hole_const_iterator it;
+
+ for ( it = poly->holes_begin(); it != poly->holes_end(); ++it ) {
+ int b = it->bounded_side( *pt );
+
+ if ( b == CGAL::ON_BOUNDED_SIDE ) {
+ return false;
+ }
+ }
+ }
+ else {
+ return false;
+ }
+
+ return true;
+ }
+
+ //
+ // Polygon vs. Segment
+ //
+
+ else if ( pa.handle.which() == PrimitiveSurface && pb.handle.which() == PrimitiveSegment ) {
+ const CGAL::Polygon_with_holes_2<Kernel>* poly = pa.as<CGAL::Polygon_with_holes_2<Kernel> >();
+ const CGAL::Segment_2<Kernel>* seg = pb.as<CGAL::Segment_2<Kernel> >();
+
+ // 1. if the segment intersects a boundary of the polygon, returns true
+ // 2. else, if one of the point of the segment intersects the polygon, returns true
+
+ GeometrySet<2> segment;
+ segment.addSegments( seg, seg+1 );
+
+ // 1.
+ GeometrySet<2> boundary;
+ boundary.addSegments( poly->outer_boundary().edges_begin(),
+ poly->outer_boundary().edges_end() );
+
+ // recurse call
+ if ( intersects( boundary, segment ) ) {
+ return true;
+ }
+
+ for ( CGAL::Polygon_with_holes_2<Kernel>::Hole_const_iterator it = poly->holes_begin();
+ it != poly->holes_end();
+ ++it ) {
+ GeometrySet<2> hole;
+ hole.addSegments( it->edges_begin(), it->edges_end() );
+
+ // recurse call
+ if ( intersects( hole, segment ) ) {
+ return true;
+ }
+ }
+
+ // 2. call the polygon, point version
+ CGAL::Point_2<Kernel> pt = seg->source();
+ PrimitiveHandle<2> ppoly( poly );
+ PrimitiveHandle<2> ppt( &pt );
+ return intersects( ppoly, ppt );
+ }
+
+ //
+ // Polygon vs. Polygon
+ //
+
+ else if ( pa.handle.which() == PrimitiveSurface && pb.handle.which() == PrimitiveSurface ) {
+ const CGAL::Polygon_with_holes_2<Kernel>* poly1 = pa.as<CGAL::Polygon_with_holes_2<Kernel> >();
+ const CGAL::Polygon_with_holes_2<Kernel>* poly2 = pb.as<CGAL::Polygon_with_holes_2<Kernel> >();
+
+ // 1. if rings intersects, returns true
+ // 2. else, if poly1 is inside poly2 or poly1 inside poly2 (but not in holes), returns true
+
+ GeometrySet<2> rings1, rings2;
+ rings1.addSegments( poly1->outer_boundary().edges_begin(),
+ poly1->outer_boundary().edges_end() );
+
+ for ( CGAL::Polygon_with_holes_2<Kernel>::Hole_const_iterator it = poly1->holes_begin();
+ it != poly1->holes_end();
+ ++it ) {
+ rings1.addSegments( it->edges_begin(), it->edges_end() );
+ }
+
+ rings2.addSegments( poly2->outer_boundary().edges_begin(),
+ poly2->outer_boundary().edges_end() );
+
+ for ( CGAL::Polygon_with_holes_2<Kernel>::Hole_const_iterator it = poly2->holes_begin();
+ it != poly2->holes_end();
+ ++it ) {
+ rings2.addSegments( it->edges_begin(), it->edges_end() );
+ }
+
+ // 1.
+ if ( intersects( rings1, rings2 ) ) {
+ return true;
+ }
+
+ // 2.
+ CGAL::Bbox_2 box1, box2;
+ box1 = poly1->bbox();
+ box2 = poly2->bbox();
+ Envelope e1( box1.xmin(), box1.xmax(), box1.ymin(), box1.ymax() );
+ Envelope e2( box2.xmin(), box2.xmax(), box2.ymin(), box2.ymax() );
+
+ // if pa is inside pb
+ if ( Envelope::contains( e2, e1 ) ) {
+ // is pa inside one of pb's holes ?
+ CGAL::Point_2<Kernel> pt = *poly1->outer_boundary().vertices_begin();
+
+ for ( CGAL::Polygon_with_holes_2<Kernel>::Hole_const_iterator it = poly2->holes_begin();
+ it != poly2->holes_end();
+ ++it ) {
+ CGAL::Bounded_side b2 = it->bounded_side( pt );
+
+ if ( b2 == CGAL::ON_BOUNDED_SIDE ) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ // if pb is inside pa
+ if ( Envelope::contains( e1, e2 ) ) {
+ // is pa inside one of pb's holes ?
+ CGAL::Point_2<Kernel> pt = *poly2->outer_boundary().vertices_begin();
+
+ for ( CGAL::Polygon_with_holes_2<Kernel>::Hole_const_iterator it = poly1->holes_begin();
+ it != poly1->holes_end();
+ ++it ) {
+ CGAL::Bounded_side b2 = it->bounded_side( pt );
+
+ if ( b2 == CGAL::ON_BOUNDED_SIDE ) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ return false;
+}
+
+
+//
+// intersects of a volume with any other type
+struct intersects_volume_x : public boost::static_visitor<bool> {
+ const MarkedPolyhedron* polyhedron;
+
+ intersects_volume_x( const MarkedPolyhedron* vol ) : polyhedron( vol ) {}
+
+ template <class T>
+ bool operator() ( const T* geometry ) const {
+ // intersection between a solid and a geometry
+ // 1. either one of the geometry' point lies inside the solid
+ // 2. or the geometry intersects one of the surfaces
+
+ // 1.
+
+ if ( polyhedron->is_closed() ) {
+ // this test is needed only if its a volume
+ // if the polyhedron is not closed, this is not a volume, actually
+
+ CGAL::Point_inside_polyhedron_3<MarkedPolyhedron, Kernel> is_in_poly( *polyhedron );
+
+ GeometrySet<3> points;
+ points.collectPoints( geometry );
+
+ for ( GeometrySet<3>::PointCollection::const_iterator pit = points.points().begin();
+ pit != points.points().end(); ++pit ) {
+ if ( is_in_poly( pit->primitive() ) != CGAL::ON_UNBOUNDED_SIDE ) {
+ return true;
+ }
+ }
+ }
+
+ // 2.
+
+ // triangulate the polyhedron_3
+ GeometrySet<3> g;
+ g.addPrimitive( *geometry );
+
+ GeometrySet<3> triangles;
+ triangulate::triangulate( *polyhedron, triangles );
+
+ return intersects( g, triangles );
+ }
+};
+
+//
+// Type of pa must be of larger dimension than type of pb
+bool _intersects( const PrimitiveHandle<3>& pa, const PrimitiveHandle<3>& pb )
+{
+ if ( pa.handle.which() == PrimitivePoint && pb.handle.which() == PrimitivePoint ) {
+ return *boost::get<const CGAL::Point_3<Kernel>* >( pa.handle )
+ == *boost::get<const CGAL::Point_3<Kernel>* >( pb.handle );
+ }
+ else if ( pa.handle.which() == PrimitiveSegment && pb.handle.which() == PrimitivePoint ) {
+ const CGAL::Segment_3<Kernel>* seg = pa.as<CGAL::Segment_3<Kernel> >();
+ const CGAL::Point_3<Kernel>* pt = pb.as<CGAL::Point_3<Kernel> >();
+ return seg->has_on( *pt );
+ }
+ else if ( pa.handle.which() == PrimitiveSegment && pb.handle.which() == PrimitiveSegment ) {
+ const CGAL::Segment_3<Kernel>* sega = pa.as<CGAL::Segment_3<Kernel> >();
+ const CGAL::Segment_3<Kernel>* segb = pb.as<CGAL::Segment_3<Kernel> >();
+ return CGAL::do_intersect( *sega, *segb );
+ }
+
+ if ( pa.handle.which() == PrimitiveVolume ) {
+ intersects_volume_x visitor( pa.as<MarkedPolyhedron >() );
+ return boost::apply_visitor( visitor, pb.handle );
+ }
+
+ if ( pa.handle.which() == PrimitiveSurface && pb.handle.which() == PrimitivePoint ) {
+ const CGAL::Triangle_3<Kernel>* tri = pa.as<CGAL::Triangle_3<Kernel> >();
+ const CGAL::Point_3<Kernel>* pt = pb.as<CGAL::Point_3<Kernel> >();
+ return tri->has_on( *pt );
+ }
+
+ if ( pa.handle.which() == PrimitiveSurface && pb.handle.which() == PrimitiveSegment ) {
+ const CGAL::Triangle_3<Kernel>* tri = pa.as<CGAL::Triangle_3<Kernel> >();
+ const CGAL::Segment_3<Kernel>* seg = pb.as<CGAL::Segment_3<Kernel> >();
+ return CGAL::do_intersect( *tri, *seg );
+ }
+
+ if ( pa.handle.which() == PrimitiveSurface && pb.handle.which() == PrimitiveSurface ) {
+ const CGAL::Triangle_3<Kernel>* tri1 = pa.as<CGAL::Triangle_3<Kernel> >();
+ const CGAL::Triangle_3<Kernel>* tri2 = pb.as<CGAL::Triangle_3<Kernel> >();
+ return CGAL::do_intersect( *tri1, *tri2 );
+ }
+
+ return false;
+}
+
+//
+// We deal here with symmetric call
+template <int Dim>
+bool dispatch_intersects_sym( const PrimitiveHandle<Dim>& pa, const PrimitiveHandle<Dim>& pb )
+{
+ // assume types are ordered by dimension within the boost::variant
+ if ( pa.handle.which() >= pb.handle.which() ) {
+ return _intersects( pa, pb );
+ }
+ else {
+ return _intersects( pb, pa );
+ }
+}
+
+template <int Dim>
+bool intersects( const PrimitiveHandle<Dim>& pa, const PrimitiveHandle<Dim>& pb )
+{
+ return dispatch_intersects_sym( pa, pb );
+}
+
+struct found_an_intersection {};
+
+template <int Dim>
+struct intersects_cb {
+ void operator()( const typename PrimitiveBox<Dim>::Type& a,
+ const typename PrimitiveBox<Dim>::Type& b ) {
+ if ( dispatch_intersects_sym( *a.handle(), *b.handle() ) ) {
+ throw found_an_intersection();
+ }
+ }
+};
+
+template <int Dim>
+bool intersects( const GeometrySet<Dim>& a, const GeometrySet<Dim>& b )
+{
+ typename SFCGAL::detail::HandleCollection<Dim>::Type ahandles, bhandles;
+ typename SFCGAL::detail::BoxCollection<Dim>::Type aboxes, bboxes;
+ a.computeBoundingBoxes( ahandles, aboxes );
+ b.computeBoundingBoxes( bhandles, bboxes );
+
+ try {
+ intersects_cb<Dim> cb;
+ CGAL::box_intersection_d( aboxes.begin(), aboxes.end(),
+ bboxes.begin(), bboxes.end(),
+ cb );
+ }
+ catch ( found_an_intersection& e ) {
+ return true;
+ }
+
+ return false;
+}
+
+template bool intersects<2>( const GeometrySet<2>& a, const GeometrySet<2>& b );
+template bool intersects<3>( const GeometrySet<3>& a, const GeometrySet<3>& b );
+
+template bool intersects<2>( const PrimitiveHandle<2>& a, const PrimitiveHandle<2>& b );
+template bool intersects<3>( const PrimitiveHandle<3>& a, const PrimitiveHandle<3>& b );
+
+bool intersects( const Geometry& ga, const Geometry& gb )
+{
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_2D( ga );
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_2D( gb );
+
+ GeometrySet<2> gsa( ga );
+ GeometrySet<2> gsb( gb );
+
+ return intersects( gsa, gsb );
+}
+
+bool intersects3D( const Geometry& ga, const Geometry& gb )
+{
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_3D( ga );
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_3D( gb );
+
+ GeometrySet<3> gsa( ga );
+ GeometrySet<3> gsb( gb );
+
+ return intersects( gsa, gsb );
+}
+
+bool intersects( const Geometry& ga, const Geometry& gb, NoValidityCheck )
+{
+ GeometrySet<2> gsa( ga );
+ GeometrySet<2> gsb( gb );
+
+ return intersects( gsa, gsb );
+}
+
+bool intersects3D( const Geometry& ga, const Geometry& gb, NoValidityCheck )
+{
+ GeometrySet<3> gsa( ga );
+ GeometrySet<3> gsb( gb );
+
+ return intersects( gsa, gsb );
+}
+
+template< int Dim >
+bool selfIntersectsImpl( const LineString& line )
+{
+
+ if ( line.numSegments() < 2 ) {
+ return false; // one segment cannot intersect
+ }
+
+ // note: zero length segments are a pain, to avoid algorithm complexity
+ // we start by filtering them out
+ const size_t numPoints = line.numPoints();
+ LineString l;
+
+ for ( size_t i = 0; i != numPoints; ++i ) {
+ if ( i==0 || l.endPoint() != line.pointN( i ) ) {
+ l.addPoint( line.pointN( i ) );
+ }
+ }
+
+ const size_t numSegments = l.numSegments();
+
+ // test any two pairs of segments
+ for ( size_t i = 0; i != numSegments; ++i ) {
+ // first line segment is point i and i+1
+ for ( size_t j = i + 1; j < numSegments; ++j ) {
+ /** @todo find a way to avoid ugly copy/paste here, toPoint_d< Dim > can be used,
+ * but I dont know what to do with Kernel::Segment_Dim and Kernel::Point_Dim
+ */
+ std::auto_ptr< Geometry > inter; // null if no intersection
+
+ if ( Dim == 2 ) {
+ const CGAL::Segment_2< Kernel > s1( l.pointN( i ).toPoint_2(), l.pointN( i + 1 ).toPoint_2() ) ;
+ const CGAL::Segment_2< Kernel > s2( l.pointN( j ).toPoint_2(), l.pointN( j + 1 ).toPoint_2() ) ;
+ const CGAL::Object out = CGAL::intersection( s1, s2 );
+
+ if ( out.is< Kernel::Point_2 >() ) {
+ inter.reset( new Point( CGAL::object_cast< Kernel::Point_2 >( out ) ) );
+ }
+ else if ( out.is< Kernel::Segment_2 >() ) {
+ const Kernel::Segment_2& s = CGAL::object_cast< Kernel::Segment_2 >( out );
+ inter.reset( new LineString( s.point( 0 ), s.point( 1 ) ) ) ;
+ }
+ }
+ else {
+ const CGAL::Segment_3< Kernel > s1( l.pointN( i ).toPoint_3(), l.pointN( i + 1 ).toPoint_3() ) ;
+ const CGAL::Segment_3< Kernel > s2( l.pointN( j ).toPoint_3(), l.pointN( j + 1 ).toPoint_3() ) ;
+ const CGAL::Object out = CGAL::intersection( s1, s2 );
+
+ if ( out.is< Kernel::Point_3 >() ) {
+ inter.reset( new Point( CGAL::object_cast< Kernel::Point_3 >( out ) ) );
+ }
+ else if ( out.is< Kernel::Segment_3 >() ) {
+ const Kernel::Segment_3& s = CGAL::object_cast< Kernel::Segment_3 >( out );
+ inter.reset( new LineString( s.point( 0 ), s.point( 1 ) ) ) ;
+ }
+ }
+
+ if ( inter.get() && inter->is< LineString >() ) {
+ return true; // segments overlap
+ }
+ else if ( inter.get() && inter->is< Point >()
+ && !( i + 1 == j ) // one contact point between consecutive segments is ok
+ && !( ( i == 0 )
+ && ( j + 1 == numSegments )
+ && inter->as< Point >() == l.startPoint()
+ && inter->as< Point >() == l.endPoint() ) ) {
+ return true; // contact point that is not a contact between startPoint and endPoint
+ }
+ }
+ }
+
+ return false;
+}
+
+bool selfIntersects( const LineString& l )
+{
+ return selfIntersectsImpl<2>( l );
+}
+bool selfIntersects3D( const LineString& l )
+{
+ return selfIntersectsImpl<3>( l );
+}
+
+
+template< int Dim >
+bool selfIntersectsImpl( const PolyhedralSurface& s, const SurfaceGraph& graph )
+{
+ size_t numPolygons = s.numPolygons();
+
+ for ( size_t pi=0; pi != numPolygons; ++pi ) {
+ for ( size_t pj=pi+1; pj < numPolygons; ++pj ) {
+ std::auto_ptr< Geometry > inter = Dim == 3
+ ? intersection3D( s.polygonN( pi ), s.polygonN( pj ) )
+ : intersection( s.polygonN( pi ), s.polygonN( pj ) ) ;
+
+ if ( !inter->isEmpty() ) {
+ // two cases:
+ // - neighbors can have a line as intersection
+ // - non neighbors can only have a point or a set of points
+ typedef SurfaceGraph::FaceGraph::adjacency_iterator Iterator;
+ std::pair< Iterator, Iterator > neighbors = boost::adjacent_vertices( pi, graph.faceGraph() );
+
+ if ( neighbors.second != std::find( neighbors.first, neighbors.second, pj ) ) {
+ // neighbor
+ //std::cerr << pi << " " << pj << " neighbor\n";
+ if ( !inter->is< LineString >() ) {
+ return true;
+ }
+ }
+ else {
+ // not a neighbor
+ //std::cerr << pi << " " << pj << " not neighbor\n";
+ if ( inter->dimension() != 0 ) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+bool selfIntersects( const PolyhedralSurface& s, const SurfaceGraph& g )
+{
+ return selfIntersectsImpl<2>( s, g );
+}
+
+bool selfIntersects3D( const PolyhedralSurface& s, const SurfaceGraph& g )
+{
+ return selfIntersectsImpl<3>( s, g );
+}
+
+template< int Dim >
+bool selfIntersectsImpl( const TriangulatedSurface& tin, const SurfaceGraph& graph )
+{
+ size_t numTriangles = tin.numTriangles();
+
+ for ( size_t ti=0; ti != numTriangles; ++ti ) {
+ for ( size_t tj=ti+1; tj < numTriangles; ++tj ) {
+ std::auto_ptr< Geometry > inter = Dim == 3
+ ? intersection3D( tin.triangleN( ti ), tin.triangleN( tj ) )
+ : intersection( tin.triangleN( ti ), tin.triangleN( tj ) ) ;
+
+ if ( !inter->isEmpty() ) {
+ // two cases:
+ // - neighbors can have a line as intersection
+ // - non neighbors can only have a point or a set of points
+ typedef SurfaceGraph::FaceGraph::adjacency_iterator Iterator;
+ std::pair< Iterator, Iterator > neighbors = boost::adjacent_vertices( ti, graph.faceGraph() );
+
+ if ( neighbors.second != std::find( neighbors.first, neighbors.second, tj ) ) {
+ // neighbor
+ //std::cerr << ti << " " << tj << " neighbor\n";
+ if ( !inter->is< LineString >() ) {
+ return true;
+ }
+ }
+ else {
+ // not a neighbor
+ //std::cerr << ti << " " << tj << " not neighbor\n";
+ if ( inter->dimension() != 0 ) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+bool selfIntersects( const TriangulatedSurface& tin, const SurfaceGraph& g )
+{
+ return selfIntersectsImpl<2>( tin, g );
+}
+
+bool selfIntersects3D( const TriangulatedSurface& tin, const SurfaceGraph& g )
+{
+ return selfIntersectsImpl<3>( tin, g );
+}
+
+}
+}
diff --git a/src/algorithm/intersects.h b/src/algorithm/intersects.h
new file mode 100644
index 0000000..834f60b
--- /dev/null
+++ b/src/algorithm/intersects.h
@@ -0,0 +1,123 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SFCGAL_INTERSECTS_ALGORITHM
+#define SFCGAL_INTERSECTS_ALGORITHM
+
+#include <SFCGAL/config.h>
+
+namespace SFCGAL {
+class Geometry;
+class LineString;
+class PolyhedralSurface;
+class TriangulatedSurface;
+namespace detail {
+template <int Dim> class GeometrySet;
+template <int Dim> class PrimitiveHandle;
+}
+
+namespace algorithm {
+class SurfaceGraph;
+// defined in isValid.h
+struct NoValidityCheck;
+
+/**
+ * Robust intersection test on 2D geometries. Force projection to z=0 if needed
+ * @pre ga and gb are valid geometries
+ * @ingroup public_api
+ */
+SFCGAL_API bool intersects( const Geometry& ga, const Geometry& gb );
+
+/**
+ * Robust intersection test on 3D geometries. Assume z = 0 if needed
+ * @pre ga and gb are valid geometries
+ * @ingroup public_api
+ */
+SFCGAL_API bool intersects3D( const Geometry& ga, const Geometry& gb );
+
+/**
+ * Intersection test on 2D geometries. Force projection to z=0 if needed
+ * @pre ga and gb are valid geometries
+ * @ingroup detail
+ * @warning the validity is assumed, no actual check is done
+ */
+SFCGAL_API bool intersects( const Geometry& ga, const Geometry& gb, NoValidityCheck );
+
+/**
+ * Intersection test on 3D geometries. Assume z = 0 if needed
+ * @pre ga and gb are valid geometries
+ * @ingroup detail
+ * @warning the validity is assumed, no actual check is done
+ */
+SFCGAL_API bool intersects3D( const Geometry& ga, const Geometry& gb, NoValidityCheck );
+
+/**
+ * Intersection test on GeometrySet
+ * @ingroup detail
+ */
+template <int Dim>
+bool intersects( const detail::GeometrySet<Dim>& a, const detail::GeometrySet<Dim>& b );
+
+/**
+ * Intersection test on a PrimitiveHandle
+ * @ingroup detail
+ */
+template <int Dim>
+bool intersects( const detail::PrimitiveHandle<Dim>& a, const detail::PrimitiveHandle<Dim>& b );
+
+/**
+ * Self intersection test for 2D LineString (false if only endpoint touch)
+ * @ingroup detail
+ */
+bool selfIntersects( const LineString& l );
+
+/**
+ * Self intersection test for 3D LineString (false if only endpoints touch)
+ * @ingroup detail
+ */
+bool selfIntersects3D( const LineString& l );
+
+/**
+ * Self intersection test for 2D PolyhedralSurface (false if only point touch)
+ * @ingroup detail
+ */
+bool selfIntersects( const PolyhedralSurface& s, const SurfaceGraph& g );
+
+/**
+ * Self intersection test for 3D PolyhedralSurface (false if only point touch)
+ * @ingroup detail
+ */
+
+bool selfIntersects3D( const PolyhedralSurface& s, const SurfaceGraph& g );
+
+/**
+ * Self intersection test for 2D TriangulatedSurface (false if only point touch)
+ * @ingroup detail
+ */
+bool selfIntersects( const TriangulatedSurface& s, const SurfaceGraph& g );
+
+/**
+ * Self intersection test for 3D TriangulatedSurface (false if only point touch)
+ * @ingroup detail
+ */
+bool selfIntersects3D( const TriangulatedSurface& s, const SurfaceGraph& g );
+}
+}
+#endif
diff --git a/src/algorithm/isValid.cpp b/src/algorithm/isValid.cpp
new file mode 100644
index 0000000..f75d732
--- /dev/null
+++ b/src/algorithm/isValid.cpp
@@ -0,0 +1,488 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/isValid.h>
+
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+#include <SFCGAL/algorithm/intersects.h>
+#include <SFCGAL/algorithm/intersection.h>
+#include <SFCGAL/algorithm/length.h>
+#include <SFCGAL/algorithm/orientation.h>
+#include <SFCGAL/algorithm/distance.h>
+#include <SFCGAL/algorithm/distance3d.h>
+#include <SFCGAL/algorithm/plane.h>
+#include <SFCGAL/algorithm/normal.h>
+#include <SFCGAL/detail/algorithm/coversPoints.h>
+#include <SFCGAL/algorithm/connection.h>
+#include <SFCGAL/detail/tools/Log.h>
+#include <SFCGAL/detail/GetPointsVisitor.h>
+#include <SFCGAL/Kernel.h>
+
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/visitors.hpp>
+#include <boost/graph/undirected_dfs.hpp>
+
+
+using namespace SFCGAL::detail::algorithm;
+
+namespace SFCGAL {
+namespace algorithm {
+
+bool SKIP_GEOM_VALIDATION = false;
+
+// to detect unconnected interior in polygon
+struct LoopDetector : public boost::dfs_visitor<> {
+ LoopDetector( bool& hasLoop ):_hasLoop( hasLoop ) {}
+
+ template <class Edge, class Graph>
+ void back_edge( Edge, const Graph& ) {
+ _hasLoop = true;
+ }
+private:
+ bool& _hasLoop;
+};
+
+
+
+/**
+ * @note empty geometries are valid, but the test is only performed in the interface function
+ * in individual functions for implementation, an assertion !empty is present for this reason
+ */
+
+//const Validity isValid( const Coordinate & p)
+//{
+// BOOST_ASSERT( !p.isEmpty() );
+// if ( !CGAL::is_finite(p.x()) || CGAL::is_finite(p.y()) ) return Validity::invalid("NaN coordinate");
+// //if ( p.x().is_inf() || p.y().is_inf() ) return Validity::invalid("infinite coordinate");
+// return Validity::valid();
+//}
+//
+const Validity isValid( const Point& p )
+{
+ if ( p.isEmpty() ) {
+ return Validity::valid();
+ }
+
+ ( void )p;
+ //return( isValid(p.coordinate() ) );
+ return Validity::valid();
+}
+
+const Validity isValid( const LineString& l, const double& toleranceAbs )
+{
+ if ( l.isEmpty() ) {
+ return Validity::valid();
+ }
+
+// const size_t numPoints = l.numPoints();
+// for ( size_t p=0; p!=numPoints; ++p) {
+// const Validity v = isValid(l.pointN(p));
+// if (!v) return Validity::invalid( ( boost::format("Point %d is invalid: %s") % p % v.reason() ).str() );
+// }
+
+ return length3D( l ) > toleranceAbs ? Validity::valid() : Validity::invalid( "no length" );
+}
+
+const Validity isValid( const Polygon& p, const double& toleranceAbs )
+{
+ if ( p.isEmpty() ) {
+ return Validity::valid();
+ }
+
+ // Closed simple rings
+ const size_t numRings = p.numRings();
+
+ for ( size_t r=0; r != numRings; ++r ) {
+ if ( p.ringN( r ).numPoints() < 4 ) {
+ return Validity::invalid( ( boost::format( "not enought points in ring %d" ) % r ).str() );
+ }
+
+// const Validity v = isValid( p.ringN(r) );
+// if (!v) return Validity::invalid((boost::format("ring %d is invalid: %s") % r % v.reason()).str() );
+
+ const double distanceToClose =
+ p.is3D() ? distancePointPoint3D( p.ringN( r ).startPoint(), p.ringN( r ).endPoint() )
+ : distancePointPoint( p.ringN( r ).startPoint(), p.ringN( r ).endPoint() )
+ ;
+
+ if ( distanceToClose > 0 ) {
+ return Validity::invalid( ( boost::format( "ring %d is not closed" ) % r ).str() );
+ }
+
+ if ( p.is3D() ? selfIntersects3D( p.ringN( r ) ) : selfIntersects( p.ringN( r ) ) ) {
+ return Validity::invalid( ( boost::format( "ring %d self intersects" ) % r ).str() );
+ }
+ }
+
+ // Orientation in 2D
+ if ( !p.is3D() ) {
+ // Opposit orientation for interior and exterior rings
+ const bool extCCWO = isCounterClockWiseOriented( p.exteriorRing() );
+
+ for ( std::size_t r=0; r<p.numInteriorRings(); ++r ) {
+ if ( extCCWO == isCounterClockWiseOriented( p.interiorRingN( r ) ) ) {
+ return Validity::invalid( ( boost::format( "exterior ring and interior ring %d have the same orientation" ) % r ).str() );
+ }
+ }
+ }
+ // Orientation in 3D
+ else {
+ // Polygone must be planar (all points in the same plane)
+ if ( !isPlane3D< Kernel >( p, toleranceAbs ) ) {
+ return Validity::invalid( "points don't lie in the same plane" );
+ }
+
+ // interior rings must be oriented opposit to exterior;
+ if ( p.hasInteriorRings() ) {
+ const CGAL::Vector_3< Kernel > nExt = normal3D< Kernel >( p.exteriorRing() );
+
+ for ( std::size_t r=0; r<p.numInteriorRings(); ++r ) {
+ const CGAL::Vector_3< Kernel > nInt = normal3D< Kernel>( p.interiorRingN( r ) );
+
+ if ( nExt * nInt > 0 ) {
+ return Validity::invalid( ( boost::format( "interior ring %d is oriented in the same direction as exterior ring" ) % r ).str() );
+ }
+ }
+ }
+ }
+
+ // Rings must not share more than one point (no intersection)
+ {
+ typedef std::pair<int,int> Edge;
+ std::vector<Edge> touchingRings;
+
+ for ( size_t ri=0; ri < numRings; ++ri ) { // no need for numRings-1, the next loop won't be entered for the last ring
+ for ( size_t rj=ri+1; rj < numRings; ++rj ) {
+ std::auto_ptr<Geometry> inter = p.is3D()
+ ? intersection3D( p.ringN( ri ), p.ringN( rj ) )
+ : intersection( p.ringN( ri ), p.ringN( rj ) );
+
+ if ( ! inter->isEmpty() && ! inter->is< Point >() ) {
+ return Validity::invalid( ( boost::format( "intersection between ring %d and %d" ) % ri % rj ).str() );
+ }
+ else if ( ! inter->isEmpty() && inter->is< Point >() ) {
+ touchingRings.push_back( Edge( ri,rj ) );
+ }
+ }
+ }
+
+ {
+ using namespace boost;
+ typedef adjacency_list< vecS, vecS, undirectedS,
+ no_property,
+ property<edge_color_t, default_color_type> > Graph;
+ typedef graph_traits<Graph>::vertex_descriptor vertex_t;
+
+ Graph g( touchingRings.begin(), touchingRings.end(), numRings );
+
+ bool hasLoop = false;
+ LoopDetector vis( hasLoop );
+ undirected_dfs( g, root_vertex( vertex_t( 0 ) ).visitor( vis ).edge_color_map( get( edge_color, g ) ) );
+
+ if ( hasLoop ) {
+ return Validity::invalid( "interior is not connected" );
+ }
+ }
+ }
+
+ if ( p.hasInteriorRings() ) {
+ // Interior rings must be interior to exterior ring
+ for ( size_t r=0; r < p.numInteriorRings(); ++r ) { // no need for numRings-1, the next loop won't be entered for the last ring
+ if ( p.is3D()
+ ? !coversPoints3D( Polygon( p.exteriorRing() ), Polygon( p.interiorRingN( r ) ) )
+ : !coversPoints( Polygon( p.exteriorRing() ), Polygon( p.interiorRingN( r ) ) )
+ ) {
+ return Validity::invalid( ( boost::format( "exterior ring doesn't cover interior ring %d" ) % r ).str() );
+ }
+ }
+
+ // Interior ring must not cover one another
+ for ( size_t ri=0; ri < p.numInteriorRings(); ++ri ) { // no need for numRings-1, the next loop won't be entered for the last ring
+ for ( size_t rj=ri+1; rj < p.numInteriorRings(); ++rj ) {
+ if ( p.is3D()
+ ? coversPoints3D( Polygon( p.interiorRingN( ri ) ), Polygon( p.interiorRingN( rj ) ) )
+ : coversPoints( Polygon( p.interiorRingN( ri ) ), Polygon( p.interiorRingN( rj ) ) )
+ ) {
+ return Validity::invalid( ( boost::format( "interior ring %d covers interior ring %d" ) % ri % rj ).str() );
+ }
+ }
+ }
+ }
+
+ return Validity::valid();
+}
+
+const Validity isValid( const Triangle& t, const double& toleranceAbs )
+{
+ return isValid( t.toPolygon(), toleranceAbs );
+}
+
+const Validity isValid( const MultiLineString& ml, const double& toleranceAbs )
+{
+ if ( ml.isEmpty() ) {
+ return Validity::valid();
+ }
+
+ const size_t numLineString = ml.numGeometries();
+
+ for ( size_t l = 0; l != numLineString; ++l ) {
+ Validity v = isValid( ml.lineStringN( l ), toleranceAbs );
+
+ if ( !v ) return Validity::invalid(
+ ( boost::format( "LineString %d is invalid: %s" ) % l % v.reason() ).str()
+ );
+ }
+
+ return Validity::valid();
+}
+
+const Validity isValid( const MultiPolygon& mp, const double& toleranceAbs )
+{
+ if ( mp.isEmpty() ) {
+ return Validity::valid();
+ }
+
+ const size_t numPolygons = mp.numGeometries();
+
+ for ( size_t p = 0; p != numPolygons; ++p ) {
+ Validity v = isValid( mp.polygonN( p ), toleranceAbs );
+
+ if ( !v ) return Validity::invalid(
+ ( boost::format( "Polygon %d is invalid: %s" ) % p % v.reason() ).str()
+ );
+ }
+
+ for ( size_t pi = 0; pi != numPolygons; ++pi ) {
+ for ( size_t pj = pi+1; pj < numPolygons; ++pj ) {
+ std::auto_ptr< Geometry > inter = mp.is3D()
+ ? intersection3D( mp.polygonN( pi ), mp.polygonN( pj ) )
+ : intersection( mp.polygonN( pi ), mp.polygonN( pj ) ) ;
+
+ // intersection can be empty, a point, or a set of points
+ if ( !inter->isEmpty() && inter->dimension() != 0 ) {
+ return Validity::invalid(
+ ( boost::format( "intersection between Polygon %d and %d" ) % pi % pj ).str()
+ );
+ }
+ }
+ }
+
+ return Validity::valid();
+}
+
+const Validity isValid( const GeometryCollection& gc, const double& toleranceAbs )
+{
+ if ( gc.isEmpty() ) {
+ return Validity::valid();
+ }
+
+ const size_t numGeom = gc.numGeometries();
+
+ for ( size_t g = 0; g != numGeom; ++g ) {
+ Validity v = isValid( gc.geometryN( g ), toleranceAbs );
+
+ if ( !v ) return Validity::invalid(
+ ( boost::format( "%s %d is invalid: %s" ) % gc.geometryN( g ).geometryType() % g % v.reason() ).str()
+ );
+ }
+
+ return Validity::valid();
+}
+
+const Validity isValid( const TriangulatedSurface& tin, const SurfaceGraph& graph, const double& toleranceAbs )
+{
+ if ( tin.isEmpty() ) {
+ return Validity::valid();
+ }
+
+ size_t numTriangles = tin.numTriangles();
+
+ for ( size_t t=0; t != numTriangles; ++t ) {
+ Validity v = isValid( tin.triangleN( t ), toleranceAbs );
+
+ if ( !v ) return Validity::invalid(
+ ( boost::format( "Triangle %d is invalid: %s" ) % t % v.reason() ).str()
+ );
+ }
+
+ if ( !isConnected( graph ) ) {
+ return Validity::invalid( "not connected" );
+ }
+
+ if ( tin.is3D() ? selfIntersects3D( tin, graph ) : selfIntersects( tin, graph ) ) {
+ return Validity::invalid( "self intersects" );
+ }
+
+ return Validity::valid();
+}
+
+const Validity isValid( const TriangulatedSurface& tin, const double& toleranceAbs )
+{
+ if ( tin.isEmpty() ) {
+ return Validity::valid();
+ }
+
+ const SurfaceGraph graph( tin );
+ return graph.isValid() ? isValid( tin, graph, toleranceAbs ) : graph.isValid() ;
+}
+
+const Validity isValid( const PolyhedralSurface& s, const SurfaceGraph& graph, const double& toleranceAbs )
+{
+ if ( s.isEmpty() ) {
+ return Validity::valid();
+ }
+
+ size_t numPolygons = s.numPolygons();
+
+ for ( size_t p=0; p != numPolygons; ++p ) {
+ Validity v = isValid( s.polygonN( p ), toleranceAbs );
+
+ if ( !v ) return Validity::invalid(
+ ( boost::format( "Polygon %d is invalid: %s" ) % p % v.reason() ).str()
+ );
+ }
+
+ if ( !isConnected( graph ) ) {
+ return Validity::invalid( "not connected" );
+ }
+
+ if ( s.is3D() ? selfIntersects3D( s, graph ) : selfIntersects( s, graph ) ) {
+ return Validity::invalid( "self intersects" );
+ }
+
+ return Validity::valid();
+}
+
+const Validity isValid( const PolyhedralSurface& s, const double& toleranceAbs )
+{
+ if ( s.isEmpty() ) {
+ return Validity::valid();
+ }
+
+ const SurfaceGraph graph( s );
+ return graph.isValid() ? isValid( s, graph, toleranceAbs ) : graph.isValid() ;
+}
+
+const Validity isValid( const Solid& solid, const double& toleranceAbs )
+{
+ if ( solid.isEmpty() ) {
+ return Validity::valid();
+ }
+
+ const size_t numShells = solid.numShells();
+
+ for ( size_t s = 0; s != numShells; ++s ) {
+ const SurfaceGraph graph( solid.shellN( s ) );
+ Validity v = isValid( solid.shellN( s ), graph, toleranceAbs );
+
+ if ( !v ) return Validity::invalid(
+ ( boost::format( "PolyhedralSurface (shell) %d is invalid: %s" ) % s % v.reason() ).str()
+ );
+
+ if ( !isClosed( graph ) ) return Validity::invalid(
+ ( boost::format( "PolyhedralSurface (shell) %d is not closed" ) % s ).str()
+ );
+ }
+
+ if ( solid.numInteriorShells() ) {
+ BOOST_THROW_EXCEPTION( Exception( "function is not fully implemented (orientation, covering and intersections of interior shells missing" ) );
+ }
+
+ return Validity::valid();
+}
+
+const Validity isValid( const MultiSolid& ms, const double& toleranceAbs )
+{
+ if ( ms.isEmpty() ) {
+ return Validity::valid();
+ }
+
+ const size_t numMultiSolid = ms.numGeometries();
+
+ for ( size_t s = 0; s != numMultiSolid; ++s ) {
+ Validity v = isValid( ms.solidN( s ), toleranceAbs );
+
+ if ( !v ) return Validity::invalid(
+ ( boost::format( "Solid %d is invalid: %s" ) % s % v.reason() ).str()
+ );
+ }
+
+ return Validity::valid();
+}
+
+
+const Validity isValid( const Geometry& g, const double& toleranceAbs )
+{
+ switch ( g.geometryTypeId() ) {
+ case TYPE_POINT:
+ return isValid( g.as< Point >() );
+
+ case TYPE_LINESTRING:
+ return isValid( g.as< LineString >(), toleranceAbs ) ;
+
+ case TYPE_POLYGON:
+ return isValid( g.as< Polygon >(), toleranceAbs ) ;
+
+ case TYPE_TRIANGLE:
+ return isValid( g.as< Triangle >(), toleranceAbs ) ;
+
+ case TYPE_SOLID:
+ return isValid( g.as< Solid >(), toleranceAbs ) ;
+
+ case TYPE_MULTIPOINT:
+ return Validity::valid();
+
+ case TYPE_MULTILINESTRING:
+ return isValid( g.as< MultiLineString >(), toleranceAbs ) ;
+
+ case TYPE_MULTIPOLYGON:
+ return isValid( g.as< MultiPolygon >(), toleranceAbs ) ;
+
+ case TYPE_MULTISOLID:
+ return isValid( g.as< MultiSolid >(), toleranceAbs ) ;
+
+ case TYPE_GEOMETRYCOLLECTION:
+ return isValid( g.as< GeometryCollection >(), toleranceAbs ) ;
+
+ case TYPE_TRIANGULATEDSURFACE:
+ return isValid( g.as< TriangulatedSurface >(), toleranceAbs ) ;
+
+ case TYPE_POLYHEDRALSURFACE:
+ return isValid( g.as< PolyhedralSurface >(), toleranceAbs ) ;
+ }
+
+ BOOST_THROW_EXCEPTION( Exception(
+ ( boost::format( "isValid( %s ) is not defined" ) % g.geometryType() ).str()
+ ) );
+ return Validity::invalid( ( boost::format( "isValid( %s ) is not defined" ) % g.geometryType() ).str() ); // to avoid warning
+}
+
+} // namespace algorithm
+} // namespace SFCGAL
diff --git a/src/algorithm/isValid.h b/src/algorithm/isValid.h
new file mode 100644
index 0000000..8c7dc57
--- /dev/null
+++ b/src/algorithm/isValid.h
@@ -0,0 +1,109 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_ALGORITHM_ISVALID_H_
+#define _SFCGAL_ALGORITHM_ISVALID_H_
+
+#include <SFCGAL/Geometry.h>
+#include <SFCGAL/Validity.h>
+#include <SFCGAL/algorithm/force2D.h>
+#include <SFCGAL/algorithm/force3D.h>
+
+namespace SFCGAL {
+namespace algorithm {
+
+extern bool SKIP_GEOM_VALIDATION;
+
+/**
+ * @brief Check validity of a geometry
+ * @ingroup public_api
+ */
+SFCGAL_API const Validity isValid( const Geometry& g, const double& toleranceAbs= 1e-9 );
+
+/**
+ * Macro used to by-pass validity check
+ * @note do not convert to function since BOOST_THROW_EXCEPTION locates the throwing point (function and line)
+ * @note exception message is apparently limited in length, thus print the reason for invalidity before its text representation (that can be very long)
+ */
+#ifndef SFCGAL_NEVER_CHECK_VALIDITY
+# define SFCGAL_ASSERT_GEOMETRY_VALIDITY_(g, ctxt) \
+ if (!SFCGAL::algorithm::SKIP_GEOM_VALIDATION)\
+ {\
+ using namespace SFCGAL;\
+ const Validity sfcgalAssertGeometryValidity = algorithm::isValid( g );\
+ if ( ! sfcgalAssertGeometryValidity ) {\
+ BOOST_THROW_EXCEPTION(GeometryInvalidityException(\
+ ( boost::format(ctxt "%s is invalid : %s : %s")\
+ % (g).geometryType()\
+ % sfcgalAssertGeometryValidity.reason()\
+ % (g).asText()\
+ ).str()\
+ ));\
+ }\
+ }
+# define SFCGAL_ASSERT_GEOMETRY_VALIDITY(g) \
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_(g,"")
+
+# define SFCGAL_ASSERT_GEOMETRY_VALIDITY_2D(g) \
+ if (!SFCGAL::algorithm::SKIP_GEOM_VALIDATION)\
+ {\
+ using namespace SFCGAL;\
+ if ( (g).is3D() ) {\
+ std::auto_ptr<SFCGAL::Geometry> sfcgalAssertGeometryValidityClone( (g).clone() );\
+ algorithm::force2D( *sfcgalAssertGeometryValidityClone );\
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_( (*sfcgalAssertGeometryValidityClone), "When converting to 2D - " ); \
+ }\
+ else {\
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY( g );\
+ }\
+ }
+# define SFCGAL_ASSERT_GEOMETRY_VALIDITY_3D(g) \
+ if (!SFCGAL::algorithm::SKIP_GEOM_VALIDATION)\
+ {\
+ using namespace SFCGAL;\
+ if ( !(g).is3D() ) {\
+ std::auto_ptr<Geometry> sfcgalAssertGeometryValidityClone( (g).clone() );\
+ algorithm::force3D( *sfcgalAssertGeometryValidityClone );\
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_( (*sfcgalAssertGeometryValidityClone), "When converting to 3D - " ); \
+ }\
+ else {\
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY( g );\
+ }\
+ }
+# define SFCGAL_ASSERT_GEOMETRY_VALIDITY_ON_PLANE(g, plane) \
+ BOOST_THROW_EXCEPTION( NotImplementedException("validation on geometry projected on arbitrary plane is not implemented") );
+#else
+# define SFCGAL_ASSERT_GEOMETRY_VALIDITY(g)
+# define SFCGAL_ASSERT_GEOMETRY_VALIDITY_2D(g)
+# define SFCGAL_ASSERT_GEOMETRY_VALIDITY_3D(g)
+# define SFCGAL_ASSERT_GEOMETRY_VALIDITY_ON_PLANE(g, plane)
+#endif
+
+/**
+ * Tag used for variants of algorithm that do not do validity check
+ * @ingroup public_api
+ */
+struct NoValidityCheck {};
+
+}//algorithm
+}//SFCGAL
+
+
+#endif
diff --git a/src/algorithm/length.cpp b/src/algorithm/length.cpp
new file mode 100644
index 0000000..2fbfbf2
--- /dev/null
+++ b/src/algorithm/length.cpp
@@ -0,0 +1,175 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/length.h>
+
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/GeometryCollection.h>
+
+#include <SFCGAL/Exception.h>
+
+namespace SFCGAL {
+namespace algorithm {
+
+///
+///
+///
+double length( const LineString& g )
+{
+ double result = 0.0 ;
+
+ for ( size_t i = 0; i < g.numSegments(); i++ ) {
+ Kernel::Segment_2 segment(
+ g.pointN( i ).toPoint_2(),
+ g.pointN( i+1 ).toPoint_2()
+ );
+ result += CGAL::sqrt( CGAL::to_double( segment.squared_length() ) ) ;
+ }
+
+ return result ;
+}
+
+///
+///
+///
+double length( const GeometryCollection& g )
+{
+ double result = 0.0 ;
+
+ for ( GeometryCollection::const_iterator it = g.begin(); it != g.end(); ++it ) {
+ result += length( *it ) ;
+ }
+
+ return result ;
+}
+
+
+///
+///
+///
+double length( const Geometry& g )
+{
+ switch ( g.geometryTypeId() ) {
+ case TYPE_POINT:
+ return 0.0 ;
+
+ case TYPE_LINESTRING:
+ return length( g.as< LineString >() ) ;
+
+ case TYPE_POLYGON:
+ return 0.0 ;
+
+ case TYPE_MULTIPOINT:
+ case TYPE_MULTILINESTRING:
+ case TYPE_MULTIPOLYGON:
+ case TYPE_GEOMETRYCOLLECTION:
+ return length( g.as< GeometryCollection >() );
+
+ case TYPE_POLYHEDRALSURFACE:
+ case TYPE_TRIANGULATEDSURFACE:
+ case TYPE_TRIANGLE:
+ case TYPE_SOLID:
+ case TYPE_MULTISOLID:
+ return 0.0 ;
+ }
+
+ BOOST_THROW_EXCEPTION( Exception(
+ ( boost::format( "undefined length for geometry type %s" ) % g.geometryType() ).str()
+ ) );
+ return 0.0 ;
+}
+
+
+
+//------ 3D
+
+
+///
+///
+///
+double length3D( const LineString& g )
+{
+ double result = 0.0 ;
+
+ for ( size_t i = 0; i < g.numSegments(); i++ ) {
+ Kernel::Segment_3 segment(
+ g.pointN( i ).toPoint_3(),
+ g.pointN( i+1 ).toPoint_3()
+ );
+ result += CGAL::sqrt( CGAL::to_double( segment.squared_length() ) ) ;
+ }
+
+ return result ;
+}
+
+///
+///
+///
+double length3D( const GeometryCollection& g )
+{
+ double result = 0.0 ;
+
+ for ( GeometryCollection::const_iterator it = g.begin(); it != g.end(); ++it ) {
+ result += length3D( *it ) ;
+ }
+
+ return result ;
+}
+
+
+///
+///
+///
+double length3D( const Geometry& g )
+{
+ switch ( g.geometryTypeId() ) {
+ case TYPE_POINT:
+ return 0.0 ;
+
+ case TYPE_LINESTRING:
+ return length3D( g.as< LineString >() ) ;
+
+ case TYPE_POLYGON:
+ return 0.0 ;
+
+ case TYPE_MULTIPOINT:
+ case TYPE_MULTILINESTRING:
+ case TYPE_MULTIPOLYGON:
+ case TYPE_GEOMETRYCOLLECTION:
+ return length3D( g.as< GeometryCollection >() );
+
+ case TYPE_POLYHEDRALSURFACE:
+ case TYPE_TRIANGULATEDSURFACE:
+ case TYPE_TRIANGLE:
+ case TYPE_SOLID:
+ case TYPE_MULTISOLID:
+ return 0.0 ;
+ }
+
+ BOOST_THROW_EXCEPTION( Exception(
+ ( boost::format( "undefined length for geometry type %s" ) % g.geometryType() ).str()
+ ) );
+ return 0.0 ;
+}
+
+
+}//algorithm
+}//SFCGAL
+
diff --git a/src/algorithm/length.h b/src/algorithm/length.h
new file mode 100644
index 0000000..d368a7e
--- /dev/null
+++ b/src/algorithm/length.h
@@ -0,0 +1,67 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_ALGORITHM_LENGTH_H_
+#define _SFCGAL_ALGORITHM_LENGTH_H_
+
+#include <SFCGAL/config.h>
+
+namespace SFCGAL {
+class Geometry ;
+class LineString ;
+class GeometryCollection ;
+} // namespace SFCGAL
+
+namespace SFCGAL {
+namespace algorithm {
+
+/**
+ * @brief Compute the 2D length for a Geometry (0 for incompatible types)
+ */
+SFCGAL_API double length( const Geometry& g ) ;
+/**
+ * @brief Compute the 2D length for a LineString
+ */
+SFCGAL_API double length( const LineString& g ) ;
+/**
+ * @brief Compute the 2D length for a GeometryCollection
+ */
+SFCGAL_API double length( const GeometryCollection& g ) ;
+
+/**
+ * @brief Compute the 2D length for a geometry
+ * @return the length of the Geometry, 0 for incompatible types
+ */
+SFCGAL_API double length3D( const Geometry& g ) ;
+/**
+ * @brief Compute the 3D length for a LineString
+ */
+SFCGAL_API double length3D( const LineString& g ) ;
+/**
+ * @brief Compute the 3D length for a GeometryCollection
+ */
+SFCGAL_API double length3D( const GeometryCollection& g ) ;
+
+
+}//algorithm
+}//SFCGAL
+
+
+#endif
diff --git a/src/algorithm/minkowskiSum.cpp b/src/algorithm/minkowskiSum.cpp
new file mode 100644
index 0000000..2edc1c3
--- /dev/null
+++ b/src/algorithm/minkowskiSum.cpp
@@ -0,0 +1,282 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/minkowskiSum.h>
+#include <SFCGAL/algorithm/isValid.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+
+#include <SFCGAL/detail/polygonSetToMultiPolygon.h>
+
+#include <CGAL/minkowski_sum_2.h>
+#include <CGAL/Polygon_2.h>
+#include <CGAL/Polygon_with_holes_2.h>
+#include <CGAL/Polygon_set_2.h>
+
+#include <CGAL/Aff_transformation_2.h>
+
+
+typedef CGAL::Polygon_2< SFCGAL::Kernel > Polygon_2 ;
+typedef CGAL::Polygon_with_holes_2< SFCGAL::Kernel > Polygon_with_holes_2 ;
+typedef CGAL::Polygon_set_2< SFCGAL::Kernel > Polygon_set_2 ;
+
+
+namespace SFCGAL {
+namespace algorithm {
+
+//-- private interface
+
+/**
+ * dispatch gA+gB sum
+ */
+void minkowskiSum( const Geometry& gA, const Polygon_2& gB, CGAL::Polygon_set_2< Kernel >& polygonSet ) ;
+/*
+ * append gA+gB into the polygonSet
+ */
+void minkowskiSum( const Point& gA, const Polygon_2& gB, Polygon_set_2& polygonSet ) ;
+/*
+ * append gA+gB into the polygonSet
+ */
+void minkowskiSum( const LineString& gA, const Polygon_2& gB, Polygon_set_2& polygonSet ) ;
+/*
+ * append gA+gB into the polygonSet
+ */
+void minkowskiSum( const Polygon& gA, const Polygon_2& gB, Polygon_set_2& polygonSet ) ;
+/*
+ * append gA+gB into the polygonSet
+ */
+void minkowskiSum( const Solid& gA, const Polygon_2& gB, Polygon_set_2& polygonSet ) ;
+/*
+ * append gA+gB into the polygonSet
+ */
+void minkowskiSumCollection( const Geometry& gA, const Polygon_2& gB, Polygon_set_2& polygonSet ) ;
+
+//-- private interface implementation
+
+///
+///
+///
+void minkowskiSum( const Geometry& gA, const Polygon_2& gB, CGAL::Polygon_set_2< Kernel >& polygonSet )
+{
+ if ( gA.isEmpty() ) {
+ return ;
+ }
+
+ switch ( gA.geometryTypeId() ) {
+ case TYPE_POINT:
+ return minkowskiSum( gA.as< Point >(), gB, polygonSet ) ;
+
+ case TYPE_LINESTRING:
+ return minkowskiSum( gA.as< LineString >(), gB, polygonSet ) ;
+
+ case TYPE_POLYGON:
+ return minkowskiSum( gA.as< Polygon >(), gB, polygonSet ) ;
+
+ case TYPE_TRIANGLE:
+ return minkowskiSum( gA.as< Triangle >().toPolygon(), gB, polygonSet ) ;
+
+ case TYPE_SOLID:
+ return minkowskiSum( gA.as< Solid >(), gB, polygonSet ) ;
+
+ case TYPE_MULTIPOINT:
+ case TYPE_MULTILINESTRING:
+ case TYPE_MULTIPOLYGON:
+ case TYPE_MULTISOLID:
+ case TYPE_GEOMETRYCOLLECTION:
+ case TYPE_TRIANGULATEDSURFACE:
+ case TYPE_POLYHEDRALSURFACE:
+ return minkowskiSumCollection( gA, gB, polygonSet ) ;
+ }
+
+ BOOST_THROW_EXCEPTION( Exception(
+ ( boost::format( "minkowskiSum( %s, 'Polygon' ) is not defined" )
+ % gA.geometryType() ).str()
+ ) );
+}
+
+/*
+ * append gA+gB into the polygonSet
+ */
+void minkowskiSum( const Point& gA, const Polygon_2& gB, Polygon_set_2& polygonSet )
+{
+ BOOST_ASSERT( gB.size() );
+
+ CGAL::Aff_transformation_2< Kernel > translate(
+ CGAL::TRANSLATION,
+ gA.toVector_2()
+ );
+
+ Polygon_2 sum ;
+
+ for ( Polygon_2::Vertex_const_iterator it = gB.vertices_begin();
+ it != gB.vertices_end(); ++it ) {
+ sum.push_back( translate.transform( *it ) );
+ }
+
+ if ( sum.is_clockwise_oriented() ) {
+ sum.reverse_orientation() ;
+ }
+
+ if ( polygonSet.is_empty() ) {
+ polygonSet.insert( sum );
+ }
+ else {
+ polygonSet.join( sum );
+ }
+}
+
+
+///
+///
+///
+void minkowskiSum( const LineString& gA, const Polygon_2& gB, Polygon_set_2& polygonSet )
+{
+ if ( gA.isEmpty() ) {
+ return ;
+ }
+
+ int npt = gA.numPoints() ;
+
+ for ( int i = 0; i < npt - 1 ; i++ ) {
+ Polygon_2 P;
+ P.push_back( gA.pointN( i ).toPoint_2() );
+ P.push_back( gA.pointN( i+1 ).toPoint_2() );
+
+ Polygon_with_holes_2 part = minkowski_sum_2( P, gB );
+
+ // merge into a polygon set
+ if ( polygonSet.is_empty() ) {
+ polygonSet.insert( part );
+ }
+ else {
+ polygonSet.join( part );
+ }
+ }
+}
+
+///
+///
+///
+void minkowskiSum( const Polygon& gA, const Polygon_2& gB, Polygon_set_2& polygonSet )
+{
+ if ( gA.isEmpty() ) {
+ return ;
+ }
+
+ /*
+ * Invoke minkowski_sum_2 for exterior ring
+ */
+ {
+ Polygon_with_holes_2 sum = minkowski_sum_2( gA.exteriorRing().toPolygon_2(), gB ) ;
+
+ if ( polygonSet.is_empty() ) {
+ polygonSet.insert( sum );
+ }
+ else {
+ polygonSet.join( sum );
+ }
+ }
+
+ /*
+ * Compute the Minkowski sum for each segment of the interior rings
+ * and perform the union of the result. The result is a polygon, and its holes
+ * correspond to the inset.
+ *
+ */
+ if ( gA.hasInteriorRings() ) {
+ Polygon_set_2 sumInteriorRings ;
+
+ for ( size_t i = 0; i < gA.numInteriorRings(); i++ ) {
+ minkowskiSum( gA.interiorRingN( i ), gB, sumInteriorRings ) ;
+ }
+
+ /*
+ * compute the difference for each hole of the resulting polygons
+ */
+ std::list<Polygon_with_holes_2> interiorPolygons ;
+ sumInteriorRings.polygons_with_holes( std::back_inserter( interiorPolygons ) ) ;
+
+ for ( std::list<Polygon_with_holes_2>::iterator it_p = interiorPolygons.begin();
+ it_p != interiorPolygons.end(); ++it_p ) {
+
+ for ( Polygon_with_holes_2::Hole_iterator it_hole = it_p->holes_begin();
+ it_hole != it_p->holes_end(); ++it_hole ) {
+
+ it_hole->reverse_orientation() ;
+ polygonSet.difference( *it_hole ) ;
+ } // foreach hole
+ }// foreach polygon
+ }
+}
+
+///
+///
+///
+void minkowskiSum( const Solid& gA, const Polygon_2& gB, Polygon_set_2& polygonSet )
+{
+ //use only the projection of exterior shell
+ minkowskiSumCollection( gA.exteriorShell(), gB, polygonSet );
+}
+
+
+///
+///
+///
+void minkowskiSumCollection( const Geometry& gA, const Polygon_2& gB, Polygon_set_2& polygonSet )
+{
+ for ( size_t i = 0; i < gA.numGeometries(); i++ ) {
+ minkowskiSum( gA.geometryN( i ), gB, polygonSet );
+ }
+}
+
+
+std::auto_ptr< Geometry > minkowskiSum( const Geometry& gA, const Polygon& gB, NoValidityCheck )
+{
+ if ( gB.isEmpty() ) {
+ return std::auto_ptr< Geometry >( gA.clone() );
+ }
+
+ Polygon_set_2 polygonSet ;
+ minkowskiSum( gA, gB.toPolygon_2(), polygonSet ) ;
+ return std::auto_ptr< Geometry >( detail::polygonSetToMultiPolygon( polygonSet ).release() ) ;
+}
+
+//-- public interface implementation
+
+///
+///
+///
+std::auto_ptr< Geometry > minkowskiSum( const Geometry& gA, const Polygon& gB )
+{
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_2D( gA );
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_2D( gB );
+
+ return minkowskiSum( gA, gB, NoValidityCheck() );
+}
+
+} // namespace algorithm
+} // namespace SFCGAL
diff --git a/src/algorithm/minkowskiSum.h b/src/algorithm/minkowskiSum.h
new file mode 100644
index 0000000..62ab5d6
--- /dev/null
+++ b/src/algorithm/minkowskiSum.h
@@ -0,0 +1,59 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_ALGORITHM_MINKOWSKISUM_H_
+#define _SFCGAL_ALGORITHM_MINKOWSKISUM_H_
+
+#include <SFCGAL/config.h>
+
+#include <memory>
+#include <SFCGAL/Geometry.h>
+
+namespace SFCGAL {
+namespace algorithm {
+struct NoValidityCheck;
+
+/**
+ * @brief 2D minkowski sum (p+q)
+ *
+ * @warning If gA is a polygon, its orientation is taken into account. A "reversed" polygon (with a clockwise-oriented exterior ring) will involve a minkowski difference rather than a sum.
+ *
+ * @todo missing cases (union)
+ * @pre gA and gB are valid geometries
+ * @ingroup public_api
+ */
+SFCGAL_API std::auto_ptr< Geometry > minkowskiSum( const Geometry& gA, const Polygon& gB ) ;
+
+/**
+ * @brief 2D minkowski sum (p+q)
+ *
+ * @warning If gA is a polygon, its orientation is taken into account. A "reversed" polygon (with a clockwise-oriented exterior ring) will involve a minkowski difference rather than a sum.
+ *
+ * @todo missing cases (union)
+ * @pre gA and gB are valid geometries
+ * @ingroup detail
+ * @warning@ No actual validity check is done.
+ */
+SFCGAL_API std::auto_ptr< Geometry > minkowskiSum( const Geometry& gA, const Polygon& gB, NoValidityCheck ) ;
+
+} // namespace algorithm
+} // namespace SFCGAL
+
+#endif
diff --git a/src/algorithm/normal.h b/src/algorithm/normal.h
new file mode 100644
index 0000000..f9f5d48
--- /dev/null
+++ b/src/algorithm/normal.h
@@ -0,0 +1,89 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_ALGORITHM_NORMAL_H_
+#define _SFCGAL_ALGORITHM_NORMAL_H_
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Polygon.h>
+
+namespace SFCGAL {
+namespace algorithm {
+
+/**
+ * Returns the 3D normal to 3 consecutive points.
+ */
+template < typename Kernel >
+CGAL::Vector_3< Kernel > normal3D(
+ const CGAL::Point_3< Kernel >& a,
+ const CGAL::Point_3< Kernel >& b,
+ const CGAL::Point_3< Kernel >& c
+)
+{
+ // bc ^ ba
+ return CGAL::cross_product( c - b, a - b ) ;
+}
+
+
+/**
+ * Returns the 3D normal to a ring (supposed to be planar and closed).
+ * @warning exact allows to avoid double rounding at the end of the computation
+*/
+template < typename Kernel >
+CGAL::Vector_3< Kernel > normal3D( const LineString& ls, bool exact = true )
+{
+ // Newell's formula
+ typename Kernel::FT nx, ny, nz;
+ nx = ny = nz = 0.0;
+
+ for ( size_t i = 0; i < ls.numPoints(); ++i ) {
+ const Point& pi = ls.pointN( i );
+ const Point& pj = ls.pointN( ( i+1 ) % ls.numPoints() );
+ typename Kernel::FT zi = pi.z() ;
+ typename Kernel::FT zj = pj.z() ;
+ nx += ( pi.y() - pj.y() ) * ( zi + zj );
+ ny += ( zi - zj ) * ( pi.x() + pj.x() );
+ nz += ( pi.x() - pj.x() ) * ( pi.y() + pj.y() );
+ }
+
+ if ( exact ) {
+ return CGAL::Vector_3<Kernel>( nx, ny, nz );
+ }
+ else {
+ return CGAL::Vector_3<Kernel>( CGAL::to_double( nx ), CGAL::to_double( ny ), CGAL::to_double( nz ) );
+ }
+}
+
+/**
+ * Returns the 3D normal to a polygon (supposed to be planar).
+ * @warning exact allows to avoid double rounding at the end of the computation
+ */
+template < typename Kernel >
+CGAL::Vector_3< Kernel > normal3D( const Polygon& polygon, bool exact = true )
+{
+ return normal3D< Kernel >( polygon.exteriorRing(), exact );
+}
+
+}//algorithm
+}//SFCGAL
+
+
+#endif
diff --git a/src/algorithm/offset.cpp b/src/algorithm/offset.cpp
new file mode 100644
index 0000000..2002e52
--- /dev/null
+++ b/src/algorithm/offset.cpp
@@ -0,0 +1,361 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/offset.h>
+
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/MultiPolygon.h>
+
+#include <SFCGAL/Exception.h>
+
+#include <SFCGAL/detail/polygonSetToMultiPolygon.h>
+#include <SFCGAL/algorithm/isValid.h>
+
+
+#include <CGAL/Polygon_2.h>
+#include <CGAL/Polygon_with_holes_2.h>
+#include <CGAL/Polygon_set_2.h>
+
+#include <CGAL/minkowski_sum_2.h>
+#include <CGAL/approximated_offset_2.h>
+#include <CGAL/offset_polygon_2.h>
+
+typedef CGAL::Polygon_2< SFCGAL::Kernel > Polygon_2 ;
+typedef CGAL::Polygon_with_holes_2< SFCGAL::Kernel > Polygon_with_holes_2 ;
+typedef CGAL::Polygon_set_2< SFCGAL::Kernel > Polygon_set_2 ;
+
+typedef CGAL::Gps_circle_segment_traits_2< SFCGAL::Kernel > Gps_traits_2;
+typedef Gps_traits_2::Curve_2 Offset_curve_2 ;
+typedef Gps_traits_2::X_monotone_curve_2 Offset_x_monotone_curve_2 ;
+typedef Gps_traits_2::Polygon_2 Offset_polygon_2;
+typedef Gps_traits_2::Polygon_with_holes_2 Offset_polygon_with_holes_2;
+typedef CGAL::General_polygon_set_2< Gps_traits_2 > Offset_polygon_set_2 ;
+
+#define SFCGAL_OFFSET_ACCURACY 0.0001
+
+#define SFCGAL_OFFSET_ASSERT_FINITE_RADIUS( r ) \
+ if ( !std::isfinite(r) ) BOOST_THROW_EXCEPTION( NonFiniteValueException("radius is non finite") );
+namespace SFCGAL {
+namespace algorithm {
+
+//-- private interface
+
+/**
+ * @brief dispatch a geometry
+ */
+void offset( const Geometry& g, const double& radius, Offset_polygon_set_2& polygonSet ) ;
+
+/**
+ * @brief offset for a Point
+ */
+void offset( const Point& g, const double& radius, Offset_polygon_set_2& polygonSet ) ;
+/**
+ * @brief offset for a LineString
+ */
+void offset( const LineString& g, const double& radius, Offset_polygon_set_2& polygonSet ) ;
+/**
+ * @brief offset for a Polygon
+ */
+void offset( const Polygon& g, const double& radius, Offset_polygon_set_2& polygonSet ) ;
+/**
+ * @brief offset for MultiPoint, MultiLineString, MultiPolygon, TriangulatedSurface, PolyhedralSurface
+ */
+void offsetCollection( const Geometry& g, const double& radius, Offset_polygon_set_2& polygonSet ) ;
+
+
+//-- helpers
+
+/**
+ * @brief approximate an Offset_polygon_2 (filter null segments)
+ */
+Polygon_2 approximate( const Offset_polygon_2& polygon, const int& n = 0 )
+{
+ std::list<std::pair<double, double> > pair_list;
+
+ /*
+ * iterate X_monotone_curve_2 components
+ */
+ for ( Offset_polygon_2::Curve_const_iterator it = polygon.curves_begin();
+ it != polygon.curves_end(); ++it ) {
+ it->approximate( std::back_inserter( pair_list ), n ) ;
+ }
+
+ // remove duplicated last point
+ pair_list.pop_back() ;
+
+ /*
+ * convertr to polygon
+ */
+ Polygon_2 result ;
+
+ bool isFirst = true ;
+ Kernel::Point_2 last ;
+
+ for ( std::list<std::pair<double, double> >::const_iterator it = pair_list.begin(); it != pair_list.end(); ++it ) {
+ Kernel::Point_2 point( it->first, it->second ) ;
+
+ if ( isFirst ) {
+ isFirst = false ;
+ }
+ else if ( point == last ) {
+ continue ;
+ }
+
+ result.push_back( point ) ;
+ last = point ;
+ }
+
+ return result ;
+}
+
+/**
+ * @brief approximate an Offset
+ */
+Polygon_with_holes_2 approximate( const Offset_polygon_with_holes_2& polygon, const int& n = 0 )
+{
+ Polygon_with_holes_2 result( approximate( polygon.outer_boundary(), n ) );
+
+ for ( Offset_polygon_with_holes_2::Hole_const_iterator it = polygon.holes_begin(); it != polygon.holes_end(); ++it ) {
+ result.add_hole( approximate( *it, n ) );
+ }
+
+ return result ;
+}
+
+
+/**
+ * @brief convert Offset_polygon_set_2 to MultiPolygon
+ */
+std::auto_ptr< MultiPolygon > polygonSetToMultiPolygon( const Offset_polygon_set_2& polygonSet, const int& n )
+{
+ std::list<Offset_polygon_with_holes_2> res;
+ polygonSet.polygons_with_holes( std::back_inserter( res ) ) ;
+
+ std::auto_ptr< MultiPolygon > result( new MultiPolygon );
+
+ for ( std::list<Offset_polygon_with_holes_2>::const_iterator it = res.begin(); it != res.end(); ++it ) {
+ result->addGeometry( new Polygon( approximate( *it, n ) ) );
+ }
+
+ return result ;
+}
+
+
+/**
+ * @brief helper to create a polygon from a circle
+ */
+Offset_polygon_2 circleToPolygon( const Kernel::Circle_2& circle )
+{
+ /*
+ * convert the circle into Offset_x_monotone_curve_2 (exactly 2)
+ */
+ Gps_traits_2 traits;
+ Offset_curve_2 curve( circle );
+
+ std::list<CGAL::Object> parts;
+ traits.make_x_monotone_2_object()( curve, std::back_inserter( parts ) );
+ BOOST_ASSERT( parts.size() == 2U );
+
+ // Construct the polygon.
+ Offset_polygon_2 result ;
+
+ for ( std::list<CGAL::Object>::const_iterator it = parts.begin(); it != parts.end(); ++it ) {
+ Offset_x_monotone_curve_2 arc;
+ CGAL::assign( arc, *it );
+ result.push_back( arc );
+ }
+
+ return result;
+}
+
+/**
+ * @brief build Point offset
+ */
+void offset( const Point& gA, const double& radius, Offset_polygon_set_2& polygonSet )
+{
+ SFCGAL_OFFSET_ASSERT_FINITE_RADIUS( radius );
+ Kernel::Circle_2 circle( gA.toPoint_2(), radius * radius );
+
+ if ( polygonSet.is_empty() ) {
+ polygonSet.insert( circleToPolygon( circle ) );
+ }
+ else {
+ polygonSet.join( circleToPolygon( circle ) );
+ }
+}
+
+
+/**
+ * @brief build LineString offset
+ */
+void offset( const LineString& lineString, const double& radius, Offset_polygon_set_2& polygonSet )
+{
+ SFCGAL_OFFSET_ASSERT_FINITE_RADIUS( radius );
+
+ for ( size_t i = 0; i < lineString.numSegments(); i++ ) {
+ Polygon_2 P ;
+ P.push_back( lineString.pointN( i ).toPoint_2() );
+ P.push_back( lineString.pointN( i+1 ).toPoint_2() );
+ Offset_polygon_with_holes_2 offset = CGAL::approximated_offset_2( P, radius, SFCGAL_OFFSET_ACCURACY ) ;
+
+ if ( polygonSet.is_empty() ) {
+ polygonSet.insert( offset );
+ }
+ else {
+ polygonSet.join( offset );
+ }
+ }
+}
+
+
+///
+///
+///
+void offset( const Polygon& g, const double& radius, Offset_polygon_set_2& polygonSet )
+{
+ SFCGAL_OFFSET_ASSERT_FINITE_RADIUS( radius );
+
+ if ( g.isEmpty() ) {
+ return ;
+ }
+
+ /*
+ * Invoke minkowski_sum_2 for exterior ring
+ */
+ {
+ Offset_polygon_with_holes_2 offset = CGAL::approximated_offset_2( g.exteriorRing().toPolygon_2(), radius, SFCGAL_OFFSET_ACCURACY ) ;
+
+ if ( polygonSet.is_empty() ) {
+ polygonSet.insert( offset );
+ }
+ else {
+ polygonSet.join( offset );
+ }
+ }
+
+ /*
+ * Compute the Minkowski sum for each segment of the interior rings
+ * and perform the union of the result. The result is a polygon, and its holes
+ * correspond to the inset.
+ *
+ */
+ if ( g.hasInteriorRings() ) {
+ Offset_polygon_set_2 sumInteriorRings ;
+
+ for ( size_t i = 0; i < g.numInteriorRings(); i++ ) {
+ offset( g.interiorRingN( i ), radius, sumInteriorRings ) ;
+ }
+
+ /*
+ * compute the difference for each hole of the resulting polygons
+ */
+ std::list< Offset_polygon_with_holes_2 > interiorPolygons ;
+ sumInteriorRings.polygons_with_holes( std::back_inserter( interiorPolygons ) ) ;
+
+ for ( std::list< Offset_polygon_with_holes_2 >::iterator it_p = interiorPolygons.begin();
+ it_p != interiorPolygons.end(); ++it_p ) {
+
+ for ( Offset_polygon_with_holes_2::Hole_iterator it_hole = it_p->holes_begin();
+ it_hole != it_p->holes_end(); ++it_hole ) {
+
+ it_hole->reverse_orientation() ;
+ polygonSet.difference( *it_hole ) ;
+ } // foreach hole
+ }// foreach polygon
+ }
+}
+
+///
+///
+///
+void offsetCollection( const Geometry& g, const double& radius, Offset_polygon_set_2& polygonSet )
+{
+ SFCGAL_OFFSET_ASSERT_FINITE_RADIUS( radius );
+
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ offset( g.geometryN( i ), radius, polygonSet );
+ }
+}
+
+///
+///
+///
+void offset( const Geometry& g, const double& radius, Offset_polygon_set_2& polygonSet )
+{
+ SFCGAL_OFFSET_ASSERT_FINITE_RADIUS( radius );
+
+ if ( g.isEmpty() ) {
+ return ;
+ }
+
+ switch ( g.geometryTypeId() ) {
+ case TYPE_POINT:
+ return offset( g.as< Point >(), radius, polygonSet ) ;
+
+ case TYPE_LINESTRING:
+ return offset( g.as< LineString >(), radius, polygonSet ) ;
+
+ case TYPE_POLYGON:
+ return offset( g.as< Polygon >(), radius, polygonSet ) ;
+
+ case TYPE_TRIANGLE:
+ return offset( g.as< Triangle >().toPolygon(), radius, polygonSet ) ;
+
+ case TYPE_SOLID:
+ return offset( g.as< Solid >().exteriorShell(), radius, polygonSet ) ;
+
+ case TYPE_MULTISOLID:
+ case TYPE_MULTIPOINT:
+ case TYPE_MULTILINESTRING:
+ case TYPE_MULTIPOLYGON:
+ case TYPE_GEOMETRYCOLLECTION:
+ case TYPE_TRIANGULATEDSURFACE:
+ case TYPE_POLYHEDRALSURFACE:
+ return offsetCollection( g, radius, polygonSet );
+ }
+}
+
+//-- public interface
+
+///
+///
+///
+std::auto_ptr< MultiPolygon > offset( const Geometry& g, const double& r, NoValidityCheck )
+{
+ SFCGAL_OFFSET_ASSERT_FINITE_RADIUS( r );
+ Offset_polygon_set_2 polygonSet ;
+ offset( g, r, polygonSet ) ;
+ return polygonSetToMultiPolygon( polygonSet, 8 );
+}
+
+std::auto_ptr< MultiPolygon > offset( const Geometry& g, const double& r )
+{
+ SFCGAL_OFFSET_ASSERT_FINITE_RADIUS( r );
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY( g );
+ return offset( g, r, NoValidityCheck() );
+}
+
+}//namespace algorithm
+}//namespace SFCGAL
+
diff --git a/src/algorithm/offset.h b/src/algorithm/offset.h
new file mode 100644
index 0000000..aac82f3
--- /dev/null
+++ b/src/algorithm/offset.h
@@ -0,0 +1,59 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_ALGORITHM_OFFSET_H_
+#define _SFCGAL_ALGORITHM_OFFSET_H_
+
+#include <SFCGAL/config.h>
+
+#include <memory>
+
+namespace SFCGAL {
+class Geometry ;
+class MultiPolygon ;
+}
+
+namespace SFCGAL {
+namespace algorithm {
+struct NoValidityCheck;
+
+/**
+ * @brief [experimental]compute polygon offset
+ *
+ * @warning test in order to compare with minkowski sum
+ * @pre g is a valid Geometry
+ * @ingroup public_api
+ */
+SFCGAL_API std::auto_ptr< MultiPolygon > offset( const Geometry& g, const double& r ) ;
+
+/**
+ * @brief [experimental]compute polygon offset
+ *
+ * @warning test in order to compare with minkowski sum
+ * @pre g is a valid Geometry
+ * @ingroup detail
+ * @warning No actual validity check is done.
+ */
+SFCGAL_API std::auto_ptr< MultiPolygon > offset( const Geometry& g, const double& r, NoValidityCheck ) ;
+
+}//namespace algorithm
+}//namespace SFCGAL
+
+#endif
diff --git a/src/algorithm/orientation.cpp b/src/algorithm/orientation.cpp
new file mode 100644
index 0000000..01f20d8
--- /dev/null
+++ b/src/algorithm/orientation.cpp
@@ -0,0 +1,169 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/orientation.h>
+
+#include <SFCGAL/algorithm/ConsistentOrientationBuilder.h>
+
+#include <SFCGAL/detail/graph/GeometryGraph.h>
+#include <SFCGAL/detail/graph/GeometryGraphBuilder.h>
+#include <SFCGAL/detail/graph/algorithm/isHalfEdge.h>
+
+#include <SFCGAL/detail/graph/algorithm/orientation.h>
+
+namespace SFCGAL {
+namespace algorithm {
+
+///
+///
+///
+void makeValidOrientation( CGAL::Polygon_2< Kernel >& polygon )
+{
+ if ( polygon.orientation() != CGAL::COUNTERCLOCKWISE ) {
+ polygon.reverse_orientation() ;
+ }
+}
+
+///
+///
+///
+void makeValidOrientation( CGAL::Polygon_with_holes_2< Kernel >& polygon )
+{
+ typedef CGAL::Polygon_with_holes_2< Kernel > Polygon_with_holes_2 ;
+
+ if ( polygon.outer_boundary().orientation() != CGAL::COUNTERCLOCKWISE ) {
+ polygon.outer_boundary().reverse_orientation() ;
+ }
+
+ for ( Polygon_with_holes_2::Hole_iterator it = polygon.holes_begin(); it != polygon.holes_end(); ++it ) {
+ if ( it->orientation() != CGAL::CLOCKWISE ) {
+ it->reverse_orientation() ;
+ }
+ }
+}
+
+///
+///
+///
+void makeValidOrientation( Polygon& polygon )
+{
+ for ( size_t i = 0; i < polygon.numRings(); i++ ) {
+ LineString& ring = polygon.ringN( i );
+
+ if ( i == 0 ) {
+ if ( ring.toPolygon_2().orientation() != CGAL::COUNTERCLOCKWISE ) {
+ ring.reverse() ;
+ }
+ }
+ else {
+ if ( ring.toPolygon_2().orientation() != CGAL::CLOCKWISE ) {
+ ring.reverse();
+ }
+ }
+ }
+}
+
+///
+///
+///
+bool hasConsistentOrientation3D( const TriangulatedSurface& g )
+{
+ using namespace graph ;
+
+ if ( g.isEmpty() ) {
+ return true ;
+ }
+
+
+ GeometryGraph graph ;
+ GeometryGraphBuilder graphBuilder( graph ) ;
+ graphBuilder.addTriangulatedSurface( g );
+ return graph::algorithm::isHalfEdge( graph ) ;
+}
+
+
+///
+///
+///
+bool hasConsistentOrientation3D( const PolyhedralSurface& g )
+{
+ using namespace graph ;
+
+ if ( g.isEmpty() ) {
+ return true ;
+ }
+
+ GeometryGraph graph ;
+ GeometryGraphBuilder graphBuilder( graph ) ;
+ graphBuilder.addPolyhedralSurface( g );
+ return graph::algorithm::isHalfEdge( graph ) ;
+}
+
+
+///
+///
+///
+void makeConsistentOrientation3D( TriangulatedSurface& g )
+{
+ ConsistentOrientationBuilder builder ;
+ builder.addTriangulatedSurface( g );
+ g = builder.buildTriangulatedSurface() ;
+}
+
+///
+///
+///
+bool isCounterClockWiseOriented( const LineString& ls )
+{
+ // Compute the 'z' part of the Newell's formula
+ // and test against 0
+ Kernel::FT z = 0 ;
+
+ for ( size_t i = 0; i < ls.numSegments(); ++i ) {
+ const Point& pi = ls.pointN( i );
+ const Point& pj = ls.pointN( i+1 );
+ z += ( pi.x() - pj.x() ) * ( pi.y() + pj.y() );
+ }
+
+ return z > 0;
+}
+
+///
+///
+///
+bool isCounterClockWiseOriented( const Triangle& tri )
+{
+ // Compute the 'z' part of the cross product
+
+ return ( tri.vertex( 2 ).x() - tri.vertex( 1 ).x() ) * ( tri.vertex( 0 ).y() - tri.vertex( 1 ).y() ) -
+ ( tri.vertex( 2 ).y() - tri.vertex( 1 ).y() ) * ( tri.vertex( 0 ).x() - tri.vertex( 1 ).x() ) > 0;
+}
+
+///
+///
+///
+bool isCounterClockWiseOriented( const Polygon& poly )
+{
+ return isCounterClockWiseOriented( poly.exteriorRing() );
+}
+
+}//algorithm
+}//SFCGAL
+
diff --git a/src/algorithm/orientation.h b/src/algorithm/orientation.h
new file mode 100644
index 0000000..479b069
--- /dev/null
+++ b/src/algorithm/orientation.h
@@ -0,0 +1,83 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_ALGORITHM_ORIENTATION_H_
+#define _SFCGAL_ALGORITHM_ORIENTATION_H_
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Geometry.h>
+
+#include <CGAL/Polygon_2.h>
+#include <CGAL/Polygon_with_holes_2.h>
+
+namespace SFCGAL {
+namespace algorithm {
+
+/**
+ * Make valid 2D orientation
+ */
+SFCGAL_API void makeValidOrientation( CGAL::Polygon_2< Kernel >& polygon ) ;
+/**
+ * Make valid 2D orientation
+ */
+SFCGAL_API void makeValidOrientation( CGAL::Polygon_with_holes_2< Kernel >& polygon ) ;
+/**
+ * Make valid 2D orientation
+ */
+SFCGAL_API void makeValidOrientation( Polygon& polygon ) ;
+
+
+/**
+ * Test if a Geometry has a consistent orientation
+ */
+SFCGAL_API bool hasConsistentOrientation3D( const TriangulatedSurface& g ) ;
+/**
+ * Test if a PolyhedralSurface has a consistent orientation
+ */
+SFCGAL_API bool hasConsistentOrientation3D( const PolyhedralSurface& g ) ;
+
+
+/**
+ * Try to make consistent orientation in a TriangulatedSurface
+ */
+SFCGAL_API void makeConsistentOrientation3D( TriangulatedSurface& g ) ;
+
+/**
+ * Test if a 2D surface is oriented counter clockwise
+ */
+SFCGAL_API bool isCounterClockWiseOriented( const Polygon& );
+
+/**
+ * Test if a 2D surface is oriented counter clockwise
+ */
+SFCGAL_API bool isCounterClockWiseOriented( const Triangle& );
+
+/**
+ * Test if a 2D surface is oriented counter clockwise
+ */
+SFCGAL_API bool isCounterClockWiseOriented( const LineString& );
+
+}//algorithm
+}//SFCGAL
+
+
+#endif
diff --git a/src/algorithm/plane.h b/src/algorithm/plane.h
new file mode 100644
index 0000000..5a45a53
--- /dev/null
+++ b/src/algorithm/plane.h
@@ -0,0 +1,234 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_ALGORITHM_PLANE_H_
+#define _SFCGAL_ALGORITHM_PLANE_H_
+
+#include <boost/format.hpp>
+
+//#include <SFCGAL/detail/ublas.h>
+
+#include <SFCGAL/Exception.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/algorithm/normal.h>
+#include <SFCGAL/detail/GetPointsVisitor.h>
+
+namespace SFCGAL {
+namespace algorithm {
+
+/**
+ * @brief Test if a 3D plane can be extracted from a Polygon
+ * @ingroup public_api
+ */
+template < typename Kernel >
+bool hasPlane3D( const Polygon& polygon,
+ CGAL::Point_3< Kernel >& a,
+ CGAL::Point_3< Kernel >& b,
+ CGAL::Point_3< Kernel >& c )
+{
+ typedef CGAL::Point_3< Kernel > Point_3 ;
+
+ const LineString& exteriorRing = polygon.exteriorRing() ;
+
+ /*
+ * look for 3 non collinear points
+ */
+ size_t n = 0 ;
+
+ for ( size_t i = 0; i < exteriorRing.numPoints(); i++ ) {
+ Point_3 p = exteriorRing.pointN( i ).toPoint_3() ;
+
+ if ( n == 0 ) {
+ a = p ;
+ n++ ;
+ }
+ else if ( n == 1 && a != p ) {
+ b = p ;
+ n++ ;
+ }
+ else if ( n == 2 && ! CGAL::collinear( a, b, p ) ) {
+ c = p ;
+ n++ ;
+ return true ;
+ }
+ }
+
+ BOOST_ASSERT( n < 3 );
+ return false;
+}
+
+/**
+ * Test if a 3D plane can be extracted from a Polygon
+ */
+template < typename Kernel >
+bool hasPlane3D( const Polygon& polygon )
+{
+ // temporary arguments
+ CGAL::Point_3< Kernel > a, b, c;
+ return hasPlane3D( polygon, a, b, c );
+}
+
+/**
+ * Get 3 non collinear points from a Polygon
+ */
+template < typename Kernel >
+void plane3D(
+ const Polygon& polygon,
+ CGAL::Point_3< Kernel >& a,
+ CGAL::Point_3< Kernel >& b,
+ CGAL::Point_3< Kernel >& c
+)
+{
+ if ( ! hasPlane3D( polygon, a, b, c ) ) {
+ BOOST_THROW_EXCEPTION(
+ Exception(
+ ( boost::format( "can't find plane for Polygon '%1%'" ) % polygon.asText( 3 ) ).str()
+ )
+ );
+ }
+}
+
+/**
+ * Returns the oriented 3D plane of a polygon (supposed to be planar).
+ * @warning result is rounded to double if exact is false (avoid huge expression tree)
+ */
+template < typename Kernel >
+CGAL::Plane_3< Kernel > plane3D( const Polygon& polygon, bool exact = true )
+{
+ CGAL::Vector_3< Kernel > nrml = normal3D< Kernel >( polygon, exact );
+
+ if ( !exact ) {
+ const double nrm = std::sqrt( CGAL::to_double( nrml.squared_length() ) );
+ nrml = CGAL::Vector_3< Kernel >( nrml.x()/nrm, nrml.y()/nrm, nrml.z()/nrm );
+ }
+
+ return CGAL::Plane_3< Kernel >( polygon.exteriorRing().pointN( 0 ).toPoint_3(), nrml );
+}
+
+
+
+/**
+ * Test if all points of a geometry lie in the same plane
+ * @ingroup detail
+ */
+template < typename Kernel >
+bool isPlane3D( const Geometry& geom,const double& toleranceAbs )
+{
+ if ( geom.isEmpty() ) {
+ return true;
+ }
+
+ using namespace SFCGAL::detail;
+ GetPointsVisitor v;
+ const_cast< Geometry& >( geom ).accept( v );
+
+ if ( v.points.size() == 0 ) {
+ return true;
+ }
+
+ // the present approach is to find a good plane by:
+ // - computing the centroid C of the point set
+ // - finding the farest point F from C
+ // - finding the farest point G from (CF)
+ // - we define the unit normal N to the plane from CFxCG
+ // - we check that points Xi are in the plane CXi.N < tolerance
+ //
+ // note that we could compute the covarence matrix of the points and use SVD
+ // but we would need a lib for that, and it may be overkill
+
+ typedef CGAL::Vector_3< Kernel > Vector_3 ;
+
+ const GetPointsVisitor::const_iterator end = v.points.end();
+
+ // centroid
+ Vector_3 c( 0,0,0 );
+ int numPoint = 0;
+
+ for ( GetPointsVisitor::const_iterator x = v.points.begin(); x != end; ++x ) {
+ c = c + ( *x )->toVector_3() ;
+ ++numPoint;
+ }
+
+ BOOST_ASSERT( numPoint );
+ c = c / numPoint;
+
+ // farest point from centroid
+ Vector_3 f = c ;
+ typename Kernel::FT maxDistanceSq = 0;
+
+ for ( GetPointsVisitor::const_iterator x = v.points.begin(); x != end; ++x ) {
+ const Vector_3 cx = ( *x )->toVector_3() - c ;
+ const typename Kernel::FT dSq = cx * cx ;
+
+ if ( dSq > maxDistanceSq ) {
+ f = ( *x )->toVector_3() ;
+ maxDistanceSq = dSq ;
+ }
+ }
+
+ if ( std::sqrt( CGAL::to_double( maxDistanceSq ) ) < toleranceAbs ) {
+ // std::cout << "all points in the same location\n";
+ return true;
+ }
+
+ // farest point from line
+ Vector_3 g=c;
+ const Vector_3 cf = f - c ; // direction of (CF)
+ maxDistanceSq = 0; // watch out, we reuse the variable
+
+ for ( GetPointsVisitor::const_iterator x = v.points.begin(); x != end; ++x ) {
+ const Vector_3 cx = ( *x )->toVector_3() - c ;
+ const Vector_3 cp = ( cx * cf ) * cf / cf.squared_length() ; // projection of x on line (CF)
+ const typename Kernel::FT dSq = ( cx - cp ).squared_length() ;
+
+ if ( dSq > maxDistanceSq ) {
+ g = ( *x )->toVector_3() ;
+ maxDistanceSq = dSq ;
+ }
+ }
+
+ if ( std::sqrt( CGAL::to_double( maxDistanceSq ) ) < toleranceAbs ) {
+ // std::cout << "all points aligned\n";
+ return true;
+ }
+
+ const Vector_3 n = CGAL::cross_product( cf, g - c );
+
+ const Vector_3 nNormed = n / std::sqrt( CGAL::to_double( n.squared_length() ) );
+
+ for ( GetPointsVisitor::const_iterator x = v.points.begin(); x != end; ++x ) {
+ const Vector_3 cx = ( *x )->toVector_3() - c ;
+
+ if ( std::abs( CGAL::to_double( cx * n ) ) > toleranceAbs ) {
+ // std::cout << "point out of plane\n";
+ return false;
+ }
+ }
+
+ // std::cout << "plane general case\n";
+ return true;
+}
+
+
+}//algorithm
+}//SFCGAL
+
+
+#endif
diff --git a/src/algorithm/straightSkeleton.cpp b/src/algorithm/straightSkeleton.cpp
new file mode 100644
index 0000000..f5dda93
--- /dev/null
+++ b/src/algorithm/straightSkeleton.cpp
@@ -0,0 +1,172 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/straightSkeleton.h>
+
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+
+#include <SFCGAL/Exception.h>
+
+#include <SFCGAL/algorithm/orientation.h>
+#include <SFCGAL/algorithm/isValid.h>
+#include <SFCGAL/algorithm/intersection.h>
+
+#include <CGAL/create_straight_skeleton_from_polygon_with_holes_2.h>
+
+namespace SFCGAL {
+namespace algorithm {
+
+typedef Kernel::Point_2 Point_2 ;
+typedef CGAL::Polygon_2<Kernel> Polygon_2 ;
+typedef CGAL::Polygon_with_holes_2<Kernel> Polygon_with_holes_2 ;
+typedef CGAL::Straight_skeleton_2<Kernel> Straight_skeleton_2 ;
+
+
+template<class K>
+void straightSkeletonToMultiLineString(
+ const CGAL::Straight_skeleton_2<K>& ss,
+ MultiLineString& result
+)
+{
+ typedef CGAL::Straight_skeleton_2<K> Ss ;
+
+ typedef typename Ss::Vertex_const_handle Vertex_const_handle ;
+ typedef typename Ss::Halfedge_const_handle Halfedge_const_handle ;
+ typedef typename Ss::Halfedge_const_iterator Halfedge_const_iterator ;
+
+ Halfedge_const_handle null_halfedge ;
+ Vertex_const_handle null_vertex ;
+
+ for ( Halfedge_const_iterator it = ss.halfedges_begin(); it != ss.halfedges_end(); ++it ) {
+ // skip contour edge
+ if ( ! it->is_bisector() ) {
+ continue ;
+ }
+
+ // avoid duplicates
+ if ( it->opposite() < it ) {
+ continue ;
+ }
+
+ result.addGeometry( new LineString(
+ Point( it->opposite()->vertex()->point() ),
+ Point( it->vertex()->point() )
+ ) );
+ }
+}
+
+
+
+///
+///
+///
+std::auto_ptr< MultiLineString > straightSkeleton( const Geometry& g, bool autoOrientation, NoValidityCheck )
+{
+ switch ( g.geometryTypeId() ) {
+ case TYPE_TRIANGLE:
+ return straightSkeleton( g.as< Triangle >().toPolygon(), autoOrientation ) ;
+
+ case TYPE_POLYGON:
+ return straightSkeleton( g.as< Polygon >(), autoOrientation ) ;
+
+ case TYPE_MULTIPOLYGON:
+ return straightSkeleton( g.as< MultiPolygon >(), autoOrientation ) ;
+
+ default:
+ return std::auto_ptr< MultiLineString >( new MultiLineString );
+ }
+}
+
+std::auto_ptr< MultiLineString > straightSkeleton( const Geometry& g, bool autoOrientation )
+{
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_2D( g );
+
+ return straightSkeleton( g, autoOrientation, NoValidityCheck() );
+}
+///
+///
+///
+std::auto_ptr< MultiLineString > straightSkeleton( const Polygon& g, bool /*autoOrientation*/ )
+{
+ std::auto_ptr< MultiLineString > result( new MultiLineString );
+
+ if ( g.isEmpty() ) {
+ return result ;
+ }
+
+ // test if holes touch, since CGAL segfaults if it does
+ const size_t numRings = g.numRings();
+
+ for ( size_t ri=1; ri < numRings; ++ri ) {
+ for ( size_t rj=ri+1; rj < numRings; ++rj ) {
+ std::auto_ptr<Geometry> inter = g.is3D()
+ ? intersection3D( g.ringN( ri ), g.ringN( rj ) )
+ : intersection( g.ringN( ri ), g.ringN( rj ) );
+
+ if ( ! inter->isEmpty() && inter->is< Point >() ) {
+ BOOST_THROW_EXCEPTION( NotImplementedException(
+ "straight skeleton of Polygon with touching interior rings is not implemented"
+ ) );
+ }
+ }
+ }
+
+
+ Polygon_with_holes_2 polygon = g.toPolygon_with_holes_2() ;
+ boost::shared_ptr< Straight_skeleton_2 > skeleton = CGAL::create_interior_straight_skeleton_2( polygon ) ;
+
+ if ( !skeleton.get() ) {
+ BOOST_THROW_EXCEPTION( Exception( "CGAL failed to create straightSkeleton" ) ) ;
+ }
+
+ straightSkeletonToMultiLineString( *skeleton, *result ) ;
+ return result ;
+}
+
+
+///
+///
+///
+std::auto_ptr< MultiLineString > straightSkeleton( const MultiPolygon& g, bool /*autoOrientation*/ )
+{
+ std::auto_ptr< MultiLineString > result( new MultiLineString );
+
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ Polygon_with_holes_2 polygon = g.polygonN( i ).toPolygon_with_holes_2() ;
+ boost::shared_ptr< Straight_skeleton_2 > skeleton = CGAL::create_interior_straight_skeleton_2( polygon ) ;
+
+ if ( !skeleton.get() ) {
+ BOOST_THROW_EXCEPTION( Exception( "CGAL failed to create straightSkeleton" ) ) ;
+ }
+
+ straightSkeletonToMultiLineString( *skeleton, *result ) ;
+ }
+
+ return result ;
+}
+
+
+}//namespace algorithm
+}//namespace SFCGAL
+
diff --git a/src/algorithm/straightSkeleton.h b/src/algorithm/straightSkeleton.h
new file mode 100644
index 0000000..52c26e2
--- /dev/null
+++ b/src/algorithm/straightSkeleton.h
@@ -0,0 +1,75 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_ALGORITHM_STRAIGHTSKELETON_H_
+#define _SFCGAL_ALGORITHM_STRAIGHTSKELETON_H_
+
+#include <SFCGAL/config.h>
+
+#include <memory>
+
+namespace SFCGAL {
+class Geometry ;
+class Polygon ;
+class MultiPolygon ;
+class MultiLineString ;
+}
+
+namespace SFCGAL {
+namespace algorithm {
+struct NoValidityCheck;
+
+/**
+ * @brief build a 2D straight skeleton for a Polygon
+ * @todo add supports for TriangulatedSurface and PolyhedralSurface
+ * @todo output M as distance to border?
+ * @param g input geometry
+ * @param autoOrientation check and fix polygon orientation
+ * @ingroup public_api
+ * @pre g is a valid geometry
+ */
+SFCGAL_API std::auto_ptr< MultiLineString > straightSkeleton( const Geometry& g, bool autoOrientation = true ) ;
+
+/**
+ * @brief build a 2D straight skeleton for a Polygon
+ * @param g input geometry
+ * @param autoOrientation check and fix polygon orientation
+ * @ingroup public_api
+ * @pre g is a valid geometry
+ * @warning No actual validity check is done
+ */
+SFCGAL_API std::auto_ptr< MultiLineString > straightSkeleton( const Geometry& g, bool autoOrientation, NoValidityCheck ) ;
+
+/**
+ * @brief build a 2D straight skeleton for a Polygon
+ * @ingroup detail
+ */
+SFCGAL_API std::auto_ptr< MultiLineString > straightSkeleton( const Polygon& g, bool autoOrientation = true ) ;
+/**
+ * @brief build a 2D straight skeleton for a Polygon
+ * @ingroup detail
+ */
+SFCGAL_API std::auto_ptr< MultiLineString > straightSkeleton( const MultiPolygon& g, bool autoOrientation = true ) ;
+
+}//namespace algorithm
+}//namespace SFCGAL
+
+
+#endif
diff --git a/src/algorithm/tesselate.cpp b/src/algorithm/tesselate.cpp
new file mode 100644
index 0000000..8269d16
--- /dev/null
+++ b/src/algorithm/tesselate.cpp
@@ -0,0 +1,95 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/tesselate.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/triangulate/triangulatePolygon.h>
+#include <SFCGAL/algorithm/isValid.h>
+
+namespace SFCGAL {
+namespace algorithm {
+
+///
+///
+///
+std::auto_ptr<Geometry> tesselate( const Geometry& g, NoValidityCheck )
+{
+ switch ( g.geometryTypeId() ) {
+ case TYPE_POINT:
+ case TYPE_LINESTRING:
+ case TYPE_TRIANGLE:
+ case TYPE_MULTIPOINT:
+ case TYPE_MULTILINESTRING:
+ return std::auto_ptr<Geometry>( g.clone() );
+
+ case TYPE_POLYGON:
+ case TYPE_POLYHEDRALSURFACE: {
+ TriangulatedSurface* triSurf = new TriangulatedSurface();
+ triangulate::triangulatePolygon3D( g, *triSurf );
+ return std::auto_ptr<Geometry>( triSurf );
+ }
+
+ case TYPE_SOLID: {
+ std::auto_ptr<GeometryCollection> ret( new GeometryCollection );
+
+ for ( size_t i = 0; i < g.as<Solid>().numShells(); ++i ) {
+ const PolyhedralSurface& shellN = g.as<Solid>().shellN( i ) ;
+
+ if ( ! shellN.isEmpty() ) {
+ ret->addGeometry( tesselate( shellN ).release() );
+ }
+ }
+
+ return std::auto_ptr<Geometry>( ret.release() );
+ }
+
+ // multipolygon and multisolid return a geometrycollection
+ case TYPE_MULTIPOLYGON:
+ case TYPE_MULTISOLID:
+ case TYPE_GEOMETRYCOLLECTION: {
+ std::auto_ptr<GeometryCollection> ret( new GeometryCollection );
+
+ for ( size_t i = 0; i < g.numGeometries(); ++i ) {
+ ret->addGeometry( tesselate( g.geometryN( i ) ).release() );
+ }
+
+ return std::auto_ptr<Geometry>( ret.release() );
+ }
+
+ default:
+ break;
+ }
+
+ return std::auto_ptr<Geometry>( g.clone() );
+}
+
+std::auto_ptr<Geometry> tesselate( const Geometry& g )
+{
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY( g );
+
+ return tesselate( g, NoValidityCheck() );
+}
+
+} // namespace algorithm
+} // namespace SFCGAL
+
+
diff --git a/src/algorithm/tesselate.h b/src/algorithm/tesselate.h
new file mode 100644
index 0000000..6636c86
--- /dev/null
+++ b/src/algorithm/tesselate.h
@@ -0,0 +1,53 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_ALGORITHM_TESSELATE_H_
+#define _SFCGAL_ALGORITHM_TESSELATE_H_
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Geometry.h>
+
+namespace SFCGAL {
+namespace algorithm {
+struct NoValidityCheck;
+
+/**
+ * Tesselate a geometry: this will triangulate surfaces (including polyhedral and solid's surfaces) and keep untouched
+ * points, lines, etc.
+ * @pre g is a valid geometry
+ * @ingroup public_api
+ */
+SFCGAL_API std::auto_ptr<SFCGAL::Geometry> tesselate( const Geometry& );
+
+/**
+ * Tesselate a geometry: this will triangulate surfaces (including polyhedral and solid's surfaces) and keep untouched
+ * points, lines, etc.
+ * @pre g is a valid geometry
+ * @ingroup detail
+ * @warning No actual validity check is done.
+ */
+SFCGAL_API std::auto_ptr<SFCGAL::Geometry> tesselate( const Geometry&, NoValidityCheck );
+
+}//algorithm
+}//SFCGAL
+
+
+#endif
diff --git a/src/algorithm/translate.cpp b/src/algorithm/translate.cpp
new file mode 100644
index 0000000..1387fbf
--- /dev/null
+++ b/src/algorithm/translate.cpp
@@ -0,0 +1,64 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/translate.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+#include <SFCGAL/detail/transform/AffineTransform3.h>
+
+
+namespace SFCGAL {
+namespace algorithm {
+
+///
+///
+///
+void translate( Geometry& g, const Kernel::Vector_3& v )
+{
+ transform::AffineTransform3 visitor(
+ CGAL::Aff_transformation_3< Kernel >( CGAL::TRANSLATION, v )
+ );
+ g.accept( visitor ) ;
+}
+
+///
+///
+///
+void translate( Geometry& g, Kernel::FT dx, Kernel::FT dy, Kernel::FT dz )
+{
+ translate( g, Kernel::Vector_3( dx,dy,dz ) );
+}
+
+} // namespace algorithm
+} // namespace SFCGAL
+
+
diff --git a/src/algorithm/translate.h b/src/algorithm/translate.h
new file mode 100644
index 0000000..6ee458f
--- /dev/null
+++ b/src/algorithm/translate.h
@@ -0,0 +1,52 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_TRANSLATE_H_
+#define _SFCGAL_TRANSLATE_H_
+
+#include <SFCGAL/export.h>
+
+#include <SFCGAL/Kernel.h>
+
+namespace SFCGAL {
+class Geometry ;
+}
+
+namespace SFCGAL {
+namespace algorithm {
+
+/**
+ * @brief translate a geometry from a given vector
+ * @todo unittest
+ * @todo rename to translate3D and add translate for 2D
+ */
+SFCGAL_API void translate( Geometry& g, const Kernel::Vector_3& v ) ;
+/**
+ * @brief translate a geometry from a given vector
+ * @todo unittest
+ * @todo rename to translate3D and add translate for 2D
+ */
+SFCGAL_API void translate( Geometry& g, Kernel::FT dx, Kernel::FT dy, Kernel::FT dz ) ;
+
+} // namespace algorithm
+} // namespace SFCGAL
+
+#endif
+
diff --git a/src/algorithm/union.cpp b/src/algorithm/union.cpp
new file mode 100644
index 0000000..1f135b1
--- /dev/null
+++ b/src/algorithm/union.cpp
@@ -0,0 +1,997 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/differencePrimitives.h>
+#include <SFCGAL/algorithm/intersection.h>
+#include <SFCGAL/algorithm/union.h>
+#include <SFCGAL/algorithm/isValid.h>
+#include <SFCGAL/triangulate/triangulate2DZ.h>
+
+#include <cstdio>
+#include <algorithm>
+
+#define DEBUG_OUT if (0) std::cerr << __FILE__ << ":" << __LINE__ << " debug: "
+
+
+namespace SFCGAL {
+
+namespace algorithm {
+
+struct EmptyPrimitive {};
+
+enum PrimitiveType {
+ PrimitivePoint = 0,
+ PrimitiveSegment = 1,
+ PrimitiveSurface = 2,
+ PrimitiveVolume = 3,
+ PrimitiveEmpty = 4
+};
+
+template <int Dim>
+struct Segment_d: detail::Segment_d<Dim>::Type {
+ typedef typename detail::Point_d<Dim>::Type PointType;
+ typedef typename detail::Segment_d<Dim>::Type SegmentType;
+ typedef typename std::vector< PointType > PointVector;
+ typedef typename std::vector< SegmentType > SegmentVector;
+
+ Segment_d( const SegmentType& s ): SegmentType( s ) {}
+ void splitAt( const PointType& p ) {
+ _split.push_back( p );
+ }
+ void remove( const SegmentType& s ) {
+ _split.push_back( s.source() );
+ _split.push_back( s.target() );
+ _remove.push_back( s );
+ }
+
+ template < class OutputIterator >
+ OutputIterator pieces( OutputIterator out ) const {
+ PointVector points( 1, this->source() );
+ points.insert( points.end(), _split.begin(), _split.end() );
+ points.push_back( this->target() );
+ std::sort( points.begin()+1, points.end()-1, Nearer< PointType >( this->source() ) );
+
+ for ( typename PointVector::const_iterator p = points.begin(), q = p+1;
+ q != points.end(); ++p, q++ ) {
+ if ( *p != *q ) {
+ PointType m = CGAL::midpoint( *p, *q );
+ typename SegmentVector::const_iterator r = _remove.begin();
+
+ for ( ; r != _remove.end() && !r->has_on( m ); ++r );
+
+ if ( r == _remove.end() ) {
+ *out++ = SegmentType( *p, *q );
+ }
+ }
+ }
+
+ return out;
+ }
+
+ SegmentVector pieces() const {
+ SegmentVector result;
+ this->pieces( std::back_inserter( result ) );
+ return result;
+ }
+
+private:
+ PointVector _split;
+ SegmentVector _remove;
+};
+
+template <int Dim> struct Surface_d {};
+
+template <>
+struct Surface_d<3>: Triangle_3 {
+ typedef std::vector< algorithm::Point_2 > PointVector;
+ typedef std::vector< Segment_2 > SegmentVector;
+ typedef std::vector< PointVector > SurfaceVector;
+
+ Surface_d( const Triangle_3& s ): Triangle_3( s ), _plane( s.supporting_plane() ) {
+ this->splitAt( s );
+ }
+
+ void splitAt( const algorithm::Point_3& p ) {
+ //@note this is a degenerated segment, but works anyway
+ _split.push_back( Segment_2( _plane.to_2d( p ), _plane.to_2d( p ) ) );
+ }
+
+ void splitAt( const Segment_3& s ) {
+ _split.push_back( Segment_2( _plane.to_2d( s.source() ), _plane.to_2d( s.target() ) ) );
+ }
+
+ template <typename Point3Iterator>
+ void splitAt( Point3Iterator begin, Point3Iterator end ) { // polygon with unclosed ring
+ if ( begin == end ) {
+ return;
+ }
+
+ Point3Iterator s = begin, t = s+1;
+
+ for ( ; t != end; ++t, ++s ) {
+ _split.push_back( Segment_2( _plane.to_2d( *s ), _plane.to_2d( *t ) ) );
+ }
+
+ _split.push_back( Segment_2( _plane.to_2d( *s ), _plane.to_2d( *begin ) ) );
+ }
+
+ void splitAt( const Triangle_3& t ) {
+ const algorithm::Point_3 v[3] = { t.vertex( 0 ), t.vertex( 1 ), t.vertex( 2 ) };
+ this->splitAt( v, v+3 );
+ }
+
+ void splitAt( const std::vector< algorithm::Point_3 >& p ) { // polygon with unclosed ring
+ this->splitAt( p.begin(), p.end() );
+ }
+
+ template <typename Point3Iterator> // polygon with unclosed ring
+ void remove( Point3Iterator begin, Point3Iterator end ) {
+ if ( begin == end ) {
+ return;
+ }
+
+ this->splitAt( begin, end );
+ PointVector v;
+
+ for ( Point3Iterator i = begin; i != end; ++i ) {
+ v.push_back( _plane.to_2d( *i ) );
+ }
+
+ _remove.push_back( v );
+ }
+
+ void remove( const std::vector< algorithm::Point_3 >& p ) {
+ this->remove( p.begin(), p.end() );
+ }
+
+ void remove( const Triangle_3& t ) {
+ const algorithm::Point_3 v[3] = { t.vertex( 0 ), t.vertex( 1 ), t.vertex( 2 ) };
+ this->remove( v, v+3 );
+ }
+
+ std::vector< Triangle_3 > pieces() {
+ // we need to process the split lines because there may be several lines at the same place
+ // and this won't play nice with the triangulation, the same stands for the lines lying
+ // on the triangle edges
+ //
+ // after that we just check, for each triangle, if a point fall in a removed part and remove it
+ // we can do that by pairwise union of all segments
+ std::vector< Segment_2 > filtered;
+ {
+ std::vector< Segment_d<2> > lines( _split.begin(), _split.begin()+3 );
+
+ for ( typename SegmentVector::const_iterator c = _split.begin()+3; c != _split.end(); ++c ) {
+ Segment_d<2> current( *c );
+
+ for ( std::vector< Segment_d<2> >::iterator l = lines.begin(); l != lines.end(); ++l ) {
+ CGAL::Object inter = CGAL::intersection( *l, current );
+ const Point_2* p = CGAL::object_cast< Point_2 >( &inter );
+ const Segment_2* s = CGAL::object_cast< Segment_2 >( &inter );
+
+ if ( p ) {
+ current.splitAt( *p );
+ l->splitAt( *p );
+ }
+ else if ( s ) {
+ current.remove( *s );
+ l->splitAt( s->source() );
+ l->splitAt( s->target() );
+ }
+ }
+
+ lines.push_back( current );
+ }
+
+ for ( std::vector< Segment_d<2> >::const_iterator l = lines.begin(); l != lines.end(); ++l ) {
+ l->pieces( std::back_inserter( filtered ) );
+ }
+ }
+
+ DEBUG_OUT << "triangulating " << filtered.size() << " lines\n";
+
+ // now we want to triangulate
+ TriangulatedSurface ts;
+ {
+ typedef triangulate::ConstraintDelaunayTriangulation::Vertex_handle Vertex_handle;
+ triangulate::ConstraintDelaunayTriangulation cdt;
+
+ for ( std::vector< Segment_2 >::const_iterator f = filtered.begin(); f != filtered.end(); ++f ) {
+ Vertex_handle s = cdt.addVertex( f->source() );
+ Vertex_handle t = cdt.addVertex( f->target() );
+ cdt.addConstraint( s, t ) ;
+ }
+
+ cdt.getTriangles( ts );
+ }
+
+ // filter removed triangles
+ std::vector< Triangle_3 > res;
+
+ for ( TriangulatedSurface::iterator t = ts.begin(); t != ts.end(); ++t ) {
+ // define a point inside triangle
+ const Point_2 a( t->vertex( 0 ).toPoint_2() );
+ const Point_2 b( t->vertex( 1 ).toPoint_2() );
+ const Point_2 c( t->vertex( 2 ).toPoint_2() );
+ const Point_2 point( a + ( Vector_2( a, b ) + Vector_2( a, c ) )/3 );
+
+ // find if triangle is in a removed spot
+ SurfaceVector::const_iterator r = _remove.begin();
+
+ for ( ; r != _remove.end()
+ && CGAL::bounded_side_2( r->begin(), r->end(), point, Kernel() )
+ == CGAL::ON_UNBOUNDED_SIDE; ++r );
+
+ if ( r == _remove.end() ) {
+ res.push_back( Triangle_3( _plane.to_3d( a ), _plane.to_3d( b ), _plane.to_3d( c ) ) );
+ }
+ }
+
+ DEBUG_OUT << "generated " << res.size() << " triangles\n";
+
+ return res;
+ }
+
+private:
+ algorithm::Plane_3 _plane;
+ SegmentVector _split;
+ SurfaceVector _remove;
+};
+
+template <>
+struct Surface_d<2>: PolygonWH_2 {
+ typedef std::vector< Point_2 > PointVector;
+ typedef std::vector< Segment_2 > SegmentVector;
+ typedef std::vector< PointVector > SurfaceVector;
+
+ Surface_d( const PolygonWH_2& s ): PolygonWH_2( s ) {}
+
+ void splitAt( const Segment_2& s ) {
+ _split.push_back( s );
+ }
+
+ void addSplitsFrom( const Surface_d<2>& other ) {
+ _split.insert( _split.end(), other._split.begin(), other._split.end() );
+ }
+
+ std::vector< PolygonWH_2 > pieces() const {
+ std::vector< PolygonWH_2 > res;
+ fix_cgal_valid_polygon( *this, std::back_inserter( res ) );
+ return res;
+ }
+
+private:
+ SegmentVector _split;
+};
+
+// for debug prints
+template <typename T >
+std::ostream& operator<<( std::ostream& out, std::set< T* >& obs )
+{
+ for ( typename std::set< T* >::iterator h = obs.begin(); h != obs.end(); ++h ) {
+ out << *h << "\n";
+ }
+
+ return out;
+}
+
+
+// takes care of RAII of primitives
+
+template <int Dim>
+class Handle {
+ struct ObservablePrimitive: boost::variant<
+ typename detail::Point_d<Dim>::Type,
+ Segment_d<Dim>,
+ Surface_d<Dim>,
+ typename detail::Volume_d<Dim>::Type,
+ EmptyPrimitive > {
+ template <class T>
+ ObservablePrimitive( const T& p ) : boost::variant<
+ typename detail::Point_d<Dim>::Type,
+ Segment_d<Dim>,
+ Surface_d<Dim>,
+ typename detail::Volume_d<Dim>::Type,
+ EmptyPrimitive >( p ) {}
+
+ template <class T>
+ inline T& as() {
+ return boost::get<T&>( *this );
+ }
+
+ std::set< ObservablePrimitive** > _observers; // this is for ref counting and handle updating
+
+ private:
+ // non copyable
+ ObservablePrimitive( const ObservablePrimitive& );
+ ObservablePrimitive& operator=( const ObservablePrimitive& );
+ };
+
+public:
+
+
+ Handle(): _p( new ObservablePrimitive*( new ObservablePrimitive( EmptyPrimitive() ) ) ) {
+ ( *_p )->_observers.insert( _p );
+ BOOST_ASSERT( ( *_p )->_observers.count( _p ) );
+ }
+
+ ~Handle() {
+ BOOST_ASSERT( ( *_p )->_observers.count( _p ) );
+ ( *_p )->_observers.erase( _p );
+
+ if ( ( *_p )->_observers.empty() ) {
+ delete ( *_p );
+ }
+
+ delete _p;
+ }
+
+ Handle( const Handle& other ):_p( new ObservablePrimitive*( *other._p ) ) {
+ ( *_p )->_observers.insert( _p );
+ BOOST_ASSERT( ( *_p )->_observers.count( _p ) );
+ }
+
+ template < class PrimitiveType >
+ explicit Handle( const PrimitiveType& primitive ): _p( new ObservablePrimitive*( new ObservablePrimitive( primitive ) ) ) {
+ ( *_p )->_observers.insert( _p );
+ BOOST_ASSERT( ( *_p )->_observers.count( _p ) );
+ }
+
+ void swap( Handle& other ) {
+ ( *_p )->_observers.erase( _p );
+ ( *other._p )->_observers.erase( other._p );
+ std::swap( _p, other._p );
+ ( *_p )->_observers.insert( _p );
+ ( *other._p )->_observers.insert( other._p );
+ BOOST_ASSERT( ( *_p )->_observers.count( _p ) );
+ BOOST_ASSERT( ( *other._p )->_observers.count( other._p ) );
+ }
+
+ Handle& operator=( Handle other ) {
+ this->swap( other );
+ BOOST_ASSERT( ( *_p )->_observers.count( _p ) );
+ return *this;
+ }
+
+ const ObservablePrimitive& operator*() const {
+ BOOST_ASSERT( ( *_p )->_observers.count( _p ) );
+ return *( *_p );
+ }
+ ObservablePrimitive& operator*() {
+ BOOST_ASSERT( ( *_p )->_observers.count( _p ) );
+ return *( *_p );
+ }
+ const ObservablePrimitive* operator->() const {
+ BOOST_ASSERT( ( *_p )->_observers.count( _p ) );
+ return ( *_p );
+ }
+ ObservablePrimitive* operator->() {
+ BOOST_ASSERT( ( *_p )->_observers.count( _p ) );
+ return ( *_p );
+ }
+
+ typename detail::Point_d<Dim>::Type& asPoint() {
+ BOOST_ASSERT( ( *_p )->_observers.count( _p ) );
+ BOOST_ASSERT( which() == PrimitivePoint );
+ return boost::get<typename detail::Point_d<Dim>::Type& >( *( *_p ) );
+ }
+
+ Segment_d<Dim>& asSegment() {
+ BOOST_ASSERT( ( *_p )->_observers.count( _p ) );
+ BOOST_ASSERT( which() == PrimitiveSegment );
+ return boost::get<Segment_d<Dim> & >( *( *_p ) );
+ }
+
+ Surface_d<Dim>& asSurface() {
+ BOOST_ASSERT( ( *_p )->_observers.count( _p ) );
+ BOOST_ASSERT( which() == PrimitiveSurface );
+ return boost::get<Surface_d<Dim> & >( *( *_p ) );
+ }
+
+ typename detail::Volume_d<Dim>::Type& asVolume() {
+ BOOST_ASSERT( ( *_p )->_observers.count( _p ) );
+ BOOST_ASSERT( which() == PrimitiveVolume );
+ return boost::get<typename detail::Volume_d<Dim>::Type& >( *( *_p ) );
+ }
+
+ PrimitiveType which() {
+ return PrimitiveType( ( *_p )->which() );
+ }
+
+ bool empty() {
+ return which() == PrimitiveEmpty;
+ }
+
+ // makes all handles observing a observe 'this' instead
+ void registerObservers( Handle a ) {
+ if ( *a._p == *_p ) {
+ return; // both aready observing the same primitive
+ }
+
+ ObservablePrimitive* observed = *( a._p );
+ std::vector< ObservablePrimitive** > observers( observed->_observers.begin(), observed->_observers.end() );
+
+ for ( typename std::vector< ObservablePrimitive** >::iterator h = observers.begin(); h != observers.end(); ++h ) {
+ *( *h ) = *_p;
+ ( *( *h ) )->_observers.insert( *h );
+ }
+
+ BOOST_ASSERT( *a._p == *_p );
+
+ delete observed; // we removed all observers
+ BOOST_ASSERT( ( *_p )->_observers.count( _p ) );
+#ifdef DEBUG
+
+ for ( typename std::vector< ObservablePrimitive** >::iterator h = observers.begin(); h != observers.end(); ++h ) {
+ BOOST_ASSERT( ( *( *h ) )->_observers.count( *h ) );
+ }
+
+#endif
+
+ }
+
+private:
+ ObservablePrimitive** _p; // mutable because no non const cpy ctor en template classes
+};
+
+template <int Dim>
+struct HandledBox {
+ typedef CGAL::Box_intersection_d::Box_with_handle_d<double, Dim, Handle<Dim>, CGAL::Box_intersection_d::ID_EXPLICIT > Type;
+ typedef std::vector< Type > Vector;
+};
+
+template <int Dim, class OutputIterator>
+OutputIterator compute_bboxes( const detail::GeometrySet<Dim>& gs, OutputIterator out )
+{
+ typename HandledBox<Dim>::Vector bboxes;
+
+ for ( typename detail::GeometrySet<Dim>::PointCollection::const_iterator it = gs.points().begin();
+ it != gs.points().end(); ++it ) {
+ *out++ = typename HandledBox<Dim>::Type( it->primitive().bbox(), Handle<Dim>( it->primitive() ) );
+ }
+
+ for ( typename detail::GeometrySet<Dim>::SegmentCollection::const_iterator it = gs.segments().begin();
+ it != gs.segments().end(); ++it ) {
+ *out++ = typename HandledBox<Dim>::Type( it->primitive().bbox(), Handle<Dim>( it->primitive() ) );
+ }
+
+ for ( typename detail::GeometrySet<Dim>::SurfaceCollection::const_iterator it = gs.surfaces().begin();
+ it != gs.surfaces().end(); ++it ) {
+ DEBUG_OUT << "Adding surface " << it->primitive() << "\n";
+ DEBUG_OUT << " surface box " << it->primitive().bbox() << "\n";
+ *out++ = typename HandledBox<Dim>::Type( it->primitive().bbox(), Handle<Dim>( it->primitive() ) );
+ }
+
+ for ( typename detail::GeometrySet<Dim>::VolumeCollection::const_iterator it = gs.volumes().begin();
+ it != gs.volumes().end(); ++it ) {
+ *out++ = typename HandledBox<Dim>::Type( compute_solid_bbox( it->primitive(), detail::dim_t<Dim>() ), Handle<Dim>( it->primitive() ) );
+ }
+
+ return out;
+}
+
+template <class Handle>
+void union_point_point( Handle a, Handle b )
+{
+ if ( a.asPoint() == b.asPoint() ) {
+ a.registerObservers( b );
+ }
+}
+
+template <class Handle>
+void union_point_segment( Handle a, Handle b )
+{
+ if ( b.asSegment().has_on( a.asPoint() ) ) {
+ b.asSegment().splitAt( a.asPoint() );
+ b.registerObservers( a );
+ }
+}
+
+void union_point_surface( Handle<2> a,Handle<2> b )
+{
+ if ( do_intersect( a.asPoint(), b.asSurface() ) ) {
+ b.registerObservers( a );
+ }
+}
+
+void union_point_surface( Handle<3> a,Handle<3> b )
+{
+ if ( b.asSurface().has_on( a.asPoint() ) ) {
+ b.registerObservers( a );
+ }
+}
+
+void union_point_volume( Handle<2> ,Handle<2> )
+{
+ BOOST_ASSERT( false ); // there shouldn't be any volume in 2D
+}
+
+void union_point_volume( Handle<3> a,Handle<3> b )
+{
+ //@todo put is in poly in a struct derived from MarkedPolyhedron to avoid rebuilding point inside every time
+ CGAL::Point_inside_polyhedron_3<MarkedPolyhedron, Kernel> is_in_poly( b.asVolume() );
+
+ if ( CGAL::ON_UNBOUNDED_SIDE != is_in_poly( a.asPoint() ) ) {
+ b.registerObservers( a );
+ }
+}
+
+
+
+template <int Dim>
+void union_segment_segment( Handle<Dim> a,Handle<Dim> b )
+{
+ typedef typename detail::TypeForDimension<Dim>::Segment SegmentType;
+ typedef typename detail::TypeForDimension<Dim>::Point PointType;
+
+ CGAL::Object inter = CGAL::intersection( a.asSegment(), b.asSegment() );
+ const PointType* p = CGAL::object_cast< PointType >( &inter );
+ const SegmentType* s = CGAL::object_cast< SegmentType >( &inter );
+
+ if ( p ) {
+ b.asSegment().splitAt( *p );
+ a.asSegment().splitAt( *p );
+ }
+ else if ( s ) {
+ b.asSegment().remove( *s );
+ a.asSegment().splitAt( s->source() );
+ a.asSegment().splitAt( s->target() );
+ }
+}
+
+void union_segment_segment( Handle<2> a,Handle<2> b )
+{
+ union_segment_segment<2>( a, b );
+}
+
+void union_segment_segment( Handle<3> a,Handle<3> b )
+{
+ union_segment_segment<3>( a, b );
+}
+
+void union_segment_surface( Handle<2> a,Handle<2> b )
+{
+ std::vector< Polygon_2 > rings( 1, b.asSurface().outer_boundary() );
+ rings.insert( rings.end(), b.asSurface().holes_begin(), b.asSurface().holes_end() );
+
+ std::vector< Point_2 > points( 1, a.asSegment().source() );
+
+ for ( std::vector< Polygon_2 >::iterator ring = rings.begin(); ring != rings.end(); ++ring ) {
+ for ( Polygon_2::Vertex_const_iterator target = ring->vertices_begin();
+ target != ring->vertices_end(); ++target ) {
+ const Segment_2 sc( target == ring->vertices_begin()
+ ? *( ring->vertices_end() - 1 )
+ : *( target - 1 )
+ ,
+ *target );
+
+ CGAL::Object inter = CGAL::intersection( a.asSegment(), sc );
+ const Point_2* p = CGAL::object_cast< Point_2 >( &inter );
+ const Segment_2* s = CGAL::object_cast< Segment_2 >( &inter );
+
+ if ( p ) {
+ points.push_back( *p );
+ }
+ else if ( s ) {
+ a.asSegment().remove( *s );
+ }
+ }
+ }
+
+ points.push_back( a.asSegment().target() );
+
+ // order point according to the distance from source
+ std::sort( points.begin()+1, points.end()-1, Nearer<Point_2>( points[0] ) );
+
+ // cut segment with pieces that have length and wich midpoint is inside polygon
+ for ( std::vector< Point_2 >::const_iterator p = points.begin(), q = p+1; q != points.end(); ++p, ++q ) {
+ if ( *p != *q && do_intersect( CGAL::midpoint( *p,*q ), b.asSurface() ) ) {
+ const Segment_2 s( *p, *q );
+ a.asSegment().remove( s );
+ b.asSurface().splitAt( s );
+ }
+ }
+}
+
+void union_segment_surface( Handle<3> a,Handle<3> b )
+{
+ CGAL::Object inter = CGAL::intersection( a.asSegment(), b.asSurface() );
+ const Segment_3* s = CGAL::object_cast< Segment_3 >( &inter );
+
+ if ( s ) {
+ a.asSegment().remove( *s );
+ b.asSurface().splitAt( *s );
+ }
+}
+
+void union_segment_volume( Handle<2> ,Handle<2> )
+{
+ BOOST_ASSERT( false ); // there shouldn't be any volume in 2D
+}
+
+void union_segment_volume( Handle<3> a,Handle<3> b )
+{
+ const Segment_3& segment = a.asSegment();
+ const MarkedPolyhedron& polyhedron = b.asVolume();
+
+ std::vector< FaceBbox > bboxes( polyhedron.facets_begin(), polyhedron.facets_end() );
+ std::vector< FaceBboxBase > bbox( 1, FaceBboxBase( segment.bbox(),polyhedron.facets_begin()->facet_begin() ) ); // nevermind the facet handle, it's not used anyway
+ FaceSegmentCollide::CollisionVector collisions;
+ FaceSegmentCollide cb( collisions );
+ CGAL::box_intersection_d( bbox.begin(), bbox.end(),
+ bboxes.begin(), bboxes.end(),
+ cb );
+
+ CGAL::Point_inside_polyhedron_3<MarkedPolyhedron, Kernel> is_in_poly( polyhedron );
+
+ if ( !collisions.size() ) {
+ // completely in or out, we just test one point
+
+ if ( CGAL::ON_UNBOUNDED_SIDE != is_in_poly( segment.source() ) ) {
+ a.asSegment().remove( a.asSegment() );
+ }
+ }
+ else {
+ std::vector< Triangle_3 > triangles;
+ collidingTriangles( collisions, std::back_inserter( triangles ) );
+
+ // first step, substract faces
+ for ( std::vector< Triangle_3 >::const_iterator tri=triangles.begin();
+ tri != triangles.end(); ++tri ) {
+ Handle<3> h( *tri );
+ union_segment_surface( a, h );
+ }
+
+ // second step, for each segment, add intersection points and test each middle point
+ // to know if it's in or out
+ std::vector< Point_3 > points;
+
+ for ( std::vector< Triangle_3 >::const_iterator tri=triangles.begin();
+ tri != triangles.end(); ++tri ) {
+ CGAL::Object inter = CGAL::intersection( segment, *tri );
+ const Point_3* p = CGAL::object_cast< Point_3 >( &inter );
+
+ if ( p ) {
+ points.push_back( *p );
+ }
+ }
+
+ if ( points.size() ) {
+ std::sort( points.begin(), points.end(), Nearer<Point_3>( segment.source() ) );
+
+ // mark segments pieces that have length and wich midpoint is inside polyhedron
+ for ( std::vector< Point_3 >::const_iterator p = points.begin(), q = p+1;
+ q != points.end(); ++p, ++q ) {
+ if ( *p != *q && CGAL::ON_UNBOUNDED_SIDE != is_in_poly( CGAL::midpoint( *p,*q ) ) ) {
+ a.asSegment().remove( Segment_3( *p, *q ) );
+ }
+ }
+ }
+ }
+}
+
+
+void union_surface_surface( Handle<2> a,Handle<2> b )
+{
+ PolygonWH_2 res;
+
+ if ( CGAL::join( fix_sfs_valid_polygon( a.asSurface() ),
+ fix_sfs_valid_polygon( b.asSurface() ), res ) ) {
+ DEBUG_OUT << "merged " << a.asSurface() << " and " << b.asSurface() << "\n";
+ Handle<2> h( res );
+ h.asSurface().addSplitsFrom( a.asSurface() );
+ h.asSurface().addSplitsFrom( b.asSurface() );
+ h.registerObservers( a );
+ h.registerObservers( b );
+ }
+}
+
+void union_surface_surface( Handle<3> a,Handle<3> b )
+{
+ CGAL::Object inter = intersection( a.asSurface(), b.asSurface() );
+ const Point_3* p = CGAL::object_cast< Point_3 >( &inter );
+ const Segment_3* s = CGAL::object_cast< Segment_3 >( &inter );
+ const Triangle_3* t = CGAL::object_cast< Triangle_3 >( &inter );
+ const std::vector<Point_3>* v = CGAL::object_cast< std::vector<Point_3> >( &inter );
+
+ if ( p ) {
+ a.asSurface().splitAt( *p );
+ b.asSurface().splitAt( *p );
+ }
+ else if ( s ) {
+ a.asSurface().splitAt( *s );
+ b.asSurface().splitAt( *s );
+ }
+ else if ( t ) {
+ a.asSurface().splitAt( *t );
+ b.asSurface().remove( *t );
+ }
+ else if ( v ) {
+ a.asSurface().splitAt( *v );
+ b.asSurface().remove( *v );
+ }
+}
+
+void union_surface_volume( Handle<2> ,Handle<2> )
+{
+ BOOST_ASSERT( false ); // there shouldn't be any volume in 2D
+}
+
+void union_surface_volume( Handle<3> a,Handle<3> b )
+{
+ detail::GeometrySet<3> res;
+ _intersection_solid_triangle( b.asVolume(), a.asSurface(), res );
+
+ for ( detail::GeometrySet<3>::SurfaceCollection::const_iterator it = res.surfaces().begin();
+ it != res.surfaces().end(); ++it ) {
+ a.asSurface().remove( it->primitive() );
+ }
+}
+
+void union_volume_volume( Handle<2> ,Handle<2> )
+{
+ BOOST_ASSERT( false ); // there shouldn't be any volume in 2D
+}
+
+void union_volume_volume( Handle<3> a,Handle<3> b )
+{
+ MarkedPolyhedron& p = const_cast<MarkedPolyhedron&>( a.asVolume() );
+ MarkedPolyhedron& q = const_cast<MarkedPolyhedron&>( b.asVolume() );
+ typedef CGAL::Polyhedron_corefinement<MarkedPolyhedron> Corefinement;
+ Corefinement coref;
+ CGAL::Emptyset_iterator no_polylines;
+
+ // volumes must at least share a face, if they share only a point, this will cause
+ // an invalid geometry, if they only share an egde it will cause the CGAL algo to
+ // throw
+ //
+ // for the moment we use hte intersection algo and test the result
+ detail::GeometrySet<3> inter;
+ intersection( detail::GeometrySet<3>( a.asVolume() ), detail::GeometrySet<3>( b.asVolume() ), inter );
+
+ if ( inter.volumes().size() || inter.surfaces().size() ) {
+ typedef std::vector<std::pair<MarkedPolyhedron*, int> > ResultType;
+ ResultType result;
+ coref( p, q, no_polylines, std::back_inserter( result ), Corefinement::Join_tag );
+
+ if ( result.size() == 1 ) {
+ Handle<3> h( *result[0].first );
+ // @todo check that the volume is valid (connection on one point isn't)
+ h.registerObservers( a );
+ h.registerObservers( b );
+ }
+
+ for ( ResultType::iterator it = result.begin(); it != result.end(); it++ ) {
+ delete it->first;
+ }
+ }
+
+}
+
+
+
+template <int Dim>
+struct UnionOnBoxCollision {
+ void operator()( typename HandledBox<Dim>::Type& a,
+ typename HandledBox<Dim>::Type& b ) {
+ DEBUG_OUT << "collision of boxes\n";
+
+ switch ( a.handle().which() ) {
+ case PrimitivePoint:
+ switch ( b.handle().which() ) {
+ case PrimitivePoint:
+ union_point_point( a.handle(), b.handle() );
+ break;
+
+ case PrimitiveSegment:
+ union_point_segment( a.handle(), b.handle() );
+ break;
+
+ case PrimitiveSurface:
+ union_point_surface( a.handle(), b.handle() );
+ break;
+
+ case PrimitiveVolume:
+ union_point_volume( a.handle(), b.handle() );
+ break;
+
+ case PrimitiveEmpty:
+ break;
+ }
+
+ break;
+
+ case PrimitiveSegment:
+ switch ( b.handle().which() ) {
+ case PrimitivePoint:
+ union_point_segment( b.handle(), a.handle() );
+ break;
+
+ case PrimitiveSegment:
+ union_segment_segment( a.handle(), b.handle() );
+ break;
+
+ case PrimitiveSurface:
+ union_segment_surface( a.handle(), b.handle() );
+ break;
+
+ case PrimitiveVolume:
+ union_segment_volume( a.handle(), b.handle() );
+ break;
+
+ case PrimitiveEmpty:
+ break;
+ }
+
+ break;
+
+ case PrimitiveSurface:
+ switch ( b.handle().which() ) {
+ case PrimitivePoint:
+ union_point_surface( b.handle(), a.handle() );
+ break;
+
+ case PrimitiveSegment:
+ union_segment_surface( b.handle(), a.handle() );
+ break;
+
+ case PrimitiveSurface:
+ union_surface_surface( a.handle(), b.handle() );
+ break;
+
+ case PrimitiveVolume:
+ union_surface_volume( a.handle(), b.handle() );
+ break;
+
+ case PrimitiveEmpty:
+ break;
+ }
+
+ break;
+
+ case PrimitiveVolume:
+ switch ( b.handle().which() ) {
+ case PrimitivePoint:
+ union_point_volume( b.handle(), a.handle() );
+ break;
+
+ case PrimitiveSegment:
+ union_segment_volume( b.handle(), a.handle() );
+ break;
+
+ case PrimitiveSurface:
+ union_surface_volume( b.handle(), a.handle() );
+ break;
+
+ case PrimitiveVolume:
+ union_volume_volume( a.handle(), b.handle() );
+ break;
+
+ case PrimitiveEmpty:
+ break;
+ }
+
+ break;
+
+ case PrimitiveEmpty:
+ break;
+ }
+ }
+};
+
+template <int Dim>
+void collectPrimitives( const typename HandledBox<Dim>::Vector& boxes, detail::GeometrySet<Dim>& output )
+{
+ Handle<Dim> empty;
+
+ for ( typename HandledBox<Dim>::Vector::const_iterator bit = boxes.begin();
+ bit != boxes.end(); ++bit ) {
+ switch ( bit->handle().which() ) {
+ case PrimitivePoint :
+ output.addPrimitive( bit->handle().asPoint() );
+ empty.registerObservers( bit->handle() );
+ break;
+
+ case PrimitiveSegment : {
+ typename std::vector< typename detail::Segment_d<Dim>::Type > pieces( bit->handle().asSegment().pieces() );
+ output.addSegments( pieces.begin(), pieces.end() );
+ empty.registerObservers( bit->handle() );
+ }
+ break;
+
+ case PrimitiveSurface : {
+ typename std::vector< typename detail::Surface_d<Dim>::Type > pieces( bit->handle().asSurface().pieces() );
+ output.addSurfaces( pieces.begin(), pieces.end() );
+ empty.registerObservers( bit->handle() );
+ }
+ break;
+
+ case PrimitiveVolume :
+ output.addPrimitive( bit->handle().asVolume() );
+ empty.registerObservers( bit->handle() );
+ break;
+
+ case PrimitiveEmpty :
+ break;
+ }
+ }
+}
+
+std::auto_ptr<Geometry> union_( const Geometry& ga, const Geometry& gb, NoValidityCheck )
+{
+ typename HandledBox<2>::Vector boxes;
+ compute_bboxes( detail::GeometrySet<2>( ga ), std::back_inserter( boxes ) );
+ const unsigned numBoxA = boxes.size();
+ compute_bboxes( detail::GeometrySet<2>( gb ), std::back_inserter( boxes ) );
+
+ CGAL::box_intersection_d( boxes.begin(), boxes.begin() + numBoxA,
+ boxes.begin() + numBoxA, boxes.end(),
+ UnionOnBoxCollision<2>() );
+
+ detail::GeometrySet<2> output;
+ collectPrimitives( boxes, output );
+ return output.recompose();
+}
+
+std::auto_ptr<Geometry> union_( const Geometry& ga, const Geometry& gb )
+{
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_2D( ga );
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_2D( gb );
+ std::auto_ptr<Geometry> result( union_( ga, gb, NoValidityCheck() ) );
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_2D( *result );
+ return result;
+}
+
+std::auto_ptr<Geometry> union3D( const Geometry& ga, const Geometry& gb, NoValidityCheck )
+{
+ typename HandledBox<3>::Vector boxes;
+ compute_bboxes( detail::GeometrySet<3>( ga ), std::back_inserter( boxes ) );
+ const unsigned numBoxA = boxes.size();
+ compute_bboxes( detail::GeometrySet<3>( gb ), std::back_inserter( boxes ) );
+
+ CGAL::box_intersection_d( boxes.begin(), boxes.begin() + numBoxA,
+ boxes.begin() + numBoxA, boxes.end(),
+ UnionOnBoxCollision<3>() );
+
+ detail::GeometrySet<3> output;
+ collectPrimitives( boxes, output );
+ return output.recompose();
+}
+
+
+std::auto_ptr<Geometry> union3D( const Geometry& ga, const Geometry& gb )
+{
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_3D( ga );
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_3D( gb );
+ std::auto_ptr<Geometry> result( union3D( ga, gb, NoValidityCheck() ) );
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_3D( *result );
+ return result;
+}
+
+void handleLeakTest()
+{
+ Handle<2> h0( Point_2( 0,0 ) );
+ Handle<2> h1( Point_2( 1,1 ) );
+ Handle<2> empty;
+ empty.registerObservers( empty );
+ empty.registerObservers( h0 );
+ h1.registerObservers( h0 );
+}
+}
+}
diff --git a/src/algorithm/union.h b/src/algorithm/union.h
new file mode 100644
index 0000000..5443a0d
--- /dev/null
+++ b/src/algorithm/union.h
@@ -0,0 +1,83 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SFCGAL_UNION_ALGORITHM
+#define SFCGAL_UNION_ALGORITHM
+
+#include <SFCGAL/config.h>
+
+#include <memory>
+
+namespace SFCGAL {
+class Geometry;
+namespace detail {
+template <int Dim> class GeometrySet;
+template <int Dim> class PrimitiveHandle;
+}
+
+namespace algorithm {
+struct NoValidityCheck;
+
+/**
+ * Union on 2D geometries.
+ * @pre ga and gb are valid geometries
+ * @ingroup public_api
+ */
+SFCGAL_API std::auto_ptr<Geometry> union_( const Geometry& ga, const Geometry& gb );
+
+/**
+ * Union on 2D geometries. No validity check variant
+ * @pre ga and gb are valid geometries
+ * @ingroup detail
+ * @warning No actual validity check is done.
+ */
+SFCGAL_API std::auto_ptr<Geometry> union_( const Geometry& ga, const Geometry& gb,NoValidityCheck );
+
+/**
+ * Union on 3D geometries. Assume z = 0 if needed
+ * @pre ga and gb are valid geometries
+ * @ingroup public_api
+ */
+SFCGAL_API std::auto_ptr<Geometry> union3D( const Geometry& ga, const Geometry& gb );
+
+/**
+ * Union on 3D geometries. Assume z = 0 if needed
+ * @pre ga and gb are valid geometries
+ * @ingroup detail
+ * @warning@ No actual validity check is done
+ */
+SFCGAL_API std::auto_ptr<Geometry> union3D( const Geometry& ga, const Geometry& gb, NoValidityCheck );
+
+/**
+ * @ingroup detail
+ */
+template <int Dim>
+void union_( const detail::GeometrySet<Dim>& a, const detail::GeometrySet<Dim>& b, detail::GeometrySet<Dim>& );
+
+/**
+ * @ingroup detail
+ */
+template <int Dim>
+void union_( const detail::PrimitiveHandle<Dim>& a, const detail::PrimitiveHandle<Dim>& b, detail::GeometrySet<Dim>& );
+
+}
+}
+
+#endif
diff --git a/src/algorithm/volume.cpp b/src/algorithm/volume.cpp
new file mode 100644
index 0000000..c0510eb
--- /dev/null
+++ b/src/algorithm/volume.cpp
@@ -0,0 +1,97 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <SFCGAL/algorithm/volume.h>
+#include <SFCGAL/algorithm/isValid.h>
+#include <SFCGAL/algorithm/tesselate.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/Solid.h>
+
+namespace SFCGAL {
+namespace algorithm {
+
+const Kernel::FT volume( const Solid& solid, NoValidityCheck )
+{
+ Kernel::FT vol = 0;
+ const CGAL::Point_3<Kernel> origin( 0,0,0 );
+ const size_t numShells = solid.numShells();
+
+ for ( size_t i=0; i<numShells; i++ ) {
+ std::auto_ptr<Geometry> t( tesselate( solid.shellN( i ), NoValidityCheck() ) );
+ const TriangulatedSurface& tin = t->as<TriangulatedSurface>();
+ const size_t numTriangles = tin.numTriangles();
+
+ for ( size_t j=0; j<numTriangles; j++ ) {
+ const Triangle& tri = tin.triangleN( j );
+ vol = vol + CGAL::volume( origin, tri.vertex( 0 ).toPoint_3(),
+ tri.vertex( 1 ).toPoint_3(),
+ tri.vertex( 2 ).toPoint_3() );
+ }
+ }
+
+ return vol;
+}
+
+const Kernel::FT volume( const Geometry& g )
+{
+ if ( g.isEmpty() ) {
+ return 0;
+ }
+
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY( g );
+
+ switch ( g.geometryTypeId() ) {
+ case TYPE_POINT:
+ case TYPE_LINESTRING:
+ case TYPE_POLYGON:
+ case TYPE_TRIANGLE:
+ case TYPE_MULTIPOINT:
+ case TYPE_MULTILINESTRING:
+ case TYPE_MULTIPOLYGON:
+ case TYPE_TRIANGULATEDSURFACE:
+ case TYPE_POLYHEDRALSURFACE:
+ return 0;
+
+ case TYPE_SOLID:
+ return volume( g.as<Solid>(), NoValidityCheck() );
+
+ case TYPE_MULTISOLID:
+ case TYPE_GEOMETRYCOLLECTION:
+ Kernel::FT v=0;
+ const GeometryCollection& c = g.as<GeometryCollection>();
+
+ for ( size_t i=0; i<c.numGeometries(); i++ ) {
+ if ( c.geometryN( i ).is<Solid>() ) {
+ v = v + volume( c.geometryN( i ).as<Solid>(), NoValidityCheck() );
+ }
+ }
+
+ return v;
+ }
+
+ BOOST_THROW_EXCEPTION( Exception(
+ ( boost::format( "volume( %s ) is not defined" ) % g.geometryType() ).str()
+ ) );
+ return 0; // to avoid warning
+}
+
+}
+}
diff --git a/src/algorithm/volume.h b/src/algorithm/volume.h
new file mode 100644
index 0000000..f6a8fe9
--- /dev/null
+++ b/src/algorithm/volume.h
@@ -0,0 +1,50 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_ALGORITHM_VOLUME_H_
+#define _SFCGAL_ALGORITHM_VOLUME_H_
+
+#include <SFCGAL/export.h>
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Geometry.h>
+
+namespace SFCGAL {
+namespace algorithm {
+
+struct NoValidityCheck;
+
+/**
+ * Computes the volume of a geometry
+ * @pre g is a valid Geometry
+ * @ingroup public_api
+ */
+SFCGAL_API const Kernel::FT volume( const Geometry& g );
+
+/**
+ * Computes the volume of a Solid
+ * @pre (not checked) volume is closed and consistently oriented
+ * @ingroup detail
+ */
+SFCGAL_API const Kernel::FT volume( const Solid& g, NoValidityCheck );
+
+}
+}
+
+#endif
diff --git a/src/capi/sfcgal_c.cpp b/src/capi/sfcgal_c.cpp
new file mode 100644
index 0000000..1ff5d53
--- /dev/null
+++ b/src/capi/sfcgal_c.cpp
@@ -0,0 +1,985 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <SFCGAL/Geometry.h>
+#include <SFCGAL/version.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/PreparedGeometry.h>
+
+#include <SFCGAL/capi/sfcgal_c.h>
+
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/io/ewkt.h>
+#include <SFCGAL/detail/io/Serialization.h>
+
+#include <SFCGAL/algorithm/isValid.h>
+#include <SFCGAL/algorithm/intersects.h>
+#include <SFCGAL/algorithm/intersection.h>
+#include <SFCGAL/algorithm/difference.h>
+#include <SFCGAL/algorithm/union.h>
+#include <SFCGAL/algorithm/convexHull.h>
+#include <SFCGAL/algorithm/distance.h>
+#include <SFCGAL/algorithm/distance3d.h>
+#include <SFCGAL/algorithm/plane.h>
+#include <SFCGAL/algorithm/volume.h>
+#include <SFCGAL/algorithm/area.h>
+#include <SFCGAL/algorithm/extrude.h>
+#include <SFCGAL/algorithm/tesselate.h>
+#include <SFCGAL/triangulate/triangulate2DZ.h>
+#include <SFCGAL/algorithm/minkowskiSum.h>
+#include <SFCGAL/algorithm/offset.h>
+#include <SFCGAL/algorithm/straightSkeleton.h>
+
+#include <SFCGAL/detail/transform/ForceZOrderPoints.h>
+#include <SFCGAL/detail/transform/ForceOrderPoints.h>
+#include <SFCGAL/detail/transform/RoundTransform.h>
+
+//
+// Note about sfcgal_geometry_t pointers: they are basically void* pointers that represent
+// pointers to a SFCGAL::Geometry.
+// In order to support multiple inheritance:
+// every input or output sfcgal_geometry_t* is a pointer to the *base class* SFCGAL::Geometry.
+// If a function wants to return a sub-class, it must be up casted before returned (static_cast)
+// If a function wants to use a sub-class from a parameter, it must also be down casted.
+// For instance, static_cast<SFCGAL::Point*>(reinterpret_cast<SFCGAL::Geometry*>(p))
+//
+// SFCGAL::PreparedGeometry has no vtable and can thus be manipuled through reinterpret_cast without
+// problem
+
+static sfcgal_error_handler_t __sfcgal_warning_handler = printf;
+static sfcgal_error_handler_t __sfcgal_error_handler = printf;
+
+#define SFCGAL_WARNING __sfcgal_warning_handler
+#define SFCGAL_ERROR __sfcgal_error_handler
+
+#define SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR( call ) \
+ try {call}\
+ catch( std::exception& e ) { SFCGAL_ERROR( "%s", e.what() ); return 0; }
+
+#define SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR_NO_RET( call ) \
+ try {call}\
+ catch( std::exception& e ) { SFCGAL_ERROR( "%s", e.what() ); }
+
+template <class T>
+inline T* down_cast( sfcgal_geometry_t* p )
+{
+ T* q = dynamic_cast<T*>( reinterpret_cast<SFCGAL::Geometry*>( p ) );
+
+ if ( !q ) {
+ BOOST_THROW_EXCEPTION( SFCGAL::Exception( "wrong geometry type" ) );
+ }
+
+ return q;
+}
+
+template <class T>
+inline const T* down_const_cast( const sfcgal_geometry_t* p )
+{
+ const T* q = dynamic_cast<const T*>( reinterpret_cast<const SFCGAL::Geometry*>( p ) );
+
+ if ( !q ) {
+ BOOST_THROW_EXCEPTION( SFCGAL::Exception( "wrong geometry type" ) );
+ }
+
+ return q;
+}
+
+extern "C" void sfcgal_set_error_handlers( sfcgal_error_handler_t warning_handler, sfcgal_error_handler_t error_handler )
+{
+ __sfcgal_warning_handler = warning_handler;
+ __sfcgal_error_handler = error_handler;
+}
+
+static sfcgal_alloc_handler_t __sfcgal_alloc_handler = malloc;
+static sfcgal_free_handler_t __sfcgal_free_handler = free;
+
+extern "C" void sfcgal_set_alloc_handlers( sfcgal_alloc_handler_t alloc_handler, sfcgal_free_handler_t free_handler )
+{
+ __sfcgal_alloc_handler = alloc_handler;
+ __sfcgal_free_handler = free_handler;
+}
+
+extern "C" void sfcgal_init()
+{
+ // Empty for now
+}
+
+extern "C" const char* sfcgal_version()
+{
+ return SFCGAL::Version();
+}
+
+extern "C" void sfcgal_set_geometry_validation( int enabled )
+{
+ SFCGAL::algorithm::SKIP_GEOM_VALIDATION = !enabled;
+}
+
+extern "C" sfcgal_geometry_type_t sfcgal_geometry_type_id( const sfcgal_geometry_t* geom )
+{
+
+ try {
+ return ( sfcgal_geometry_type_t )reinterpret_cast<const SFCGAL::Geometry*>( geom )->geometryTypeId();
+ }
+ catch( std::exception& e ) {
+ SFCGAL_ERROR( "%s", e.what() );
+ return SFCGAL_TYPE_POINT; // to avoid warning
+ }
+}
+
+extern "C" int sfcgal_geometry_is_valid( const sfcgal_geometry_t* geom )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return ( int )bool( SFCGAL::algorithm::isValid( *reinterpret_cast<const SFCGAL::Geometry*>( geom ) ) );
+ )
+}
+
+extern "C" int sfcgal_geometry_is_3d( const sfcgal_geometry_t* geom )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return ( int )reinterpret_cast<const SFCGAL::Geometry*>( geom )->is3D();
+ )
+}
+
+extern "C" int sfcgal_geometry_is_empty( const sfcgal_geometry_t* geom )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return ( int )reinterpret_cast<const SFCGAL::Geometry*>( geom )->isEmpty();
+ )
+}
+
+extern "C" sfcgal_geometry_t* sfcgal_geometry_clone( const sfcgal_geometry_t* geom )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return reinterpret_cast<const SFCGAL::Geometry*>( geom )->clone();
+ )
+}
+
+extern "C" void sfcgal_geometry_delete( sfcgal_geometry_t* geom )
+{
+ delete reinterpret_cast<SFCGAL::Geometry*>( geom );
+}
+
+extern "C" void sfcgal_geometry_as_text( const sfcgal_geometry_t* pgeom, char** buffer, size_t* len )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR_NO_RET(
+ std::string wkt = reinterpret_cast<const SFCGAL::Geometry*>( pgeom )->asText();
+ *buffer = ( char* )__sfcgal_alloc_handler( wkt.size() + 1 );
+ *len = wkt.size();
+ strncpy( *buffer, wkt.c_str(), *len );
+ )
+}
+
+extern "C" void sfcgal_geometry_as_text_decim( const sfcgal_geometry_t* pgeom, int numDecimals, char** buffer, size_t* len )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR_NO_RET(
+ std::string wkt = reinterpret_cast<const SFCGAL::Geometry*>( pgeom )->asText( numDecimals );
+ *buffer = ( char* )__sfcgal_alloc_handler( wkt.size() + 1 );
+ *len = wkt.size();
+ strncpy( *buffer, wkt.c_str(), *len );
+ )
+}
+
+/**
+ * Point
+ */
+extern "C" sfcgal_geometry_t* sfcgal_point_create()
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<SFCGAL::Geometry*>( new SFCGAL::Point() );
+ )
+}
+
+extern "C" sfcgal_geometry_t* sfcgal_point_create_from_xy( double x, double y )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<SFCGAL::Geometry*>( new SFCGAL::Point( x, y ) );
+ )
+}
+extern "C" sfcgal_geometry_t* sfcgal_point_create_from_xyz( double x, double y, double z )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<SFCGAL::Geometry*>( new SFCGAL::Point( x, y, z ) );
+ )
+}
+
+extern "C" double sfcgal_point_x( const sfcgal_geometry_t* geom )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return CGAL::to_double( down_const_cast<SFCGAL::Point>( geom )->x() );
+ )
+}
+
+extern "C" double sfcgal_point_y( const sfcgal_geometry_t* geom )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return CGAL::to_double( down_const_cast<SFCGAL::Point>( geom )->y() );
+ )
+}
+
+extern "C" double sfcgal_point_z( const sfcgal_geometry_t* geom )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return CGAL::to_double( down_const_cast<SFCGAL::Point>( geom )->z() );
+ )
+}
+
+/**
+ * LineString
+ */
+extern "C" sfcgal_geometry_t* sfcgal_linestring_create()
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<SFCGAL::Geometry*>( new SFCGAL::LineString() );
+ )
+}
+
+extern "C" size_t sfcgal_linestring_num_points( const sfcgal_geometry_t* geom )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return down_const_cast<SFCGAL::LineString>( geom )->numPoints();
+ )
+}
+
+extern "C" const sfcgal_geometry_t* sfcgal_linestring_point_n( const sfcgal_geometry_t* geom, size_t i )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<const SFCGAL::Geometry*>( &( down_const_cast<SFCGAL::LineString>( geom )->pointN( i ) ) );
+ )
+}
+
+extern "C" void sfcgal_linestring_add_point( sfcgal_geometry_t* geom, sfcgal_geometry_t* point )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR_NO_RET(
+ down_cast<SFCGAL::LineString>( geom )->addPoint( down_cast<SFCGAL::Point>( point ) );
+ )
+}
+
+/**
+ * Triangle
+ */
+extern "C" sfcgal_geometry_t* sfcgal_triangle_create()
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<SFCGAL::Geometry*>( new SFCGAL::Triangle() );
+ )
+}
+
+extern "C" sfcgal_geometry_t* sfcgal_triangle_create_from_points( const sfcgal_geometry_t* pa,
+ const sfcgal_geometry_t* pb,
+ const sfcgal_geometry_t* pc )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<SFCGAL::Geometry*>( new SFCGAL::Triangle( *down_const_cast<SFCGAL::Point>( pa ),
+ *down_const_cast<SFCGAL::Point>( pb ),
+ *down_const_cast<SFCGAL::Point>( pc ) ) );
+ )
+}
+
+
+extern "C" const sfcgal_geometry_t* sfcgal_triangle_vertex( const sfcgal_geometry_t* geom, int i )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<const SFCGAL::Geometry*>( &down_const_cast<SFCGAL::Triangle>( geom )->vertex( i ) );
+ )
+}
+
+extern "C" void sfcgal_triangle_set_vertex( sfcgal_geometry_t* geom, int i, const sfcgal_geometry_t* point )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR_NO_RET(
+ down_cast<SFCGAL::Triangle>( geom )->vertex( i ) = *down_const_cast<const SFCGAL::Point>( point );
+ )
+}
+
+extern "C" void sfcgal_triangle_set_vertex_from_xy( sfcgal_geometry_t* geom, int i, double x, double y )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR_NO_RET(
+ down_cast<SFCGAL::Triangle>( geom )->vertex( i ) = SFCGAL::Point( x, y );
+ )
+}
+
+extern "C" void sfcgal_triangle_set_vertex_from_xyz( sfcgal_geometry_t* geom, int i, double x, double y, double z )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR_NO_RET(
+ down_cast<SFCGAL::Triangle>( geom )->vertex( i ) = SFCGAL::Point( x, y, z );
+ )
+}
+
+/**
+ * Polygon
+ */
+extern "C" sfcgal_geometry_t* sfcgal_polygon_create()
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<SFCGAL::Geometry*>( new SFCGAL::Polygon() );
+ )
+}
+
+extern "C" sfcgal_geometry_t* sfcgal_polygon_create_from_exterior_ring( sfcgal_geometry_t* ring )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<SFCGAL::Geometry*>( new SFCGAL::Polygon( down_cast<SFCGAL::LineString>( ring ) ) );
+ )
+}
+
+extern "C" const sfcgal_geometry_t* sfcgal_polygon_exterior_ring( const sfcgal_geometry_t* geom )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<const SFCGAL::Geometry*>( &down_const_cast<SFCGAL::Polygon>( geom )->exteriorRing() );
+ )
+}
+
+extern "C" size_t sfcgal_polygon_num_interior_rings( const sfcgal_geometry_t* geom )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return down_const_cast<SFCGAL::Polygon>( geom )->numInteriorRings();
+ )
+}
+
+extern "C" const sfcgal_geometry_t* sfcgal_polygon_interior_ring_n( const sfcgal_geometry_t* geom, size_t i )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<const SFCGAL::Geometry*>( &down_const_cast<SFCGAL::Polygon>( geom )->interiorRingN( i ) );
+ )
+}
+
+extern "C" void sfcgal_polygon_add_interior_ring( sfcgal_geometry_t* geom, sfcgal_geometry_t* ring )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR_NO_RET(
+ down_cast<SFCGAL::Polygon>( geom )->addRing( down_cast<SFCGAL::LineString>( ring ) );
+ )
+}
+
+/**
+ * Geometry collection
+ */
+
+extern "C" sfcgal_geometry_t* sfcgal_geometry_collection_create()
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<SFCGAL::Geometry*>( new SFCGAL::GeometryCollection() );
+ )
+}
+
+extern "C" size_t sfcgal_geometry_collection_num_geometries( const sfcgal_geometry_t* geom )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return down_const_cast<SFCGAL::GeometryCollection>( geom )->numGeometries();
+ )
+}
+
+extern "C" const sfcgal_geometry_t* sfcgal_geometry_collection_geometry_n( const sfcgal_geometry_t* geom, size_t i )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ const SFCGAL::GeometryCollection* g = down_const_cast<SFCGAL::GeometryCollection>( geom );
+ return static_cast<const SFCGAL::Geometry*>( &g->geometryN( i ) );
+ )
+}
+
+extern "C" void sfcgal_geometry_collection_add_geometry( sfcgal_geometry_t* geom, sfcgal_geometry_t* ngeom )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR_NO_RET(
+ down_cast<SFCGAL::GeometryCollection>( geom )->addGeometry( reinterpret_cast<SFCGAL::Geometry*>( ngeom ) );
+ )
+}
+
+/**
+ * Multi-*
+ */
+extern "C" sfcgal_geometry_t* sfcgal_multi_point_create()
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<SFCGAL::Geometry*>( new SFCGAL::MultiPoint() );
+ )
+}
+
+extern "C" sfcgal_geometry_t* sfcgal_multi_linestring_create()
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<SFCGAL::Geometry*>( new SFCGAL::MultiLineString() );
+ )
+}
+
+extern "C" sfcgal_geometry_t* sfcgal_multi_polygon_create()
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<SFCGAL::Geometry*>( new SFCGAL::MultiPolygon() );
+ )
+}
+
+/**
+ * Polyhedral surface
+ */
+
+extern "C" sfcgal_geometry_t* sfcgal_polyhedral_surface_create()
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<SFCGAL::Geometry*>( new SFCGAL::PolyhedralSurface() );
+ )
+}
+
+extern "C" size_t sfcgal_polyhedral_surface_num_polygons( const sfcgal_geometry_t* geom )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return down_const_cast<SFCGAL::PolyhedralSurface>( geom )->numPolygons();
+ )
+}
+
+extern "C" const sfcgal_geometry_t* sfcgal_polyhedral_surface_polygon_n( const sfcgal_geometry_t* geom, size_t i )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<const SFCGAL::Geometry*>( &down_const_cast<SFCGAL::PolyhedralSurface>( geom )->polygonN( i ) );
+ )
+}
+
+extern "C" void sfcgal_polyhedral_surface_add_polygon( sfcgal_geometry_t* geom, sfcgal_geometry_t* poly )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR_NO_RET(
+ return down_cast<SFCGAL::PolyhedralSurface>( geom )->addPolygon( down_cast<SFCGAL::Polygon>( poly ) );
+ )
+}
+
+/**
+ * Triangulated surface
+ */
+
+extern "C" sfcgal_geometry_t* sfcgal_triangulated_surface_create()
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<SFCGAL::Geometry*>( new SFCGAL::TriangulatedSurface() );
+ )
+}
+
+extern "C" size_t sfcgal_triangulated_surface_num_triangles( const sfcgal_geometry_t* geom )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return down_const_cast<SFCGAL::TriangulatedSurface>( geom )->numTriangles();
+ )
+}
+
+extern "C" const sfcgal_geometry_t* sfcgal_triangulated_surface_triangle_n( const sfcgal_geometry_t* geom, size_t i )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<const SFCGAL::Geometry*>( &down_const_cast<SFCGAL::TriangulatedSurface>( geom )->triangleN( i ) );
+ )
+}
+
+extern "C" void sfcgal_triangulated_surface_add_triangle( sfcgal_geometry_t* geom, sfcgal_geometry_t* triangle )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR_NO_RET(
+ down_cast<SFCGAL::TriangulatedSurface>( geom )->addTriangle( down_cast<SFCGAL::Triangle>( triangle ) );
+ )
+}
+
+/**
+ * Solid
+ */
+
+extern "C" sfcgal_geometry_t* sfcgal_solid_create()
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<SFCGAL::Geometry*>( new SFCGAL::Solid() );
+ )
+}
+
+extern "C" sfcgal_geometry_t* sfcgal_solid_create_from_exterior_shell( sfcgal_geometry_t* shell )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<SFCGAL::Geometry*>( new SFCGAL::Solid( down_cast<SFCGAL::PolyhedralSurface>( shell ) ) );
+ )
+}
+
+extern "C" size_t sfcgal_solid_num_shells( const sfcgal_geometry_t* geom )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return down_const_cast<SFCGAL::Solid>( geom )->numShells();
+ )
+}
+
+extern "C" const sfcgal_geometry_t* sfcgal_solid_shell_n( const sfcgal_geometry_t* geom, size_t i )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return static_cast<const SFCGAL::Geometry*>( &down_const_cast<SFCGAL::Solid>( geom )->shellN( i ) );
+ )
+}
+
+extern "C" void sfcgal_solid_add_interior_shell( sfcgal_geometry_t* geom , sfcgal_geometry_t* shell )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR_NO_RET(
+ down_cast<SFCGAL::Solid>( geom )->addInteriorShell( down_cast<SFCGAL::PolyhedralSurface>( shell ) );
+ )
+}
+
+extern "C" sfcgal_prepared_geometry_t* sfcgal_prepared_geometry_create()
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return new SFCGAL::PreparedGeometry();
+ )
+}
+
+extern "C" sfcgal_prepared_geometry_t* sfcgal_prepared_geometry_create_from_geometry( sfcgal_geometry_t* geom, srid_t srid )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return new SFCGAL::PreparedGeometry( reinterpret_cast<SFCGAL::Geometry*>( geom ), srid );
+ )
+}
+
+extern "C" void sfcgal_prepared_geometry_delete( sfcgal_prepared_geometry_t* pgeom )
+{
+ delete reinterpret_cast<SFCGAL::PreparedGeometry*>( pgeom );
+}
+
+extern "C" const sfcgal_geometry_t* sfcgal_prepared_geometry_geometry( const sfcgal_prepared_geometry_t* pgeom )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return &reinterpret_cast<const SFCGAL::PreparedGeometry*>( pgeom )->geometry();
+ )
+}
+
+extern "C" void sfcgal_prepared_geometry_set_geometry( sfcgal_prepared_geometry_t* pgeom, sfcgal_geometry_t* geom )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR_NO_RET(
+ reinterpret_cast<SFCGAL::PreparedGeometry*>( pgeom )->resetGeometry( reinterpret_cast<SFCGAL::Geometry*>( geom ) );
+ )
+}
+
+extern "C" srid_t sfcgal_prepared_geometry_srid( const sfcgal_prepared_geometry_t* pgeom )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return reinterpret_cast<const SFCGAL::PreparedGeometry*>( pgeom )->SRID();
+ )
+}
+
+extern "C" void sfcgal_prepared_geometry_set_srid( sfcgal_prepared_geometry_t* pgeom, srid_t srid )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR_NO_RET(
+ reinterpret_cast<SFCGAL::PreparedGeometry*>( pgeom )->SRID() = srid;
+ )
+}
+
+extern "C" void sfcgal_prepared_geometry_as_ewkt( const sfcgal_prepared_geometry_t* pgeom, int num_decimals, char** buffer, size_t* len )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR_NO_RET(
+ std::string ewkt = reinterpret_cast<const SFCGAL::PreparedGeometry*>( pgeom )->asEWKT( num_decimals );
+ *buffer = ( char* )__sfcgal_alloc_handler( ewkt.size() + 1 );
+ *len = ewkt.size();
+ strncpy( *buffer, ewkt.c_str(), *len );
+ )
+}
+
+extern "C" sfcgal_geometry_t* sfcgal_io_read_wkt( const char* str, size_t len )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR(
+ return SFCGAL::io::readWkt( str, len ).release();
+ )
+}
+
+extern "C" void sfcgal_io_write_binary_prepared( const sfcgal_prepared_geometry_t* geom, char** buffer, size_t* len )
+{
+ SFCGAL_GEOMETRY_CONVERT_CATCH_TO_ERROR_NO_RET(
+ const SFCGAL::PreparedGeometry* g = reinterpret_cast<const SFCGAL::PreparedGeometry*>( geom );
+ std::string str = SFCGAL::io::writeBinaryPrepared( *g );
+ *buffer = ( char* )__sfcgal_alloc_handler( str.size() + 1 );
+ *len = str.size();
+ memcpy( *buffer, str.c_str(), *len );
+ )
+}
+
+extern "C" sfcgal_prepared_geometry_t* sfcgal_io_read_binary_prepared( const char* str, size_t len )
+{
+ std::string sstr( str, len );
+ std::auto_ptr<SFCGAL::PreparedGeometry> g;
+
+ try {
+ g = SFCGAL::io::readBinaryPrepared( sstr );
+ }
+ catch ( std::exception& e ) {
+ SFCGAL_WARNING( "During read_binary_prepared" );
+ SFCGAL_ERROR( "%s", e.what() );
+ return 0;
+ }
+
+ return g.release();
+}
+
+extern "C" sfcgal_prepared_geometry_t* sfcgal_io_read_ewkt( const char* str, size_t len )
+{
+ std::auto_ptr<SFCGAL::PreparedGeometry> g;
+
+ try {
+ g = SFCGAL::io::readEwkt( str, len );
+ }
+ catch ( std::exception& e ) {
+ SFCGAL_ERROR( "%s", e.what() );
+ return 0;
+ }
+
+ SFCGAL::PreparedGeometry* pg = g.release();
+ return pg;
+}
+
+// Functions that take two geometries and return a scalar
+//
+// name: C function name
+// ret_type: C function return type
+// sfcgal_function: C++ SFCGAL method to call
+// cpp_type: C++ return type (might be different than ret_type)
+// fail_value: returned value on failure
+#define SFCGAL_GEOMETRY_FUNCTION_BINARY_SCALAR( name, sfcgal_function, ret_type, cpp_type, fail_value ) \
+ extern "C" ret_type sfcgal_geometry_##name( const sfcgal_geometry_t* ga, const sfcgal_geometry_t* gb ) \
+ { \
+ cpp_type r; \
+ try \
+ { \
+ r = sfcgal_function( *(const SFCGAL::Geometry*)(ga), *(const SFCGAL::Geometry*)(gb) ); \
+ } \
+ catch ( std::exception& e ) \
+ { \
+ SFCGAL_WARNING( "During " #name "(A,B) :" ); \
+ SFCGAL_WARNING( " with A: %s", ((const SFCGAL::Geometry*)(ga))->asText().c_str() ); \
+ SFCGAL_WARNING( " and B: %s", ((const SFCGAL::Geometry*)(gb))->asText().c_str() ); \
+ SFCGAL_ERROR( "%s", e.what() ); \
+ return fail_value; \
+ } \
+ return r; \
+ }
+
+#define SFCGAL_GEOMETRY_FUNCTION_BINARY_PREDICATE( name, sfcgal_function ) \
+ SFCGAL_GEOMETRY_FUNCTION_BINARY_SCALAR( name, sfcgal_function, int, bool, -1 )
+
+SFCGAL_GEOMETRY_FUNCTION_BINARY_PREDICATE( intersects, SFCGAL::algorithm::intersects )
+SFCGAL_GEOMETRY_FUNCTION_BINARY_PREDICATE( intersects_3d, SFCGAL::algorithm::intersects3D )
+
+#define SFCGAL_GEOMETRY_FUNCTION_BINARY_MEASURE( name, sfcgal_function ) \
+ SFCGAL_GEOMETRY_FUNCTION_BINARY_SCALAR( name, sfcgal_function, double, double, -1.0 )
+
+SFCGAL_GEOMETRY_FUNCTION_BINARY_MEASURE( distance, SFCGAL::algorithm::distance )
+SFCGAL_GEOMETRY_FUNCTION_BINARY_MEASURE( distance_3d, SFCGAL::algorithm::distance3D )
+
+
+#define SFCGAL_GEOMETRY_FUNCTION_BINARY_CONSTRUCTION( name, sfcgal_function ) \
+ extern "C" sfcgal_geometry_t* sfcgal_geometry_##name( const sfcgal_geometry_t* ga, const sfcgal_geometry_t* gb ) \
+ { \
+ std::auto_ptr<SFCGAL::Geometry> result; \
+ try \
+ { \
+ result = sfcgal_function( *(const SFCGAL::Geometry*)(ga), *(const SFCGAL::Geometry*)(gb) ); \
+ } \
+ catch ( std::exception& e ) \
+ { \
+ SFCGAL_WARNING( "During " #name "(A,B) :" ); \
+ SFCGAL_WARNING( " with A: %s", ((const SFCGAL::Geometry*)(ga))->asText().c_str() ); \
+ SFCGAL_WARNING( " and B: %s", ((const SFCGAL::Geometry*)(gb))->asText().c_str() ); \
+ SFCGAL_ERROR( "%s", e.what() ); \
+ return 0; \
+ } \
+ return result.release(); \
+ }
+
+SFCGAL_GEOMETRY_FUNCTION_BINARY_CONSTRUCTION( intersection, SFCGAL::algorithm::intersection )
+SFCGAL_GEOMETRY_FUNCTION_BINARY_CONSTRUCTION( intersection_3d, SFCGAL::algorithm::intersection3D )
+SFCGAL_GEOMETRY_FUNCTION_BINARY_CONSTRUCTION( difference, SFCGAL::algorithm::difference )
+SFCGAL_GEOMETRY_FUNCTION_BINARY_CONSTRUCTION( difference_3d, SFCGAL::algorithm::difference3D )
+SFCGAL_GEOMETRY_FUNCTION_BINARY_CONSTRUCTION( union, SFCGAL::algorithm::union_ )
+SFCGAL_GEOMETRY_FUNCTION_BINARY_CONSTRUCTION( union_3d, SFCGAL::algorithm::union3D )
+
+#define SFCGAL_GEOMETRY_FUNCTION_UNARY_CONSTRUCTION( name, sfcgal_function ) \
+ extern "C" sfcgal_geometry_t* sfcgal_geometry_##name( const sfcgal_geometry_t* ga ) \
+ { \
+ std::auto_ptr<SFCGAL::Geometry> result; \
+ try \
+ { \
+ result = sfcgal_function( *(const SFCGAL::Geometry*)(ga) ); \
+ } \
+ catch ( std::exception& e ) \
+ { \
+ SFCGAL_WARNING( "During " #name "(A) :" ); \
+ SFCGAL_WARNING( " with A: %s", ((const SFCGAL::Geometry*)(ga))->asText().c_str() ); \
+ SFCGAL_ERROR( "%s", e.what() ); \
+ return 0; \
+ } \
+ return result.release(); \
+ }
+
+SFCGAL_GEOMETRY_FUNCTION_UNARY_CONSTRUCTION( convexhull, SFCGAL::algorithm::convexHull )
+SFCGAL_GEOMETRY_FUNCTION_UNARY_CONSTRUCTION( convexhull_3d, SFCGAL::algorithm::convexHull3D )
+SFCGAL_GEOMETRY_FUNCTION_UNARY_CONSTRUCTION( straight_skeleton, SFCGAL::algorithm::straightSkeleton )
+SFCGAL_GEOMETRY_FUNCTION_UNARY_CONSTRUCTION( tesselate, SFCGAL::algorithm::tesselate )
+
+#define SFCGAL_GEOMETRY_FUNCTION_UNARY_MEASURE( name, sfcgal_function ) \
+ extern "C" double sfcgal_geometry_##name( const sfcgal_geometry_t* ga ) \
+ { \
+ double r; \
+ try \
+ { \
+ r = sfcgal_function( *(const SFCGAL::Geometry*)(ga) ); \
+ } \
+ catch ( std::exception& e ) \
+ { \
+ SFCGAL_WARNING( "During " #name "(A) :" ); \
+ SFCGAL_WARNING( " with A: %s", ((const SFCGAL::Geometry*)(ga))->asText().c_str() ); \
+ SFCGAL_ERROR( "%s", e.what() ); \
+ return -1.0; \
+ } \
+ return r; \
+ }
+
+extern "C" double sfcgal_geometry_volume( const sfcgal_geometry_t* ga )
+{
+ double r;
+
+ try {
+ r = CGAL::to_double( SFCGAL::algorithm::volume( *( const SFCGAL::Geometry* )( ga ) ) );
+ }
+ catch ( std::exception& e ) {
+ SFCGAL_WARNING( "During volume(A) :" );
+ SFCGAL_WARNING( " with A: %s", ( ( const SFCGAL::Geometry* )( ga ) )->asText().c_str() );
+ SFCGAL_ERROR( "%s", e.what() );
+ return -1.0;
+ }
+
+ return r;
+}
+
+SFCGAL_GEOMETRY_FUNCTION_UNARY_MEASURE( area, SFCGAL::algorithm::area )
+SFCGAL_GEOMETRY_FUNCTION_UNARY_MEASURE( area_3d, SFCGAL::algorithm::area3D )
+
+extern "C" int sfcgal_geometry_is_planar( const sfcgal_geometry_t* ga )
+{
+ const SFCGAL::Geometry* g = reinterpret_cast<const SFCGAL::Geometry*>( ga );
+
+ if ( g->geometryTypeId() != SFCGAL::TYPE_POLYGON ) {
+ SFCGAL_ERROR( "is_planar() only applies to polygons" );
+ return -1;
+ }
+
+ bool r;
+
+ try {
+ r = SFCGAL::algorithm::hasPlane3D< SFCGAL::Kernel >( g->as< const SFCGAL::Polygon >() );
+ }
+ catch ( std::exception& e ) {
+ SFCGAL_WARNING( "During is_planar(A) :" );
+ SFCGAL_WARNING( " with A: %s", ( ( const SFCGAL::Geometry* )( ga ) )->asText().c_str() );
+ SFCGAL_ERROR( "%s", e.what() );
+ return -1.0;
+ }
+
+ return r ? 1 : 0;
+}
+
+/**
+ * Get geometry orientation.
+ * Returns:
+ * -1 for a counter clock wise orientation,
+ * 1 for a clock wise orientation,
+ * 0 for invalid or undetermined orientation
+ */
+extern "C" int sfcgal_geometry_orientation( const sfcgal_geometry_t* ga )
+{
+ const SFCGAL::Geometry* g = reinterpret_cast<const SFCGAL::Geometry*>( ga );
+
+ if ( g->geometryTypeId() != SFCGAL::TYPE_POLYGON ) {
+ SFCGAL_ERROR( "orientation() only applies to polygons" );
+ return 0;
+ }
+
+ bool r;
+
+ try {
+ r = g->as<const SFCGAL::Polygon>().isCounterClockWiseOriented();
+ }
+ catch ( std::exception& e ) {
+ SFCGAL_WARNING( "During orientation(A) :" );
+ SFCGAL_WARNING( " with A: %s", ( ( const SFCGAL::Geometry* )( ga ) )->asText().c_str() );
+ SFCGAL_ERROR( "%s", e.what() );
+ return -1.0;
+ }
+
+ return r ? -1 : 1;
+}
+
+extern "C" sfcgal_geometry_t* sfcgal_geometry_make_solid( const sfcgal_geometry_t* ga )
+{
+ const SFCGAL::Geometry* g = reinterpret_cast<const SFCGAL::Geometry*>( ga );
+
+ if ( g->geometryTypeId() != SFCGAL::TYPE_POLYHEDRALSURFACE ) {
+ SFCGAL_ERROR( "make_solid() only applies to polyhedral surfaces" );
+ return 0;
+ }
+
+ return static_cast<SFCGAL::Geometry*>( new SFCGAL::Solid( g->as<const SFCGAL::PolyhedralSurface>() ) );
+}
+
+extern "C" sfcgal_geometry_t* sfcgal_geometry_force_lhr( const sfcgal_geometry_t* ga )
+{
+ const SFCGAL::Geometry* g = reinterpret_cast<const SFCGAL::Geometry*>( ga );
+ SFCGAL::Geometry* gb = g->clone();
+ SFCGAL::transform::ForceOrderPoints force( /* ccw */ true );
+
+ try {
+ gb->accept( force );
+ }
+ catch ( std::exception& e ) {
+ SFCGAL_WARNING( "During force_lhr(A) :" );
+ SFCGAL_WARNING( " with A: %s", ( ( const SFCGAL::Geometry* )( ga ) )->asText().c_str() );
+ SFCGAL_ERROR( "%s", e.what() );
+ return 0;
+ }
+
+ return gb;
+}
+
+extern "C" sfcgal_geometry_t* sfcgal_geometry_force_rhr( const sfcgal_geometry_t* ga )
+{
+ const SFCGAL::Geometry* g = reinterpret_cast<const SFCGAL::Geometry*>( ga );
+ SFCGAL::Geometry* gb = g->clone();
+ SFCGAL::transform::ForceOrderPoints force( /* ccw */ false );
+
+ try {
+ gb->accept( force );
+ }
+ catch ( std::exception& e ) {
+ SFCGAL_WARNING( "During force_rhr(A) :" );
+ SFCGAL_WARNING( " with A: %s", ( ( const SFCGAL::Geometry* )( ga ) )->asText().c_str() );
+ SFCGAL_ERROR( "%s", e.what() );
+ return 0;
+ }
+
+ return gb;
+}
+
+extern "C" sfcgal_geometry_t* sfcgal_geometry_triangulate_2dz( const sfcgal_geometry_t* ga )
+{
+ const SFCGAL::Geometry* g = reinterpret_cast<const SFCGAL::Geometry*>( ga );
+ SFCGAL::TriangulatedSurface* surf = new SFCGAL::TriangulatedSurface;
+
+ try {
+ SFCGAL::triangulate::ConstraintDelaunayTriangulation cdt;
+ SFCGAL::triangulate::triangulate2DZ( *g, cdt );
+ cdt.getTriangles( *surf );
+ }
+ catch ( std::exception& e ) {
+ SFCGAL_WARNING( "During triangulate_2d(A) :" );
+ SFCGAL_WARNING( " with A: %s", ( ( const SFCGAL::Geometry* )( ga ) )->asText().c_str() );
+ SFCGAL_ERROR( "%s", e.what() );
+ return 0;
+ }
+
+ return static_cast<SFCGAL::Geometry*>( surf );
+}
+
+extern "C" sfcgal_geometry_t* sfcgal_geometry_extrude( const sfcgal_geometry_t* ga, double x, double y, double z )
+{
+ const SFCGAL::Geometry* g = reinterpret_cast<const SFCGAL::Geometry*>( ga );
+ SFCGAL::Geometry* gb = g->clone();
+ SFCGAL::transform::ForceZOrderPoints forceZ;
+ std::auto_ptr<SFCGAL::Geometry> result;
+
+ try {
+ gb->accept( forceZ );
+ result = SFCGAL::algorithm::extrude( *gb, x, y, z );
+ }
+ catch ( std::exception& e ) {
+ SFCGAL_WARNING( "During extrude(A, %g, %g, %g) :", x, y, z );
+ SFCGAL_WARNING( " with A: %s", ( ( const SFCGAL::Geometry* )( ga ) )->asText().c_str() );
+ SFCGAL_ERROR( "%s", e.what() );
+ return 0;
+ }
+
+ return result.release();
+}
+
+extern "C" sfcgal_geometry_t* sfcgal_geometry_round( const sfcgal_geometry_t* ga, int scale )
+{
+ const SFCGAL::Geometry* g = reinterpret_cast<const SFCGAL::Geometry*>( ga );
+ SFCGAL::Geometry* gb = g->clone();
+ // SFCGAL_WARNING( "geom: %s %s", gb->asText().c_str(), typeid(g).name() );
+
+ SFCGAL::transform::RoundTransform roundT( scale );
+
+ try {
+ gb->accept( roundT );
+ }
+ catch ( std::exception& e ) {
+ SFCGAL_WARNING( "During round(A):" );
+ SFCGAL_WARNING( " with A: %s", ( ( const SFCGAL::Geometry* )( ga ) )->asText().c_str() );
+ SFCGAL_ERROR( "%s", e.what() );
+ return 0;
+ }
+
+ // SFCGAL_WARNING( "processed geom: %s", gb->asText().c_str() );
+ return gb;
+}
+
+extern "C" sfcgal_geometry_t* sfcgal_geometry_minkowski_sum( const sfcgal_geometry_t* ga, const sfcgal_geometry_t* gb )
+{
+ const SFCGAL::Geometry* g1 = reinterpret_cast<const SFCGAL::Geometry*>( ga );
+ const SFCGAL::Geometry* g2 = reinterpret_cast<const SFCGAL::Geometry*>( gb );
+
+ if ( g2->geometryTypeId() != SFCGAL::TYPE_POLYGON ) {
+ SFCGAL_ERROR( "minkowski_sum(): the second argument must be a polygon" );
+ return 0;
+ }
+
+ std::auto_ptr<SFCGAL::Geometry> sum;
+
+ try {
+ sum = SFCGAL::algorithm::minkowskiSum( *g1, g2->as<const SFCGAL::Polygon>() );
+ }
+ catch ( std::exception& e ) {
+ SFCGAL_WARNING( "During minkowski_sum(A,B):" );
+ SFCGAL_WARNING( " with A: %s", ( ( const SFCGAL::Geometry* )( ga ) )->asText().c_str() );
+ SFCGAL_WARNING( " and B: %s", ( ( const SFCGAL::Geometry* )( gb ) )->asText().c_str() );
+ SFCGAL_ERROR( "%s", e.what() );
+ return 0;
+ }
+
+ return sum.release();
+}
+
+extern "C" sfcgal_geometry_t* sfcgal_geometry_offset_polygon( const sfcgal_geometry_t* ga, double offset )
+{
+ const SFCGAL::Geometry* g1 = reinterpret_cast<const SFCGAL::Geometry*>( ga );
+ std::auto_ptr<SFCGAL::MultiPolygon> mp;
+
+ try {
+ mp = SFCGAL::algorithm::offset( *g1, offset );
+ }
+ catch ( std::exception& e ) {
+ SFCGAL_WARNING( "During offset(A,%g):", offset );
+ SFCGAL_WARNING( " with A: %s", ( ( const SFCGAL::Geometry* )( ga ) )->asText().c_str() );
+ SFCGAL_ERROR( "%s", e.what() );
+ return 0;
+ }
+
+ return mp.release();
+}
+
diff --git a/src/capi/sfcgal_c.h b/src/capi/sfcgal_c.h
new file mode 100644
index 0000000..10b8195
--- /dev/null
+++ b/src/capi/sfcgal_c.h
@@ -0,0 +1,845 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_CAPI_H_
+#define _SFCGAL_CAPI_H_
+
+#include <SFCGAL/config.h>
+#include <stdint.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// TODO : return of errors ! => error handler
+
+/**
+ *
+ * Minimal C API for SFCGAL
+ *
+ */
+
+/*--------------------------------------------------------------------------------------*
+ *
+ * Support for SFCGAL::Geometry class hierarchy
+ *
+ *--------------------------------------------------------------------------------------*/
+
+/**
+ * sfcgal_geometry_t is an opaque pointer type that is used to represent a pointer to SFCGAL::Geometry
+ * @ingroup capi
+ */
+typedef void sfcgal_geometry_t;
+
+/**
+ * Geometric types
+ * @ingroup capi
+ */
+typedef enum {
+ // TYPE_GEOMETRY = 0, //abstract
+ SFCGAL_TYPE_POINT = 1,
+ SFCGAL_TYPE_LINESTRING = 2,
+ SFCGAL_TYPE_POLYGON = 3,
+ SFCGAL_TYPE_MULTIPOINT = 4,
+ SFCGAL_TYPE_MULTILINESTRING = 5,
+ SFCGAL_TYPE_MULTIPOLYGON = 6,
+ SFCGAL_TYPE_GEOMETRYCOLLECTION = 7,
+ // TYPE_CIRCULARSTRING = 8,
+ // TYPE_COMPOUNDCURVE = 9,
+ // TYPE_CURVEPOLYGON = 10,
+ // TYPE_MULTICURVE = 11, //abstract
+ // TYPE_MULTISURFACE = 12, //abstract
+ // TYPE_CURVE = 13, //abstract
+ // TYPE_SURFACE = 14, //abstract
+ SFCGAL_TYPE_POLYHEDRALSURFACE = 15,
+ SFCGAL_TYPE_TRIANGULATEDSURFACE = 16,
+
+ //-- not official codes
+ SFCGAL_TYPE_TRIANGLE = 100, //17 in Wikipedia???
+ SFCGAL_TYPE_SOLID = 101,
+ SFCGAL_TYPE_MULTISOLID = 102
+} sfcgal_geometry_type_t ;
+
+/**
+ * Set the geometry validation mode
+ * @ingroup capi
+ */
+SFCGAL_API void sfcgal_set_geometry_validation( int enabled );
+
+/**
+ * Returns the type of a given geometry
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_type_t sfcgal_geometry_type_id( const sfcgal_geometry_t* );
+
+/**
+ * Tests if the given geometry is valid or not
+ * @ingroup capi
+ */
+SFCGAL_API int sfcgal_geometry_is_valid( const sfcgal_geometry_t* );
+
+/**
+ * Tests if the given geometry is 3D or not
+ * @ingroup capi
+ */
+SFCGAL_API int sfcgal_geometry_is_3d( const sfcgal_geometry_t* );
+
+/**
+ * Tests if the given geometry is empty or not
+ * @ingroup capi
+ */
+SFCGAL_API int sfcgal_geometry_is_empty( const sfcgal_geometry_t* );
+
+/**
+ * Returns a deep clone of the given geometry
+ * @post returns a pointer to an allocated geometry that must be deallocated by @ref sfcgal_geometry_delete
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_clone( const sfcgal_geometry_t* );
+
+/**
+ * Deletes a given geometry
+ * @pre the given pointer must have been previously allocated by a creation function
+ * @ingroup capi
+ */
+SFCGAL_API void sfcgal_geometry_delete( sfcgal_geometry_t* );
+
+/**
+ * Returns a WKT representation of the given geometry using CGAL exact integer fractions as coordinate values
+ * @post buffer is returned allocated and must be freed by the caller
+ * @ingroup capi
+ */
+SFCGAL_API void sfcgal_geometry_as_text( const sfcgal_geometry_t*, char** buffer, size_t* len );
+
+/**
+ * Returns a WKT representation of the given geometry using floating point coordinate values.
+ * Floating point precision can be set via the numDecimals parameter.
+ * Setting numDecimals to -1 yields the same result as sfcgal_geometry_as_text.
+ * @post buffer is returned allocated and must be freed by the caller
+ * @ingroup capi
+ */
+SFCGAL_API void sfcgal_geometry_as_text_decim( const sfcgal_geometry_t*, int numDecimals, char** buffer, size_t* len );
+
+/**
+ * Creates an empty point
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_point_create();
+
+/**
+ * Creates a point from two X and Y coordinates
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_point_create_from_xy( double x, double y );
+
+/**
+ * Creates a point from three X, Y and Z coordinates
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_point_create_from_xyz( double x, double y, double z );
+
+/**
+ * Returns the X coordinate of the given Point
+ * @pre the given geometry must be a Point
+ * @pre the given point must not be empty
+ * @ingroup capi
+ */
+SFCGAL_API double sfcgal_point_x( const sfcgal_geometry_t* );
+
+/**
+ * Returns the Y coordinate of the given Point
+ * @pre the given geometry must be a Point
+ * @pre the given point must not be empty
+ * @ingroup capi
+ */
+SFCGAL_API double sfcgal_point_y( const sfcgal_geometry_t* );
+
+/**
+ * Returns the Z coordinate of the given Point
+ * @pre the given geometry must be a Point
+ * @pre the given point must not be empty
+ * @post the Z coordinate can value NaN if the given point is 2D only
+ * @ingroup capi
+ */
+SFCGAL_API double sfcgal_point_z( const sfcgal_geometry_t* );
+
+/**
+ * Creates an empty LineString
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_linestring_create();
+
+/**
+ * Returns the number of points of the given LineString
+ * @pre linestring must be a LineString
+ * @ingroup capi
+ */
+SFCGAL_API size_t sfcgal_linestring_num_points( const sfcgal_geometry_t* linestring );
+
+/**
+ * Returns the ith point of a given LineString
+ * @param i is the point index in the LineString
+ * @pre linestring must be a LineString
+ * @pre i >= and i < sfcgal_linestring_num_points
+ * @post the returned Point is not writable and must not be deallocated by the caller
+ * @ingroup capi
+ */
+SFCGAL_API const sfcgal_geometry_t* sfcgal_linestring_point_n( const sfcgal_geometry_t* linestring, size_t i );
+
+/**
+ * Adds a point to a LineString
+ * @param linestring is the LineString where the Point has to be added to
+ * @param point is the Point to add to the given LineString
+ * @pre i >= and i < sfcgal_linestring_num_points
+ * @post the ownership of Point is taken by the function
+ * @ingroup capi
+ */
+SFCGAL_API void sfcgal_linestring_add_point( sfcgal_geometry_t* linestring, sfcgal_geometry_t* point );
+
+/**
+ * Creates an empty Triangle
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_triangle_create();
+
+/**
+ * Creates a Triangle from three given Point
+ * @pre pta must be a Triangle
+ * @pre ptb must be a Triangle
+ * @pre ptc must be a Triangle
+ * @post the ownership of the three points are not taken. The caller is still responsible of their deallocation
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_triangle_create_from_points( const sfcgal_geometry_t* pta,
+ const sfcgal_geometry_t* ptb,
+ const sfcgal_geometry_t* ptc );
+
+/**
+ * Returns one the Triangle's vertex as a Point
+ * @pre triangle must be a Triangle
+ * @pre i >= 0 and i < 3
+ * @post returns a pointer to one of the vertices as a Point. This pointer is not writable and must not be deallocated by the caller
+ * @ingroup capi
+ */
+SFCGAL_API const sfcgal_geometry_t* sfcgal_triangle_vertex( const sfcgal_geometry_t* triangle, int i );
+
+/**
+ * Sets one vertex of a Triangle
+ * @pre triangle must be a Triangle
+ * @pre vertex must be a Point
+ * @post returns a pointer to one of the vertices as a Point. This pointer is not writable and must not be deallocated by the caller
+ * @ingroup capi
+ */
+SFCGAL_API void sfcgal_triangle_set_vertex( sfcgal_geometry_t* triangle, int i, const sfcgal_geometry_t* vertex );
+
+/**
+ * Sets one vertex of a Triangle from two coordinates
+ * @pre triangle must be a Triangle
+ * @pre i >= 0 and i < 3
+ * @ingroup capi
+ */
+SFCGAL_API void sfcgal_triangle_set_vertex_from_xy( sfcgal_geometry_t* triangle, int i, double x, double y );
+
+/**
+ * Sets one vertex of a Triangle from three coordinates
+ * @pre triangle must be a Triangle
+ * @pre i >= 0 and i < 3
+ * @ingroup capi
+ */
+SFCGAL_API void sfcgal_triangle_set_vertex_from_xyz( sfcgal_geometry_t* triangle, int i, double x, double y, double z );
+
+/**
+ * Creates an empty Polygon
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_polygon_create();
+
+/**
+ * Creates an empty Polygon from an extrior ring
+ * @pre ring must be a LineString
+ * @post the ownership of the given ring is taken. The caller is not responsible anymore of its deallocation
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_polygon_create_from_exterior_ring( sfcgal_geometry_t* ring );
+
+/**
+ * Returns the exterior ring of a given Polygon
+ * @pre polygon must be a Polygon
+ * @pre polygon must not be empty
+ * @post the returned ring is a LineString, is not writable and must not be deallocated by the caller
+ * @ingroup capi
+ */
+SFCGAL_API const sfcgal_geometry_t* sfcgal_polygon_exterior_ring( const sfcgal_geometry_t* polygon );
+
+/**
+ * Returns the number of interior rings of a given Polygon
+ * @pre polygon must be a Polygon
+ * @ingroup capi
+ */
+SFCGAL_API size_t sfcgal_polygon_num_interior_rings( const sfcgal_geometry_t* polygon );
+
+/**
+ * Returns the ith interior ring of a given Polygon
+ * @pre polygon must be a Polygon
+ * @pre i >= 0 and i < sfcgal_polygon_num_interior_rings
+ * @post the returned ring is a LineString, is not writable and must not be deallocated by the caller
+ * @ingroup capi
+ */
+SFCGAL_API const sfcgal_geometry_t* sfcgal_polygon_interior_ring_n( const sfcgal_geometry_t* polygon, size_t i );
+
+/**
+ * Adds an interior ring to a given Polygon
+ * @pre polygon must be a Polygon
+ * @pre ring must be a LineString
+ * @ingroup capi
+ */
+SFCGAL_API void sfcgal_polygon_add_interior_ring( sfcgal_geometry_t* polygon, sfcgal_geometry_t* ring );
+
+/**
+ * Creates an empty GeometryCollection
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_collection_create();
+
+/**
+ * Returns the number of geometries of a given GeometryCollection
+ * @pre collection is a GeometryCollection
+ * @ingroup capi
+ */
+SFCGAL_API size_t sfcgal_geometry_collection_num_geometries( const sfcgal_geometry_t* collection );
+
+/**
+ * Returns the ith geometry of a GeometryCollection
+ * @pre collection is a GeometryCollection
+ * @pre i >= 0 and i < sfcgal_geometry_collection_num_geometries
+ * @post the returned Geometry is not writable and must not be deallocated by the caller
+ * @ingroup capi
+ */
+SFCGAL_API const sfcgal_geometry_t* sfcgal_geometry_collection_geometry_n( const sfcgal_geometry_t* collection , size_t i );
+
+/**
+ * Adds a Geometry to a given GeometryCollection
+ * @pre collection must be a GeometryCollection
+ * @post the ownership of the given geometry is taken. The caller is not responsible anymore of its deallocation
+ * @ingroup capi
+ */
+SFCGAL_API void sfcgal_geometry_collection_add_geometry( sfcgal_geometry_t* collection, sfcgal_geometry_t* geometry );
+
+/**
+ * Creates an empty MultiPoint
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_multi_point_create();
+
+/**
+ * Creates an empty MultiLineString
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_multi_linestring_create();
+
+/**
+ * Creates an empty MultiPolygon
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_multi_polygon_create();
+
+/**
+ * Creates an empty PolyhedralSurface
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_polyhedral_surface_create();
+
+/**
+ * Returns the number of polygons of a given PolyhedralSurface
+ * @pre polyhedral must be a PolyhedralSurface
+ * @ingroup capi
+ */
+SFCGAL_API size_t sfcgal_polyhedral_surface_num_polygons( const sfcgal_geometry_t* polyhedral );
+
+/**
+ * Returns the ith polygon of a given PolyhedralSurface
+ * @pre polyhedral must be a PolyhedralSurface
+ * @pre i >= 0 and i < sfcgal_polyhedral_surface_num_polygons(polyhedral)
+ * @post the returned Polygon is not writable and must not be deallocated by the caller
+ * @ingroup capi
+ */
+SFCGAL_API const sfcgal_geometry_t* sfcgal_polyhedral_surface_polygon_n( const sfcgal_geometry_t* polyhedral, size_t i );
+
+/**
+ * Adds a Polygon to a given PolyhedralSurface
+ * @pre polyhedral must be a PolyhedralSurface
+ * @pre polygon must be a Polygon
+ * @post the ownership of the Polygon is taken. The caller is not responsible anymore of its deallocation
+ * @ingroup capi
+ */
+SFCGAL_API void sfcgal_polyhedral_surface_add_polygon( sfcgal_geometry_t* polyhedral, sfcgal_geometry_t* polygon );
+
+/**
+ * Creates an empty TriangulatedSurface
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_triangulated_surface_create();
+
+/**
+ * Returns the number of triangles of a given TriangulatedSurface
+ * @pre tin must be a TriangulatedSurface
+ * @ingroup capi
+ */
+SFCGAL_API size_t sfcgal_triangulated_surface_num_triangles( const sfcgal_geometry_t* tin );
+
+/**
+ * Returns the ith Triangle of a given TriangulatedSurface
+ * @pre tin must be a TriangulatedSurface
+ * @pre i >= 0 and i < sfcgal_triangulated_surface_num_triangles( tin )
+ * @post the returned Triangle is not writable and must not be deallocated by the caller
+ * @ingroup capi
+ */
+SFCGAL_API const sfcgal_geometry_t* sfcgal_triangulated_surface_triangle_n( const sfcgal_geometry_t* tin, size_t i );
+
+/**
+ * Adds a Triangle to a given TriangulatedSurface
+ * @pre tin must be a TriangulatedSurface
+ * @pre triangle must be a Triangle
+ * @post the ownership of the Triangle is taken. The caller is not responsible anymore of its deallocation
+ * @ingroup capi
+ */
+SFCGAL_API void sfcgal_triangulated_surface_add_triangle( sfcgal_geometry_t* tin, sfcgal_geometry_t* triangle );
+
+/**
+ * Creates an empty Solid
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_solid_create();
+
+/**
+ * Creates a Solid from an exterior shell
+ * @pre ring must be a PolyhedralSurface
+ * @post the ownership of the given shell is taken. The caller is not responsible anymore of its deallocation
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_solid_create_from_exterior_shell( sfcgal_geometry_t* shell );
+
+/**
+ * Returns the number of shells of a given Solid
+ * @pre solid must be a Solid
+ * @ingroup capi
+ */
+SFCGAL_API size_t sfcgal_solid_num_shells( const sfcgal_geometry_t* solid );
+
+/**
+ * Returns the ith shell of a given Solid
+ * @pre solid must be a Solid
+ * @pre i >= 0 and i < sfcgal_solid_num_shells( tin )
+ * @post the returned PolyhedralSurface is not writable and must not be deallocated by the caller
+ * @ingroup capi
+ */
+SFCGAL_API const sfcgal_geometry_t* sfcgal_solid_shell_n( const sfcgal_geometry_t* solid, size_t i );
+
+/**
+ * Adds a shell to a given Solid
+ * @pre solid must be a Solid
+ * @pre shell must be a PolyhedralSurface
+ * @post the ownership of the shell is taken. The caller is not responsible anymore of its deallocation
+ * @ingroup capi
+ */
+SFCGAL_API void sfcgal_solid_add_shell( sfcgal_geometry_t* solid, sfcgal_geometry_t* shell );
+
+
+/*--------------------------------------------------------------------------------------*
+ *
+ * Support for SFCGAL::PreparedGeometry
+ *
+ *--------------------------------------------------------------------------------------*/
+
+/**
+ * Opaque type that represents the C++ type SFCGAL::PreparedGeometry
+ * @ingroup capi
+ */
+typedef void sfcgal_prepared_geometry_t;
+
+typedef uint32_t srid_t;
+
+/**
+ * Creates an empty PreparedGeometry
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_prepared_geometry_t* sfcgal_prepared_geometry_create();
+
+/**
+ * Creates a PreparedGeometry from a Geometry and an SRID
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_prepared_geometry_t* sfcgal_prepared_geometry_create_from_geometry( sfcgal_geometry_t* geometry, srid_t srid );
+
+/**
+ * Deletes a given PreparedGeometry
+ * @pre prepared must be a PreparedGeometry
+ * @post the underlying Geometry linked to the given PreparedGeometry is also deleted
+ * @ingroup capi
+ */
+SFCGAL_API void sfcgal_prepared_geometry_delete( sfcgal_prepared_geometry_t* prepared );
+
+/**
+ * Returns the Geometry associated with a given PreparedGeometry
+ * @pre prepared must be a PreparedGeometry
+ * @post the returned Geometry is not writable and must not be deallocated by the caller
+ * @ingroup capi
+ */
+SFCGAL_API const sfcgal_geometry_t* sfcgal_prepared_geometry_geometry( const sfcgal_prepared_geometry_t* prepared );
+
+/**
+ * Sets the Geometry associated with the given PreparedGeometry
+ * @pre prepared must be a PreparedGeometry
+ * @post the ownership of the given geometry is taken. The caller is not responsible anymore of its deallocation
+ * @ingroup capi
+ */
+SFCGAL_API void sfcgal_prepared_geometry_set_geometry( sfcgal_prepared_geometry_t* prepared, sfcgal_geometry_t* geometry );
+
+/**
+ * Returns SRID associated with a given PreparedGeometry
+ * @pre prepared must be a PreparedGeometry
+ * @ingroup capi
+ */
+SFCGAL_API srid_t sfcgal_prepared_geometry_srid( const sfcgal_prepared_geometry_t* prepared );
+
+/**
+ * Sets SRID associated with a given PreparedGeometry
+ * @pre prepared must be a PreparedGeometry
+ * @ingroup capi
+ */
+SFCGAL_API void sfcgal_prepared_geometry_set_srid( sfcgal_prepared_geometry_t* prepared, srid_t );
+
+/**
+ * Returns an EWKT representation of the given PreparedGeometry
+ * @param num_decimals number of decimals. -2 for a variable number of decimals. -1 for an exact representation
+ * @post buffer is returned allocated and must be freed by the caller
+ * @ingroup capi
+ */
+SFCGAL_API void sfcgal_prepared_geometry_as_ewkt( const sfcgal_prepared_geometry_t* prepared, int num_decimals, char** buffer, size_t* len );
+
+/*--------------------------------------------------------------------------------------*
+ *
+ * I/O functions
+ *
+ *--------------------------------------------------------------------------------------*/
+
+/**
+ * io::readWKT
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_io_read_wkt( const char*, size_t len );
+SFCGAL_API sfcgal_prepared_geometry_t* sfcgal_io_read_ewkt( const char*, size_t len );
+
+/**
+ * Serialization
+ */
+/* allocates into char**, must be freed by the caller */
+SFCGAL_API void sfcgal_io_write_binary_prepared( const sfcgal_prepared_geometry_t*, char**, size_t* );
+SFCGAL_API sfcgal_prepared_geometry_t* sfcgal_io_read_binary_prepared( const char*, size_t l );
+
+/*--------------------------------------------------------------------------------------*
+ *
+ * Spatial processing
+ *
+ *--------------------------------------------------------------------------------------*/
+
+/**
+ * Tests the intersection of geom1 and geom2
+ * @pre isValid(geom1) == true
+ * @pre isValid(geom2) == true
+ * @ingroup capi
+ */
+SFCGAL_API int sfcgal_geometry_intersects( const sfcgal_geometry_t* geom1, const sfcgal_geometry_t* geom2 );
+
+/**
+ * Tests the 3D intersection of geom1 and geom2
+ * @pre isValid(geom1) == true
+ * @pre isValid(geom2) == true
+ * @ingroup capi
+ */
+SFCGAL_API int sfcgal_geometry_intersects_3d( const sfcgal_geometry_t* geom1, const sfcgal_geometry_t* geom2 );
+
+/**
+ * Returns the intersection of geom1 and geom2
+ * @pre isValid(geom1) == true
+ * @pre isValid(geom2) == true
+ * @post isValid(return) == true
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_intersection( const sfcgal_geometry_t* geom1, const sfcgal_geometry_t* geom2 );
+
+/**
+ * Returns the 3D intersection of geom1 and geom2
+ * @pre isValid(geom1) == true
+ * @pre isValid(geom2) == true
+ * @post isValid(return) == true
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_intersection_3d( const sfcgal_geometry_t* geom1, const sfcgal_geometry_t* geom2 );
+
+/**
+ * Returns the difference of geom1 and geom2
+ * @pre isValid(geom1) == true
+ * @pre isValid(geom2) == true
+ * @post isValid(return) == true
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_difference( const sfcgal_geometry_t* geom1, const sfcgal_geometry_t* geom2 );
+
+/**
+ * Returns the 3D difference of geom1 and geom2
+ * @pre isValid(geom1) == true
+ * @pre isValid(geom2) == true
+ * @post isValid(return) == true
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_difference_3d( const sfcgal_geometry_t* geom1, const sfcgal_geometry_t* geom2 );
+
+/**
+ * Returns the union of geom1 and geom2
+ * @pre isValid(geom1) == true
+ * @pre isValid(geom2) == true
+ * @post isValid(return) == true
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_union( const sfcgal_geometry_t* geom1, const sfcgal_geometry_t* geom2 );
+
+/**
+ * Returns the 3D union of geom1 and geom2
+ * @pre isValid(geom1) == true
+ * @pre isValid(geom2) == true
+ * @post isValid(return) == true
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_union_3d( const sfcgal_geometry_t* geom1, const sfcgal_geometry_t* geom2 );
+
+/**
+ * Returns the convex hull of geom
+ * @pre isValid(geom) == true
+ * @post isValid(return) == true
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_convexhull( const sfcgal_geometry_t* geom );
+
+/**
+ * Returns the 3D convex hull of geom
+ * @pre isValid(geom) == true
+ * @post isValid(return) == true
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_convexhull_3d( const sfcgal_geometry_t* geom );
+
+/**
+ * Returns the volume of geom (must be a volume)
+ * @pre isValid(geom) == true
+ * @ingroup capi
+ */
+SFCGAL_API double sfcgal_geometry_volume( const sfcgal_geometry_t* geom );
+
+/**
+ * Returns the area of geom
+ * @pre isValid(geom) == true
+ * @ingroup capi
+ */
+SFCGAL_API double sfcgal_geometry_area( const sfcgal_geometry_t* geom );
+
+/**
+ * Returns the 3D area of geom
+ * @pre isValid(geom) == true
+ * @ingroup capi
+ */
+SFCGAL_API double sfcgal_geometry_area_3d( const sfcgal_geometry_t* geom );
+
+/**
+ * Tests if the given Geometry is planar
+ * @pre isValid(geom) == true
+ * @ingroup capi
+ */
+SFCGAL_API int sfcgal_geometry_is_planar( const sfcgal_geometry_t* geom );
+
+/**
+ * Returns the orientation of the given Polygon
+ * -1 for a counter clockwise orientation
+ * 1 for a clockwise orientation
+ * 0 for an invalid or undetermined orientation
+ * @pre geom is a Polygon
+ * @pre isValid(geom) == true
+ * @ingroup capi
+ */
+SFCGAL_API int sfcgal_geometry_orientation( const sfcgal_geometry_t* geom );
+
+/**
+ * Returns a tesselation of the given Geometry
+ * @pre isValid(geom) == true
+ * @post isValid(return) == true
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_tesselate( const sfcgal_geometry_t* geom );
+
+/**
+ * Returns a triangulation of the given Geometry
+ * @pre isValid(geom) == true
+ * @post isValid(return) == true
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_triangulate_2dz( const sfcgal_geometry_t* geom );
+
+/**
+ * Returns an extrusion of the given Geometry
+ * @pre isValid(geom) == true
+ * @post isValid(return) == true
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_extrude( const sfcgal_geometry_t* geom, double ex, double ey, double ez );
+
+/**
+ * Convert a PolyhedralSurface to a Solid
+ * @pre isValid(geom) == true
+ * @post isValid(return) == true
+ * @ingroup detail
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_make_solid( const sfcgal_geometry_t* geom );
+
+/**
+ * Force a Left Handed Rule on the given Geometry
+ * @pre isValid(geom) == true
+ * @post isValid(return) == true
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_force_lhr( const sfcgal_geometry_t* geom );
+
+/**
+ * Force a Right Handed Rule on the given Geometry
+ * @pre isValid(geom) == true
+ * @post isValid(return) == true
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_force_rhr( const sfcgal_geometry_t* geom );
+
+/**
+ * Computes the distance of the two given Geometry objects
+ * @pre isValid(geom1) == true
+ * @pre isValid(geom2) == true
+ * @ingroup capi
+ */
+SFCGAL_API double sfcgal_geometry_distance( const sfcgal_geometry_t* geom1, const sfcgal_geometry_t* geom2 );
+
+/**
+ * Computes the 3D distance of the two given Geometry objects
+ * @pre isValid(geom1) == true
+ * @pre isValid(geom2) == true
+ * @ingroup capi
+ */
+SFCGAL_API double sfcgal_geometry_distance_3d( const sfcgal_geometry_t* geom1, const sfcgal_geometry_t* geom2 );
+
+/**
+ * Round coordinates of the given Geometry
+ * @pre isValid(geom) == true
+ * @post isValid(return) == true
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_round( const sfcgal_geometry_t* geom, int r );
+
+/**
+ * Returns the minkowski sum geom1 + geom2
+ * @pre isValid(geom1) == true
+ * @pre isValid(geom2) == true
+ * @post isValid(return) == true
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_minkowski_sum( const sfcgal_geometry_t* geom1, const sfcgal_geometry_t* geom2 );
+
+/**
+ * Returns the offset polygon of the given Geometry.
+ * @pre isValid(geom) == true
+ * @post isValid(return) == true
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_offset_polygon( const sfcgal_geometry_t* geom, double radius );
+
+/**
+ * Returns the straight skeleton of the given Geometry
+ * @pre isValid(geom) == true
+ * @post isValid(return) == true
+ * @ingroup capi
+ */
+SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_straight_skeleton( const sfcgal_geometry_t* geom );
+
+/*--------------------------------------------------------------------------------------*
+ *
+ * Error handling
+ *
+ *--------------------------------------------------------------------------------------*/
+
+/**
+ * Warning and error handlers
+ * @ingroup capi
+ */
+typedef int ( *sfcgal_error_handler_t ) ( const char*, ... );
+
+/**
+ * Sets the error handlers. These callbacks are called on warning or error
+ * @param warning_handler is the printf-styled callback function that will be called when a function raises a warning.
+ * The default behaviour is to call printf.
+ * @param error_handler is the printf-style callback function that will be called when a function generates an error.
+ * The default behaviour is to call printf.
+ * @ingroup capi
+ */
+SFCGAL_API void sfcgal_set_error_handlers( sfcgal_error_handler_t warning_handler, sfcgal_error_handler_t error_handler );
+
+/*--------------------------------------------------------------------------------------*
+ *
+ * Memory allocation
+ *
+ *--------------------------------------------------------------------------------------*/
+
+typedef void* ( *sfcgal_alloc_handler_t ) ( size_t );
+typedef void ( *sfcgal_free_handler_t ) ( void* );
+
+/**
+ * Sets the error handlers. These callbacks are called on warning or error
+ * @param malloc_handler is the function to call for memory allocation. The default behaviour is to call malloc()
+ * @param free_handler is the function to call for memory deallocation. The default behaviour is to call free()
+ * @ingroup capi
+ */
+SFCGAL_API void sfcgal_set_alloc_handlers( sfcgal_alloc_handler_t malloc_handler, sfcgal_free_handler_t free_handler );
+
+/*--------------------------------------------------------------------------------------*
+ *
+ * Init
+ *
+ *--------------------------------------------------------------------------------------*/
+
+/**
+ * This function must be called before all the other one.
+ * @ingroup capi
+ */
+SFCGAL_API void sfcgal_init();
+
+/**
+ * Get version
+ * @ingroup capi
+ */
+SFCGAL_API const char* sfcgal_version();
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/config.h.cmake b/src/config.h.cmake
new file mode 100644
index 0000000..e2fa5e3
--- /dev/null
+++ b/src/config.h.cmake
@@ -0,0 +1,41 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _SFCGAL_CONFIG_H_
+#define _SFCGAL_CONFIG_H_
+
+#include <SFCGAL/export.h>
+
+/**
+ * indicates if GMP is available
+ */
+#cmakedefine SFCGAL_WITH_GMP
+/**
+ * indicates if MPFR is available
+ */
+#cmakedefine SFCGAL_WITH_MPFR
+
+
+/**
+ * indicates if OpenSceneGraph dependency is activated
+ */
+#cmakedefine SFCGAL_WITH_OSG
+
+#endif
+
diff --git a/src/detail/ComplexComparator.h b/src/detail/ComplexComparator.h
new file mode 100644
index 0000000..9a7a7ce
--- /dev/null
+++ b/src/detail/ComplexComparator.h
@@ -0,0 +1,46 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_DETAIL_COMPLEXCOMPARATOR_H_
+#define _SFCGAL_DETAIL_COMPLEXCOMPARATOR_H_
+
+#include <SFCGAL/config.h>
+
+#include <complex>
+
+namespace SFCGAL {
+namespace detail {
+
+/**
+ * lexicographic order on complex
+ */
+struct SFCGAL_API ComplexComparator {
+ template < typename T >
+ inline bool operator () ( const std::complex< T >& a, const std::complex< T >& b ) {
+ return ( a.real() < b.real() ) || ( a.real() == b.real() && a.imag() < b.imag() );
+ }
+};
+
+
+}//detail
+}//SFCGAL
+
+
+#endif
diff --git a/src/detail/EnvelopeVisitor.cpp b/src/detail/EnvelopeVisitor.cpp
new file mode 100644
index 0000000..3bd9c9a
--- /dev/null
+++ b/src/detail/EnvelopeVisitor.cpp
@@ -0,0 +1,172 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/EnvelopeVisitor.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+
+namespace SFCGAL {
+namespace detail {
+
+///
+///
+///
+EnvelopeVisitor::EnvelopeVisitor( Envelope& envelope_ ):
+ envelope( envelope_ )
+{
+
+}
+
+///
+///
+///
+void EnvelopeVisitor::visit( const Point& g )
+{
+ envelope.expandToInclude( g.coordinate() );
+}
+
+
+///
+///
+///
+void EnvelopeVisitor::visit( const LineString& g )
+{
+ for ( size_t i = 0; i < g.numPoints(); i++ ) {
+ visit( g.pointN( i ) );
+ }
+}
+
+///
+///
+///
+void EnvelopeVisitor::visit( const Polygon& g )
+{
+ for ( size_t i = 0; i < g.numRings(); i++ ) {
+ visit( g.ringN( i ) );
+ }
+}
+
+///
+///
+///
+void EnvelopeVisitor::visit( const Triangle& g )
+{
+ for ( size_t i = 0; i < 3; i++ ) {
+ visit( g.vertex( i ) );
+ }
+}
+
+
+///
+///
+///
+void EnvelopeVisitor::visit( const Solid& g )
+{
+ for ( size_t i = 0; i < g.numShells(); i++ ) {
+ visit( g.shellN( i ) );
+ }
+}
+
+///
+///
+///
+void EnvelopeVisitor::visit( const MultiPoint& g )
+{
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ visit( g.pointN( i ) );
+ }
+}
+
+///
+///
+///
+void EnvelopeVisitor::visit( const MultiLineString& g )
+{
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ visit( g.lineStringN( i ) );
+ }
+}
+
+///
+///
+///
+void EnvelopeVisitor::visit( const MultiPolygon& g )
+{
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ visit( g.polygonN( i ) );
+ }
+}
+
+///
+///
+///
+void EnvelopeVisitor::visit( const MultiSolid& g )
+{
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ visit( g.solidN( i ) );
+ }
+}
+
+///
+///
+///
+void EnvelopeVisitor::visit( const GeometryCollection& g )
+{
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ g.geometryN( i ).accept( *this );
+ }
+}
+
+///
+///
+///
+void EnvelopeVisitor::visit( const PolyhedralSurface& g )
+{
+ for ( size_t i = 0; i < g.numPolygons(); i++ ) {
+ visit( g.polygonN( i ) );
+ }
+}
+
+///
+///
+///
+void EnvelopeVisitor::visit( const TriangulatedSurface& g )
+{
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ visit( g.geometryN( i ) );
+ }
+}
+
+
+}//detail
+}//SFCGAL
+
diff --git a/src/detail/EnvelopeVisitor.h b/src/detail/EnvelopeVisitor.h
new file mode 100644
index 0000000..7b3d308
--- /dev/null
+++ b/src/detail/EnvelopeVisitor.h
@@ -0,0 +1,63 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_DETAIL_ENVELOPEVISITOR_H_
+#define _SFCGAL_DETAIL_ENVELOPEVISITOR_H_
+
+#include <SFCGAL/config.h>
+#include <SFCGAL/Envelope.h>
+#include <SFCGAL/GeometryVisitor.h>
+
+#include <vector>
+
+namespace SFCGAL {
+namespace detail {
+
+/**
+ * Get the list of points from a Geometry
+ *
+ * @todo ConstPointVisitor
+ */
+class SFCGAL_API EnvelopeVisitor : public ConstGeometryVisitor {
+public:
+ EnvelopeVisitor( Envelope& envelope_ );
+
+ virtual void visit( const Point& g ) ;
+ virtual void visit( const LineString& g ) ;
+ virtual void visit( const Polygon& g ) ;
+ virtual void visit( const Triangle& g ) ;
+ virtual void visit( const Solid& g ) ;
+ virtual void visit( const MultiPoint& g ) ;
+ virtual void visit( const MultiLineString& g ) ;
+ virtual void visit( const MultiPolygon& g ) ;
+ virtual void visit( const MultiSolid& g ) ;
+ virtual void visit( const GeometryCollection& g ) ;
+ virtual void visit( const PolyhedralSurface& g ) ;
+ virtual void visit( const TriangulatedSurface& g ) ;
+public:
+ Envelope& envelope ;
+};
+
+
+}//detail
+}//SFCGAL
+
+
+#endif
diff --git a/src/detail/GeometrySet.cpp b/src/detail/GeometrySet.cpp
new file mode 100644
index 0000000..5947bfc
--- /dev/null
+++ b/src/detail/GeometrySet.cpp
@@ -0,0 +1,1070 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <SFCGAL/detail/GeometrySet.h>
+
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/Envelope.h>
+#include <SFCGAL/detail/TypeForDimension.h>
+
+#include <SFCGAL/algorithm/covers.h>
+#include <SFCGAL/algorithm/volume.h>
+#include <SFCGAL/algorithm/connection.h>
+
+#include <CGAL/Bbox_3.h>
+#include <CGAL/IO/Polyhedron_iostream.h>
+
+#include <boost/graph/adjacency_list.hpp>
+
+#include <map>
+
+bool operator< ( const CGAL::Segment_2<SFCGAL::Kernel>& sega, const CGAL::Segment_2<SFCGAL::Kernel>& segb )
+{
+ if ( sega.source() == segb.source() ) {
+ return sega.target() < segb.target();
+ }
+
+ return sega.source() < segb.source();
+}
+
+bool operator< ( const CGAL::Segment_3<SFCGAL::Kernel>& sega, const CGAL::Segment_3<SFCGAL::Kernel>& segb )
+{
+ if ( sega.source() == segb.source() ) {
+ return sega.target() < segb.target();
+ }
+
+ return sega.source() < segb.source();
+}
+
+namespace SFCGAL {
+namespace detail {
+
+void _decompose_triangle( const Triangle& tri, GeometrySet<2>::SurfaceCollection& surfaces, dim_t<2> )
+{
+ CGAL::Polygon_2<Kernel> outer;
+ outer.push_back( tri.vertex( 0 ).toPoint_2() );
+ outer.push_back( tri.vertex( 1 ).toPoint_2() );
+ outer.push_back( tri.vertex( 2 ).toPoint_2() );
+
+ if ( outer.orientation() == CGAL::CLOCKWISE ) {
+ outer.reverse_orientation();
+ }
+
+ surfaces.push_back( CGAL::Polygon_with_holes_2<Kernel>( outer ) );
+}
+void _decompose_triangle( const Triangle& tri, GeometrySet<3>::SurfaceCollection& surfaces, dim_t<3> )
+{
+ CGAL::Triangle_3<Kernel> outtri( tri.vertex( 0 ).toPoint_3(),
+ tri.vertex( 1 ).toPoint_3(),
+ tri.vertex( 2 ).toPoint_3() );
+ surfaces.push_back( outtri );
+}
+
+void _decompose_polygon( const Polygon& poly, GeometrySet<2>::SurfaceCollection& surfaces, dim_t<2> )
+{
+ BOOST_ASSERT( ! poly.isEmpty() );
+ surfaces.push_back( poly.toPolygon_with_holes_2() );
+}
+void _decompose_polygon( const Polygon& poly, GeometrySet<3>::SurfaceCollection& surfaces, dim_t<3> )
+{
+ BOOST_ASSERT( ! poly.isEmpty() );
+ TriangulatedSurface surf;
+ triangulate::triangulatePolygon3D( poly, surf );
+
+ for ( size_t i = 0; i < surf.numTriangles(); ++i ) {
+ const Triangle& tri = surf.triangleN( i );
+ surfaces.push_back( CGAL::Triangle_3<Kernel>( tri.vertex( 0 ).toPoint_3(),
+ tri.vertex( 1 ).toPoint_3(),
+ tri.vertex( 2 ).toPoint_3() )
+ );
+ }
+}
+
+void _decompose_solid( const Solid&, GeometrySet<2>::VolumeCollection&, dim_t<2> )
+{
+}
+void _decompose_solid( const Solid& solid, GeometrySet<3>::VolumeCollection& volumes, dim_t<3> )
+{
+ BOOST_ASSERT( ! solid.isEmpty() );
+ // volume orientation test
+ // TODO: simplfiy ?
+ MarkedPolyhedron p = *solid.exteriorShell().toPolyhedron_3<Kernel, MarkedPolyhedron >();
+
+ if ( algorithm::volume( solid ) < 0 ) {
+ // if the volume is "inverted", we reverse it
+ // TODO: Once every boolean operations work with complement geometries, we may want to keep the solid inverted
+ p.inside_out();
+ }
+
+ volumes.push_back( p );
+}
+
+template <int Dim>
+GeometrySet<Dim>::GeometrySet( )
+{
+}
+
+template <int Dim>
+GeometrySet<Dim>::GeometrySet( const Geometry& g )
+{
+ _decompose( g );
+}
+
+template <int Dim>
+GeometrySet<Dim>::GeometrySet( const typename TypeForDimension<Dim>::Point& g, int /*flags*/ )
+{
+ addPrimitive( g );
+}
+
+template <int Dim>
+GeometrySet<Dim>::GeometrySet( const typename TypeForDimension<Dim>::Segment& g, int /*flags*/ )
+{
+ addPrimitive( g );
+}
+
+template <int Dim>
+GeometrySet<Dim>::GeometrySet( const typename TypeForDimension<Dim>::Surface& g, int /*flags*/ )
+{
+ addPrimitive( g );
+}
+
+template <int Dim>
+GeometrySet<Dim>::GeometrySet( const typename TypeForDimension<Dim>::Volume& g, int /*flags*/ )
+{
+ addPrimitive( g );
+}
+
+template <int Dim>
+void GeometrySet<Dim>::merge( const GeometrySet<Dim>& g )
+{
+ std::copy( g.points().begin(), g.points().end(), std::inserter( points(), points().end() ) );
+ std::copy( g.segments().begin(), g.segments().end(), std::inserter( segments(), segments().end() ) );
+ std::copy( g.surfaces().begin(), g.surfaces().end(), std::back_inserter( surfaces() ) );
+ std::copy( g.volumes().begin(), g.volumes().end(), std::back_inserter( volumes() ) );
+}
+
+template <int Dim>
+void GeometrySet<Dim>::addGeometry( const Geometry& g )
+{
+ _decompose( g );
+}
+
+template <>
+void GeometrySet<2>::addPrimitive( const PrimitiveHandle<2>& p )
+{
+ switch ( p.handle.which() ) {
+ case PrimitivePoint:
+ _points.insert( *boost::get<const TypeForDimension<2>::Point*>( p.handle ) );
+ break;
+
+ case PrimitiveSegment:
+ _segments.insert( *boost::get<const TypeForDimension<2>::Segment*>( p.handle ) );
+ break;
+
+ case PrimitiveSurface:
+ _surfaces.push_back( *boost::get<const TypeForDimension<2>::Surface*>( p.handle ) );
+ break;
+
+ default:
+ break;
+ }
+}
+
+template <>
+void GeometrySet<3>::addPrimitive( const PrimitiveHandle<3>& p )
+{
+ switch ( p.handle.which() ) {
+ case PrimitivePoint:
+ _points.insert( *boost::get<const TypeForDimension<3>::Point*>( p.handle ) );
+ break;
+
+ case PrimitiveSegment:
+ _segments.insert( *boost::get<const TypeForDimension<3>::Segment*>( p.handle ) );
+ break;
+
+ case PrimitiveSurface:
+ _surfaces.push_back( *boost::get<const TypeForDimension<3>::Surface*>( p.handle ) );
+ break;
+
+ case PrimitiveVolume: {
+ const TypeForDimension<3>::Volume& vol = *boost::get<const TypeForDimension<3>::Volume*>( p.handle );
+ BOOST_ASSERT( !vol.empty() );
+ _volumes.push_back( vol );
+ break;
+ }
+ }
+}
+
+template <>
+void GeometrySet<3>::addPrimitive( const CGAL::Object& o, bool pointsAsRing )
+{
+ typedef TypeForDimension<3>::Point TPoint;
+ typedef TypeForDimension<3>::Segment TSegment;
+ typedef TypeForDimension<3>::Surface TSurface;
+ typedef TypeForDimension<3>::Volume TVolume;
+
+ if ( const TPoint* p = CGAL::object_cast<TPoint>( &o ) ) {
+ _points.insert( TPoint( *p ) );
+ }
+ else if ( const std::vector<TPoint>* pts = CGAL::object_cast<std::vector<TPoint> >( &o ) ) {
+ if ( pointsAsRing ) {
+ // if pointsAsRing is true, build a polygon out of points
+ // FIXME : we use triangulation here, which is not needed
+ // We should have created a (planar) Polyhedron directly out of the points
+ LineString ls;
+
+ for ( size_t i = 0; i < pts->size(); ++i ) {
+ ls.addPoint( ( *pts )[i] );
+ }
+
+ // close the ring
+ ls.addPoint( ( *pts )[0] );
+ Polygon poly( ls );
+ _decompose_polygon( poly, _surfaces, dim_t<3>() );
+ }
+ else {
+ std::copy( pts->begin(), pts->end(), std::inserter( _points, _points.end() ) );
+ }
+ }
+ else if ( const TSegment* p = CGAL::object_cast<TSegment>( &o ) ) {
+ _segments.insert( TSegment( *p ) );
+ }
+ else if ( const TSurface* p = CGAL::object_cast<TSurface>( &o ) ) {
+ _surfaces.push_back( TSurface( *p ) );
+ }
+ else if ( const TVolume* p = CGAL::object_cast<TVolume>( &o ) ) {
+ BOOST_ASSERT( ! p->empty() );
+ _volumes.push_back( TVolume( *p ) );
+ }
+}
+
+template <>
+void GeometrySet<2>::addPrimitive( const CGAL::Object& o, bool pointsAsRing )
+{
+ typedef TypeForDimension<2>::Point TPoint;
+ typedef TypeForDimension<2>::Segment TSegment;
+ typedef TypeForDimension<2>::Surface TSurface;
+ typedef TypeForDimension<2>::Volume TVolume;
+
+ if ( const TPoint* p = CGAL::object_cast<TPoint>( &o ) ) {
+ _points.insert( TPoint( *p ) );
+ }
+ else if ( const std::vector<TPoint>* pts = CGAL::object_cast<std::vector<TPoint> >( &o ) ) {
+ if ( pointsAsRing ) {
+ // if pointsAsRing is true, build a polygon out of points
+ CGAL::Polygon_2<Kernel> poly;
+
+ for ( size_t i = 0; i < pts->size(); ++i ) {
+ poly.push_back( ( *pts )[i] );
+ }
+
+ CGAL::Polygon_with_holes_2<Kernel> polyh( poly );
+ _surfaces.push_back( polyh );
+ }
+ else {
+ std::copy( pts->begin(), pts->end(), std::inserter( _points, _points.end() ) );
+ }
+ }
+ else if ( const CGAL::Triangle_2<Kernel>* tri = CGAL::object_cast<CGAL::Triangle_2<Kernel> >( &o ) ) {
+ // convert to a polygon
+ CGAL::Polygon_2<Kernel> poly;
+ poly.push_back( tri->vertex( 0 ) );
+ poly.push_back( tri->vertex( 1 ) );
+ poly.push_back( tri->vertex( 2 ) );
+ CGAL::Polygon_with_holes_2<Kernel> polyh( poly );
+ _surfaces.push_back( polyh );
+ }
+ else if ( const TSegment* p = CGAL::object_cast<TSegment>( &o ) ) {
+ _segments.insert( TSegment( *p ) );
+ }
+ else if ( const TSurface* p = CGAL::object_cast<TSurface>( &o ) ) {
+ BOOST_ASSERT( ! p->is_unbounded() );
+ _surfaces.push_back( TSurface( *p ) );
+ }
+ else if ( const TVolume* p = CGAL::object_cast<TVolume>( &o ) ) {
+ _volumes.push_back( TVolume( *p ) );
+ }
+}
+
+template <int Dim>
+void GeometrySet<Dim>::addPrimitive( const typename TypeForDimension<Dim>::Point& p, int flags )
+{
+ _points.insert( CollectionElement<typename Point_d<Dim>::Type>( p, flags ) );
+}
+
+template <int Dim>
+void GeometrySet<Dim>::addPrimitive( const typename TypeForDimension<Dim>::Segment& p, int flags )
+{
+ _segments.insert( CollectionElement<typename Segment_d<Dim>::Type>( p, flags ) );
+}
+
+template <>
+void GeometrySet<2>::addPrimitive( const TypeForDimension<2>::Surface& p, int flags )
+{
+ BOOST_ASSERT( ! p.is_unbounded() );
+ _surfaces.push_back( p );
+ _surfaces.back().setFlags( flags );
+}
+template <>
+void GeometrySet<3>::addPrimitive( const TypeForDimension<3>::Surface& p, int flags )
+{
+ _surfaces.push_back( p );
+ _surfaces.back().setFlags( flags );
+}
+
+template <>
+void GeometrySet<2>::addPrimitive( const TypeForDimension<2>::Volume&, int )
+{
+}
+
+template <>
+void GeometrySet<3>::addPrimitive( const TypeForDimension<3>::Volume& p, int flags )
+{
+ BOOST_ASSERT( ! p.empty() );
+
+ if ( p.is_closed() ) {
+ _volumes.push_back( GeometrySet<3>::VolumeCollection::value_type( p, flags ) );
+ }
+ else {
+ // it is an unclosed volume, i.e. a surface
+ BOOST_ASSERT( p.is_pure_triangle() );
+ CGAL::Point_3<Kernel> p1, p2, p3;
+
+ for ( MarkedPolyhedron::Facet_const_iterator fit = p.facets_begin();
+ fit != p.facets_end();
+ ++fit ) {
+ MarkedPolyhedron::Halfedge_around_facet_const_circulator cit = fit->facet_begin();
+ p1 = cit->vertex()->point();
+ cit++;
+ p2 = cit->vertex()->point();
+ cit++;
+ p3 = cit->vertex()->point();
+ CGAL::Triangle_3<Kernel> tri( p1, p2, p3 );
+ _surfaces.push_back( tri );
+ }
+ }
+}
+
+template <int Dim>
+bool GeometrySet<Dim>::hasPoints() const
+{
+ return ! points().empty();
+}
+
+template <int Dim>
+bool GeometrySet<Dim>::hasSegments() const
+{
+ return ! segments().empty();
+}
+
+template <>
+bool GeometrySet<2>::hasSurfaces() const
+{
+ return ! surfaces().empty();
+}
+template <>
+bool GeometrySet<3>::hasSurfaces() const
+{
+ if ( ! surfaces().empty() ) {
+ return true;
+ }
+
+ if ( ! volumes().empty() ) {
+ for ( VolumeCollection::const_iterator it = _volumes.begin(); it != _volumes.end(); ++it ) {
+ if ( ! it->primitive().is_closed() ) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+template <>
+bool GeometrySet<2>::hasVolumes() const
+{
+ return false;
+}
+template <>
+bool GeometrySet<3>::hasVolumes() const
+{
+ if ( ! volumes().empty() ) {
+ return true;
+ }
+
+ if ( ! volumes().empty() ) {
+ for ( VolumeCollection::const_iterator it = _volumes.begin(); it != _volumes.end(); ++it ) {
+ if ( it->primitive().is_closed() ) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+template <int Dim>
+void GeometrySet<Dim>::_decompose( const Geometry& g )
+{
+ if ( g.isEmpty() ) {
+ return;
+ }
+
+ if ( g.is<GeometryCollection>() ) {
+ const GeometryCollection& collect = g.as<GeometryCollection>();
+
+ for ( size_t i = 0; i < g.numGeometries(); ++i ) {
+ _decompose( collect.geometryN( i ) );
+ }
+
+ return;
+ }
+
+ switch ( g.geometryTypeId() ) {
+ case TYPE_POINT:
+ _points.insert( g.as<Point>().toPoint_d<Dim>() );
+ break;
+
+ case TYPE_LINESTRING: {
+ const LineString& ls = g.as<LineString>();
+
+ for ( size_t i = 0; i < ls.numPoints() - 1; ++i ) {
+ typename TypeForDimension<Dim>::Segment seg( ls.pointN( i ).toPoint_d<Dim>(),
+ ls.pointN( i+1 ).toPoint_d<Dim>() );
+ _segments.insert( seg );
+ }
+
+ break;
+ }
+
+ case TYPE_TRIANGLE: {
+ _decompose_triangle( g.as<Triangle>(), _surfaces, dim_t<Dim>() );
+ break;
+ }
+
+ case TYPE_POLYGON: {
+ _decompose_polygon( g.as<Polygon>(), _surfaces, dim_t<Dim>() );
+ break;
+ }
+
+ case TYPE_TRIANGULATEDSURFACE: {
+ const TriangulatedSurface& tri = g.as<TriangulatedSurface>();
+
+ for ( size_t i = 0; i < tri.numTriangles(); ++i ) {
+ _decompose( tri.triangleN( i ) );
+ }
+
+ break;
+ }
+
+ case TYPE_POLYHEDRALSURFACE: {
+ const PolyhedralSurface& tri = g.as<PolyhedralSurface>();
+
+ for ( size_t i = 0; i < tri.numPolygons(); ++i ) {
+ _decompose( tri.polygonN( i ) );
+ }
+
+ break;
+ }
+
+ case TYPE_SOLID: {
+ const Solid& solid = g.as<Solid>();
+ _decompose_solid( solid, _volumes, dim_t<Dim>() );
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+
+template <int Dim>
+void GeometrySet<Dim>::computeBoundingBoxes( typename HandleCollection<Dim>::Type& handles,
+ typename BoxCollection<Dim>::Type& boxes ) const
+{
+ boxes.clear();
+
+ for ( typename PointCollection::const_iterator it = _points.begin(); it != _points.end(); ++it ) {
+ const typename TypeForDimension<Dim>::Point* pt = &( it->primitive() );
+ PrimitiveHandle<Dim> h( pt );
+ handles.push_back( h );
+ boxes.push_back( typename PrimitiveBox<Dim>::Type( it->primitive().bbox(), &handles.back() ) );
+ }
+
+ for ( typename SegmentCollection::const_iterator it = _segments.begin(); it != _segments.end(); ++it ) {
+ handles.push_back( PrimitiveHandle<Dim>( &( it->primitive() ) ) );
+ boxes.push_back( typename PrimitiveBox<Dim>::Type( it->primitive().bbox(), &handles.back() ) );
+ }
+
+ for ( typename SurfaceCollection::const_iterator it = _surfaces.begin(); it != _surfaces.end(); ++it ) {
+ handles.push_back( PrimitiveHandle<Dim>( &( it->primitive() ) ) );
+ boxes.push_back( typename PrimitiveBox<Dim>::Type( it->primitive().bbox(), &handles.back() ) );
+ }
+
+ for ( typename VolumeCollection::const_iterator it = _volumes.begin(); it != _volumes.end(); ++it ) {
+ handles.push_back( PrimitiveHandle<Dim>( &( it->primitive() ) ) );
+ boxes.push_back( typename PrimitiveBox<Dim>::Type( compute_solid_bbox( it->primitive(), dim_t<Dim>() ),
+ &handles.back() ) );
+ }
+}
+
+template <int Dim>
+void recompose_points( const typename GeometrySet<Dim>::PointCollection& points,
+ std::vector<Geometry*>& rpoints,
+ dim_t<Dim> )
+{
+ if ( points.empty() ) {
+ return;
+ // rpoints.push_back( new Point() );
+ }
+ else {
+ for ( typename GeometrySet<Dim>::PointCollection::const_iterator it = points.begin();
+ it != points.end();
+ ++it ) {
+ rpoints.push_back( new Point( it->primitive() ) );
+ }
+ }
+}
+
+// compare less than
+struct ComparePoints {
+ bool operator()( const CGAL::Point_2<Kernel>& lhs, const CGAL::Point_2<Kernel>& rhs ) {
+ return lhs.x() < rhs.x() || lhs.y() < rhs.y();
+ }
+ bool operator()( const CGAL::Point_3<Kernel>& lhs, const CGAL::Point_3<Kernel>& rhs ) {
+ return lhs.x() < rhs.x() || lhs.y() < rhs.y() || lhs.z() < rhs.z();
+ }
+};
+
+
+template <int Dim>
+void recompose_segments( const typename GeometrySet<Dim>::SegmentCollection& segments,
+ std::vector<Geometry*>& lines,
+ dim_t<Dim> )
+{
+ if ( segments.empty() ) {
+ // lines.push_back( new LineString );
+ return;
+ }
+
+ // what we need is a graph, we do a depth first traversal and stop a linestring
+ // when more than one segment is connected
+ // first we need to label vertices
+ // then build the graph and traverse depth first
+ std::vector<Point> points;
+ typedef std::pair<int,int> Edge;
+ std::vector<Edge> edges;
+ {
+ typedef typename std::map< typename TypeForDimension<Dim>::Point, int, ComparePoints > PointMap;
+ PointMap pointMap;
+
+ for ( typename GeometrySet<Dim>::SegmentCollection::const_iterator it = segments.begin();
+ it != segments.end();
+ ++it ) {
+ const typename PointMap::const_iterator foundSource = pointMap.find( it->primitive().source() );
+ const typename PointMap::const_iterator foundTarget = pointMap.find( it->primitive().target() );
+ const int sourceId = foundSource != pointMap.end() ? foundSource->second : points.size();
+
+ if ( foundSource == pointMap.end() ) {
+ points.push_back( it->primitive().source() );
+ pointMap[ it->primitive().source() ] = sourceId;
+ }
+
+ const int targetId = foundTarget != pointMap.end() ? foundTarget->second : points.size();
+
+ if ( foundTarget == pointMap.end() ) {
+ points.push_back( it->primitive().target() );
+ pointMap[ it->primitive().target() ] = targetId;
+ }
+
+ edges.push_back( Edge( sourceId, targetId ) );
+ }
+ }
+
+ typedef boost::adjacency_list< boost::vecS, boost::vecS, boost::bidirectionalS,
+ boost::no_property,
+ boost::property<boost::edge_color_t, boost::default_color_type> > Graph;
+ Graph g( edges.begin(), edges.end(), edges.size() );
+
+ // now we find all branches without bifurcations,
+
+ boost::graph_traits<Graph>::edge_iterator ei, ei_end;
+
+ for ( boost::tie( ei, ei_end ) = boost::edges( g ); ei != ei_end; ++ei ) {
+ if ( boost::get( boost::edge_color, g )[*ei] == boost::white_color ) {
+ // not already marked, find the first ancestor with multiple connections, or no connections
+ // or self (in case of a loop)
+ boost::graph_traits<Graph>::edge_descriptor root = *ei;
+ {
+ boost::graph_traits<Graph>::in_edge_iterator ej, ek;
+
+ for ( boost::tie( ej, ek ) = boost::in_edges( boost::source( root, g ), g );
+ ek - ej == 1 && *ej != *ei ;
+ boost::tie( ej, ek ) = boost::in_edges( boost::source( root, g ), g ) ) {
+ root = *ej;
+ }
+ }
+
+ // now we go down
+ LineString* line = new LineString;
+ lines.push_back( line );
+ line->addPoint( points[ boost::source( root, g ) ] );
+ line->addPoint( points[ boost::target( root, g ) ] );
+ boost::get( boost::edge_color, g )[root] = boost::black_color;
+
+ boost::graph_traits<Graph>::out_edge_iterator ej, ek;
+
+ for ( boost::tie( ej, ek ) = boost::out_edges( boost::target( root, g ), g );
+ ek - ej == 1 && *ej != root;
+ boost::tie( ej, ek ) = boost::out_edges( boost::target( *ej, g ), g ) ) {
+ line->addPoint( points[ boost::target( *ej, g ) ] );
+ boost::get( boost::edge_color, g )[*ej] = boost::black_color;
+ }
+ }
+ }
+}
+
+void recompose_surfaces( const GeometrySet<2>::SurfaceCollection& surfaces, std::vector<Geometry*>& output, dim_t<2> )
+{
+ for ( GeometrySet<2>::SurfaceCollection::const_iterator it = surfaces.begin(); it != surfaces.end(); ++it ) {
+ if ( it->primitive().holes_begin() == it->primitive().holes_end() &&
+ it->primitive().outer_boundary().size() == 3 ) {
+ CGAL::Polygon_2<Kernel>::Vertex_iterator vit = it->primitive().outer_boundary().vertices_begin();
+ CGAL::Point_2<Kernel> p1( *vit++ );
+ CGAL::Point_2<Kernel> p2( *vit++ );
+ CGAL::Point_2<Kernel> p3( *vit++ );
+ output.push_back( new Triangle( CGAL::Triangle_2<Kernel>( p1, p2, p3 ) ) );
+ }
+ else {
+ output.push_back( new Polygon( it->primitive() ) );
+ }
+ }
+}
+
+void recompose_surfaces( const GeometrySet<3>::SurfaceCollection& surfaces, std::vector<Geometry*>& output, dim_t<3> )
+{
+ if ( surfaces.empty() ) {
+ return;
+ }
+
+ // TODO : regroup triangles of the same mesh
+ if ( surfaces.size() == 1 ) {
+ output.push_back( new Triangle( surfaces.begin()->primitive() ) );
+ return;
+ }
+
+
+ std::auto_ptr<TriangulatedSurface> tri( new TriangulatedSurface );
+
+ for ( GeometrySet<3>::SurfaceCollection::const_iterator it = surfaces.begin(); it != surfaces.end(); ++it ) {
+ tri->addTriangle( new Triangle( it->primitive() ) );
+ }
+
+ algorithm::SurfaceGraph graph( *tri );
+ std::vector< size_t > component( boost::num_vertices( graph.faceGraph() ) );
+ BOOST_ASSERT( tri->numTriangles() == component.size() );
+ const size_t numComponents = boost::connected_components( graph.faceGraph(), &component[0] );
+
+ if ( 1 == numComponents ) {
+ output.push_back( tri.release() );
+ }
+ else {
+ std::vector< TriangulatedSurface* > sout( numComponents );
+
+ for ( unsigned c = 0; c < numComponents; c++ ) {
+ sout[c] = new TriangulatedSurface;
+ output.push_back( sout[c] );
+ }
+
+ const size_t numTriangles = tri->numTriangles() ;
+
+ for ( size_t t = 0; t != numTriangles; ++t ) {
+ sout[ component[t] ]->addTriangle( tri->triangleN( t ) );
+ }
+ }
+}
+
+void recompose_volumes( const GeometrySet<2>::VolumeCollection&, std::vector<Geometry*>&, dim_t<2> )
+{
+}
+
+void recompose_volumes( const GeometrySet<3>::VolumeCollection& volumes, std::vector<Geometry*>& output, dim_t<3> )
+{
+ if ( volumes.empty() ) {
+ return;
+ }
+
+ for ( GeometrySet<3>::VolumeCollection::const_iterator vit = volumes.begin(); vit != volumes.end(); ++vit ) {
+ if ( vit->flags() & FLAG_IS_PLANAR ) {
+ // extract the boundary
+ std::list<CGAL::Point_3<Kernel> > boundary;
+
+ for ( MarkedPolyhedron::Halfedge_const_iterator it = vit->primitive().halfedges_begin();
+ it != vit->primitive().halfedges_end();
+ ++it ) {
+ if ( !it->is_border() ) {
+ continue;
+ }
+
+ CGAL::Point_3<Kernel> p1 = it->prev()->vertex()->point();
+ CGAL::Point_3<Kernel> p2 = it->vertex()->point();
+
+ // TODO: test for colinearity
+ // Temporary vertice may have been introduced during triangulations
+ // and since we expect here a planar surface, it is safe to simplify the boundary
+ // by eliminating collinear points.
+ if ( boundary.size() == 0 ) {
+ boundary.push_back( p1 );
+ boundary.push_back( p2 );
+ }
+ else if ( boundary.back() == p1 ) {
+ boundary.push_back( p2 );
+ }
+ else if ( boundary.front() == p2 ) {
+ boundary.push_front( p1 );
+ }
+ }
+
+ if ( boundary.size() == 3 ) {
+ // It is a triangle
+
+ Point p[3];
+ std::list<CGAL::Point_3<Kernel> >::const_iterator it = boundary.begin();
+
+ for ( size_t i = 0; i < 3; ++i, ++it ) {
+ p[i] = *it;
+ }
+
+ output.push_back( new Triangle( p[0], p[1], p[2] ) );
+ }
+ else {
+ // Else it is a polygon
+ LineString* ls = new LineString;
+
+ for ( std::list<CGAL::Point_3<Kernel> >::const_iterator it = boundary.begin(); it != boundary.end(); ++it ) {
+ ls->addPoint( *it );
+ }
+
+ output.push_back( new Polygon( ls ) );
+ }
+ }
+ else {
+
+ PolyhedralSurface* shell = new PolyhedralSurface( vit->primitive() );
+ // TODO: test open / closed
+ output.push_back( new Solid( shell ) );
+ }
+ }
+}
+
+template <int Dim>
+std::auto_ptr<Geometry> GeometrySet<Dim>::recompose() const
+{
+ std::vector<Geometry*> geometries;
+
+ recompose_points( _points, geometries, dim_t<Dim>() );
+ recompose_segments( _segments, geometries, dim_t<Dim>() );
+ recompose_surfaces( _surfaces, geometries, dim_t<Dim>() );
+ recompose_volumes( _volumes, geometries, dim_t<Dim>() );
+
+ if ( geometries.empty() ) {
+ return std::auto_ptr<Geometry>( new GeometryCollection );
+ }
+
+ if ( geometries.size() == 1 ) {
+ return std::auto_ptr<Geometry>( geometries[0] );
+ }
+
+ // else we have a mix of different types
+ bool hasCommonType = true;
+ int commonType = geometries[0]->geometryTypeId();
+
+ for ( size_t i = 0; i < geometries.size(); ++i ) {
+ if ( geometries[i]->geometryTypeId() != commonType ) {
+ hasCommonType = false;
+ break;
+ }
+ }
+
+ GeometryCollection* ret = 0;
+
+ if ( hasCommonType ) {
+ if ( commonType == TYPE_POINT ) {
+ ret = new MultiPoint;
+ }
+ else if ( commonType == TYPE_LINESTRING ) {
+ ret = new MultiLineString;
+ }
+ else if ( commonType == TYPE_POLYGON ) {
+ ret = new MultiPolygon;
+ }
+ else if ( commonType == TYPE_SOLID ) {
+ ret = new MultiSolid;
+ }
+ else {
+ // one common type, but no MULTI equivalent
+ ret = new GeometryCollection;
+ }
+ }
+ else {
+ ret = new GeometryCollection;
+ }
+
+ BOOST_ASSERT( ret != 0 );
+
+ for ( size_t i = 0; i < geometries.size(); ++i ) {
+ ret->addGeometry( geometries[i] );
+ }
+
+ return std::auto_ptr<Geometry>( ret );
+}
+
+void _collect_points( const CGAL::Polygon_with_holes_2<Kernel>& poly, GeometrySet<2>::PointCollection& points )
+{
+ for ( CGAL::Polygon_2<Kernel>::Vertex_iterator vit = poly.outer_boundary().vertices_begin();
+ vit != poly.outer_boundary().vertices_end();
+ ++vit ) {
+ points.insert( *vit );
+ }
+
+ for ( CGAL::Polygon_with_holes_2<Kernel>::Hole_const_iterator hit = poly.holes_begin();
+ hit != poly.holes_end();
+ ++hit ) {
+ for ( CGAL::Polygon_2<Kernel>::Vertex_iterator vit = hit->vertices_begin();
+ vit != hit->vertices_end();
+ ++vit ) {
+ points.insert( *vit );
+ }
+ }
+}
+
+void _collect_points( const CGAL::Triangle_3<Kernel>& tri, GeometrySet<3>::PointCollection& points )
+{
+ points.insert( tri.vertex( 0 ) );
+ points.insert( tri.vertex( 1 ) );
+ points.insert( tri.vertex( 2 ) );
+}
+
+void _collect_points( const NoVolume&, GeometrySet<2>::PointCollection& )
+{
+}
+
+void _collect_points( const MarkedPolyhedron& poly, GeometrySet<3>::PointCollection& points )
+{
+ for ( MarkedPolyhedron::Vertex_const_iterator vit = poly.vertices_begin();
+ vit != poly.vertices_end();
+ ++vit ) {
+ points.insert( vit->point() );
+ }
+}
+
+template <int Dim>
+void GeometrySet<Dim>::collectPoints( const PrimitiveHandle<Dim>& pa )
+{
+ typedef typename TypeForDimension<Dim>::Point TPoint;
+ typedef typename TypeForDimension<Dim>::Segment TSegment;
+ typedef typename TypeForDimension<Dim>::Surface TSurface;
+ typedef typename TypeForDimension<Dim>::Volume TVolume;
+
+ switch ( pa.handle.which() ) {
+ case PrimitivePoint: {
+ const TPoint* pt = boost::get<const TPoint*>( pa.handle );
+ _points.insert( *pt );
+ break;
+ }
+
+ case PrimitiveSegment: {
+ const TSegment* seg = boost::get<const TSegment*>( pa.handle );
+ _points.insert( seg->source() );
+ _points.insert( seg->target() );
+ break;
+ }
+
+ case PrimitiveSurface: {
+ _collect_points( *boost::get<const TSurface*>( pa.handle ), _points );
+ break;
+ }
+
+ case PrimitiveVolume: {
+ _collect_points( *boost::get<const TVolume*>( pa.handle ), _points );
+ break;
+ }
+ }
+}
+
+template <int Dim, class IT>
+void _filter_covered( IT ibegin, IT iend, GeometrySet<Dim>& output )
+{
+ for ( IT it = ibegin; it != iend; ++it ) {
+ GeometrySet<Dim> v1;
+ v1.addPrimitive( it->primitive() );
+ bool v1_covered = false;
+
+ for ( IT it2 = it; it2 != iend; ++it2 ) {
+ if ( it == it2 ) {
+ continue;
+ }
+
+ GeometrySet<Dim> v2;
+ v2.addPrimitive( it2->primitive() );
+
+ if ( algorithm::covers( v2, v1 ) ) {
+ v1_covered = true;
+ break;
+ }
+ }
+
+ // if its not covered by another primitive
+ if ( !v1_covered ) {
+ // and not covered by another already inserted primitive
+ bool b = algorithm::covers( output, v1 );
+
+ if ( !b ) {
+ output.addPrimitive( it->primitive(), it->flags() );
+ }
+ }
+ }
+}
+
+template <>
+void GeometrySet<2>::addBoundary( const TypeForDimension<2>::Surface& surface )
+{
+ addSegments( surface.outer_boundary().edges_begin(), surface.outer_boundary().edges_end() );
+
+ for ( CGAL::Polygon_with_holes_2<Kernel>::Hole_const_iterator hit = surface.holes_begin();
+ hit != surface.holes_end();
+ ++hit ) {
+ addSegments( hit->edges_begin(), hit->edges_end() );
+ }
+}
+
+template <>
+void GeometrySet<3>::addBoundary( const TypeForDimension<3>::Surface& )
+{
+ // TODO
+}
+
+
+template <>
+int GeometrySet<2>::dimension() const
+{
+ if ( ! surfaces().empty() ) {
+ return 2;
+ }
+
+ if ( ! segments().empty() ) {
+ return 1;
+ }
+
+ if ( ! points().empty() ) {
+ return 0;
+ }
+
+ return -1;
+}
+
+template <>
+int GeometrySet<3>::dimension() const
+{
+ if ( ! volumes().empty() ) {
+ for ( GeometrySet<3>::VolumeCollection::const_iterator it = volumes().begin();
+ it != volumes().end();
+ ++it ) {
+ if ( it->primitive().is_closed() ) {
+ return 3;
+ }
+ }
+
+ return 2;
+ }
+
+ if ( ! surfaces().empty() ) {
+ return 2;
+ }
+
+ if ( ! segments().empty() ) {
+ return 1;
+ }
+
+ if ( ! points().empty() ) {
+ return 0;
+ }
+
+ return -1;
+}
+
+template <int Dim>
+void GeometrySet<Dim>::filterCovered( GeometrySet<Dim>& output ) const
+{
+ _filter_covered( _volumes.begin(), _volumes.end(), output );
+ _filter_covered( _surfaces.begin(), _surfaces.end(), output );
+ _filter_covered( _segments.begin(), _segments.end(), output );
+ _filter_covered( _points.begin(), _points.end(), output );
+}
+
+std::ostream& operator<<( std::ostream& ostr, const GeometrySet<2>& g )
+{
+ ostr << "points: ";
+ std::ostream_iterator<CollectionElement<Point_d<2>::Type> > out_pt ( ostr,", " );
+ std::copy( g.points().begin(), g.points().end(), out_pt );
+ ostr << std::endl << "segments: ";
+ std::ostream_iterator<CollectionElement<Segment_d<2>::Type> > out_seg ( ostr,", " );
+ std::copy( g.segments().begin(), g.segments().end(), out_seg );
+ ostr << std::endl << "surfaces: ";
+ std::ostream_iterator<CollectionElement<Surface_d<2>::Type> > out_surf ( ostr,", " );
+ std::copy( g.surfaces().begin(), g.surfaces().end(), out_surf );
+ ostr << std::endl;
+ return ostr;
+}
+
+std::ostream& operator<<( std::ostream& ostr, const GeometrySet<3>& g )
+{
+ ostr << "points: ";
+ std::ostream_iterator<CollectionElement<Point_d<3>::Type> > out_pt ( ostr,", " );
+ std::copy( g.points().begin(), g.points().end(), out_pt );
+ ostr << std::endl << "segments: ";
+ std::ostream_iterator<CollectionElement<Segment_d<3>::Type> > out_seg ( ostr,", " );
+ std::copy( g.segments().begin(), g.segments().end(), out_seg );
+ ostr << std::endl << "surfaces: ";
+ std::ostream_iterator<CollectionElement<Surface_d<3>::Type> > out_surf ( ostr,", " );
+ std::copy( g.surfaces().begin(), g.surfaces().end(), out_surf );
+ ostr << std::endl << "volumes: ";
+ std::ostream_iterator<CollectionElement<Volume_d<3>::Type> > out_vol ( ostr,", " );
+ std::copy( g.volumes().begin(), g.volumes().end(), out_vol );
+ ostr << std::endl;
+ return ostr;
+}
+
+template class GeometrySet<2>;
+template class GeometrySet<3>;
+} // detail
+} // SFCGAL
diff --git a/src/detail/GeometrySet.h b/src/detail/GeometrySet.h
new file mode 100644
index 0000000..385bf33
--- /dev/null
+++ b/src/detail/GeometrySet.h
@@ -0,0 +1,376 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _SFCGAL_DETAIL_GEOMETRY_SET_H_
+#define _SFCGAL_DETAIL_GEOMETRY_SET_H_
+
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <boost/variant.hpp>
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/detail/TypeForDimension.h>
+
+#include <CGAL/Bbox_2.h>
+#include <CGAL/Bbox_3.h>
+#include <CGAL/Box_intersection_d/Box_with_handle_d.h>
+
+// comparison operator on segments, for use in a std::set
+bool operator< ( const CGAL::Segment_2<SFCGAL::Kernel>& sega, const CGAL::Segment_2<SFCGAL::Kernel>& segb );
+bool operator< ( const CGAL::Segment_3<SFCGAL::Kernel>& sega, const CGAL::Segment_3<SFCGAL::Kernel>& segb );
+
+namespace SFCGAL {
+class Geometry;
+namespace detail {
+
+///
+/// Primitive type enumeration. Note that the value is the dimension !
+enum PrimitiveType {
+ PrimitivePoint = 0,
+ PrimitiveSegment = 1,
+ PrimitiveSurface = 2,
+ PrimitiveVolume = 3
+};
+
+///
+/// Primitive handle. Holds a pointer to a primitive, through the 'handle' member
+template <int Dim>
+struct PrimitiveHandle {
+ //
+ // We use boost::variant here for convenience, whereas it is needed
+ typedef boost::variant< const typename Point_d<Dim>::Type*,
+ const typename Segment_d<Dim>::Type*,
+ const typename Surface_d<Dim>::Type*,
+ const typename Volume_d<Dim>::Type* > Type;
+ Type handle;
+
+ template <class T>
+ PrimitiveHandle( const T* p ) : handle( p ) {}
+
+ template <class T>
+ inline const T* as() const {
+ return boost::get<const T*>( handle );
+ }
+};
+
+///
+/// PrimitiveBox. Type used for CGAL::Box_intersection_d
+template <int Dim>
+struct PrimitiveBox {
+ typedef CGAL::Box_intersection_d::Box_with_handle_d<double, Dim, PrimitiveHandle<Dim>*> Type;
+};
+
+
+///
+/// BoxCollection for use with CGAL::Box_intersection_d
+template <int Dim>
+struct BoxCollection {
+ typedef std::vector<typename PrimitiveBox<Dim>::Type> Type;
+};
+
+///
+/// HandleCollection. Used to store PrimitiveHandle
+template <int Dim>
+struct HandleCollection {
+ typedef std::list<PrimitiveHandle<Dim> > Type;
+};
+
+///
+/// Flags available for each type of Geometry type.
+/// Primitives can be 'flagged' in order to speed up recomposition
+enum ElementFlag {
+ // the polyhedron is planar => build a triangle or a polygon
+ FLAG_IS_PLANAR = 1
+};
+
+///
+/// CollectionElement, a Primitive with flags
+/// Primitive : Point_d, Segment_d, Surface_d, Volume_d
+template <class Primitive>
+class CollectionElement {
+public:
+ int flags() const {
+ return _flags;
+ }
+ void setFlags( int flags ) {
+ _flags = flags;
+ }
+
+ Primitive& primitive() {
+ return _primitive;
+ }
+ const Primitive& primitive() const {
+ return _primitive;
+ }
+
+ // constructor from Primitive
+ CollectionElement() : _flags( 0 ) {}
+ CollectionElement( const Primitive& p ) : _primitive( p ), _flags( 0 ) {}
+ CollectionElement( const Primitive& p, int f ) : _primitive( p ), _flags( f ) {}
+
+ CollectionElement( const CollectionElement& other ) :
+ _primitive( other._primitive ),
+ _flags( other._flags ) {
+ }
+ bool operator< ( const CollectionElement& other ) const {
+ return _primitive < other._primitive;
+ }
+private:
+ Primitive _primitive;
+ int _flags;
+};
+
+template <class Primitive>
+std::ostream& operator<<( std::ostream& ostr, const CollectionElement<Primitive>& p )
+{
+ ostr << p.primitive() << " flags: " << p.flags();
+ return ostr;
+}
+
+///
+/// A GeometrySet represents a set of CGAL primitives.
+/// Primitive are either of dimension 0 (points),
+/// dimension 1 (segments), dimension 2 (surfaces, a.k.a. polygon or triangles)
+/// or dimension 3 (polyhedron)
+template <int Dim>
+class GeometrySet {
+public:
+ // Points are stored in an ordered set
+ typedef std::set<CollectionElement<typename Point_d<Dim>::Type> > PointCollection;
+ // Segments are stored in an ordered set
+ typedef std::set<CollectionElement<typename Segment_d<Dim>::Type> > SegmentCollection;
+ typedef std::list<CollectionElement<typename Surface_d<Dim>::Type> > SurfaceCollection;
+ typedef std::list<CollectionElement<typename Volume_d<Dim>::Type> > VolumeCollection;
+
+ GeometrySet();
+
+ /**
+ * Construct a GeometrySet from a SFCGAL::Geometry
+ */
+ GeometrySet( const Geometry& g );
+
+ /**
+ * Construct a GeometrySet from a Point
+ */
+ GeometrySet( const typename TypeForDimension<Dim>::Point& g, int flags = 0 );
+
+ /**
+ * Construct a GeometrySet from a Segment
+ */
+ GeometrySet( const typename TypeForDimension<Dim>::Segment& g, int flags = 0 );
+
+ /**
+ * Construct a GeometrySet from a Surface
+ */
+ GeometrySet( const typename TypeForDimension<Dim>::Surface& g, int flags = 0 );
+
+ /**
+ * Construct a GeometrySet from a Volume
+ */
+ GeometrySet( const typename TypeForDimension<Dim>::Volume& g, int flags = 0 );
+
+ /**
+ * Add primitives from another set
+ */
+ void merge( const GeometrySet<Dim>& g );
+
+ /**
+ * Add a geometry by decomposing it into CGAL primitives
+ */
+ void addGeometry( const Geometry& g );
+
+ /**
+ * add a primitive from a PrimitiveHandle to the set
+ */
+ void addPrimitive( const PrimitiveHandle<Dim>& p );
+
+ /**
+ * add a primitive from a CGAL::Object to the set
+ * pointsAsRing : if set to true, build a polygon if o is a vector of points
+ */
+ void addPrimitive( const CGAL::Object& o, bool pointsAsRing = false );
+
+ /**
+ * add a point to the set
+ */
+ void addPrimitive( const typename TypeForDimension<Dim>::Point& g, int flags = 0 );
+ template <class IT>
+ void addPoints( IT ibegin, IT iend ) {
+ std::copy( ibegin, iend, std::inserter( _points, _points.end() ) );
+ }
+
+ /**
+ * collect all points of b and add them to the point list
+ */
+ void collectPoints( const PrimitiveHandle<Dim>& b );
+
+ /**
+ * add a segment to the set
+ */
+ void addPrimitive( const typename TypeForDimension<Dim>::Segment& g, int flags = 0 );
+ template <class IT>
+ void addSegments( IT ibegin, IT iend ) {
+ std::copy( ibegin, iend, std::inserter( _segments, _segments.end() ) );
+ }
+
+ /**
+ * add a surface to the set
+ */
+ void addPrimitive( const typename TypeForDimension<Dim>::Surface& g, int flags = 0 );
+ template <class IT>
+ void addSurfaces( IT ibegin, IT iend ) {
+ std::copy( ibegin, iend, std::back_inserter( _surfaces ) );
+ }
+
+ /**
+ * add a volume to the set
+ */
+ void addPrimitive( const typename TypeForDimension<Dim>::Volume& g, int flags = 0 );
+ template <class IT>
+ void addVolumes( IT ibegin, IT iend ) {
+ std::copy( ibegin, iend, std::back_inserter( _volumes ) );
+ }
+
+ /**
+ * Get the maximum geometry dimension of the set
+ * -1 : empty
+ * 0 : there are points
+ * 1 : there are segments
+ * 2 : there are surfaces
+ * 3 : there are volumes
+ */
+ int dimension() const;
+
+ /**
+ * Add the boundary (segments) of a surface
+ */
+ void addBoundary( const typename TypeForDimension<Dim>::Surface& surface );
+
+ /**
+ * Add the boundary (surfaces) of a volume
+ */
+ void addBoundary( const typename TypeForDimension<Dim>::Volume& volume );
+
+ /**
+ * Compute all bounding boxes and handles of the set
+ */
+ void computeBoundingBoxes( typename HandleCollection<Dim>::Type& handles, typename BoxCollection<Dim>::Type& boxes ) const;
+
+ inline PointCollection& points() {
+ return _points;
+ }
+ inline const PointCollection& points() const {
+ return _points;
+ }
+
+ inline SegmentCollection& segments() {
+ return _segments;
+ }
+ inline const SegmentCollection& segments() const {
+ return _segments;
+ }
+
+ inline SurfaceCollection& surfaces() {
+ return _surfaces;
+ }
+ inline const SurfaceCollection& surfaces() const {
+ return _surfaces;
+ }
+
+ inline VolumeCollection& volumes() {
+ return _volumes;
+ }
+ inline const VolumeCollection& volumes() const {
+ return _volumes;
+ }
+
+ /**
+ * Returns true if the set holds points
+ */
+ bool hasPoints() const;
+ /**
+ * Returns true if the set holds segments
+ */
+ bool hasSegments() const;
+ /**
+ * Returns true if the set holds surfaces
+ */
+ bool hasSurfaces() const;
+ /**
+ * Returns true if the set holds volumes
+ */
+ bool hasVolumes() const;
+
+ /**
+ * convert the set to a SFCGAL::Geometry
+ */
+ std::auto_ptr<Geometry> recompose() const;
+
+ /**
+ * Filter (remove) primitives that are already covered by others
+ */
+ void filterCovered( GeometrySet<Dim>& output ) const;
+
+private:
+ ///
+ /// Given an input SFCGAL::Geometry, decompose it into CGAL primitives
+ void _decompose( const Geometry& g );
+
+ PointCollection _points;
+ SegmentCollection _segments;
+ SurfaceCollection _surfaces;
+ VolumeCollection _volumes;
+};
+
+///
+/// Display operator
+SFCGAL_API std::ostream& operator<<( std::ostream&, const GeometrySet<2>& g );
+///
+/// Display operator
+SFCGAL_API std::ostream& operator<<( std::ostream&, const GeometrySet<3>& g );
+
+
+// bbox of a 'volume' for 2D, will never be called
+inline
+CGAL::Bbox_2 compute_solid_bbox( const NoVolume&, dim_t<2> )
+{
+ return CGAL::Bbox_2();
+}
+
+inline
+CGAL::Bbox_3 compute_solid_bbox( const TypeForDimension<3>::Volume& vol, dim_t<3> )
+{
+ BOOST_ASSERT( vol.size_of_vertices () );
+ MarkedPolyhedron::Point_const_iterator pit = vol.points_begin();
+ CGAL::Bbox_3 ret( pit->bbox() );
+ ++pit;
+
+ for ( ; pit != vol.points_end(); ++pit ) {
+ ret = ret + pit->bbox();
+ }
+
+ return ret;
+}
+} // namespace detail
+} // namespace SFCGAL
+
+#endif
diff --git a/src/detail/GetPointsVisitor.cpp b/src/detail/GetPointsVisitor.cpp
new file mode 100644
index 0000000..44ffb8a
--- /dev/null
+++ b/src/detail/GetPointsVisitor.cpp
@@ -0,0 +1,160 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/GetPointsVisitor.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+namespace SFCGAL {
+namespace detail {
+
+///
+///
+///
+void GetPointsVisitor::visit( const Point& g )
+{
+ points.push_back( &g );
+}
+
+///
+///
+///
+void GetPointsVisitor::visit( const LineString& g )
+{
+ for ( size_t i = 0; i < g.numPoints(); i++ ) {
+ visit( g.pointN( i ) );
+ }
+}
+
+///
+///
+///
+void GetPointsVisitor::visit( const Polygon& g )
+{
+ for ( size_t i = 0; i < g.numRings(); i++ ) {
+ visit( g.ringN( i ) );
+ }
+}
+
+///
+///
+///
+void GetPointsVisitor::visit( const Triangle& g )
+{
+ visit( g.vertex( 0 ) );
+ visit( g.vertex( 1 ) );
+ visit( g.vertex( 2 ) );
+}
+
+///
+///
+///
+void GetPointsVisitor::visit( const Solid& g )
+{
+ for ( size_t i = 0; i < g.numShells(); i++ ) {
+ visit( g.shellN( i ) );
+ }
+}
+
+///
+///
+///
+void GetPointsVisitor::visit( const MultiPoint& g )
+{
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ visit( g.pointN( i ) );
+ }
+}
+
+///
+///
+///
+void GetPointsVisitor::visit( const MultiLineString& g )
+{
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ visit( g.lineStringN( i ) );
+ }
+}
+
+///
+///
+///
+void GetPointsVisitor::visit( const MultiPolygon& g )
+{
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ visit( g.polygonN( i ) );
+ }
+}
+
+///
+///
+///
+void GetPointsVisitor::visit( const MultiSolid& g )
+{
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ visit( g.solidN( i ) );
+ }
+}
+
+///
+///
+///
+void GetPointsVisitor::visit( const GeometryCollection& g )
+{
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ g.geometryN( i ).accept( *this );
+ }
+}
+
+///
+///
+///
+void GetPointsVisitor::visit( const PolyhedralSurface& g )
+{
+ for ( size_t i = 0; i < g.numPolygons(); i++ ) {
+ visit( g.polygonN( i ) );
+ }
+}
+
+///
+///
+///
+void GetPointsVisitor::visit( const TriangulatedSurface& g )
+{
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ visit( g.geometryN( i ) );
+ }
+}
+
+
+
+}//detail
+}//SFCGAL
diff --git a/src/detail/GetPointsVisitor.h b/src/detail/GetPointsVisitor.h
new file mode 100644
index 0000000..7bfc322
--- /dev/null
+++ b/src/detail/GetPointsVisitor.h
@@ -0,0 +1,59 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_DETAIL_GETPOINTSVISITOR_H_
+#define _SFCGAL_DETAIL_GETPOINTSVISITOR_H_
+
+#include <SFCGAL/config.h>
+
+#include <vector>
+#include <SFCGAL/GeometryVisitor.h>
+
+namespace SFCGAL {
+namespace detail {
+
+/**
+ * Get the list of points from a Geometry
+ */
+class SFCGAL_API GetPointsVisitor : public ConstGeometryVisitor {
+public:
+ virtual void visit( const Point& g ) ;
+ virtual void visit( const LineString& g ) ;
+ virtual void visit( const Polygon& g ) ;
+ virtual void visit( const Triangle& g ) ;
+ virtual void visit( const Solid& g ) ;
+ virtual void visit( const MultiPoint& g ) ;
+ virtual void visit( const MultiLineString& g ) ;
+ virtual void visit( const MultiPolygon& g ) ;
+ virtual void visit( const MultiSolid& g ) ;
+ virtual void visit( const GeometryCollection& g ) ;
+ virtual void visit( const PolyhedralSurface& g ) ;
+ virtual void visit( const TriangulatedSurface& g ) ;
+public:
+ typedef std::vector< const Point* >::const_iterator const_iterator;
+ std::vector< const Point* > points ;
+};
+
+
+}//detail
+}//SFCGAL
+
+
+#endif
diff --git a/src/detail/Interval.cpp b/src/detail/Interval.cpp
new file mode 100644
index 0000000..02cf7cf
--- /dev/null
+++ b/src/detail/Interval.cpp
@@ -0,0 +1,192 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/Interval.h>
+#include <SFCGAL/numeric.h>
+
+#include <algorithm>
+
+
+namespace SFCGAL {
+namespace detail {
+
+///
+///
+///
+Interval::Interval():
+ _lower( NaN() ),
+ _upper( NaN() )
+{
+
+}
+
+///
+///
+///
+Interval::Interval( const double& value ):
+ _lower( value ),
+ _upper( value )
+{
+
+}
+
+///
+///
+///
+Interval::Interval( const double& v1, const double& v2 ):
+ _lower( std::min( v1,v2 ) ),
+ _upper( std::max( v1,v2 ) )
+{
+
+}
+
+
+///
+///
+///
+Interval::Interval( const Interval& other ):
+ _lower( other._lower ),
+ _upper( other._upper )
+{
+
+}
+
+
+///
+///
+///
+Interval& Interval::operator = ( const Interval& other )
+{
+ _lower = other._lower ;
+ _upper = other._upper ;
+ return *this ;
+}
+
+
+///
+///
+///
+Interval::~Interval()
+{
+
+}
+
+
+///
+///
+///
+bool Interval::isEmpty() const
+{
+ return isNaN( _lower ) || isNaN( _upper );
+}
+
+
+
+///
+///
+///
+void Interval::expandBy( const double& d )
+{
+ if ( isEmpty() ) {
+ return ;
+ }
+
+ _lower = _lower - d ;
+ _upper = _upper + d ;
+}
+
+///
+///
+///
+void Interval::expandToInclude( const Interval& other )
+{
+ //ignore empty interval
+ if ( other.isEmpty() ) {
+ return ;
+ }
+
+ if ( isEmpty() ) {
+ ( *this ) = other ;
+ }
+ else {
+ _lower = std::min( _lower, other._lower );
+ _upper = std::max( _upper, other._upper );
+ }
+}
+
+
+
+///
+///
+///
+void Interval::expandToInclude( const double& value )
+{
+ if ( isNaN( value ) ) {
+ return ;
+ }
+
+ if ( isEmpty() ) {
+ _lower = value ;
+ _upper = value ;
+ }
+ else {
+ _lower = std::min( _lower, value ) ;
+ _upper = std::max( _upper, value ) ;
+ }
+}
+
+///
+///
+///
+bool Interval::intersects( const Interval& other ) const
+{
+ //empty intervals never intersects
+ if ( isEmpty() || other.isEmpty() ) {
+ return false ;
+ }
+
+ return ! ( _lower > other._upper || _upper < other._lower ) ;
+}
+
+///
+///
+///
+bool Interval::operator == ( const Interval& other ) const
+{
+ if ( isEmpty() && other.isEmpty() ) {
+ return true ;
+ }
+
+ return _lower == other._lower && _upper == other._upper ;
+}
+
+///
+///
+///
+bool Interval::operator != ( const Interval& other ) const
+{
+ return ! ( ( *this ) == other );
+}
+
+
+
+}//detail
+}//SFCGAL
+
diff --git a/src/detail/Interval.h b/src/detail/Interval.h
new file mode 100644
index 0000000..f15de13
--- /dev/null
+++ b/src/detail/Interval.h
@@ -0,0 +1,129 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_DETAIL_INTERVAL_H_
+#define _SFCGAL_DETAIL_INTERVAL_H_
+
+#include <SFCGAL/config.h>
+
+namespace SFCGAL {
+namespace detail {
+
+/**
+ * Represents an interval
+ */
+class SFCGAL_API Interval {
+public:
+ /**
+ * default constructor (empty interval)
+ */
+ Interval() ;
+ /**
+ * collapsed interval constructor
+ */
+ Interval( const double& value ) ;
+ /**
+ * constructor with two values
+ */
+ Interval( const double& v1, const double& v2 ) ;
+ /**
+ * copy constructor
+ */
+ Interval( const Interval& other ) ;
+ /**
+ * assign operator
+ */
+ Interval& operator = ( const Interval& other ) ;
+ /**
+ * destructor
+ */
+ ~Interval() ;
+
+ /**
+ * indicates if the interval is empty
+ */
+ bool isEmpty() const ;
+
+
+ /**
+ * returns the lower value
+ */
+ inline const double& lower() const {
+ return _lower;
+ }
+ /**
+ * returns the upper value
+ */
+ inline const double& upper() const {
+ return _upper;
+ }
+ /**
+ * returns the with of the interval
+ */
+ inline double width() const {
+ return _upper - _lower ;
+ }
+
+ /**
+ * expand the interval
+ *
+ * @warning no effect if isEmpty()
+ */
+ void expandBy( const double& d ) ;
+ /**
+ * expand the interval to include an other interval.
+ *
+ * @warning no effect if other.isEmpty()
+ */
+ void expandToInclude( const Interval& other ) ;
+ /**
+ * expand the interval to include a value
+ *
+ * @warning no effect if value is NaN
+ */
+ void expandToInclude( const double& value ) ;
+
+
+ /**
+ * test if this intersects other
+ */
+ bool intersects( const Interval& other ) const ;
+
+
+ /**
+ * compare two intervals
+ * @warning true for empty intervals
+ */
+ bool operator == ( const Interval& other ) const ;
+ /**
+ * compare two intervals
+ * @warning false for empty intervals
+ */
+ bool operator != ( const Interval& other ) const ;
+
+private:
+ double _lower ;
+ double _upper ;
+};
+
+}//detail
+}//SFCGAL
+
+#endif
diff --git a/src/detail/TestGeometry.h b/src/detail/TestGeometry.h
new file mode 100644
index 0000000..6f12c76
--- /dev/null
+++ b/src/detail/TestGeometry.h
@@ -0,0 +1,250 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_TESTGEOMETRY_H_
+#define _SFCGAL_TESTGEOMETRY_H_
+
+namespace SFCGAL {
+
+struct TestGeometry {
+ const std::string wkt;
+ const bool isValid;
+ const std::string comment;
+};
+
+// include poly with touching holes that disconnect interior
+//
+
+inline
+const std::vector< TestGeometry > createTestGeometries()
+{
+ TestGeometry testGeometry[] = {
+ // Point2D
+ // valid
+ {"POINT EMPTY", true, ""},
+ {"POINT(-1.0 -1.0)", true, ""},
+ // Point3D
+ // valid
+ {"POINT(-1.0 -1.0 -1.0)", true, ""},
+ // Linestring2D
+ // valid
+ {"LINESTRING EMPTY", true , ""},
+ {"LINESTRING(-1.0 -1.0,1.0 1.0)", true , ""},
+ // invalid
+ {"LINESTRING(-1.0 -1.0,-1.0 -1.0)", false, "zero length"},
+ // Linestring3D
+ {"LINESTRING(-1.0 -1.0 -1.0,1.0 1.0 1.0)", true , ""},
+ {"LINESTRING(-1.0 -1.0 -1.0,-1.0 -1.0 -1.0)", false, "zero length"},
+ // Polygon2D
+ // valid
+ {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0))", true , ""},
+ {"POLYGON((0 0,10 0,10 0,10 10,0 10,0 0))", true, "duplicated point"},
+ {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,-0.5 0.5,0.5 0.5,0.5 -0.5,-0.5 -0.5))", true, "with interior ring"},
+ {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,-0.5 0.5,0.5 0.5,1.0 -0.5,-0.5 -0.5))", true, "one contact point between interior ans exterior"},
+ {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,-0.5 0.5,-0.1 0.5,-0.1 -0.5,-0.5 -0.5),(0.1 -0.5,0.1 0.5,0.5 0.5,0.5 -0.5,0.1 -0.5))", true, "with interior rings"},
+ {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,-0.5 0.5,-0.1 0.5,0.1 -0.5,-0.5 -0.5),(0.1 -0.5,0.1 0.5,0.5 0.5,0.5 -0.5,0.1 -0.5))", true, "one contact point between 2 interior rings"},
+ {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-.7 0,.7 0,0 -.7,-.7 0),(-.5 0,-.5 .5,0 .5,-.5 0),(.5 0,.1 .5,.5 .5,.5 0))", true, "3 touching interior ring define a connected interior"},
+ // invalid
+ {"POLYGON((-1.0 -1.0,-1.0 1.0,-1.0 -1.0))", false, "only 3 points"},
+ {"POLYGON((-1.0 -1.0,-1.0 1.0,1.0 1.0,-1.0 -1.0,-1.0 1.0))", false, "not closed"},
+ {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 -1.0,-1.0 -1.0,-1.0 -1.0))", false, "zero surface"},
+ {"POLYGON((-1.0 -1.0,2.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0))", false, "ring adjacency (spyke)"},
+ {"POLYGON((-1.0 -1.0,1.0 1.0,1.0 -1.0,-1.0 1.0,-1.0 -1.0))", false, "ring intersection"},
+ {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,-0.5 0.5,-0.5 -0.5))", false, "interior ring only 3 points"},
+ {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,0.5 -0.5,0.5 0.5,-0.5 0.5,-0.5 -0.5))", false, "interior ring counterclockwise"},
+ {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,-0.5 0.5,0.5 0.5,-0.5 -0.5,-0.5 0.5))", false, "interior ring not closed"},
+ {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,0.5 -0.5,0.5 -0.5,-0.5 -0.5,-0.5 -0.5))", false, "interior ring no surface"},
+ {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,0.7 -0.5,0.5 -0.5,0.5 0.5,-0.5 0.5,-0.5 -0.5))", false, "interior ring adjacency (spyke)"},
+ {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,0.5 0.5,0.5 -0.5,-0.5 0.5,-0.5 -0.5))", false, "interior ring intersection"},
+ {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,1.0 -0.5,1.0 0.5,-0.5 0.5,-0.5 -0.5))", false, "interior ring adjacent to exterior"},
+ {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,2.0 -0.5,2.0 0.5,-0.5 0.5,-0.5 -0.5))", false, "interior ring intersection with exterior"},
+ {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(1.5 -0.5,2.0 -0.5,2.0 0.5,1.5 0.5,1.5 -0.5))", false, "interior ring is ouside exterior"},
+ {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,0.0 -0.5,0.0 0.5,-0.5 0.5,-0.5 -0.5),(0.0 -0.5,0.5 -0.5,0.5 0.5,0.0 0.5,0.0 -0.5))", false, "adjacent interior rings"},
+ {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,0.2 -0.4,-0.1 0.5,-0.5 0.5,-0.5 -0.5),(0.1 -0.5,0.5 -0.5,0.5 0.5,0.1 0.5,0.1 -0.5))", false, "intersection between interior rings"},
+ {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,0.5 -0.5,0.5 0.5,-0.5 0.5,-0.5 -0.5),(-0.2 -0.2,0.2 -0.2,0.2 0.2,-0.2 0.2,-0.2 -0.2))", false, "one inetrior ring is inside the other"},
+ {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-.7 0,.7 0,0 -.7,-.7 0),(-.5 0,-.5 .5,0 .5,-.5 0),(.5 0,0 .5,.5 .5,.5 0))", false, "3 touching interior ring define an unconnected interior"},
+ // Polygon3D
+ // valid
+ {"POLYGON((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0))", true, ""},
+ {"POLYGON((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0),(1.0 -0.5 -0.5,1.0 -0.5 0.5,1.0 0.5 0.5,1.0 0.5 -0.5,1.0 -0.5 -0.5))", true, "with interior ring"},
+ {"POLYGON((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0),(1.0 -0.5 -0.5,1.0 -0.5 0.5,1.0 0.5 0.5,1.0 1.0 -0.5,1.0 -0.5 -0.5))", true, "one contact point between interior and exterior"},
+ {"POLYGON((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0),(1.0 -0.5 -0.5,1.0 -0.5 0.5,1.0 -0.1 0.5,1.0 -0.1 -0.5,1.0 -0.5 -0.5),(1.0 0.1 -0.5,1.0 0.1 0.5,1.0 0.5 0.5,1.0 0.5 -0.5,1.0 0.1 -0.5))", true, "two interior rings"},
+ {"POLYGON((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0),(1.0 -0.5 -0.5,1.0 -0.5 0.5,1.0 -0.1 0.5,1.0 0.1 -0.5,1.0 -0.5 -0.5),(1.0 0.1 -0.5,1.0 0.1 0.5,1.0 0.5 0.5,1.0 0.5 -0.5,1.0 0.1 -0.5))", true, "one contact point between 2 interior rings"},
+ // invalid
+ {"POLYGON((1.0 -1.0 -1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0))", false, "only 3 points"},
+ {"POLYGON((1.0 -1.0 -1.0,1.0 -1.0 1.0,1.0 1.0 1.0,1.0 -1.0 -1.0,1.0 -1.0 1.0))", false, "not closed"},
+ {"POLYGON((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 1.0 -1.0,1.0 -1.0 -1.0,1.0 -1.0 -1.0))", false, "zero surface"},
+ {"POLYGON((0.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0))", false, "non plane"},
+ {"POLYGON((1.0 -1.0 -1.0,1.0 2.0 -1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0))", false, "ring adjacency (spike)"},
+ {"POLYGON((1.0 -1.0 -1.0,1.0 1.0 1.0,1.0 1.0 -1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0))", false, "ring self intersection"},
+ {"POLYGON((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0),(1.0 -0.5 -0.5,1.0 -0.5 0.5,1.0 -0.5 -0.5))", false, "interior ring only 3 points"},
+ {"POLYGON((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0),(1.0 -0.5 -0.5,1.0 -0.5 0.5,1.0 0.5 0.5,1.0 -0.5 -0.5,1.0 -0.5 0.5))", false, "interior ring not closed"},
+ {"POLYGON((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0),(1.0 -0.5 -0.5,1.0 0.5 -0.5,1.0 0.5 -0.5,1.0 -0.5 -0.5,1.0 -0.5 -0.5))", false, "interior ring no surface"},
+ {"POLYGON((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0),(1.0 -0.5 -0.5,1.0 0.7 -0.5,1.0 0.5 -0.5,1.0 0.5 0.5,1.0 -0.5 0.5,1.0 -0.5 -0.5))", false, "interior ring adjacency (1.0 spyke)"},
+ {"POLYGON((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0),(1.0 -0.5 -0.5,1.0 0.5 0.5,1.0 0.5 -0.5,1.0 -0.5 0.5,1.0 -0.5 -0.5))", false, "interior ring intersection"},
+ {"POLYGON((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0),(1.0 -0.5 -0.5,1.0 1.0 -0.5,1.0 1.0 0.5,1.0 -0.5 0.5,1.0 -0.5 -0.5))", false, "interior ring adjacent to exterior"},
+ {"POLYGON((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0),(1.0 -0.5 -0.5,1.0 2.0 -0.5,1.0 2.0 0.5,1.0 -0.5 0.5,1.0 -0.5 -0.5))", false, "interior ring intersection with exterior"},
+ {"POLYGON((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0),(1.0 1.5 -0.5,1.0 2.0 -0.5,1.0 2.0 0.5,1.0 1.5 0.5,1.0 1.5 -0.5))", false, "interior ring is ouside exterior"},
+ {"POLYGON((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0),(1.0 -0.5 -0.5,1.0 0.0 -0.5,1.0 0.0 0.5,1.0 -0.5 0.5,1.0 -0.5 -0.5),(1.0 0.0 -0.5,1.0 0.5 -0.5,1.0 0.5 0.5,1.0 0.0 0.5,1.0 0.0 -0.5))", false, "adjacent interior rings"},
+ {"POLYGON((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0),(1.0 -0.5 -0.5,1.0 0.2 -0.4,1.0 -0.1 0.5,1.0 -0.5 0.5,1.0 -0.5 -0.5),(1.0 0.1 -0.5,1.0 0.5 -0.5,1.0 0.5 0.5,1.0 0.1 0.5,1.0 0.1 -0.5))", false, "intersection between interior rings"},
+ {"POLYGON((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0),(1.0 -0.5 -0.5,1.0 0.5 -0.5,1.0 0.5 0.5,1.0 -0.5 0.5,1.0 -0.5 -0.5),(1.0 -0.2 -0.2,1.0 0.2 -0.2,1.0 0.2 0.2,1.0 -0.2 0.2,1.0 -0.2 -0.2))", false, "one inetrior ring is inside the other"},
+ // Multipoint2D
+ // valid
+ {"MULTIPOINT(EMPTY,EMPTY)", true, ""},
+ {"MULTIPOINT((-1.0 -1.0),EMPTY)", true, ""},
+ {"MULTIPOINT((-1.0 -1.0),(1.0 1.0))", true, ""},
+ // Multipoint3D
+ // valid
+ {"MULTIPOINT((-1.0 -1.0 -1),(1.0 1.0 1.0))", true, ""},
+ // MultiLinestring2D
+ // valid
+ {"MULTILINESTRING(EMPTY,EMPTY)", true, ""},
+ {"MULTILINESTRING((-1.0 -1.0,1.0 1.0),EMPTY)", true, ""},
+ {"MULTILINESTRING((-1.0 -1.0,1.0 1.0),(1.0 1.0,1.0 -1.0))", true, ""},
+ // invalid
+ {"MULTILINESTRING((-1.0 -1.0,1.0 1.0),(1.0 1.0,1.0 1.0))", false, "second linestring has zero length"},
+ // MultiLinestring3D
+ // valid
+ {"MULTILINESTRING(EMPTY,EMPTY)", true, ""},
+ {"MULTILINESTRING((1.0 -1.0 -1.0,1.0 1.0 1.0),EMPTY)", true, ""},
+ {"MULTILINESTRING((1.0 -1.0 -1.0,1.0 1.0 1.0),(1.0 1.0 1.0,1.0 1.0 -1.0))", true, ""},
+ {"MULTILINESTRING((1.0 -1.0 -1.0,1.0 1.0 1.0),(1.0 1.0 1.0,1.0 1.0 -1.0))", true, ""},
+ // invalid
+ {"MULTILINESTRING((1.0 -1.0 -1.0,1.0 1.0 1.0),(1.0 1.0 1.0,1.0 1.0 1.0))", false, "the second linestring has length zero"},
+ // MultiPolygon2D
+ // valid
+ {"MULTIPOLYGON(EMPTY,EMPTY)", true, ""},
+ {"MULTIPOLYGON(((-3.0 -1.0,-1.0 -1.0,-1.0 1.0,-3.0 1.0,-3.0 -1.0)),EMPTY)", true, ""},
+ {"MULTIPOLYGON(((-3.0 -1.0,-1.0 -1.0,-1.0 1.0,-3.0 1.0,-3.0 -1.0)),((1.0 -1.0,3.0 -1.0,3.0 1.0,1.0 1.0,1.0 -1.0)))", true, ""},
+ {"MULTIPOLYGON(((-3.0 -1.0,1.0 -1.0,-1.0 1.0,-3.0 1.0,-3.0 -1.0)),((1.0 -1.0,3.0 -1.0,3.0 1.0,1.0 1.0,1.0 -1.0)))", true, "one contact point"},
+ // invalid
+ {"MULTIPOLYGON(((-3.0 -1.0,-1.0 -1.0,-1.0 1.0,-3.0 1.0,-3.0 -1.0)),((1.0 -1.0,3.0 -1.0,3.0 1.0,1.0 1.0)))", false, "second polygon is invalid"},
+ {"MULTIPOLYGON(((-2.0 -1.0,0.0 -1.0,0.0 1.0,-2.0 1.0,-2.0 -1.0)),((0.0 -1.0,2.0 -1.0,2.0 1.0,0.0 1.0,0.0 -1.0)))", false, "adjacent"},
+ {"MULTIPOLYGON(((-3.0 -1.0,1.3 0.0,-1.0 1.0,-3.0 1.0,-3.0 -1.0)),((1.0 -1.0,3.0 -1.0,3.0 1.0,1.0 1.0,1.0 -1.0)))", false, "intersection"},
+ // MultiPolygon3D
+ // valid
+ {"MULTIPOLYGON(EMPTY,EMPTY)", true, ""},
+ {"MULTIPOLYGON(((1.0 -3.0 -1.0,1.0 -1.0 -1.0,1.0 -1.0 1.0,1.0 -3.0 1.0,1.0 -3.0 -1.0)),EMPTY)", true, ""},
+ {"MULTIPOLYGON(((1.0 -3.0 -1.0,1.0 -1.0 -1.0,1.0 -1.0 1.0,1.0 -3.0 1.0,1.0 -3.0 -1.0)),((1.0 1.0 -1.0,1.0 3.0 -1.0,1.0 3.0 1.0,1.0 1.0 1.0,1.0 1.0 -1.0)))", true, ""},
+ {"MULTIPOLYGON(((1.0 -3.0 -1.0,1.0 1.0 -1.0,1.0 -1.0 1.0,1.0 -3.0 1.0,1.0 -3.0 -1.0)),((1.0 1.0 -1.0,1.0 3.0 -1.0,1.0 3.0 1.0,1.0 1.0 1.0,1.0 1.0 -1.0)))", true, "one contact point"},
+ // invalid
+ {"MULTIPOLYGON(((1.0 -3.0 -1.0,1.0 -1.0 -1.0,1.0 -1.0 1.0,1.0 -3.0 1.0,1.0 -3.0 -1.0)),((1.0 1.0 -1.0,1.0 3.0 -1.0,1.0 3.0 1.0,1.0 1.0 1.0)))", false, "second polygon is invalid"},
+ {"MULTIPOLYGON(((1.0 -2.0 -1.0,1.0 0.0 -1.0,1.0 0.0 1.0,1.0 -2.0 1.0,1.0 -2.0 -1.0)),((1.0 0.0 -1.0,1.0 2.0 -1.0,1.0 2.0 1.0,1.0 0.0 1.0,1.0 0.0 -1.0)))", false, "adjacent"},
+ {"MULTIPOLYGON(((1.0 -3.0 -1.0,1.0 1.3 0.0,1.0 -1.0 1.0,1.0 -3.0 1.0,1.0 -3.0 -1.0)),((1.0 1.0 -1.0,1.0 3.0 -1.0,1.0 3.0 1.0,1.0 1.0 1.0,1.0 1.0 -1.0)))", false, "intersection"},
+ // Triangle2D
+ // valid
+ {"TRIANGLE((-1.0 -1.0,1.0 -1.0,-1.0 1.0,-1.0 -1.0))", true, ""},
+ // invalid
+ {"TRIANGLE((-1.0 -1.0,1.0 -1.0,-1.0 -1.0))", false, "only 3 points"},
+ {"TRIANGLE((-1.0 -1.0,1.0 -1.0,-1.0 -1.0,-1.0 -1.0))", false, "zero surface"},
+ // Triangle3D
+ // valid
+ {"TRIANGLE((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0))", true, ""},
+ // invalid
+ {"TRIANGLE((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 -1.0 -1.0))", false, "only 3 points"},
+ {"TRIANGLE((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 -1.0 -1.0,1.0 -1.0 -1.0))", false, "zero surface"},
+ // TIN2D
+ // valid
+ {"TIN(((-1.0 -1.0,1.0 -1.0,-1.0 1.0,-1.0 -1.0)),((-1.0 1.0,1.0 -1.0,1.0 1.0,-1.0 1.0)))", true, ""},
+ // invalid
+ {"TIN(((-1.0 -1.0,1.0 -1.0,-1.0 1.0,-1.0 -1.0)),((-1.0 1.0,1.0 -1.0,-1.0 1.0)))", false, "second triangle is invalid"},
+ {"TIN(((-1.0 -1.0,1.0 -1.0,-1.0 1.0,-1.0 -1.0)),((1.0 -1.0,-1.0 1.0,1.0 1.0,1.0 -1.0)))", false, "inconsitent orientation"},
+ {"TIN(((-1.0 -1.0,1.0 -1.0,-1.0 1.0,-1.0 -1.0)),((0.0 1.0,2.0 -1.0,2.0 1.0,0.0 1.0)))", false, "not connected"},
+ // TIN3D
+ // valid
+ {"TIN(((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0)),((1.0 -1.0 1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0)))", true, ""},
+ // invalid
+ {"TIN(((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0)),((1.0 -1.0 1.0,1.0 1.0 -1.0,1.0 -1.0 1.0)))", false, "second triangle is invalid"},
+ {"TIN(((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0)),((1.0 1.0 -1.0,1.0 -1.0 1.0,1.0 1.0 1.0,1.0 1.0 -1.0)))", false, "inconsitent orientation"},
+ {"TIN(((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0)),((1.0 0.0 1.0,1.0 2.0 -1.0,1.0 2.0 1.0,1.0 0.0 1.0)))", false, "not connected"},
+ {"TIN(((0.0 0.0 0.0,1.0 0.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0)),((0.0 0.0 0.0,0.0 1.0 0.0,0.0 0.0 1.0,0.0 0.0 0.0)),((0.0 0.0 0.0,0.0 0.0 1.0,0.5 0.1 -0.1,0.0 0.0 0.0)))", false, "self intersect"},
+ // PolyhedralSurface2D
+ // valid
+ {"POLYHEDRALSURFACE(((-1.0 -1.0,1.0 -1.0,-1.0 1.0,-1.0 -1.0)),((-1.0 1.0,1.0 -1.0,1.0 1.0,-1.0 1.0)))", true, ""},
+ // invalid
+ {"POLYHEDRALSURFACE(((-1.0 -1.0,1.0 -1.0,-1.0 1.0,-1.0 -1.0)),((-1.0 1.0,1.0 -1.0,-1.0 1.0)))", false, "second polygon is invalid"},
+ {"POLYHEDRALSURFACE(((-1.0 -1.0,1.0 -1.0,-1.0 1.0,-1.0 -1.0)),((1.0 -1.0,-1.0 1.0,1.0 1.0,1.0 -1.0)))", false, "inconsitent orientation"},
+ {"POLYHEDRALSURFACE(((-1.0 -1.0,1.0 -1.0,-1.0 1.0,-1.0 -1.0)),((0.0 1.0,2.0 -1.0,2.0 1.0,0.0 1.0)))", false, "not connected"},
+ // PolyhedralSurface3D
+ // valid
+ {"POLYHEDRALSURFACE(((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0)),((1.0 -1.0 1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0)))", true, ""},
+ {
+ "POLYHEDRALSURFACE(((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)),\
+ ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),\
+ ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),\
+ ((1 1 1, 0 1 1, 0 0 1, 1 0 1, 1 1 1)),\
+ ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)),\
+ ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1)))", true, "a simple cube"
+ },
+ // invalid
+ {"POLYHEDRALSURFACE(((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0)),((1.0 -1.0 1.0,1.0 1.0 -1.0,1.0 -1.0 1.0)))", false, "second polygon is invalid"},
+ {"POLYHEDRALSURFACE(((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0)),((1.0 1.0 -1.0,1.0 -1.0 1.0,1.0 1.0 1.0,1.0 1.0 -1.0)))", false, "inconsitent orientation"},
+ {"POLYHEDRALSURFACE(((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0)),((1.0 0.0 1.0,1.0 2.0 -1.0,1.0 2.0 1.0,1.0 0.0 1.0)))", false, "not connected"},
+ {"POLYHEDRALSURFACE(((0.0 0.0 0.0,1.0 0.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0)),((0.0 0.0 0.0,0.0 1.0 0.0,0.0 0.0 1.0,0.0 0.0 0.0)),((0.0 0.0 0.0,0.0 0.0 1.0,0.5 0.1 -0.1,0.0 0.0 0.0)))", false, "self intersect"},
+ {
+ "POLYHEDRALSURFACE(((0 0 -1, 0 1 -1, 1 1 -1, 1 0 -1, 0 0 -1)),\
+ ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),\
+ ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),\
+ ((1 1 1, 0 1 1, 0 0 1, 1 0 1, 1 1 1)),\
+ ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)),\
+ ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1)))", false, "not connected"
+ },
+ // Solid
+ // valid
+ {
+ "SOLID((((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)),\
+ ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),\
+ ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),\
+ ((1 1 1, 0 1 1, 0 0 1, 1 0 1, 1 1 1)),\
+ ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)),\
+ ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1))))", true, "a simple cube"
+ },
+ {
+ "SOLID((((0 0 0, 1 0 0, 1 1 0, 0 1 0, 0 0 0)),\
+ ((0 0 0, 0 1 0, 0 1 1, 0 0 1, 0 0 0)),\
+ ((0 0 0, 0 0 1, 1 0 1, 1 0 0, 0 0 0)),\
+ ((1 1 1, 1 0 1, 0 0 1, 0 1 1, 1 1 1)),\
+ ((1 1 1, 1 1 0, 1 0 0, 1 0 1, 1 1 1)),\
+ ((1 1 1, 0 1 1, 0 1 0, 1 1 0, 1 1 1))))", true, "a reversed cube (inside/out)"
+ },
+ // invalid
+ {
+ "SOLID((((0 0 -1, 0 1 -1, 1 1 -1, 1 0 -1, 0 0 -1)),\
+ ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),\
+ ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),\
+ ((1 1 1, 0 1 1, 0 0 1, 1 0 1, 1 1 1)),\
+ ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)),\
+ ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1))))", false, "not connected"
+ },
+ {
+ "SOLID((((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)),\
+ ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),\
+ ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),\
+ ((1 1 1, 0 1 1, 0 0 1, 1 0 1, 1 1 1)),\
+ ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1))))", false, "not closed"
+ }
+ };
+
+ return std::vector<TestGeometry>( testGeometry, testGeometry + sizeof( testGeometry )/sizeof( TestGeometry ) ) ;
+}
+
+}
+
+#endif
diff --git a/src/detail/TypeForDimension.h b/src/detail/TypeForDimension.h
new file mode 100644
index 0000000..01e280c
--- /dev/null
+++ b/src/detail/TypeForDimension.h
@@ -0,0 +1,169 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SFCGAL_DETAIL_TYPE_FOR_DIMENSION_H
+#define SFCGAL_DETAIL_TYPE_FOR_DIMENSION_H
+
+#include <CGAL/Segment_2.h>
+#include <CGAL/Segment_3.h>
+#include <CGAL/Triangle_2.h>
+#include <CGAL/Triangle_3.h>
+#include <CGAL/Polygon_with_holes_2.h>
+#include <CGAL/Polyhedron_3.h>
+
+namespace SFCGAL {
+namespace detail {
+///
+/// Type traits for CGAL types.
+///
+/// CGAL types cannot be directly parametrized by their dimension.
+/// For instance, there are both a Triangle_2<K> and a Triangle_3<K> type
+///
+/// TypeForKernel<K, 2>::Point is equivalent to CGAL::Point_2<K> for instance
+/// TypeForDimension<2>::Bbox is equivalent to CGAL::Bbox_2
+
+struct SFCGAL_API NoVolume {};
+
+///
+/// Generic traits, default dimension is 2
+template <int Dim>
+struct TypeForDimension {
+ typedef CGAL::Bbox_2 Bbox;
+ typedef Kernel::Point_2 Point;
+ typedef Kernel::Segment_2 Segment;
+ typedef Kernel::Triangle_2 Triangle;
+ typedef CGAL::Polygon_with_holes_2<Kernel> Surface;
+ typedef NoVolume Volume;
+};
+
+
+///
+/// Extended polyhedron_3 type with a boolean marker on halfedges
+/// This is used internally for polyhedra boolean operations
+template <class Refs>
+struct Halfedge_with_mark : public CGAL::HalfedgeDS_halfedge_base<Refs> {
+ Halfedge_with_mark()
+ : CGAL::HalfedgeDS_halfedge_base<Refs>(), mark( false ) {
+ }
+
+ bool mark; // A boundary marker for faces with different status
+ void set_mark() { // this will be called by Intersection_of_Polyhedra_3
+ mark = true;
+ }
+};
+
+// An items type using my halfedge.
+struct SFCGAL_API Items_with_mark_on_hedge : public CGAL::Polyhedron_items_3 {
+ template <class Refs, class Traits>
+ struct Halfedge_wrapper {
+ typedef Halfedge_with_mark<Refs> Halfedge;
+ };
+};
+
+
+typedef CGAL::Polyhedron_3<Kernel, Items_with_mark_on_hedge> MarkedPolyhedron;
+
+///
+/// Specialization for dimension = 3
+template <>
+struct TypeForDimension<3> {
+ typedef CGAL::Bbox_3 Bbox;
+ typedef Kernel::Point_3 Point;
+ typedef Kernel::Segment_3 Segment;
+ typedef Kernel::Triangle_3 Triangle;
+ typedef Kernel::Triangle_3 Surface;
+ typedef MarkedPolyhedron Volume;
+};
+
+///
+/// Another way of looking at TypeForDimension<Dim>::Point
+template <int Dim>
+struct Point_d {
+ typedef typename TypeForDimension<Dim>::Point Type;
+};
+///
+/// Another way of looking at TypeForDimension<Dim>::Segment
+template <int Dim>
+struct Segment_d {
+ typedef typename TypeForDimension<Dim>::Segment Type;
+};
+///
+/// Another way of looking at TypeForDimension<Dim>::Surface
+template <int Dim>
+struct Surface_d {
+ typedef typename TypeForDimension<Dim>::Surface Type;
+};
+///
+/// Another way of looking at TypeForDimension<Dim>::Volume
+template <int Dim>
+struct Volume_d {
+ typedef typename TypeForDimension<Dim>::Volume Type;
+};
+
+///
+/// Create a distinct type for each dimension
+template <int N>
+struct dim_t {
+ enum { v = N };
+};
+
+///
+/// Get a primitive dimension (0: point, 1: line, 2: surface, 3: volume) from a type
+template <class T>
+struct PrimitiveDimension {
+ static const int value = 0;
+};
+
+template <>
+struct PrimitiveDimension<TypeForDimension<2>::Segment> {
+ static const int value = 1;
+};
+template <>
+struct PrimitiveDimension<TypeForDimension<3>::Segment> {
+ static const int value = 1;
+};
+template <>
+struct PrimitiveDimension<TypeForDimension<2>::Surface> {
+ static const int value = 2;
+};
+template <>
+struct PrimitiveDimension<TypeForDimension<3>::Surface> {
+ static const int value = 2;
+};
+template <>
+struct PrimitiveDimension<TypeForDimension<2>::Volume> {
+ static const int value = 3;
+};
+template <>
+struct PrimitiveDimension<TypeForDimension<3>::Volume> {
+ static const int value = 3;
+};
+
+///
+/// Tests if a primitive type has a larger dimension than another one
+template <class X, class Y>
+struct IsPrimitiveLarger {
+ static const bool value = PrimitiveDimension<X>::value > PrimitiveDimension<Y>::value;
+};
+
+} // namespace detail
+} // namespace SFCGAL
+
+#endif
diff --git a/src/detail/algorithm/coversPoints.cpp b/src/detail/algorithm/coversPoints.cpp
new file mode 100644
index 0000000..a7e6bb2
--- /dev/null
+++ b/src/detail/algorithm/coversPoints.cpp
@@ -0,0 +1,70 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <SFCGAL/detail/algorithm/coversPoints.h>
+#include <SFCGAL/Geometry.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/algorithm/intersects.h>
+#include <SFCGAL/detail/GeometrySet.h>
+#include <SFCGAL/detail/GetPointsVisitor.h>
+
+namespace SFCGAL {
+namespace detail {
+namespace algorithm {
+template <int Dim>
+bool _coversPoints( const Geometry& ga, const Geometry& gb )
+{
+ if ( ga.isEmpty() || gb.isEmpty() ) {
+ return false;
+ }
+
+ GeometrySet<Dim> gsa( ga );
+
+ // get all points of gb;
+ detail::GetPointsVisitor visitor;
+ gb.accept( visitor );
+
+ for ( detail::GetPointsVisitor::const_iterator it = visitor.points.begin(); it != visitor.points.end(); ++it ) {
+ const Point* ppt = *it;
+
+ // a geometry set of one point
+ GeometrySet<Dim> gsp( *ppt );
+
+ if ( !SFCGAL::algorithm::intersects( gsp, gsa ) ) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool coversPoints( const Geometry& ga, const Geometry& gb )
+{
+ return _coversPoints<2>( ga, gb );
+}
+
+bool coversPoints3D( const Geometry& ga, const Geometry& gb )
+{
+ return _coversPoints<3>( ga, gb );
+}
+}
+}
+}
diff --git a/src/detail/algorithm/coversPoints.h b/src/detail/algorithm/coversPoints.h
new file mode 100644
index 0000000..8997c93
--- /dev/null
+++ b/src/detail/algorithm/coversPoints.h
@@ -0,0 +1,49 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SFCGAL_COVERS_POINTS_ALGORITHM
+#define SFCGAL_COVERS_POINTS_ALGORITHM
+
+#include <SFCGAL/config.h>
+
+#include <vector>
+
+namespace SFCGAL {
+class Geometry;
+namespace detail {
+namespace algorithm {
+
+
+/**
+ * Pseudo cover test on 2D geometries. Collect points of gb and tests if no points of gb is outside ga
+ * @ingroup@ detail
+ */
+SFCGAL_API bool coversPoints( const Geometry& ga, const Geometry& gb );
+
+/**
+ * Pseudo cover test on 3D geometries. Collect points of gb and tests if no points of gb is outside ga
+ * @ingroup@ detail
+ */
+SFCGAL_API bool coversPoints3D( const Geometry& ga, const Geometry& gb );
+}
+}
+}
+
+#endif
diff --git a/src/detail/generator/building.cpp b/src/detail/generator/building.cpp
new file mode 100644
index 0000000..2e9c689
--- /dev/null
+++ b/src/detail/generator/building.cpp
@@ -0,0 +1,200 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/generator/building.h>
+
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+#include <SFCGAL/algorithm/force3D.h>
+#include <SFCGAL/algorithm/orientation.h>
+
+#include <CGAL/create_straight_skeleton_from_polygon_with_holes_2.h>
+
+#include <boost/format.hpp>
+
+namespace SFCGAL {
+namespace generator {
+
+typedef Kernel::Point_2 Point_2 ;
+typedef Kernel::Point_3 Point_3 ;
+typedef CGAL::Polygon_2<Kernel> Polygon_2 ;
+typedef CGAL::Polygon_with_holes_2<Kernel> Polygon_with_holes_2 ;
+typedef CGAL::Straight_skeleton_2<Kernel> Straight_skeleton_2 ;
+
+/**
+ * @brief Basic building generator relying on a straight skeleton
+ */
+std::auto_ptr< Geometry > building(
+ const Polygon& g,
+ const Kernel::FT& wallHeight,
+ const Kernel::FT& roofSlope
+) ;
+/**
+ * @brief Basic building generator relying on a straight skeleton
+ */
+std::auto_ptr< Geometry > building(
+ const MultiPolygon& g,
+ const Kernel::FT& wallHeight,
+ const Kernel::FT& roofSlope
+) ;
+
+
+
+void _buildingWall( const Polygon_2& ring, const Kernel::FT& wallHeight, PolyhedralSurface& shell )
+{
+ size_t npt = ring.size() ;
+
+ for ( size_t i = 0; i < npt; i++ ) {
+ const Point_2& a = ring.vertex( i ) ;
+ const Point_2& b = ring.vertex( ( i+1 ) % npt ) ;
+
+ LineString wallRing ;
+ wallRing.addPoint( new Point( a.x(), a.y(), Kernel::FT( 0 ) ) );
+ wallRing.addPoint( new Point( b.x(), b.y(), Kernel::FT( 0 ) ) );
+ wallRing.addPoint( new Point( b.x(), b.y(), wallHeight ) );
+ wallRing.addPoint( new Point( a.x(), a.y(), wallHeight ) );
+ wallRing.addPoint( new Point( a.x(), a.y(), Kernel::FT( 0 ) ) );
+ shell.addPolygon( Polygon( wallRing ) );
+ }
+}
+
+
+///
+///
+///
+std::auto_ptr< Geometry > building(
+ const Polygon& g,
+ const Kernel::FT& wallHeight,
+ const Kernel::FT& roofSlope
+)
+{
+ //typedef Straight_skeleton_2::Vertex_const_handle Vertex_const_handle ;
+ typedef Straight_skeleton_2::Halfedge_const_handle Halfedge_const_handle ;
+ //typedef Straight_skeleton_2::Halfedge_const_iterator Halfedge_const_iterator ;
+ typedef Straight_skeleton_2::Face_const_iterator Face_const_iterator ;
+
+
+ // convert to CGAL polygon and generate straight skeleton
+ Polygon_with_holes_2 polygon = g.toPolygon_with_holes_2() ;
+
+ // fix orientation
+ algorithm::makeValidOrientation( polygon ) ;
+
+ boost::shared_ptr< Straight_skeleton_2 > skeleton = CGAL::create_interior_straight_skeleton_2( polygon ) ;
+
+ std::auto_ptr< PolyhedralSurface > shell( new PolyhedralSurface );
+ // bottom part
+ {
+ Polygon bottom( polygon );
+ bottom.reverse();
+ algorithm::force3D( bottom );
+ shell->addPolygon( bottom );
+ }
+
+ // walls
+ {
+ //exterior rings
+ _buildingWall( polygon.outer_boundary(), wallHeight, *shell ) ;
+
+ //interior rings
+ for ( Polygon_with_holes_2::Hole_const_iterator it = polygon.holes_begin(); it != polygon.holes_end(); ++it ) {
+ _buildingWall( *it, wallHeight, *shell ) ;
+ }
+ }
+
+ // roof
+ {
+ for ( Face_const_iterator it = skeleton->faces_begin(); it != skeleton->faces_end(); ++it ) {
+
+ LineString roofFaceRing ;
+ Halfedge_const_handle h = it->halfedge(), done( h ) ;
+ bool infiniteTimeFound = false ;
+
+ do {
+ infiniteTimeFound = infiniteTimeFound || h->has_infinite_time() ;
+
+ Point_2 point = h->vertex()->point() ;
+ Kernel::FT zPoint = wallHeight + h->vertex()->time() * roofSlope ;
+
+ roofFaceRing.addPoint( Point( point.x(), point.y(), zPoint ) );
+
+ h = h->next() ;
+ }
+ while ( h != done && ! infiniteTimeFound );
+
+ if ( ! infiniteTimeFound ) {
+ roofFaceRing.addPoint( roofFaceRing.startPoint() );
+ shell->addPolygon( Polygon( roofFaceRing ) );
+ }
+ }
+ }
+
+ return std::auto_ptr< Geometry >( new Solid( shell.release() ) );
+}
+
+///
+///
+///
+std::auto_ptr< Geometry > building(
+ const MultiPolygon& g,
+ const Kernel::FT& wallHeight,
+ const Kernel::FT& roofSlope
+)
+{
+ std::auto_ptr< MultiSolid > multiSolid( new MultiSolid );
+
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ multiSolid->addGeometry( building( g.polygonN( i ), wallHeight, roofSlope ).release() );
+ }
+
+ return std::auto_ptr< Geometry >( multiSolid.release() );
+}
+
+
+///
+///
+///
+std::auto_ptr< Geometry > building(
+ const Geometry& g,
+ const Kernel::FT& wallHeight,
+ const Kernel::FT& roofSlope
+)
+{
+ switch ( g.geometryTypeId() ) {
+ case TYPE_POLYGON:
+ return building( g.as< Polygon >(), wallHeight, roofSlope ) ;
+
+ case TYPE_MULTIPOLYGON:
+ return building( g.as< MultiPolygon >(), wallHeight, roofSlope ) ;
+
+ default:
+ BOOST_THROW_EXCEPTION( Exception(
+ ( boost::format( "bad geometry type (%s) in generator::building" ) % g.geometryType() ).str()
+ ) );
+ return std::auto_ptr< Geometry >( new GeometryCollection() );
+ }
+}
+
+
+} // namespace generator
+} // namespace SFCGAL
diff --git a/src/detail/generator/building.h b/src/detail/generator/building.h
new file mode 100644
index 0000000..20c8b43
--- /dev/null
+++ b/src/detail/generator/building.h
@@ -0,0 +1,54 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_GENERATOR_BUILDING_H_
+#define _SFCGAL_GENERATOR_BUILDING_H_
+
+#include <SFCGAL/config.h>
+
+#include <memory>
+
+#include <SFCGAL/Kernel.h>
+
+namespace SFCGAL {
+class Geometry ;
+class Polygon ;
+}
+
+namespace SFCGAL {
+namespace generator {
+
+/**
+ * @brief Basic building generator relying on a straight skeleton
+ *
+ * @warning only supports Polygon and MultiPolygon
+ * @todo unittest
+ */
+SFCGAL_API std::auto_ptr< Geometry > building(
+ const Geometry& g,
+ const Kernel::FT& wallHeight,
+ const Kernel::FT& roofSlope
+) ;
+
+
+} // namespace generator
+} // namespace SFCGAL
+
+#endif
diff --git a/src/detail/generator/disc.cpp b/src/detail/generator/disc.cpp
new file mode 100644
index 0000000..8a5c00c
--- /dev/null
+++ b/src/detail/generator/disc.cpp
@@ -0,0 +1,64 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifdef _MSC_VER
+# define _USE_MATH_DEFINES
+#endif
+
+#include <SFCGAL/detail/generator/disc.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+
+#include <cmath>
+
+namespace SFCGAL {
+namespace generator {
+
+///
+///
+///
+std::auto_ptr< Polygon > disc(
+ const Point& center,
+ const double& radius,
+ const unsigned int& nQuadrantSegments
+)
+{
+ BOOST_ASSERT( nQuadrantSegments > 1 );
+
+ std::auto_ptr< LineString > exteriorRing( new LineString() ) ;
+
+ double dTheta = M_PI_4 / nQuadrantSegments ;
+
+ for ( size_t i = 0; i < nQuadrantSegments * 4; i++ ) {
+ Kernel::Vector_2 p = center.toVector_2() + radius * Kernel::Vector_2( cos( i*dTheta ), sin( i*dTheta ) ) ;
+ exteriorRing->addPoint( new Point( p.x(), p.y() ) ) ;
+ }
+
+ exteriorRing->addPoint( exteriorRing->startPoint() ) ;
+
+ return std::auto_ptr< Polygon >( new Polygon( exteriorRing.release() ) );
+}
+
+} // namespace generator
+} // namespace SFCGAL
+
diff --git a/src/detail/generator/disc.h b/src/detail/generator/disc.h
new file mode 100644
index 0000000..851b6a9
--- /dev/null
+++ b/src/detail/generator/disc.h
@@ -0,0 +1,49 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_GENERATOR_DISC_H_
+#define _SFCGAL_GENERATOR_DISC_H_
+
+#include <SFCGAL/config.h>
+
+#include <memory>
+
+namespace SFCGAL {
+class Point ;
+class Polygon ;
+}
+
+namespace SFCGAL {
+namespace generator {
+
+/**
+ * Generate a discrete circle
+ * @todo unittest
+ */
+SFCGAL_API std::auto_ptr< Polygon > disc(
+ const Point& center,
+ const double& radius,
+ const unsigned int& nQuadrantSegments = 8U
+) ;
+
+} // namespace generator
+} // namespace SFCGAL
+
+#endif
diff --git a/src/detail/generator/hoch.cpp b/src/detail/generator/hoch.cpp
new file mode 100644
index 0000000..1ae9e23
--- /dev/null
+++ b/src/detail/generator/hoch.cpp
@@ -0,0 +1,82 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/generator/hoch.h>
+
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+
+namespace SFCGAL {
+namespace generator {
+
+std::vector< Kernel::Vector_2 > _hoch( const std::vector< Kernel::Vector_2 >& points )
+{
+ std::vector< Kernel::Vector_2 > result ;
+ result.reserve( points.size() * 2 ) ;
+ size_t numPoints = points.size() ;
+
+ for ( size_t i = 0; i < numPoints; i++ ) {
+ const Kernel::Vector_2& a = points[ i ] ;
+ const Kernel::Vector_2& b = points[ ( i + 1 ) % numPoints ] ;
+
+ Kernel::Vector_2 ab = b - a ;
+ Kernel::Vector_2 normal( -ab.y(), ab.x() );
+
+ result.push_back( a );
+ result.push_back( a + ab / 3 );
+ result.push_back( a + ab / 2 + normal * sqrt( 3.0 ) / 6.0 );
+ result.push_back( a + ( ab * 2 )/3 );
+ }
+
+ return result ;
+}
+
+///
+///
+///
+std::auto_ptr< Polygon > hoch( const unsigned int& order )
+{
+ std::vector< Kernel::Vector_2 > points ;
+ points.push_back( Kernel::Vector_2( 1.0, sqrt( 3.0 ) ) );
+ points.push_back( Kernel::Vector_2( 2.0, 0.0 ) );
+ points.push_back( Kernel::Vector_2( 0.0, 0.0 ) );
+
+
+ for ( unsigned int k = 0 ; k < order; k++ ) {
+ points = _hoch( points );
+ }
+
+ std::auto_ptr< Polygon > result( new Polygon() ) ;
+ std::auto_ptr< LineString > ring( new LineString() ) ;
+
+ for ( std::vector< Kernel::Vector_2 >::const_iterator it = points.begin(); it != points.end(); ++it ) {
+ ring->addPoint( new Point( it->x(), it->y() ) ) ;
+ }
+
+ ring->addPoint( new Point( points.front().x(), points.front().y() ) ) ;
+
+ result->setExteriorRing( ring.release() );
+
+ return result ;
+}
+
+} // namespace generator
+} // namespace SFCGAL
+
diff --git a/src/detail/generator/hoch.h b/src/detail/generator/hoch.h
new file mode 100644
index 0000000..9846e0e
--- /dev/null
+++ b/src/detail/generator/hoch.h
@@ -0,0 +1,44 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_GENERATOR_HOCH_H_
+#define _SFCGAL_GENERATOR_HOCH_H_
+
+#include <SFCGAL/config.h>
+
+#include <memory>
+
+namespace SFCGAL {
+class Polygon ;
+}
+
+namespace SFCGAL {
+namespace generator {
+
+/**
+ * generate hoch snowflake
+ * @todo unittest
+ */
+SFCGAL_API std::auto_ptr< Polygon > hoch( const unsigned int& order ) ;
+
+} // namespace generator
+} // namespace SFCGAL
+
+#endif
diff --git a/src/detail/generator/sierpinski.cpp b/src/detail/generator/sierpinski.cpp
new file mode 100644
index 0000000..0b58c87
--- /dev/null
+++ b/src/detail/generator/sierpinski.cpp
@@ -0,0 +1,80 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/generator/sierpinski.h>
+
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/MultiPolygon.h>
+
+namespace SFCGAL {
+namespace generator {
+
+
+std::vector< Kernel::Triangle_2 > _sierpinski( const std::vector< Kernel::Triangle_2 >& triangles )
+{
+ std::vector< Kernel::Triangle_2 > result ;
+ result.reserve( triangles.size() * 3 ) ;
+
+ for ( size_t i = 0; i < triangles.size(); i++ ) {
+ const Kernel::Point_2& a = triangles[i].vertex( 0 ) ;
+ const Kernel::Point_2& b = triangles[i].vertex( 1 ) ;
+ const Kernel::Point_2& c = triangles[i].vertex( 2 ) ;
+
+ Kernel::Point_2 iAB = a + ( b - a ) / 2 ;
+ Kernel::Point_2 iBC = b + ( c - b ) / 2 ;
+ Kernel::Point_2 iCA = c + ( a - c ) / 2 ;
+
+ result.push_back( Kernel::Triangle_2( a, iAB, iCA ) );
+ result.push_back( Kernel::Triangle_2( b, iBC, iAB ) );
+ result.push_back( Kernel::Triangle_2( c, iCA, iBC ) );
+ }
+
+ return result ;
+}
+
+///
+///
+///
+std::auto_ptr< MultiPolygon > sierpinski( const unsigned int& order )
+{
+ std::vector< Kernel::Triangle_2 > triangles ;
+ triangles.push_back( Kernel::Triangle_2(
+ Kernel::Point_2( 1.0, sqrt( 3.0 ) ),
+ Kernel::Point_2( 2.0, 0.0 ),
+ Kernel::Point_2( 0.0, 0.0 )
+ ) );
+
+ for ( unsigned int k = 0 ; k < order; k++ ) {
+ triangles = _sierpinski( triangles );
+ }
+
+ std::auto_ptr< MultiPolygon > result( new MultiPolygon ) ;
+
+ for ( size_t i = 0; i < triangles.size(); i++ ) {
+ result->addGeometry( Triangle( triangles[i] ).toPolygon() ) ;
+ }
+
+ return result ;
+}
+
+} // namespace generator
+} // namespace SFCGAL
+
+
diff --git a/src/detail/generator/sierpinski.h b/src/detail/generator/sierpinski.h
new file mode 100644
index 0000000..6b1d422
--- /dev/null
+++ b/src/detail/generator/sierpinski.h
@@ -0,0 +1,44 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_GENERATOR_SIERPINSKI_H_
+#define _SFCGAL_GENERATOR_SIERPINSKI_H_
+
+#include <SFCGAL/config.h>
+
+#include <memory>
+
+namespace SFCGAL {
+class MultiPolygon ;
+}
+
+namespace SFCGAL {
+namespace generator {
+
+/**
+ * generate hoch snowflake
+ * @todo unittest
+ */
+SFCGAL_API std::auto_ptr< MultiPolygon > sierpinski( const unsigned int& order ) ;
+
+} // namespace generator
+} // namespace SFCGAL
+
+#endif
diff --git a/src/detail/graph/Edge.cpp b/src/detail/graph/Edge.cpp
new file mode 100644
index 0000000..0adfb3d
--- /dev/null
+++ b/src/detail/graph/Edge.cpp
@@ -0,0 +1,38 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/graph/Edge.h>
+
+namespace SFCGAL {
+namespace graph {
+
+///
+///
+///
+Edge::Edge( const int& face_ ):
+ face( face_ )
+{
+
+}
+
+}//graph
+}//SFCGAL
+
+
diff --git a/src/detail/graph/Edge.h b/src/detail/graph/Edge.h
new file mode 100644
index 0000000..e751ba5
--- /dev/null
+++ b/src/detail/graph/Edge.h
@@ -0,0 +1,42 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_GRAPH_EDGE_H_
+#define _SFCGAL_GRAPH_EDGE_H_
+
+#include <SFCGAL/config.h>
+
+namespace SFCGAL {
+namespace graph {
+
+/**
+ * @brief [private]An edge in a GeometryGraph with minimal requirements (some algorithms could need
+ * more informations)
+ */
+struct SFCGAL_API Edge {
+ Edge( const int& face_ = -1 );
+
+ int face ;
+};
+
+}//graph
+}//SFCGAL
+
+#endif
diff --git a/src/detail/graph/GeometryGraph.h b/src/detail/graph/GeometryGraph.h
new file mode 100644
index 0000000..7b54883
--- /dev/null
+++ b/src/detail/graph/GeometryGraph.h
@@ -0,0 +1,444 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_GRAPH_GEOMETRYGRAPH_H_
+#define _SFCGAL_GRAPH_GEOMETRYGRAPH_H_
+
+#include <boost/graph/adjacency_list.hpp>
+
+#include <SFCGAL/detail/graph/Vertex.h>
+#include <SFCGAL/detail/graph/Edge.h>
+
+
+namespace SFCGAL {
+namespace graph {
+
+/**
+ *
+ */
+typedef enum {
+ DIRECT = 0,
+ REVERSE = 1
+} EdgeDirection ;
+
+
+/**
+ * reverse EdgeDirection (DIRECT=>REVERSE, REVERSE=>DIRECT)
+ */
+inline EdgeDirection reverse( const EdgeDirection& direction )
+{
+ return ( EdgeDirection )( 1 - direction ) ;
+}
+
+
+/**
+ *
+ * @brief [private]Represents the vertices and edges for a list of geometries.
+ *
+ * A boost::adjancency_list is wrapped in order to be able to annex some informations
+ * and to provide basic functionalities.
+ *
+ * @warning duplicate matching is performed in GeometryGraphBuilder (allows to modify position once it's done)
+ *
+ */
+template < typename VertexProperties, typename EdgeProperties >
+class GeometryGraphT {
+public:
+ typedef VertexProperties vertex_properties ;
+ typedef EdgeProperties edge_properties ;
+
+ /**
+ * the wrapped graphEdgeProperties
+ */
+ typedef boost::adjacency_list<
+ boost::listS, /* stable identifiers */
+ boost::listS, /* parallel edges allowed + stable identifiers */
+ boost::bidirectionalS,
+ vertex_properties,
+ edge_properties
+ > graph_t ;
+
+ typedef typename boost::graph_traits< graph_t >::vertex_descriptor vertex_descriptor ;
+ typedef typename boost::graph_traits< graph_t >::edge_descriptor edge_descriptor ;
+
+ typedef typename boost::graph_traits< graph_t >::vertex_iterator vertex_iterator ;
+ typedef typename boost::graph_traits< graph_t >::edge_iterator edge_iterator ;
+ /**
+ * An edge descriptor, with a direction.
+ *
+ * From the vertex point of view, out edges are DIRECT, in edges are REVERSE.
+ */
+ typedef std::pair< edge_descriptor, EdgeDirection> directed_edge_descriptor ;
+
+ typedef typename boost::graph_traits< graph_t >::in_edge_iterator in_edge_iterator ;
+ typedef typename boost::graph_traits< graph_t >::out_edge_iterator out_edge_iterator ;
+
+
+ /**
+ * [vertex]returns the number of vertices
+ */
+ inline size_t numVertices() const {
+ return boost::num_vertices( _graph );
+ }
+
+ /**
+ * [iterator]return vertex iterator
+ *
+ * @code
+ * typename GeometryGraph<V,E>::vertex_iterator it, end ;
+ * for ( boost::tie( it, end ) = g.vertices(); it != end; ++it ){
+ * typename GeometryGraph<V,E>::vertex_descriptor vertex = *it ;
+ * std::cout << g[ vertex ].coordinate << std::endl;
+ * }
+ * @endcode
+ */
+ inline std::pair< vertex_iterator, vertex_iterator > vertices() const {
+ return boost::vertices( _graph );
+ }
+
+ /**
+ * [vertex]add a vertex to the graph
+ * @return the identifier of the vertex
+ */
+ vertex_descriptor addVertex( const vertex_properties& properties = vertex_properties() ) {
+ return boost::add_vertex( properties, _graph );
+ }
+ /**
+ * [vertex]Remove a vertex (and all its adjacent edges)
+ */
+ void removeVertex( const vertex_descriptor& vertex ) {
+ boost::clear_vertex( vertex );
+ boost::remove_vertex( vertex );
+ }
+
+ /**
+ * [edge]returns the number of vertices
+ */
+ inline size_t numEdges() const {
+ return boost::num_edges( _graph );
+ }
+
+ /**
+ * [iterator]return edge iterator
+ *
+ * @code
+ * typename GeometryGraph<V,E>::edge_iterator it, end ;
+ * for ( boost::tie( it, end ) = g.edges(); it != end; ++it ){
+ * typename GeometryGraph<V,E>::edge_descriptor edge = *it ;
+ * std::cout << g.source(edge) << "," << g.target(edge) << std::endl;
+ * }
+ * @endcode
+ */
+ inline std::pair< edge_iterator, edge_iterator > edges() const {
+ return boost::edges( _graph );
+ }
+
+ /**
+ * [edge]Add an Edge to the Graph
+ * @return the identifier of the vertex
+ */
+ edge_descriptor addEdge(
+ const vertex_descriptor& source,
+ const vertex_descriptor& target,
+ const EdgeProperties& properties = EdgeProperties()
+ ) {
+ return boost::add_edge( source, target, properties, _graph ).first;
+ }
+
+ /**
+ * [edge]get the source vertex for an edge
+ */
+ vertex_descriptor source( const edge_descriptor& edge ) const {
+ return boost::source( edge, _graph ) ;
+ }
+ /**
+ * [edge]get the source vertex for an edge
+ */
+ vertex_descriptor source( const edge_descriptor& edge, const EdgeDirection& direction ) const {
+ return direction == DIRECT ? boost::source( edge, _graph ) : boost::target( edge, _graph ) ;
+ }
+ /**
+ * [edge]get the source vertex for an edge with a direction
+ */
+ vertex_descriptor source( const directed_edge_descriptor& edge ) const {
+ return source( edge.first, edge.second ) ;
+ }
+
+ /**
+ * [edge]get the target vertex for an edge
+ */
+ vertex_descriptor target( const edge_descriptor& edge ) const {
+ return boost::target( edge, _graph ) ;
+ }
+ /**
+ * [edge]get the target vertex for an edge with a direction
+ */
+ vertex_descriptor target( const edge_descriptor& edge, const EdgeDirection& direction ) const {
+ return direction == DIRECT ? boost::target( edge, _graph ) : boost::source( edge, _graph ) ;
+ }
+ /**
+ * [edge]get the target vertex for an edge with a direction
+ */
+ vertex_descriptor target( const directed_edge_descriptor& edge ) const {
+ return target( edge.first, edge.second );
+ }
+ /**
+ * [edge]Remove an edge
+ */
+ void removeEdge( const edge_descriptor& edge ) {
+ boost::remove_edge( edge, _graph );
+ }
+
+ /**
+ * [edge]Get edges from a to b and from b to a
+ */
+ std::vector< directed_edge_descriptor > edges( const vertex_descriptor& a, const vertex_descriptor& b ) const {
+ std::vector< directed_edge_descriptor > result ;
+
+ //out_edges from a targeting b
+ {
+ out_edge_iterator it, end ;
+
+ for ( boost::tie( it,end ) = boost::out_edges( a,_graph ); it != end; ++it ) {
+ if ( target( *it ) != b ) {
+ continue ;
+ }
+
+ result.push_back( std::make_pair( *it, DIRECT ) );
+ }
+ }
+ //out_edges from b targeting a
+ {
+ out_edge_iterator it, end ;
+
+ for ( boost::tie( it,end ) = boost::out_edges( b,_graph ); it != end; ++it ) {
+ if ( target( *it ) != a ) {
+ continue ;
+ }
+
+ result.push_back( std::make_pair( *it, REVERSE ) );
+ }
+ }
+ return result ;
+ }
+
+ /**
+ * returns the degree of a vertex
+ */
+ inline size_t degree( const vertex_descriptor& vertex ) const {
+ return boost::degree( vertex,_graph );
+ }
+
+
+ /**
+ * [adjacency]get in edges
+ */
+ std::vector< edge_descriptor > inEdges( const vertex_descriptor& vertex ) {
+ std::vector< edge_descriptor > edges ;
+
+ in_edge_iterator it, end ;
+
+ for ( boost::tie( it, end ) = boost::in_edges( vertex, _graph ); it != end; ++it ) {
+ edges.push_back( *it );
+ }
+
+ return edges ;
+ }
+ /**
+ * [adjacency]get out edges
+ */
+ std::vector< edge_descriptor > outEdges( const vertex_descriptor& vertex ) const {
+ std::vector< edge_descriptor > edges ;
+
+ out_edge_iterator it, end ;
+
+ for ( boost::tie( it, end ) = boost::out_edges( vertex, _graph ); it != end; ++it ) {
+ edges.push_back( *it );
+ }
+
+ return edges ;
+ }
+ /**
+ * [adjacency]get in/out edges
+ */
+ std::vector< directed_edge_descriptor > inOutEdges( const vertex_descriptor& vertex ) const {
+ std::vector< directed_edge_descriptor > edges ;
+ {
+ in_edge_iterator it, end ;
+
+ for ( boost::tie( it, end ) = boost::in_edges( vertex, _graph ); it != end; ++it ) {
+ edges.push_back( std::make_pair( *it, REVERSE ) );
+ }
+ }
+
+ //out edges
+ {
+ out_edge_iterator it, end ;
+
+ for ( boost::tie( it, end ) = boost::out_edges( vertex, _graph ); it != end; ++it ) {
+ edges.push_back( std::make_pair( *it, DIRECT ) );
+ }
+ }
+ return edges ;
+ }
+
+
+ /**
+ * [adjacency]Returns the list of the adjacent vertices using both DIRECT and REVERSE direction
+ * @param vertex input vertex
+ * @param withReverseDirection indicates if in_edges are used
+ */
+ std::set< vertex_descriptor > adjacentVertices( const vertex_descriptor& vertex, bool withReverseDirection = true ) {
+ std::set< vertex_descriptor > vertices ;
+ // out edges
+ {
+ out_edge_iterator it, end ;
+
+ for ( boost::tie( it, end ) = boost::out_edges( vertex, _graph ); it != end; ++it ) {
+ vertex_descriptor reached = target( *it ) ;
+
+ if ( reached != vertex ) {
+ vertices.insert( reached );
+ }
+ }
+ }
+
+ // in edges
+ if ( withReverseDirection ) {
+ in_edge_iterator it, end ;
+
+ for ( boost::tie( it, end ) = boost::in_edges( vertex, _graph ); it != end; ++it ) {
+ vertex_descriptor reached = source( *it ) ;
+
+ if ( reached != vertex ) {
+ vertices.insert( reached );
+ }
+ }
+ }
+
+ return vertices ;
+ }
+
+
+ /**
+ * [helper]indicates if edges are opposite
+ */
+ inline bool areOpposite( const edge_descriptor& a, const edge_descriptor& b ) const {
+ return source( a ) == target( b ) && target( a ) == source( b ) ;
+ }
+ /**
+ * [helper]indicates if edges are opposite
+ */
+ inline bool areParallel( const edge_descriptor& a, const edge_descriptor& b ) const {
+ return source( a ) == source( b ) && target( a ) == target( b ) ;
+ }
+
+
+ /**
+ * [EdgeString]revert the order of a list of edges. Old edges are removed from the graph, new
+ * ones are created.
+ *
+ * @warning properties are kept but oriented one (left face, right face, etc.) are lost.
+ */
+ void reverse( std::vector< edge_descriptor >& edges ) {
+ std::vector< edge_descriptor > result ;
+
+ for ( typename std::vector< edge_descriptor >::reverse_iterator it = edges.rbegin();
+ it != edges.rend(); ++it ) {
+ edge_descriptor newEdge = addEdge( target( *it ), source( *it ), ( *this )[*it] );
+ result.push_back( newEdge );
+ removeEdge( *it );
+ }
+
+ edges = result ;
+ }
+
+ /**
+ * returns the VertexProperties attached to a Vertex
+ */
+ inline const vertex_properties& operator [] ( const vertex_descriptor& vertex ) const {
+ return _graph[ vertex ];
+ }
+ /**
+ * returns the VertexProperties attached to a Vertex
+ */
+ inline vertex_properties& operator [] ( const vertex_descriptor& vertex ) {
+ return _graph[ vertex ];
+ }
+
+
+ /**
+ * returns the VertexProperties attached to a Vertex
+ */
+ inline const edge_properties& operator [] ( const edge_descriptor& edge ) const {
+ return _graph[ edge ];
+ }
+ /**
+ * returns the VertexProperties attached to a Vertex
+ */
+ inline edge_properties& operator [] ( const edge_descriptor& edge ) {
+ return _graph[ edge ];
+ }
+
+ /**
+ * returns the wrapped boost::graph
+ */
+ inline graph_t& graph() {
+ return _graph ;
+ }
+ /**
+ * returns the wrapped boost::graph
+ */
+ inline const graph_t& graph() const {
+ return _graph ;
+ }
+
+
+ /**
+ * implicit cast to the wrapped boost graph in order to keep boost graph interface
+ */
+ operator graph_t& ( void ) {
+ return _graph;
+ }
+ /**
+ * implicit cast to the wrapped boost graph in order to keep boost graph interface
+ */
+ operator const graph_t& ( void ) const {
+ return _graph;
+ }
+private:
+ /**
+ * a wrapped boost::graph
+ */
+ graph_t _graph ;
+};
+
+
+/**
+ * Default GeometryGraph with predefined Vertex and Edge properties for general usage
+ */
+typedef GeometryGraphT< Vertex, Edge > GeometryGraph ;
+
+
+}//graph
+}//SFCGAL
+
+
+#endif
diff --git a/src/detail/graph/GeometryGraphBuilder.h b/src/detail/graph/GeometryGraphBuilder.h
new file mode 100644
index 0000000..70dbc71
--- /dev/null
+++ b/src/detail/graph/GeometryGraphBuilder.h
@@ -0,0 +1,230 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_GRAPH_GEOMETRYGRAPHBUILDER_H_
+#define _SFCGAL_GRAPH_GEOMETRYGRAPHBUILDER_H_
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+
+#include <SFCGAL/detail/graph/GeometryGraph.h>
+
+namespace SFCGAL {
+namespace graph {
+
+/**
+ * @brief [private]Convert Geometries to a GeometryGraph. Identifier in the Graph are returned in order to
+ * allow the user to keep identify the geometry.
+ *
+ * @todo wrap vertex_descriptor, std::vector< edge_descriptor >, etc. in SharedPoint, SharedLineString, SharedPolygon, etc.
+ * and add utility method on the Graph?
+ */
+template < typename Graph >
+class GeometryGraphBuilderT {
+public:
+ typedef Graph graph_t ;
+
+ typedef typename graph_t::vertex_properties vertex_properties ;
+ typedef typename graph_t::edge_properties edge_properties ;
+ typedef typename graph_t::vertex_descriptor vertex_descriptor ;
+ typedef typename graph_t::edge_descriptor edge_descriptor ;
+
+ /**
+ * allows to match duplicates
+ */
+ typedef std::map< Coordinate, vertex_descriptor > coordinate_list ;
+
+ /**
+ * default constructor
+ */
+ GeometryGraphBuilderT( graph_t& graph ):
+ _graph( graph ) {
+
+ }
+
+ /**
+ * destructor
+ */
+ ~GeometryGraphBuilderT() {
+
+ }
+
+
+ /**
+ * add a Point to the Graph
+ */
+ vertex_descriptor addPoint( const Point& point ) {
+ BOOST_ASSERT( ! point.isEmpty() );
+
+ typename coordinate_list::const_iterator it = _vertices.find( point.coordinate() ) ;
+
+ if ( it != _vertices.end() ) {
+ return it->second ;
+ }
+ else {
+ vertex_descriptor vertex = _graph.addVertex( vertex_properties( point.coordinate() ) );
+ _vertices.insert( std::make_pair( point.coordinate(), vertex ) );
+ return vertex ;
+ }
+ }
+
+ /**
+ * add a Point to the Graph
+ * @return the edge inserted into the graph
+ */
+ edge_descriptor addLineSegment(
+ const Point& a,
+ const Point& b,
+ const edge_properties& edgeProperties = edge_properties()
+ ) {
+ BOOST_ASSERT( ! a.isEmpty() );
+ BOOST_ASSERT( ! b.isEmpty() );
+
+ return _graph.addEdge(
+ addPoint( a ),
+ addPoint( b ),
+ edgeProperties
+ );
+ }
+
+ /**
+ * add a LineString to the graph
+ * @return the list of edges inserted into the graph
+ */
+ std::vector< edge_descriptor > addLineString(
+ const LineString& lineString,
+ const edge_properties& edgeProperties = edge_properties()
+ ) {
+ BOOST_ASSERT( ! lineString.isEmpty() );
+
+ std::vector< edge_descriptor > edges ;
+
+ for ( size_t i = 0; i < lineString.numPoints() - 1; i++ ) {
+ edges.push_back( addLineSegment( lineString.pointN( i ), lineString.pointN( i+1 ), edgeProperties ) );
+ }
+
+ return edges ;
+ }
+
+ /**
+ * add a Triangle to the graph
+ * @return the list of edges inserted into the graph
+ */
+ std::vector< edge_descriptor > addTriangle(
+ const Triangle& triangle,
+ const edge_properties& edgeProperties = edge_properties()
+ ) {
+ BOOST_ASSERT( ! triangle.isEmpty() );
+
+ std::vector< edge_descriptor > edges ;
+
+ for ( size_t i = 0; i < 3; i++ ) {
+ edges.push_back( addLineSegment(
+ triangle.vertex( i ),
+ triangle.vertex( i+1 ),
+ edgeProperties
+ ) );
+ }
+
+ return edges ;
+ }
+
+
+ /**
+ * add a Polygon to the graph
+ * @returns the list of rings inserted into the graph
+ */
+ std::vector< std::vector< edge_descriptor > > addPolygon(
+ const Polygon& polygon,
+ const edge_properties& edgeProperties = edge_properties()
+ ) {
+ BOOST_ASSERT( ! polygon.isEmpty() );
+
+ std::vector< std::vector< edge_descriptor > > rings ;
+
+ for ( size_t i = 0; i < polygon.numRings(); i++ ) {
+ rings.push_back( addLineString( polygon.ringN( i ), edgeProperties ) );
+ }
+
+ return rings ;
+ }
+
+ /**
+ * add a TriangulatedSurface to the graph
+ * @returns the list of rings inserted into the graph
+ */
+ std::vector< std::vector< edge_descriptor > > addTriangulatedSurface(
+ const TriangulatedSurface& triangulatedSurface,
+ const edge_properties& edgeProperties = edge_properties()
+ ) {
+ BOOST_ASSERT( ! triangulatedSurface.isEmpty() );
+
+ std::vector< std::vector< edge_descriptor > > triangles ;
+
+ for ( size_t i = 0; i < triangulatedSurface.numGeometries(); i++ ) {
+ triangles.push_back( addTriangle( triangulatedSurface.geometryN( i ), edgeProperties ) );
+ }
+
+ return triangles ;
+ }
+
+
+ /**
+ * add a PolyhedralSurface to the graph
+ * @returns the list of rings inserted into the graph
+ */
+ std::vector< std::vector< std::vector< edge_descriptor > > > addPolyhedralSurface(
+ const PolyhedralSurface& polyhedralSurface,
+ const edge_properties& edgeProperties = edge_properties()
+ ) {
+ BOOST_ASSERT( ! polyhedralSurface.isEmpty() );
+
+ std::vector< std::vector< std::vector< edge_descriptor > > > polygons ;
+
+ for ( size_t i = 0; i < polyhedralSurface.numPolygons(); i++ ) {
+ polygons.push_back( addPolygon( polyhedralSurface.polygonN( i ), edgeProperties ) );
+ }
+
+ return polygons ;
+ }
+
+
+private:
+ graph_t& _graph ;
+ coordinate_list _vertices ;
+
+ /**
+ * no copy constructor
+ */
+ GeometryGraphBuilderT( const GeometryGraphBuilderT& other ) ;
+};
+
+
+typedef GeometryGraphBuilderT< GeometryGraph > GeometryGraphBuilder ;
+
+}//topology
+}//SFCGAL
+
+
+#endif
diff --git a/src/detail/graph/Vertex.cpp b/src/detail/graph/Vertex.cpp
new file mode 100644
index 0000000..7bd052b
--- /dev/null
+++ b/src/detail/graph/Vertex.cpp
@@ -0,0 +1,38 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/graph/Vertex.h>
+
+namespace SFCGAL {
+namespace graph {
+
+///
+///
+///
+Vertex::Vertex( const Coordinate& coordinate_ ):
+ coordinate( coordinate_ )
+{
+
+}
+
+}//graph
+}//SFCGAL
+
+
diff --git a/src/detail/graph/Vertex.h b/src/detail/graph/Vertex.h
new file mode 100644
index 0000000..3c53b98
--- /dev/null
+++ b/src/detail/graph/Vertex.h
@@ -0,0 +1,47 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_GRAPH_VERTEX_H_
+#define _SFCGAL_GRAPH_VERTEX_H_
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Coordinate.h>
+
+namespace SFCGAL {
+namespace graph {
+
+/**
+ * @brief [private]A vertex in a GeometryGraph with minimal requirements (some algorithms could need
+ * a richer class)
+ */
+struct SFCGAL_API Vertex {
+ /**
+ * [requirement]Constructor with coordinate
+ */
+ Vertex( const Coordinate& coordinate_ = Coordinate() ) ;
+
+ Coordinate coordinate ;
+};
+
+}//graph
+}//SFCGAL
+
+#endif
diff --git a/src/detail/graph/algorithm/isHalfEdge.h b/src/detail/graph/algorithm/isHalfEdge.h
new file mode 100644
index 0000000..a2fd8de
--- /dev/null
+++ b/src/detail/graph/algorithm/isHalfEdge.h
@@ -0,0 +1,77 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_GRAPH_ALGORITHM_ISCONNECTED_H_
+#define _SFCGAL_GRAPH_ALGORITHM_ISCONNECTED_H_
+
+#include <set>
+#include <complex>
+
+#include <SFCGAL/detail/ComplexComparator.h>
+
+#include <SFCGAL/detail/graph/GeometryGraph.h>
+
+#include <boost/graph/copy.hpp>
+#include <boost/graph/connected_components.hpp>
+
+namespace SFCGAL {
+namespace graph {
+namespace algorithm {
+
+
+/**
+ * @brief [private]Test if a bidirectional graph is an half-edge (in order to validate orientation)
+ */
+template < typename V, typename E >
+bool isHalfEdge( const GeometryGraphT<V,E>& graph )
+{
+ typedef typename GeometryGraphT<V,E>::vertex_descriptor vertex_descriptor ;
+ //typedef typename GeometryGraphT<V,E>::edge_descriptor edge_descriptor ;
+ typedef typename GeometryGraphT<V,E>::edge_iterator edge_iterator ;
+
+ /*
+ * try to insert all edges in a map, return false if an edge already exists (i.e. there are parallel edges)
+ */
+ std::set< std::complex< vertex_descriptor >, detail::ComplexComparator > edges ;
+ edge_iterator it,end ;
+
+ for ( boost::tie( it,end ) = graph.edges(); it != end; ++it ) {
+ std::complex< vertex_descriptor > cedge(
+ graph.source( *it ),
+ graph.target( *it )
+ );
+
+ if ( edges.find( cedge ) != edges.end() ) {
+ return false ;
+ }
+ else {
+ edges.insert( cedge );
+ }
+ }
+
+ return true ;
+}
+
+
+}//algorithm
+}//graph
+}//SFCGAL
+
+#endif
diff --git a/src/detail/graph/algorithm/orientation.h b/src/detail/graph/algorithm/orientation.h
new file mode 100644
index 0000000..ec4ac31
--- /dev/null
+++ b/src/detail/graph/algorithm/orientation.h
@@ -0,0 +1,108 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_GRAPH_ALGORITHM_MAKECONSISTENTORIENTATION_H_
+#define _SFCGAL_GRAPH_ALGORITHM_MAKECONSISTENTORIENTATION_H_
+
+#include <map>
+#include <SFCGAL/detail/graph/GeometryGraph.h>
+
+namespace SFCGAL {
+namespace graph {
+namespace algorithm {
+
+/**
+ * @brief [private]Study orientation between two EdgeStrings
+ * @return true on success
+ */
+template < typename Graph >
+void studyOrientation(
+ Graph& graph,
+ std::vector< typename Graph::edge_descriptor >& reference,
+ std::vector< typename Graph::edge_descriptor >& target,
+ bool& hasOppositeEdge,
+ bool& hasParallelEdge
+)
+{
+ /*
+ * look for opposite or parallel edges in reference and target
+ */
+ hasOppositeEdge = false ;
+ hasParallelEdge = false ;
+
+ for ( size_t i = 0; i < reference.size(); i++ ) {
+ for ( size_t j = 0; j < target.size(); j++ ) {
+ if ( graph.areOpposite( reference[i], target[j] ) ) {
+ hasOppositeEdge = true ;
+ }
+
+ if ( graph.areParallel( reference[i], target[j] ) ) {
+ hasParallelEdge = true ;
+ }
+ }
+ }
+}
+
+
+/**
+ * Try to build consistent orientation between two edge string
+ * @return true on success
+ */
+template < typename Graph >
+bool makeConsistentOrientation(
+ Graph& graph,
+ std::vector< typename Graph::edge_descriptor >& reference,
+ std::vector< typename Graph::edge_descriptor >& target
+)
+{
+ /*
+ * look for opposite or parallel edges in "reference" and "target" edge sets
+ */
+ bool hasOppositeEdge, hasParallelEdge ;
+ studyOrientation( graph,reference,target,hasOppositeEdge,hasParallelEdge );
+
+ /*
+ * if both opposite and parallel edge are found, there is no possible
+ * consistent orientation
+ */
+ if ( hasOppositeEdge && hasParallelEdge ) {
+ BOOST_THROW_EXCEPTION( Exception(
+ "can't make consistent orientation between EdgeStrings (both opposite and parallel edge found)"
+ ) );
+ }
+
+ /*
+ * Only parallel edge found, lets revert the orientation of the "target" edge set
+ */
+ if ( hasParallelEdge ) {
+ graph.reverse( target );
+ return true ;
+ }
+ else {
+ return false ;
+ }
+}
+
+
+}//algorithm
+}//graph
+}//SFCGAL
+
+#endif
diff --git a/src/detail/io/OsgFactory.cpp b/src/detail/io/OsgFactory.cpp
new file mode 100644
index 0000000..eaaaeb2
--- /dev/null
+++ b/src/detail/io/OsgFactory.cpp
@@ -0,0 +1,241 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/config.h>
+#ifdef SFCGAL_WITH_OSG
+
+#include <SFCGAL/detail/io/OsgFactory.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+
+#include <SFCGAL/triangulate/triangulatePolygon.h>
+#include <SFCGAL/Exception.h>
+
+
+namespace SFCGAL {
+namespace detail {
+namespace io {
+
+void OsgFactory::addToGeometry( osg::Geometry* geometry, const Geometry& g )
+{
+ if ( g.is<GeometryCollection>() ) {
+ addToGeometry( geometry, g.as<GeometryCollection>() );
+ return;
+ }
+
+ switch ( g.geometryTypeId() ) {
+ case TYPE_POINT:
+ addToGeometry( geometry, g.as<Point>() );
+ break;
+
+ case TYPE_LINESTRING:
+ addToGeometry( geometry, g.as<LineString>() );
+ break;
+
+ case TYPE_POLYGON:
+ addToGeometry( geometry, g.as<Polygon>() );
+ break;
+
+ case TYPE_TRIANGLE:
+ addToGeometry( geometry, g.as<Triangle>() );
+ break;
+
+ case TYPE_TRIANGULATEDSURFACE:
+ addToGeometry( geometry, g.as<TriangulatedSurface>() );
+ break;
+
+ case TYPE_POLYHEDRALSURFACE:
+ addToGeometry( geometry, g.as<PolyhedralSurface>() );
+ break;
+
+ case TYPE_SOLID:
+ addToGeometry( geometry, g.as<Solid>() );
+ break;
+
+ default:
+ BOOST_THROW_EXCEPTION( Exception(
+ ( boost::format( "can't convert %1% to osg::Geometry" ) % g.geometryType() ).str()
+ ) );
+ break;
+ }
+}
+
+void OsgFactory::addToGeometry( osg::Geometry* geometry, const Point& p )
+{
+ osg::Vec3Array* vertices = static_cast<osg::Vec3Array*>( geometry->getVertexArray() );
+
+ size_t start = vertices->size();
+ osg::DrawElementsUInt* primitiveSet = new osg::DrawElementsUInt( osg::PrimitiveSet::POINTS, start );
+ primitiveSet->push_back( createVertex( vertices, p ) );
+ geometry->addPrimitiveSet( primitiveSet );
+}
+
+void OsgFactory::addToGeometry( osg::Geometry* geometry, const LineString& g )
+{
+ osg::Vec3Array* vertices = static_cast<osg::Vec3Array*>( geometry->getVertexArray() );
+
+ size_t start = vertices->size() ;
+
+ for ( size_t i = 0; i < g.numPoints(); i++ ) {
+ createVertex( vertices, g.pointN( i ) ) ;
+ }
+
+ geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, start, g.numPoints() ) );
+}
+
+void OsgFactory::addToGeometry( osg::Geometry* geometry, const Triangle& g )
+{
+ osg::Vec3Array* vertices = static_cast<osg::Vec3Array*>( geometry->getVertexArray() );
+
+ size_t start = vertices->size();
+ osg::DrawElementsUInt* primitiveSet = new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, start );
+
+ for ( size_t i = 0; i < 3; i++ ) {
+ primitiveSet->push_back( createVertex( vertices, g.vertex( i ) ) );
+ }
+
+ geometry->addPrimitiveSet( primitiveSet );
+}
+
+void OsgFactory::addToGeometry( osg::Geometry* geometry, const TriangulatedSurface& g )
+{
+ osg::Vec3Array* vertices = static_cast<osg::Vec3Array*>( geometry->getVertexArray() );
+ osg::Vec3Array* normals = static_cast<osg::Vec3Array*>( geometry->getNormalArray() );
+
+ size_t start = vertices->size() ;
+
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ const Triangle& triangle = g.geometryN( i );
+
+ osg::Vec3 a = createVec3( triangle.vertex( 0 ) );
+ osg::Vec3 b = createVec3( triangle.vertex( 1 ) );
+ osg::Vec3 c = createVec3( triangle.vertex( 2 ) );
+
+ //vertices
+ createVertex( vertices, a ) ;
+ createVertex( vertices, b ) ;
+ createVertex( vertices, c ) ;
+
+ //normal
+ osg::Vec3 normal = ( c - b ) ^ ( a - b ) ;
+ normal.normalize();
+
+ normals->push_back( normal ) ;
+ normals->push_back( normal ) ;
+ normals->push_back( normal ) ;
+ }
+
+ geometry->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
+ geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::TRIANGLES, start, g.numGeometries() * 3 ) );
+}
+
+void OsgFactory::addToGeometry( osg::Geometry* geometry, const Polygon& g )
+{
+ TriangulatedSurface surf;
+ triangulate::triangulatePolygon3D( g, surf );
+ addToGeometry( geometry, surf );
+}
+
+void OsgFactory::addToGeometry( osg::Geometry* geometry, const PolyhedralSurface& g )
+{
+ TriangulatedSurface surf;
+ triangulate::triangulatePolygon3D( g, surf );
+ addToGeometry( geometry, surf );
+}
+
+void OsgFactory::addToGeometry( osg::Geometry* geometry, const Solid& g )
+{
+ TriangulatedSurface triangulatedSurface ;
+
+ for ( size_t i = 0; i < g.numShells(); i++ ) {
+ triangulate::triangulatePolygon3D( g.shellN( i ), triangulatedSurface );
+ }
+
+ addToGeometry( geometry, triangulatedSurface );
+}
+
+void OsgFactory::addToGeometry( osg::Geometry* geometry, const GeometryCollection& g )
+{
+ for ( size_t i = 0; i < g.numGeometries(); ++i ) {
+ // pseudo-recurse call
+ addToGeometry( geometry, g.geometryN( i ) );
+ }
+}
+///
+///
+///
+osg::Geometry* OsgFactory::createGeometry( const Geometry& g )
+{
+ if ( g.isEmpty() ) {
+ return NULL;
+ }
+
+ osg::ref_ptr<osg::Geometry> geometry( new osg::Geometry );
+ geometry->setVertexArray( new osg::Vec3Array() );
+ geometry->setNormalArray( new osg::Vec3Array() );
+
+ addToGeometry( geometry.get(), g );
+ return geometry.release();
+}
+
+///
+///
+///
+osg::Vec3 OsgFactory::createVec3( const Point& g ) const
+{
+ return osg::Vec3(
+ CGAL::to_double( g.x() ),
+ CGAL::to_double( g.y() ),
+ CGAL::to_double( g.z() )
+ ) ;
+}
+
+///
+///
+///
+size_t OsgFactory::createVertex( osg::Vec3Array* vertices, const Point& g )
+{
+ return createVertex( vertices, createVec3( g ) );
+}
+
+///
+///
+///
+size_t OsgFactory::createVertex( osg::Vec3Array* vertices, const osg::Vec3& g )
+{
+ size_t id = vertices->size();
+ vertices->push_back( g );
+ return id ;
+}
+
+}//io
+}//detail
+}//SFCGAL
+
+
+#endif // SFCGAL_WITH_OSG
+
diff --git a/src/detail/io/OsgFactory.h b/src/detail/io/OsgFactory.h
new file mode 100644
index 0000000..d5642d9
--- /dev/null
+++ b/src/detail/io/OsgFactory.h
@@ -0,0 +1,114 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_IO_OSGFACTORY_H_
+#define _SFCGAL_IO_OSGFACTORY_H_
+
+#include <SFCGAL/config.h>
+
+#ifndef SFCGAL_WITH_OSG
+# error "SFCGAL is not built with OpenSceneGraph support, this header can't be included"
+#endif
+
+#include <osg/Geometry>
+
+#include <SFCGAL/Geometry.h>
+
+namespace SFCGAL {
+namespace detail {
+namespace io {
+
+/**
+ * @brief helper class to convert SFCGAL::Geometry to osg::Geometry
+ */
+class SFCGAL_API OsgFactory {
+public:
+ /**
+ * create a osg::Geometry from a Point
+ */
+ osg::Geometry* createGeometry( const Geometry& g ) ;
+
+ /**
+ * create a osg::Vec3 from a Point
+ */
+ osg::Vec3 createVec3( const Point& g ) const ;
+
+protected:
+ /**
+ * create a vertex and returns its position in a vertice array
+ */
+ size_t createVertex( osg::Vec3Array* vertices, const Point& g ) ;
+ /**
+ * create a vertex and returns its position in a vertice array
+ */
+ size_t createVertex( osg::Vec3Array* vertices, const osg::Vec3& g ) ;
+
+ /**
+ * add a SFCGAL::Geometry to a osg::Geometry (dispatch method)
+ */
+ void addToGeometry( osg::Geometry*, const Geometry& );
+
+ /**
+ * add a Point to a osg::Geometry
+ */
+ void addToGeometry( osg::Geometry*, const Point& );
+
+ /**
+ * add a LineString to a osg::Geometry
+ */
+ void addToGeometry( osg::Geometry*, const LineString& );
+
+ /**
+ * add a Triangle to a osg::Geometry
+ */
+ void addToGeometry( osg::Geometry*, const Triangle& );
+
+ /**
+ * add a Polygon to a osg::Geometry
+ */
+ void addToGeometry( osg::Geometry*, const Polygon& );
+
+ /**
+ * add a TIN to a osg::Geometry
+ */
+ void addToGeometry( osg::Geometry*, const TriangulatedSurface& );
+
+ /**
+ * add a PolyhedralSurface to a osg::Geometry
+ */
+ void addToGeometry( osg::Geometry*, const PolyhedralSurface& );
+
+ /**
+ * add a Solid to a osg::Geometry
+ */
+ void addToGeometry( osg::Geometry*, const Solid& );
+
+ /**
+ * add a GeometryCollection to a osg::Geometry
+ */
+ void addToGeometry( osg::Geometry*, const GeometryCollection& );
+};
+
+}//io
+}//detail
+}//SFCGAL
+
+
+#endif
diff --git a/src/detail/io/Serialization.cpp b/src/detail/io/Serialization.cpp
new file mode 100644
index 0000000..19a0964
--- /dev/null
+++ b/src/detail/io/Serialization.cpp
@@ -0,0 +1,173 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/io/Serialization.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+namespace SFCGAL {
+namespace io {
+
+BinarySerializer::BinarySerializer( std::ostream& ostr ) : boost::archive::binary_oarchive( ostr )
+{
+ using namespace SFCGAL;
+ register_type< Point >();
+ register_type< LineString >();
+ register_type< Triangle >();
+ register_type< Polygon >();
+ register_type< TriangulatedSurface >();
+ register_type< PolyhedralSurface >();
+ register_type< Solid >();
+ register_type< GeometryCollection >();
+ register_type< MultiPoint >();
+ register_type< MultiLineString >();
+ register_type< MultiPolygon >();
+ register_type< MultiSolid >();
+}
+
+BinaryUnserializer::BinaryUnserializer( std::istream& ostr ) : boost::archive::binary_iarchive( ostr )
+{
+ using namespace SFCGAL;
+ register_type< Point >();
+ register_type< LineString >();
+ register_type< Triangle >();
+ register_type< Polygon >();
+ register_type< TriangulatedSurface >();
+ register_type< PolyhedralSurface >();
+ register_type< Solid >();
+ register_type< GeometryCollection >();
+ register_type< MultiPoint >();
+ register_type< MultiLineString >();
+ register_type< MultiPolygon >();
+ register_type< MultiSolid >();
+}
+
+///
+///
+///
+std::string writeBinaryGeometry( const Geometry& g )
+{
+ std::ostringstream ostr;
+ BinarySerializer arc( ostr );
+ // use the pointer version to force dynamic type writing
+ const Geometry* pg = &g;
+ arc << pg;
+ return ostr.str();
+}
+
+///
+///
+///
+std::string writeBinaryPrepared( const PreparedGeometry& g )
+{
+ std::ostringstream ostr;
+ BinarySerializer arc( ostr );
+ const PreparedGeometry* pg = &g;
+ arc << pg;
+ return ostr.str();
+}
+
+///
+///
+///
+std::auto_ptr<Geometry> readBinaryGeometry( const std::string& str )
+{
+ std::istringstream istr( str );
+ BinaryUnserializer iarc( istr );
+ Geometry* g;
+ iarc >> g;
+ return std::auto_ptr<Geometry>( g );
+}
+
+///
+///
+///
+std::auto_ptr<PreparedGeometry> readBinaryPrepared( const std::string& str )
+{
+ std::istringstream istr( str );
+ BinaryUnserializer iarc( istr );
+ PreparedGeometry* pg;
+ iarc >> pg;
+ return std::auto_ptr<PreparedGeometry>( pg );
+}
+}
+}
+namespace boost {
+namespace serialization {
+
+void save( boost::archive::text_oarchive& ar, const CGAL::Gmpz& z, const unsigned int /*version*/ )
+{
+ std::ostringstream ostr;
+ ostr << z;
+ std::string str = ostr.str();
+ ar << str;
+}
+
+// specialization for binary archives
+void save ( boost::archive::binary_oarchive& ar, const CGAL::Gmpz& z, const unsigned int/* version*/ )
+{
+ const mpz_t& mpz = z.mpz();
+ int32_t size = mpz->_mp_size;
+ ar& size;
+ uint32_t rsize = size >= 0 ? size : -size;
+
+ for ( uint32_t i = 0; i < rsize; ++i ) {
+ ar& mpz->_mp_d[i];
+ }
+}
+
+
+void load( boost::archive::text_iarchive& ar, CGAL::Gmpz& z, const unsigned int /*version*/ )
+{
+ std::string line;
+ ar >> line;
+ std::istringstream istr( line );
+ istr >> z;
+}
+
+void load( boost::archive::binary_iarchive& ar, CGAL::Gmpz& z, const unsigned int /*version*/ )
+{
+ int32_t size;
+ uint32_t rsize;
+ mpz_t& mpz = z.mpz();
+ ar& size;
+ rsize = size >= 0 ? size : -size;
+ mpz->_mp_size = size;
+ _mpz_realloc( mpz, rsize );
+ uint32_t i;
+
+ for ( i = 0; i < rsize; ++i ) {
+ ar& mpz->_mp_d[i];
+ }
+}
+
+}
+}
diff --git a/src/detail/io/Serialization.h b/src/detail/io/Serialization.h
new file mode 100644
index 0000000..40dbbdb
--- /dev/null
+++ b/src/detail/io/Serialization.h
@@ -0,0 +1,165 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_SERIALIZATION_
+#define _SFCGAL_SERIALIZATION_
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Geometry.h>
+#include <SFCGAL/PreparedGeometry.h>
+
+#include <boost/assert.hpp>
+#include <boost/serialization/split_member.hpp>
+#include <boost/serialization/split_free.hpp>
+#include <boost/archive/binary_oarchive.hpp>
+#include <boost/archive/binary_iarchive.hpp>
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+namespace SFCGAL {
+
+namespace io {
+
+class SFCGAL_API BinarySerializer : public boost::archive::binary_oarchive {
+public:
+ BinarySerializer( std::ostream& ostr );
+};
+
+class SFCGAL_API BinaryUnserializer : public boost::archive::binary_iarchive {
+public:
+ BinaryUnserializer( std::istream& istr );
+};
+
+/**
+ * Convert a Geometry to its binary representation
+ * @warning resulting string may contain 0s
+ */
+SFCGAL_API std::string writeBinaryGeometry( const SFCGAL::Geometry& );
+
+/**
+ * Convert a PreparedGeometry to its binary representation
+ * @warning resulting string may contain 0s
+ */
+SFCGAL_API std::string writeBinaryPrepared( const SFCGAL::PreparedGeometry& );
+
+/**
+ * Read a Geometry from a binary representation
+ */
+SFCGAL_API std::auto_ptr<SFCGAL::Geometry> readBinaryGeometry( const std::string& );
+
+/**
+ * Read a PreparedGeometry from a binary representation
+ */
+SFCGAL_API std::auto_ptr<SFCGAL::PreparedGeometry> readBinaryPrepared( const std::string& );
+}
+}
+
+namespace boost {
+namespace serialization {
+
+/**
+ * Serialization of Gmpz for text archives
+ */
+SFCGAL_API void save( boost::archive::text_oarchive& ar, const CGAL::Gmpz& z, const unsigned int version );
+
+/**
+ * Serialization of Gmpz for binary archives
+ */
+SFCGAL_API void save ( boost::archive::binary_oarchive& ar, const CGAL::Gmpz& z, const unsigned int version );
+
+/**
+ * Unserialization of Gmpz for text archives
+ */
+SFCGAL_API void load( boost::archive::text_iarchive& ar, CGAL::Gmpz& z, const unsigned int version );
+
+/**
+ * Unserialization of Gmpz for binary archives
+ */
+SFCGAL_API void load( boost::archive::binary_iarchive& ar, CGAL::Gmpz& z, const unsigned int version );
+
+template<class Archive>
+void serialize( Archive& ar, CGAL::Gmpz& z, const unsigned int version )
+{
+ split_free( ar, z, version );
+}
+
+/**
+ * Serializer of Gmpq
+ */
+template<class Archive>
+void save( Archive& ar, const CGAL::Gmpq& q, const unsigned int /*version*/ )
+{
+ CGAL::Gmpz n = q.numerator();
+ CGAL::Gmpz d = q.denominator();
+ ar& n;
+ ar& d;
+}
+
+/**
+ * Unserializer of Gmpq
+ */
+template<class Archive>
+void load( Archive& ar, CGAL::Gmpq& q, const unsigned int /*version*/ )
+{
+ CGAL::Gmpz n;
+ CGAL::Gmpz d;
+ ar& n;
+ ar& d;
+ q = CGAL::Gmpq( n, d );
+}
+template<class Archive>
+void serialize( Archive& ar, CGAL::Gmpq& q, const unsigned int version )
+{
+ split_free( ar, q, version );
+}
+
+
+/**
+ * Serializer of Kernel::FT
+ */
+template<class Archive>
+void save( Archive& ar, const SFCGAL::Kernel::FT& q, const unsigned int /*version*/ )
+{
+ SFCGAL::Kernel::Exact_kernel::FT eq = CGAL::exact( q );
+ ar << eq;
+}
+
+/**
+ * Unserializer of Kernel::FT
+ */
+template<class Archive>
+void load( Archive& ar, SFCGAL::Kernel::FT& q, const unsigned int /*version*/ )
+{
+ SFCGAL::Kernel::Exact_kernel::FT eq;
+ ar >> eq;
+ q = eq;
+}
+template<class Archive>
+void serialize( Archive& ar, SFCGAL::Kernel::FT& q, const unsigned int version )
+{
+ split_free( ar, q, version );
+}
+
+}
+}
+
+#endif
diff --git a/src/detail/io/WktReader.cpp b/src/detail/io/WktReader.cpp
new file mode 100644
index 0000000..3b8c925
--- /dev/null
+++ b/src/detail/io/WktReader.cpp
@@ -0,0 +1,690 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/io/WktReader.h>
+
+#include <memory>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+#include <SFCGAL/Exception.h>
+
+namespace SFCGAL {
+namespace detail {
+namespace io {
+
+///
+///
+///
+WktReader::WktReader( std::istream& s ):
+ _reader( s )
+{
+
+
+}
+
+///
+///
+///
+srid_t WktReader::readSRID()
+{
+ srid_t srid = 0;
+
+ if ( _reader.imatch( "SRID=" ) ) {
+ _reader.read( srid );
+
+ if ( !_reader.match( ";" ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+ }
+
+ return srid;
+}
+
+///
+///
+Geometry* WktReader::readGeometry()
+{
+ GeometryType geometryType = readGeometryType() ;
+ _is3D = _reader.imatch( "Z" );
+ _isMeasured = _reader.imatch( "M" );
+
+ switch ( geometryType ) {
+ case TYPE_POINT : {
+ std::auto_ptr< Point > g( new Point() );
+ readInnerPoint( *g );
+ return g.release() ;
+ }
+
+ case TYPE_LINESTRING: {
+ std::auto_ptr< LineString > g( new LineString() );
+ readInnerLineString( *g );
+ return g.release() ;
+ }
+
+ case TYPE_TRIANGLE: {
+ std::auto_ptr< Triangle > g( new Triangle() );
+ readInnerTriangle( *g );
+ return g.release() ;
+ }
+
+ case TYPE_POLYGON: {
+ std::auto_ptr< Polygon > g( new Polygon() );
+ readInnerPolygon( *g );
+ return g.release() ;
+ }
+
+ case TYPE_MULTIPOINT : {
+ std::auto_ptr< MultiPoint > g( new MultiPoint() );
+ readInnerMultiPoint( *g );
+ return g.release() ;
+ }
+
+ case TYPE_MULTILINESTRING : {
+ std::auto_ptr< MultiLineString > g( new MultiLineString() );
+ readInnerMultiLineString( *g );
+ return g.release() ;
+ }
+
+ case TYPE_MULTIPOLYGON : {
+ std::auto_ptr< MultiPolygon > g( new MultiPolygon() );
+ readInnerMultiPolygon( *g );
+ return g.release() ;
+ }
+
+ case TYPE_GEOMETRYCOLLECTION : {
+ std::auto_ptr< GeometryCollection > g( new GeometryCollection() );
+ readInnerGeometryCollection( *g );
+ return g.release() ;
+ }
+
+ case TYPE_TRIANGULATEDSURFACE : {
+ std::auto_ptr< TriangulatedSurface > g( new TriangulatedSurface() );
+ readInnerTriangulatedSurface( *g );
+ return g.release() ;
+ }
+
+ case TYPE_POLYHEDRALSURFACE : {
+ std::auto_ptr< PolyhedralSurface > g( new PolyhedralSurface() );
+ readInnerPolyhedralSurface( *g );
+ return g.release() ;
+ }
+
+ case TYPE_SOLID : {
+ std::auto_ptr< Solid > g( new Solid() );
+ readInnerSolid( *g );
+ return g.release() ;
+ }
+
+ case TYPE_MULTISOLID : {
+ std::auto_ptr< MultiSolid > g( new MultiSolid() );
+ readInnerMultiSolid( *g );
+ return g.release() ;
+ }
+ }
+
+ BOOST_THROW_EXCEPTION( WktParseException( "unexpected geometry" ) );
+}
+
+///
+///
+///
+GeometryType WktReader::readGeometryType()
+{
+ if ( _reader.imatch( "POINT" ) ) {
+ return TYPE_POINT ;
+ }
+ else if ( _reader.imatch( "LINESTRING" ) ) {
+ return TYPE_LINESTRING ;
+ }
+ else if ( _reader.imatch( "POLYGON" ) ) {
+ return TYPE_POLYGON ;
+ }
+ else if ( _reader.imatch( "TRIANGLE" ) ) {
+ //not official
+ return TYPE_TRIANGLE ;
+ }
+ else if ( _reader.imatch( "MULTIPOINT" ) ) {
+ return TYPE_MULTIPOINT ;
+ }
+ else if ( _reader.imatch( "MULTILINESTRING" ) ) {
+ return TYPE_MULTILINESTRING ;
+ }
+ else if ( _reader.imatch( "MULTIPOLYGON" ) ) {
+ return TYPE_MULTIPOLYGON ;
+ }
+ else if ( _reader.imatch( "GEOMETRYCOLLECTION" ) ) {
+ return TYPE_GEOMETRYCOLLECTION ;
+ }
+ else if ( _reader.imatch( "TIN" ) ) {
+ return TYPE_TRIANGULATEDSURFACE ;
+ }
+ else if ( _reader.imatch( "POLYHEDRALSURFACE" ) ) {
+ return TYPE_POLYHEDRALSURFACE ;
+ }
+ else if ( _reader.imatch( "SOLID" ) ) {
+ //not official
+ return TYPE_SOLID ;
+ }
+ else if ( _reader.imatch( "MULTISOLID" ) ) {
+ //not official
+ return TYPE_MULTISOLID ;
+ }
+
+ std::ostringstream oss;
+ oss << "can't parse WKT geometry type (" << _reader.context() << ")" ;
+ BOOST_THROW_EXCEPTION( WktParseException( oss.str() ) );
+}
+
+
+///
+///
+///
+void WktReader::readInnerPoint( Point& g )
+{
+ if ( _reader.imatch( "EMPTY" ) ) {
+ return ;
+ }
+
+ if ( ! _reader.match( '(' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+
+ readPointCoordinate( g );
+
+ if ( ! _reader.match( ')' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+}
+
+///
+///
+///
+void WktReader::readInnerLineString( LineString& g )
+{
+ if ( _reader.imatch( "EMPTY" ) ) {
+ return ;
+ }
+
+ if ( ! _reader.match( '(' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+
+ while ( ! _reader.eof() ) {
+
+ std::auto_ptr< Point > p( new Point() ) ;
+
+ if ( readPointCoordinate( *p ) ) {
+ g.addPoint( p.release() );
+ }
+ else {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+
+ if ( _reader.match( ',' ) ) {
+ continue ;
+ }
+
+ break;
+ }
+
+
+ if ( g.numPoints() < 2U ) {
+ BOOST_THROW_EXCEPTION( WktParseException( "WKT parse error, LineString should have at least 2 points" ) );
+ }
+
+
+ if ( ! _reader.match( ')' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+}
+
+///
+///
+///
+void WktReader::readInnerPolygon( Polygon& g )
+{
+ if ( _reader.imatch( "EMPTY" ) ) {
+ return ;
+ }
+
+ if ( ! _reader.match( '(' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+
+ for( int i = 0; ! _reader.eof() ; i++ ) {
+ if ( i == 0 ) {
+ readInnerLineString( g.exteriorRing() ) ;
+ }
+ else {
+ std::auto_ptr< LineString > interiorRing( new LineString );
+ readInnerLineString( *interiorRing ) ;
+ g.addRing( interiorRing.release() ) ;
+ }
+
+ //break if not followed by another ring
+ if ( ! _reader.match( ',' ) ) {
+ break ;
+ }
+ }
+
+ if ( ! _reader.match( ')' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+}
+
+
+///
+///
+///
+void WktReader::readInnerTriangle( Triangle& g )
+{
+ if ( _reader.imatch( "EMPTY" ) ) {
+ return ;
+ }
+
+ if ( ! _reader.match( '(' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+
+ if ( ! _reader.match( '(' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+
+ // 4 points to read
+ std::vector< Point > points ;
+
+ while ( ! _reader.eof() ) {
+ points.push_back( Point() ) ;
+ readPointCoordinate( points.back() );
+
+ if ( ! _reader.match( "," ) ) {
+ break;
+ }
+ }
+
+ if ( points.size() != 4 ) {
+ BOOST_THROW_EXCEPTION( WktParseException( "WKT parse error, expected 4 points for triangle" ) );
+ }
+
+ if ( points.back() != points.front() ) {
+ BOOST_THROW_EXCEPTION( WktParseException( "WKT parse error, first point different of the last point for triangle" ) );
+ }
+
+ g = Triangle( points[0], points[1], points[2] );
+
+ if ( ! _reader.match( ')' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+
+ if ( ! _reader.match( ')' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+}
+
+///
+///
+///
+void WktReader::readInnerMultiPoint( MultiPoint& g )
+{
+ if ( _reader.imatch( "EMPTY" ) ) {
+ return ;
+ }
+
+ if ( ! _reader.match( '(' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+
+ while( ! _reader.eof() ) {
+ std::auto_ptr< Point > p( new Point() );
+
+ if ( !_reader.imatch( "EMPTY" ) ) {
+ // optional open/close parenthesis
+ bool parenthesisOpen = false ;
+
+ if ( _reader.match( '(' ) ) {
+ parenthesisOpen = true ;
+ }
+
+ readPointCoordinate( *p );
+
+ if ( parenthesisOpen && ! _reader.match( ')' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+ }
+
+ g.addGeometry( p.release() );
+
+ //break if not followed by another points
+ if ( ! _reader.match( ',' ) ) {
+ break ;
+ }
+ }
+
+ if ( ! _reader.match( ')' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+
+}
+
+///
+///
+///
+void WktReader::readInnerMultiLineString( MultiLineString& g )
+{
+ if ( _reader.imatch( "EMPTY" ) ) {
+ return ;
+ }
+
+ if ( ! _reader.match( '(' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+
+ while( ! _reader.eof() ) {
+
+ std::auto_ptr< LineString > lineString( new LineString() );
+ readInnerLineString( *lineString );
+ g.addGeometry( lineString.release() );
+
+ //break if not followed by another points
+ if ( ! _reader.match( ',' ) ) {
+ break ;
+ }
+ }
+
+ if ( ! _reader.match( ')' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+}
+
+///
+///
+///
+void WktReader::readInnerMultiPolygon( MultiPolygon& g )
+{
+ if ( _reader.imatch( "EMPTY" ) ) {
+ return ;
+ }
+
+ if ( ! _reader.match( '(' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+
+ while( ! _reader.eof() ) {
+
+ std::auto_ptr< Polygon > polygon( new Polygon() );
+ readInnerPolygon( *polygon );
+ g.addGeometry( polygon.release() );
+
+ //break if not followed by another points
+ if ( ! _reader.match( ',' ) ) {
+ break ;
+ }
+ }
+
+ if ( ! _reader.match( ')' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+}
+
+///
+///
+///
+void WktReader::readInnerGeometryCollection( GeometryCollection& g )
+{
+ if ( _reader.imatch( "EMPTY" ) ) {
+ return ;
+ }
+
+ if ( ! _reader.match( '(' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+
+ while( ! _reader.eof() ) {
+
+ //read a full wkt geometry ex : POINT(2.0 6.0)
+ g.addGeometry( readGeometry() );
+
+ //break if not followed by another points
+ if ( ! _reader.match( ',' ) ) {
+ break ;
+ }
+ }
+
+ if ( ! _reader.match( ')' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+}
+
+///
+///
+///
+void WktReader::readInnerTriangulatedSurface( TriangulatedSurface& g )
+{
+ if ( _reader.imatch( "EMPTY" ) ) {
+ return ;
+ }
+
+ if ( ! _reader.match( '(' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+
+ while( ! _reader.eof() ) {
+ std::auto_ptr< Triangle > triangle( new Triangle() ) ;
+ readInnerTriangle( *triangle );
+ g.addTriangle( triangle.release() ) ;
+
+ //break if not Oui tout à fait, le Z n'est pas pris en compte dans ce cas là.followed by another points
+ if ( ! _reader.match( ',' ) ) {
+ break ;
+ }
+ }
+
+
+ if ( ! _reader.match( ')' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+}
+
+///
+///
+///
+void WktReader::readInnerPolyhedralSurface( PolyhedralSurface& g )
+{
+ if ( _reader.imatch( "EMPTY" ) ) {
+ return ;
+ }
+
+ if ( ! _reader.match( '(' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+
+ while( ! _reader.eof() ) {
+ std::auto_ptr< Polygon > polygon( new Polygon() ) ;
+ readInnerPolygon( *polygon );
+ g.addPolygon( polygon.release() );
+
+ //break if not followed by another points
+ if ( ! _reader.match( ',' ) ) {
+ break ;
+ }
+ }
+
+ if ( ! _reader.match( ')' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+}
+
+
+///
+///
+///
+void WktReader::readInnerSolid( Solid& g )
+{
+ if ( _reader.imatch( "EMPTY" ) ) {
+ return ;
+ }
+
+ //solid begin
+ if ( ! _reader.match( '(' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+
+ for ( int i = 0; ! _reader.eof(); i++ ) {
+ if ( i == 0 ) {
+ readInnerPolyhedralSurface( g.exteriorShell() );
+ }
+ else {
+ std::auto_ptr< PolyhedralSurface > shell( new PolyhedralSurface ) ;
+ readInnerPolyhedralSurface( *shell );
+ g.addInteriorShell( shell.release() );
+ }
+
+ //break if not followed by another points
+ if ( ! _reader.match( ',' ) ) {
+ break ;
+ }
+ }
+
+ //solid end
+ if ( ! _reader.match( ')' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+}
+
+///
+///
+///
+void WktReader::readInnerMultiSolid( MultiSolid& g )
+{
+ if ( _reader.imatch( "EMPTY" ) ) {
+ return ;
+ }
+
+ if ( ! _reader.match( '(' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+
+ while( ! _reader.eof() ) {
+
+ std::auto_ptr< Solid > solid( new Solid() );
+ readInnerSolid( *solid );
+ g.addGeometry( solid.release() );
+
+ //break if not followed by another points
+ if ( ! _reader.match( ',' ) ) {
+ break ;
+ }
+ }
+
+ if ( ! _reader.match( ')' ) ) {
+ BOOST_THROW_EXCEPTION( WktParseException( parseErrorMessage() ) );
+ }
+}
+
+
+///
+///
+///
+bool WktReader::readPointCoordinate( Point& p )
+{
+ std::vector< Kernel::Exact_kernel::FT > coordinates ;
+ Kernel::Exact_kernel::FT d;
+
+ if ( _reader.imatch( "EMPTY" ) ) {
+ p = Point();
+ return false;
+ }
+
+ while ( _reader.read( d ) ) {
+ coordinates.push_back( d );
+ }
+
+ if ( coordinates.size() < 2 ) {
+ BOOST_THROW_EXCEPTION( WktParseException(
+ ( boost::format( "WKT parse error, Coordinate dimension < 2 (%s)" ) % _reader.context() ).str()
+ ) );
+ }
+
+ if ( coordinates.size() > 4 ) {
+ BOOST_THROW_EXCEPTION( WktParseException( "WKT parse error, Coordinate dimension > 4" ) );
+ }
+
+ if ( _isMeasured && _is3D ) {
+ // XYZM
+ if ( coordinates.size() != 4 ) {
+ BOOST_THROW_EXCEPTION( WktParseException( "bad coordinate dimension" ) );
+ }
+
+ p = Point( coordinates[0], coordinates[1], coordinates[2] );
+ p.setM( coordinates[3].to_double() );
+ }
+ else if ( _isMeasured && ! _is3D ) {
+ // XYM
+ if ( coordinates.size() != 3 ) {
+ BOOST_THROW_EXCEPTION( WktParseException( "bad coordinate dimension (expecting XYM coordinates)" ) );
+ }
+
+ p = Point( coordinates[0], coordinates[1] );
+ p.setM( coordinates[2].to_double() );
+ }
+ else if ( coordinates.size() == 3 ) {
+ // XYZ
+ p = Point( coordinates[0], coordinates[1], coordinates[2] );
+ }
+ else {
+ // XY
+ p = Point( coordinates[0], coordinates[1] );
+ }
+
+ return true ;
+}
+
+
+///
+///
+///
+std::string WktReader::parseErrorMessage()
+{
+ std::ostringstream oss;
+ oss << "WKT parse error (" << _reader.context() << ")" ;
+ return oss.str();
+}
+
+
+
+
+
+
+}//io
+}//detail
+}//SFCGAL
+
diff --git a/src/detail/io/WktReader.h b/src/detail/io/WktReader.h
new file mode 100644
index 0000000..1c70797
--- /dev/null
+++ b/src/detail/io/WktReader.h
@@ -0,0 +1,168 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_IO_WKTREADER_H_
+#define _SFCGAL_IO_WKTREADER_H_
+
+#include <sstream>
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Geometry.h>
+#include <SFCGAL/PreparedGeometry.h>
+
+#include <SFCGAL/detail/tools/InputStreamReader.h>
+
+namespace SFCGAL {
+namespace detail {
+namespace io {
+
+/**
+ * read WKT geometry
+ *
+ * @warning M is ignored
+ * @ŧodo take M in account?
+ */
+class SFCGAL_API WktReader {
+public:
+ /**
+ * read WKT from input stream
+ */
+ WktReader( std::istream& s );
+
+ /**
+ * read an SRID, if present
+ *
+ */
+ srid_t readSRID() ;
+
+ /**
+ * read a geometry from a string
+ *
+ * @warning returns new instance
+ */
+ Geometry* readGeometry() ;
+
+ /**
+ * read geometry type
+ */
+ GeometryType readGeometryType() ;
+ /**
+ * read coordinate type [Z][M]
+ */
+ CoordinateType readCoordinateType() ;
+
+ /**
+ * Read Point content from wkt
+ *
+ * ex : (1.0 2.0 14.0)
+ */
+ void readInnerPoint( Point& g ) ;
+ /**
+ * Read LineString content from wkt
+ *
+ * ex : (1.0 2.0,1.0,6.0)
+ */
+ void readInnerLineString( LineString& g ) ;
+ /**
+ * Read Polygon content from wkt
+ *
+ * ex : ((30 10, 10 20, 20 40, 40 40, 30 10))
+ */
+ void readInnerPolygon( Polygon& g ) ;
+ /**
+ * Read Triangle content from wkt
+ */
+ void readInnerTriangle( Triangle& g ) ;
+
+ /**
+ * Read MultiPoint content from wkt
+ *
+ * ex : (0.0 1.0,5.0 6.0) or ((0.0 4.0),(5.0 6.0))
+ */
+ void readInnerMultiPoint( MultiPoint& g ) ;
+ /**
+ * Read MultiLineString content from wkt
+ */
+ void readInnerMultiLineString( MultiLineString& g ) ;
+ /**
+ * Read MultiPolygon content from wkt
+ */
+ void readInnerMultiPolygon( MultiPolygon& g ) ;
+
+ /**
+ * Read GeometryCollection content from wkt
+ */
+ void readInnerGeometryCollection( GeometryCollection& g ) ;
+
+ /**
+ * Read TriangulatedSurface content from wkt
+ */
+ void readInnerTriangulatedSurface( TriangulatedSurface& g ) ;
+
+ /**
+ * Read PolyhedralSurface content from wkt
+ */
+ void readInnerPolyhedralSurface( PolyhedralSurface& g ) ;
+
+
+ /**
+ * Read Solid content from wkt
+ */
+ void readInnerSolid( Solid& g ) ;
+
+ /**
+ * Read MultiSolid content from wkt
+ */
+ void readInnerMultiSolid( MultiSolid& g ) ;
+
+ /**
+ * Read coordinate from WKT
+ * @todo ZM management
+ */
+ bool readPointCoordinate( Point& p ) ;
+
+private:
+ /**
+ * input stream
+ */
+ tools::InputStreamReader _reader;
+
+ /**
+ * actually reading 3D ?
+ */
+ bool _is3D ;
+ /**
+ * actually reading Measured ?
+ */
+ bool _isMeasured ;
+
+
+ /**
+ * returns default parse error message
+ */
+ std::string parseErrorMessage() ;
+};
+
+}//io
+}//detail
+}//SFCGAL
+
+#endif
diff --git a/src/detail/io/WktWriter.cpp b/src/detail/io/WktWriter.cpp
new file mode 100644
index 0000000..900cdc8
--- /dev/null
+++ b/src/detail/io/WktWriter.cpp
@@ -0,0 +1,525 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/io/WktWriter.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+#include <exception>
+#include <boost/exception/all.hpp>
+
+namespace SFCGAL {
+namespace detail {
+namespace io {
+
+///
+///
+///
+WktWriter::WktWriter( std::ostream& s ):
+ _s( s ),
+ _exactWrite( false )
+{
+
+}
+
+void WktWriter::writeRec( const Geometry& g )
+{
+ switch( g.geometryTypeId() ) {
+ case TYPE_POINT:
+ write( g.as< Point >() );
+ return ;
+
+ case TYPE_LINESTRING:
+ write( g.as< LineString >() );
+ return ;
+
+ case TYPE_POLYGON:
+ write( g.as< Polygon >() );
+ return ;
+
+ case TYPE_GEOMETRYCOLLECTION:
+ write( g.as< GeometryCollection >() );
+ return ;
+
+ case TYPE_MULTIPOINT:
+ write( g.as< MultiPoint >() );
+ return ;
+
+ case TYPE_MULTILINESTRING:
+ write( g.as< MultiLineString >() );
+ return ;
+
+ case TYPE_MULTIPOLYGON:
+ write( g.as< MultiPolygon >() );
+ return ;
+
+ case TYPE_TRIANGLE:
+ write( g.as< Triangle >() );
+ return ;
+
+ case TYPE_TRIANGULATEDSURFACE:
+ write( g.as< TriangulatedSurface >() );
+ return ;
+
+ case TYPE_POLYHEDRALSURFACE:
+ write( g.as< PolyhedralSurface >() );
+ return ;
+
+ case TYPE_SOLID:
+ write( g.as< Solid >() );
+ return ;
+
+ case TYPE_MULTISOLID:
+ write( g.as< MultiSolid >() );
+ return ;
+ }
+
+ std::ostringstream oss;
+ oss << "WktWriter : '" << g.geometryType() << "' is not supported" ;
+ BOOST_THROW_EXCEPTION( std::runtime_error( oss.str() ) );
+}
+
+///
+///
+///
+void WktWriter::write( const Geometry& g, bool exact )
+{
+ _exactWrite = exact;
+ writeRec( g );
+}
+
+///
+///
+///
+void WktWriter::writeCoordinateType( const Geometry& g )
+{
+ if ( g.is3D() && g.isMeasured() ) {
+ _s << " ZM";
+ }
+ else if ( ! g.is3D() && g.isMeasured() ) {
+ _s << " M";
+ }
+}
+
+///
+///
+///
+void WktWriter::writeCoordinate( const Point& g )
+{
+ if ( _exactWrite ) {
+ _s << CGAL::exact( g.x() ) << " " << CGAL::exact( g.y() );
+
+ if ( g.is3D() ) {
+ _s << " " << CGAL::exact( g.z() );
+ }
+ }
+ else {
+ _s << g.x() << " " << g.y() ;
+
+ if ( g.is3D() ) {
+ _s << " " << g.z() ;
+ }
+ }
+
+ // m coordinate
+ if ( g.isMeasured() ) {
+ _s << " " << g.m() ;
+ }
+}
+
+///
+///
+///
+void WktWriter::write( const Point& g )
+{
+ _s << "POINT" ;
+ writeCoordinateType( g );
+
+ if ( g.isEmpty() ) {
+ _s << " EMPTY" ;
+ return ;
+ }
+
+ writeInner( g );
+}
+
+///
+///
+///
+void WktWriter::writeInner( const Point& g )
+{
+ if ( g.isEmpty() ) {
+ _s << "EMPTY" ;
+ return ;
+ }
+
+ _s << "(";
+ writeCoordinate( g );
+ _s << ")";
+}
+
+///
+///
+///
+void WktWriter::write( const LineString& g )
+{
+ _s << "LINESTRING" ;
+ writeCoordinateType( g );
+
+ if ( g.isEmpty() ) {
+ _s << " EMPTY" ;
+ return ;
+ }
+
+ writeInner( g );
+}
+
+///
+///
+///
+void WktWriter::writeInner( const LineString& g )
+{
+ _s << "(";
+
+ for ( size_t i = 0; i < g.numPoints(); i++ ) {
+ if ( i != 0 ) {
+ _s << ",";
+ }
+
+ writeCoordinate( g.pointN( i ) );
+ }
+
+ _s << ")";
+}
+
+
+///
+///
+///
+void WktWriter::write( const Polygon& g )
+{
+ _s << "POLYGON" ;
+ writeCoordinateType( g );
+
+ if ( g.isEmpty() ) {
+ _s << " EMPTY" ;
+ return ;
+ }
+
+ writeInner( g );
+}
+
+///
+///
+///
+void WktWriter::writeInner( const Polygon& g )
+{
+ _s << "(";
+ writeInner( g.exteriorRing() );
+
+ for ( size_t i = 0; i < g.numInteriorRings(); i++ ) {
+ _s << ",";
+ writeInner( g.interiorRingN( i ) );
+ }
+
+ _s << ")";
+}
+
+///
+///
+///
+void WktWriter::write( const GeometryCollection& g )
+{
+ _s << "GEOMETRYCOLLECTION" ;
+ writeCoordinateType( g );
+
+ if ( g.isEmpty() ) {
+ _s << " EMPTY" ;
+ return ;
+ }
+
+ _s << "(" ;
+
+ for ( size_t i = 0 ; i < g.numGeometries(); i++ ) {
+ if ( i != 0 ) {
+ _s << ",";
+ }
+
+ writeRec( g.geometryN( i ) );
+ }
+
+ _s << ")" ;
+}
+
+///
+///
+///
+void WktWriter::write( const MultiPoint& g )
+{
+ _s << "MULTIPOINT" ;
+ writeCoordinateType( g );
+
+ if ( g.isEmpty() ) {
+ _s << " EMPTY" ;
+ return ;
+ }
+
+ _s << "(";
+
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ if ( i != 0 ) {
+ _s << "," ;
+ }
+
+ writeInner( g.geometryN( i ).as< Point >() );
+ }
+
+ _s << ")";
+}
+
+///
+///
+///
+void WktWriter::write( const MultiLineString& g )
+{
+ _s << "MULTILINESTRING" ;
+ writeCoordinateType( g );
+
+ if ( g.isEmpty() ) {
+ _s << " EMPTY" ;
+ return ;
+ }
+
+ _s << "(";
+
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ if ( i != 0 ) {
+ _s << "," ;
+ }
+
+ writeInner( g.geometryN( i ).as< LineString >() );
+ }
+
+ _s << ")";
+}
+
+///
+///
+///
+void WktWriter::write( const MultiPolygon& g )
+{
+ _s << "MULTIPOLYGON" ;
+ writeCoordinateType( g );
+
+ if ( g.isEmpty() ) {
+ _s << " EMPTY" ;
+ return ;
+ }
+
+ _s << "(";
+
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ if ( i != 0 ) {
+ _s << "," ;
+ }
+
+ writeInner( g.geometryN( i ).as< Polygon >() );
+ }
+
+ _s << ")";
+}
+
+
+///
+///
+///
+void WktWriter::write( const MultiSolid& g )
+{
+ _s << "MULTISOLID" ;
+ writeCoordinateType( g );
+
+ if ( g.isEmpty() ) {
+ _s << " EMPTY" ;
+ return ;
+ }
+
+ _s << "(";
+
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ if ( i != 0 ) {
+ _s << "," ;
+ }
+
+ writeInner( g.geometryN( i ).as< Solid >() );
+ }
+
+ _s << ")";
+}
+
+///
+///
+///
+void WktWriter::write( const Triangle& g )
+{
+ _s << "TRIANGLE" ;
+ writeCoordinateType( g );
+
+ if ( g.isEmpty() ) {
+ _s << " EMPTY" ;
+ return ;
+ }
+
+ writeInner( g );
+}
+
+///
+///
+///
+void WktWriter::writeInner( const Triangle& g )
+{
+ _s << "(";
+ _s << "(";
+
+ //close triangle
+ for ( size_t i = 0; i < 4; i++ ) {
+ if ( i != 0 ) {
+ _s << "," ;
+ }
+
+ writeCoordinate( g.vertex( i ) );
+ }
+
+ _s << ")";
+ _s << ")";
+}
+
+///
+///
+///
+void WktWriter::write( const TriangulatedSurface& g )
+{
+ _s << "TIN" ;
+ writeCoordinateType( g );
+
+ if ( g.isEmpty() ) {
+ _s << " EMPTY" ;
+ return ;
+ }
+
+ _s << "(" ; //begin TIN
+
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ if ( i != 0 ) {
+ _s << ",";
+ }
+
+ writeInner( g.geometryN( i ) );
+ }
+
+ _s << ")" ; //end TIN
+}
+
+
+///
+///
+///
+void WktWriter::write( const PolyhedralSurface& g )
+{
+ _s << "POLYHEDRALSURFACE" ;
+ writeCoordinateType( g );
+
+ if ( g.isEmpty() ) {
+ _s << " EMPTY" ;
+ return ;
+ }
+
+ writeInner( g );
+}
+
+///
+///
+///
+void WktWriter::writeInner( const PolyhedralSurface& g )
+{
+ _s << "(" ; //begin POLYHEDRALSURFACE
+
+ for ( size_t i = 0; i < g.numPolygons(); i++ ) {
+ if ( i != 0 ) {
+ _s << ",";
+ }
+
+ writeInner( g.polygonN( i ) );
+ }
+
+ _s << ")" ; //end POLYHEDRALSURFACE
+}
+
+///
+///
+///
+void WktWriter::write( const Solid& g )
+{
+ _s << "SOLID" ;
+ writeCoordinateType( g );
+
+ if ( g.isEmpty() ) {
+ _s << " EMPTY" ;
+ return ;
+ }
+
+ writeInner( g );
+}
+
+///
+///
+///
+void WktWriter::writeInner( const Solid& g )
+{
+ _s << "(" ; //begin SOLID
+ writeInner( g.exteriorShell() );
+
+ for ( size_t i = 0; i < g.numInteriorShells(); i++ ) {
+ _s << ",";
+ writeInner( g.interiorShellN( i ) );
+ }
+
+ _s << ")" ; //end SOLID
+}
+
+
+
+
+}//io
+}//detail
+}//SFCGAL
+
+
+
diff --git a/src/detail/io/WktWriter.h b/src/detail/io/WktWriter.h
new file mode 100644
index 0000000..7bc3b01
--- /dev/null
+++ b/src/detail/io/WktWriter.h
@@ -0,0 +1,94 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_IO_WKTWRITER_H_
+#define _SFCGAL_IO_WKTWRITER_H_
+
+#include <sstream>
+
+#include <SFCGAL/config.h>
+#include <SFCGAL/Geometry.h>
+
+namespace SFCGAL {
+namespace detail {
+namespace io {
+
+/**
+ * Writer for WKT
+ *
+ * @warning Triangles are transformed into polygons
+ */
+class SFCGAL_API WktWriter {
+public:
+ WktWriter( std::ostream& s ) ;
+
+ /**
+ * @todo replace with visitor dispatch
+ */
+ void write( const Geometry& g, bool exact = false ) ;
+
+protected:
+ /**
+ * write coordinate type (""|" Z"|" ZM")
+ */
+ void writeCoordinateType( const Geometry& g );
+
+ void writeCoordinate( const Point& g );
+
+ void write( const Point& g ) ;
+ void writeInner( const Point& g ) ;
+
+ void write( const LineString& g ) ;
+ void writeInner( const LineString& g ) ;
+
+ void write( const Polygon& g ) ;
+ void writeInner( const Polygon& g ) ;
+
+ void write( const GeometryCollection& g ) ;
+
+ void write( const MultiPoint& g ) ;
+ void write( const MultiLineString& g ) ;
+ void write( const MultiPolygon& g ) ;
+ void write( const MultiSolid& g ) ;
+
+ void write( const Triangle& g );
+ void writeInner( const Triangle& g ) ;
+
+ void write( const TriangulatedSurface& g );
+
+ void write( const PolyhedralSurface& g );
+ void writeInner( const PolyhedralSurface& g );
+
+ void write( const Solid& g );
+ void writeInner( const Solid& g );
+
+ // for recursive call use
+ void writeRec( const Geometry& g ) ;
+private:
+ std::ostream& _s ;
+ bool _exactWrite;
+};
+
+
+}//io
+}//detail
+}//SFCGAL
+
+#endif
diff --git a/src/detail/polygonSetToMultiPolygon.cpp b/src/detail/polygonSetToMultiPolygon.cpp
new file mode 100644
index 0000000..318b0bf
--- /dev/null
+++ b/src/detail/polygonSetToMultiPolygon.cpp
@@ -0,0 +1,50 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/polygonSetToMultiPolygon.h>
+
+#include <CGAL/Polygon_with_holes_2.h>
+
+#include <list>
+
+namespace SFCGAL {
+namespace detail {
+
+///
+///
+///
+std::auto_ptr< MultiPolygon > polygonSetToMultiPolygon( const CGAL::Polygon_set_2< Kernel >& polygonSet )
+{
+ typedef CGAL::Polygon_with_holes_2< Kernel > Polygon_with_holes_2 ;
+
+ std::list<Polygon_with_holes_2> res;
+ polygonSet.polygons_with_holes( std::back_inserter( res ) ) ;
+
+ std::auto_ptr< MultiPolygon > result( new MultiPolygon );
+
+ for ( std::list<Polygon_with_holes_2>::const_iterator it = res.begin(); it != res.end(); ++it ) {
+ result->addGeometry( new Polygon( *it ) );
+ }
+
+ return result ;
+}
+
+} // namespace detail
+} // namespace SFCGAL
diff --git a/src/detail/polygonSetToMultiPolygon.h b/src/detail/polygonSetToMultiPolygon.h
new file mode 100644
index 0000000..6d93436
--- /dev/null
+++ b/src/detail/polygonSetToMultiPolygon.h
@@ -0,0 +1,42 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_DETAIL_POLYGONSETTOMULTIPOLYGON_H_
+#define _SFCGAL_DETAIL_POLYGONSETTOMULTIPOLYGON_H_
+
+#include <SFCGAL/config.h>
+
+#include <CGAL/Polygon_set_2.h>
+#include <SFCGAL/MultiPolygon.h>
+
+namespace SFCGAL {
+namespace detail {
+
+/**
+ * @brief convert a CGAL::Polygon_set_2 to a MultiPolygon
+ * @todo unittest
+ */
+SFCGAL_API std::auto_ptr< MultiPolygon > polygonSetToMultiPolygon( const CGAL::Polygon_set_2< Kernel >& polygonSet ) ;
+
+} // namespace detail
+} // namespace SFCGAL
+
+
+#endif
diff --git a/src/detail/tools/CharArrayBuffer.cpp b/src/detail/tools/CharArrayBuffer.cpp
new file mode 100644
index 0000000..3de8f0d
--- /dev/null
+++ b/src/detail/tools/CharArrayBuffer.cpp
@@ -0,0 +1,104 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <iostream>
+
+#include <SFCGAL/detail/tools/CharArrayBuffer.h>
+
+#include <cstring>
+
+CharArrayBuffer::CharArrayBuffer( const char* begin, const char* end ) :
+ begin_( begin ),
+ end_( end ),
+ current_( begin_ )
+{
+}
+
+CharArrayBuffer::CharArrayBuffer( const char* str ) :
+ begin_( str ),
+ end_( begin_ + std::strlen( str ) ),
+ current_( begin_ )
+{
+}
+
+
+std::streampos CharArrayBuffer::seekoff( std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode )
+{
+ if ( way == std::ios_base::cur ) {
+ if ( current_ + off < end_ ) {
+ current_ += off;
+ }
+ else {
+ return -1;
+ }
+ }
+ else if ( way == std::ios_base::beg ) {
+ if ( begin_ + off < end_ ) {
+ current_ = begin_ + off;
+ }
+ else {
+ return -1;
+ }
+ }
+
+ return current_ - begin_;
+}
+
+std::streampos CharArrayBuffer::seekpos( std::streampos pos, std::ios_base::openmode )
+{
+ if ( begin_ + pos >= end_ ) {
+ return -1;
+ }
+
+ current_ = begin_ + pos;
+ return current_ - begin_;
+}
+
+CharArrayBuffer::int_type CharArrayBuffer::underflow()
+{
+ if ( current_ == end_ ) {
+ return traits_type::eof();
+ }
+
+ return traits_type::to_int_type( *current_ );
+}
+
+CharArrayBuffer::int_type CharArrayBuffer::uflow()
+{
+ if ( current_ == end_ ) {
+ return traits_type::eof();
+ }
+
+ return traits_type::to_int_type( *current_++ );
+}
+
+CharArrayBuffer::int_type CharArrayBuffer::pbackfail( int_type ch )
+{
+ if ( current_ == begin_ || ( ch != traits_type::eof() && ch != current_[-1] ) ) {
+ return traits_type::eof();
+ }
+
+ return traits_type::to_int_type( *--current_ );
+}
+
+std::streamsize CharArrayBuffer::showmanyc()
+{
+ return end_ - current_;
+}
diff --git a/src/detail/tools/CharArrayBuffer.h b/src/detail/tools/CharArrayBuffer.h
new file mode 100644
index 0000000..304cefd
--- /dev/null
+++ b/src/detail/tools/CharArrayBuffer.h
@@ -0,0 +1,60 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_TOOLS_CHARARRAYBUFFER_H_
+#define _SFCGAL_TOOLS_CHARARRAYBUFFER_H_
+
+#include <SFCGAL/config.h>
+
+#include <streambuf>
+
+
+///
+/// Streambuf on a char*
+///
+/// http://www.mr-edd.co.uk/blog/beginners_guide_streambuf
+///
+class SFCGAL_API CharArrayBuffer : public std::streambuf {
+public:
+ CharArrayBuffer( const char* begin, const char* end );
+ explicit CharArrayBuffer( const char* str );
+
+private:
+ int_type underflow();
+ int_type uflow();
+ int_type pbackfail( int_type ch );
+ std::streamsize showmanyc();
+
+ // copy ctor and assignment not implemented;
+ // copying not allowed
+ CharArrayBuffer( const CharArrayBuffer& );
+ CharArrayBuffer& operator= ( const CharArrayBuffer& );
+
+ std::streampos seekpos( std::streampos pos, std::ios_base::openmode );
+ std::streampos seekoff ( std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode );
+private:
+ const char* const begin_;
+ const char* const end_;
+ const char* current_;
+};
+
+
+#endif
+
diff --git a/src/detail/tools/InputStreamReader.h b/src/detail/tools/InputStreamReader.h
new file mode 100644
index 0000000..d2f1d66
--- /dev/null
+++ b/src/detail/tools/InputStreamReader.h
@@ -0,0 +1,241 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_TOOLS_INPUTSTREAMREADER_H_
+#define _SFCGAL_TOOLS_INPUTSTREAMREADER_H_
+
+#include <SFCGAL/config.h>
+
+#include <cctype>
+#include <string>
+#include <sstream>
+#include <stack>
+
+namespace SFCGAL {
+namespace tools {
+
+template < typename CharType > class BasicInputStreamReader ;
+
+/**
+ * typedef for std::istream
+ */
+typedef BasicInputStreamReader< char > InputStreamReader ;
+/**
+ * typedef for std::wistream
+ */
+typedef BasicInputStreamReader< wchar_t > WInputStreamReader ;
+
+
+/**
+ * Helper class to parse data from stream.
+ */
+template < typename CharType >
+class BasicInputStreamReader {
+public:
+ typedef CharType char_type ;
+ typedef typename std::basic_string< char_type > string_type ;
+ typedef typename std::basic_istream< char_type > istream_type ;
+ typedef typename std::basic_istream< char_type >::pos_type pos_type ;
+
+ /// \brief constructor with an input stream
+ BasicInputStreamReader( istream_type& s, bool skipWhiteSpaces = true ):
+ _s( s ),
+ _states(),
+ _skipWhiteSpaces( skipWhiteSpaces ) {
+ _s >> std::noskipws ;
+ }
+
+ /// \brief try to match a char in the input stream
+ bool match( char_type const& c ) {
+ begin();
+
+ if ( _skipWhiteSpaces ) {
+ skipWhiteSpaces();
+ }
+
+ if ( ! _s.eof() && _s.get() == c ) {
+ commit();
+ return true ;
+ }
+ else {
+ rollback();
+ return false;
+ }
+ }
+
+
+ /// \brief try to match a char in the input stream, case-insensitive variant
+ bool imatch( char_type const& c ) {
+ begin();
+
+ if ( _skipWhiteSpaces ) {
+ skipWhiteSpaces();
+ }
+
+ if ( ! _s.eof() && ::tolower( _s.get() ) == ::tolower( c ) ) {
+ commit();
+ return true ;
+ }
+ else {
+ rollback();
+ return false;
+ }
+ }
+
+ /// \brief try to match a string in the input stream
+ bool match( string_type const& str ) {
+ begin();
+
+ if ( _skipWhiteSpaces ) {
+ skipWhiteSpaces();
+ }
+
+ for ( typename string_type::const_iterator it = str.begin(); it != str.end(); ++it ) {
+ if ( ! _s.eof() && _s.get() == *it ) {
+ continue ;
+ }
+
+ rollback();
+ return false ;
+ }
+
+ commit();
+ return true ;
+ }
+
+ /// \brief try to match a string in the input stream, case-insensitive variant
+ bool imatch( string_type const& str ) {
+ begin();
+
+ if ( _skipWhiteSpaces ) {
+ skipWhiteSpaces();
+ }
+
+ for ( typename string_type::const_iterator it = str.begin(); it != str.end(); ++it ) {
+ if ( ! _s.eof() && ::tolower( _s.get() ) == ::tolower( *it ) ) {
+ continue ;
+ }
+
+ rollback();
+ return false ;
+ }
+
+ commit();
+ return true ;
+ }
+
+ /// \brief try to read a value in the input stream, restore state if read fails
+ template < typename T >
+ bool read( T& value ) {
+ begin();
+
+ if ( _skipWhiteSpaces ) {
+ skipWhiteSpaces();
+ }
+
+ if ( _s >> value ) {
+ commit();
+ return true ;
+ }
+ else {
+ rollback();
+ return false ;
+ }
+ }
+
+ /// \brief save input stream state (read position)
+ void begin() {
+ _states.push( _s.tellg() );
+ }
+ /// \brief validate read from input stream
+ void commit() {
+ _states.pop();
+ }
+ /// \brief restore stream state (read position)
+ void rollback() {
+ _s.seekg( _states.top() ) ;
+ _s.clear();
+ _states.pop();
+ }
+
+ /// \brief test if read is complete (either tried to reader after eof, either on eof)
+ bool eof() const {
+ return _s.eof() || ( _s.peek() == std::char_traits< char_type >::eof() ) ;
+ }
+
+ /// \brief returns the wrapped stream
+ inline istream_type& s() {
+ return _s;
+ }
+ /// \brief returns the wrapped stream
+ inline istream_type const& s() const {
+ return _s;
+ }
+
+
+ /**
+ * returns a string corresponding to the current state
+ */
+ string_type context( size_t nMax = 20 ) {
+ begin();
+ std::basic_ostringstream< char_type > oss ;
+
+ for ( size_t i = 0; i < nMax; i++ ) {
+ if ( eof() ) {
+ break;
+ }
+
+ oss << ( char_type )s().get();
+ }
+
+ if ( ! eof() ) {
+ oss << "..." ;
+ }
+
+ rollback();
+ return oss.str();
+ }
+
+private:
+ /// \brief the input stream
+ istream_type& _s ;
+ /// \brief read position saved
+ std::stack< pos_type > _states ;
+ /// \brief indicates if white chars should be skipped
+ bool _skipWhiteSpaces ;
+
+ /// \brief skip white spaces
+ void skipWhiteSpaces() {
+ while ( ! _s.eof() && std::isspace( _s.peek() ) ) {
+ _s.get();
+ continue;
+ }
+ }
+
+ /// \brief no copy
+ BasicInputStreamReader( BasicInputStreamReader const& other );
+};
+
+
+}//tools
+}//ign
+
+
+#endif
diff --git a/src/detail/tools/Log.cpp b/src/detail/tools/Log.cpp
new file mode 100644
index 0000000..eef7eaf
--- /dev/null
+++ b/src/detail/tools/Log.cpp
@@ -0,0 +1,150 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <iostream>
+#include <boost/date_time.hpp>
+
+#include <SFCGAL/detail/tools/Log.h>
+
+namespace SFCGAL {
+
+///
+///
+///
+Logger::~Logger()
+{
+
+}
+
+///
+///
+///
+Logger* Logger::get()
+{
+ static Logger log( std::cout );
+ return &log;
+}
+
+///
+///
+///
+void Logger::log(
+ const Level& level,
+ const boost::format& message,
+ const std::string& filename,
+ const int& lineNumber
+)
+{
+ log( level, message.str(), filename, lineNumber );
+}
+
+///
+///
+///
+void Logger::log(
+ const Level& level,
+ const std::string& message,
+ const std::string& filename,
+ const int& lineNumber
+)
+{
+ using namespace boost::posix_time;
+
+ if ( level < _logLevel ) {
+ return ;
+ }
+
+ //ptime now = second_clock::local_time();
+ //_out << to_iso_string(now) << ":" ;
+
+ if ( _displayFilePosition && ! filename.empty() ) {
+ _out << filename << ":" ;
+ }
+
+ if ( _displayFilePosition && lineNumber >= 0 ) {
+ _out << lineNumber << ":" ;
+ }
+
+ switch ( level ) {
+ case Debug:
+ _out << " debug: ";
+ break;
+
+ case Info:
+ _out << " info: ";
+ break;
+
+ case Warning:
+ _out << " warning: ";
+ break;
+
+ case Error:
+ _out << " error: ";
+ break;
+
+ case Critical:
+ _out << " critical: ";
+ break;
+ }
+
+ _out << message << std::endl ;
+}
+
+
+///
+///
+///
+const Logger::Level& Logger::logLevel() const
+{
+ return _logLevel ;
+}
+
+///
+///
+///
+void Logger::setLogLevel( const Level& logLevel )
+{
+ _logLevel = logLevel ;
+}
+
+///
+///
+///
+Logger::Logger( std::ostream& str ):
+ _logLevel( Warning ),
+ _displayFilePosition( true ),
+ _out( str.rdbuf() )
+{
+
+}
+
+///
+///
+///
+Logger& logger()
+{
+ return * Logger::get() ;
+}
+
+
+}//SFCGAL
+
+
+
diff --git a/src/detail/tools/Log.h b/src/detail/tools/Log.h
new file mode 100644
index 0000000..a8add24
--- /dev/null
+++ b/src/detail/tools/Log.h
@@ -0,0 +1,187 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_LOG_H_
+#define _SFCGAL_LOG_H_
+
+#include <SFCGAL/config.h>
+
+#include <string>
+#include <boost/format.hpp>
+
+#include <boost/iostreams/concepts.hpp>
+#include <boost/iostreams/stream.hpp>
+
+
+/**
+ *
+ * Helper method to log debug message
+ *
+ * \code
+ * SFCGAL_DEBUG( "start new method" ) ;
+ * \endcode
+ */
+#define SFCGAL_DEBUG( message ) SFCGAL::Logger::get()->log( SFCGAL::Logger::Debug, message, __FILE__, __LINE__ )
+/**
+ *
+ * Helper method to log information message
+ *
+ * \code
+ * SFCGAL_INFO( "start new method" ) ;
+ * \endcode
+ */
+#define SFCGAL_INFO( message ) SFCGAL::Logger::get()->log( SFCGAL::Logger::Info, message, __FILE__, __LINE__ )
+/**
+ *
+ * Helper method to log warning message
+ *
+ * \code
+ * SFCGAL_WARNING( "start new method" ) ;
+ * \endcode
+ */
+#define SFCGAL_WARNING( message ) SFCGAL::Logger::get()->log( SFCGAL::Logger::Warning, message, __FILE__, __LINE__ )
+/**
+ *
+ * Helper method to log error message
+ *
+ * \code
+ * SFCGAL_ERROR( "invalid geometry" ) ;
+ * \endcode
+ */
+#define SFCGAL_ERROR( message ) SFCGAL::Logger::get()->log( SFCGAL::Logger::Info, message, __FILE__, __LINE__ )
+/**
+ *
+ * Helper method to log critical message
+ *
+ * \code
+ * SFCGAL_ERROR( "unexpected behavior in triangulate" ) ;
+ * \endcode
+ */
+#define SFCGAL_CRITICAL( message ) SFCGAL::Logger::get()->log( SFCGAL::Logger::Critical, message, __FILE__, __LINE__ )
+
+
+namespace SFCGAL {
+
+/**
+ * [Singleton]Logger class
+ *
+ * @warning saved_lines and co removed (dangerous for memory and could be done in a LogWriter).
+ */
+class SFCGAL_API Logger {
+public:
+ /**
+ * destructor
+ */
+ ~Logger();
+
+ /**
+ * log level
+ */
+ typedef enum {
+ Debug,
+ Info,
+ Warning,
+ Error,
+ Critical
+ } Level ;
+
+ /**
+ * singleton accessor
+ */
+ static Logger* get() ;
+
+ /**
+ * log a message using boost format
+ * @param level the log level
+ * @param message the message to log
+ * @param filename the filename (optional)
+ * @param lineNumber the line number in the file (optional)
+ */
+ void log(
+ const Level& level,
+ const boost::format& message,
+ const std::string& filename = "",
+ const int& lineNumber = -1
+ );
+
+ /**
+ * log a message
+ * @param level the log level
+ * @param message the message to log
+ * @param filename the filename (optional)
+ * @param lineNumber the line number in the file (optional)
+ */
+ void log(
+ const Level& level,
+ const std::string& message,
+ const std::string& filename = "",
+ const int& lineNumber = -1
+ );
+
+ /**
+ * get the current log level
+ */
+ const Level& logLevel() const ;
+ /**
+ * set the log level
+ */
+ void setLogLevel( const Level& logLevel ) ;
+
+private:
+ /**
+ * current log level
+ */
+ Level _logLevel ;
+ /**
+ * display file position?
+ */
+ bool _displayFilePosition ;
+
+ /**
+ * private constructor
+ */
+ Logger( std::ostream& );
+ /**
+ * no copy constructor
+ */
+ Logger( const Logger& other );
+
+ std::ostream _out;
+};
+
+/**
+ * get the logger
+ */
+SFCGAL_API Logger& logger() ;
+
+
+}//SFCGAL
+
+#define SFCGAL_LOG( level, msg ) do { SFCGAL::Logger::get() << "[" << (level) << " " << __FILE__ << ":" << __LINE__ << "] " << msg << std::endl; } while (0)
+
+#ifndef NDEBUG
+# define LOG_DEBUG( msg ) do { SFCGAL_LOG( "DEBUG", msg ); } while(0)
+#else
+# define LOG_DEBUG( msg ) do {} while(0)
+#endif
+#define LOG_NOTICE( msg ) do { SFCGAL_LOG( "NOTICE", msg ); } while(0)
+#define LOG_ERROR( msg ) do { SFCGAL_LOG( "ERROR", msg ); } while(0)
+
+#endif
diff --git a/src/detail/tools/Registry.cpp b/src/detail/tools/Registry.cpp
new file mode 100644
index 0000000..a683a43
--- /dev/null
+++ b/src/detail/tools/Registry.cpp
@@ -0,0 +1,160 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/tools/Registry.h>
+
+#include <SFCGAL/Geometry.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+#include <SFCGAL/Exception.h>
+#include <SFCGAL/detail/tools/Log.h>
+
+namespace SFCGAL {
+namespace tools {
+
+Registry* Registry::_instance = 0 ;
+
+///
+///
+///
+Registry::~Registry()
+{
+ for ( prototype_iterator it = _prototypes.begin(); it != _prototypes.end(); ++it ) {
+ delete *it ;
+ }
+}
+
+///
+///
+///
+void Registry::addPrototype( const Geometry& g )
+{
+ //find prototype by name
+ const_prototype_iterator it = _prototypes.begin() ;
+
+ for ( ; it != _prototypes.end(); ++it ) {
+ if ( ( *it )->geometryTypeId() == g.geometryTypeId() ) {
+ break;
+ }
+ }
+
+ if ( it != _prototypes.end() ) {
+ return ;
+ }
+
+ _prototypes.push_back( g.clone() );
+}
+
+///
+///
+///
+std::vector< std::string > Registry::getGeometryTypes() const
+{
+ std::vector< std::string > names ;
+
+ for ( const_prototype_iterator it = _prototypes.begin(); it != _prototypes.end(); ++it ) {
+ names.push_back( ( *it )->geometryType() );
+ }
+
+ return names ;
+}
+
+///
+///
+///
+Geometry* Registry::newGeometryByTypeName( const std::string& geometryTypeName ) const
+{
+ for ( const_prototype_iterator it = _prototypes.begin(); it != _prototypes.end(); ++it ) {
+ if ( geometryTypeName == ( *it )->geometryType() ) {
+ return ( *it )->clone() ;
+ }
+ }
+
+ SFCGAL_WARNING( boost::format( "Registry can't create a new Geometry for the type '%s' (returning null pointer)" ) % geometryTypeName );
+ return NULL ;
+}
+
+///
+///
+///
+Geometry* Registry::newGeometryByTypeId( int typeId ) const
+{
+ for ( const_prototype_iterator it = _prototypes.begin(); it != _prototypes.end(); ++it ) {
+ if ( typeId == ( *it )->geometryTypeId() ) {
+ return ( *it )->clone() ;
+ }
+ }
+
+ SFCGAL_WARNING( boost::format( "Registry can't create a new Geometry for the type '%d' (returning null pointer)" ) % typeId );
+ return NULL ;
+}
+
+///
+///
+///
+Registry& Registry::instance()
+{
+ if ( ! Registry::_instance ) {
+ Registry::_instance = new Registry();
+ }
+
+ return *_instance ;
+}
+
+///
+///
+///
+Registry::Registry():
+ _prototypes()
+{
+ addPrototype( Point() );
+ addPrototype( LineString() );
+ addPrototype( Polygon() );
+ addPrototype( Triangle() );
+ addPrototype( Solid() );
+
+ addPrototype( GeometryCollection() );
+
+ addPrototype( MultiPoint() );
+ addPrototype( MultiLineString() );
+ addPrototype( MultiPolygon() );
+ addPrototype( MultiSolid() );
+
+ addPrototype( TriangulatedSurface() );
+ addPrototype( PolyhedralSurface() );
+}
+
+
+
+}//namespace tools
+}//namespace SFCGAL
+
+
diff --git a/src/detail/tools/Registry.h b/src/detail/tools/Registry.h
new file mode 100644
index 0000000..755c5c1
--- /dev/null
+++ b/src/detail/tools/Registry.h
@@ -0,0 +1,93 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_REGISTRY_H_
+#define _SFCGAL_REGISTRY_H_
+
+#include <SFCGAL/config.h>
+
+#include <string>
+#include <map>
+#include <vector>
+
+namespace SFCGAL {
+class Geometry ;
+}
+
+namespace SFCGAL {
+namespace tools {
+
+/**
+ * Registry for dynamic information about SFCGAL library
+ */
+class SFCGAL_API Registry {
+public:
+ typedef std::vector< Geometry* >::iterator prototype_iterator ;
+ typedef std::vector< Geometry* >::const_iterator const_prototype_iterator ;
+
+ /**
+ * destructor
+ */
+ ~Registry();
+
+ /**
+ * Register a new Geometry type
+ */
+ void addPrototype( const Geometry& g ) ;
+
+ /**
+ * returns the list of the geometry types
+ */
+ std::vector< std::string > getGeometryTypes() const ;
+
+ /**
+ * returns a new instance of the given geometryTypeName
+ */
+ Geometry* newGeometryByTypeName( const std::string& geometryTypeName ) const ;
+
+ /**
+ * returns a new instance of the given geometryType
+ */
+ Geometry* newGeometryByTypeId( int typeId ) const ;
+
+ /**
+ * returns the instance of the registry
+ */
+ static Registry& instance() ;
+private:
+ /**
+ * static instance of the Singleton
+ */
+ static Registry* _instance ;
+ /**
+ * prototypes of the geometries
+ */
+ std::vector< Geometry* > _prototypes ;
+
+ /**
+ * init registry
+ */
+ Registry() ;
+};
+
+}//namespace tools
+}//namespace SFCGAL
+
+#endif
diff --git a/src/detail/transform/AffineTransform2.cpp b/src/detail/transform/AffineTransform2.cpp
new file mode 100644
index 0000000..3cafe6a
--- /dev/null
+++ b/src/detail/transform/AffineTransform2.cpp
@@ -0,0 +1,50 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/transform/AffineTransform2.h>
+
+#include <SFCGAL/Point.h>
+
+namespace SFCGAL {
+namespace transform {
+
+///
+///
+///
+AffineTransform2::AffineTransform2( CGAL::Aff_transformation_2< Kernel > transform ):
+ _transform( transform )
+{
+
+}
+
+/*
+ * [SFCGAL::Transform]
+ */
+void AffineTransform2::transform( Point& p )
+{
+ if ( ! p.isEmpty() ) {
+ p = Point( p.toPoint_2().transform( _transform ) );
+ }
+}
+
+
+}//transform
+}//SFCGAL
+
diff --git a/src/detail/transform/AffineTransform2.h b/src/detail/transform/AffineTransform2.h
new file mode 100644
index 0000000..47ffbc0
--- /dev/null
+++ b/src/detail/transform/AffineTransform2.h
@@ -0,0 +1,62 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_TRANSFORM_AFFINETRANSFORM2_H_
+#define _SFCGAL_TRANSFORM_AFFINETRANSFORM2_H_
+
+#include <SFCGAL/config.h>
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Transform.h>
+
+#include <CGAL/Aff_transformation_2.h>
+
+
+namespace SFCGAL {
+namespace transform {
+
+/**
+ * Wrapper for CGAL::Aff_transform_2
+ * @todo unittest
+ */
+class SFCGAL_API AffineTransform2 : public Transform {
+public:
+ /**
+ * Constructor with a transform
+ */
+ AffineTransform2( CGAL::Aff_transformation_2< Kernel > transform ) ;
+
+ /*
+ * [SFCGAL::Transform]
+ */
+ virtual void transform( Point& p ) ;
+
+private:
+ CGAL::Aff_transformation_2< Kernel > _transform ;
+};
+
+
+}//transform
+}//SFCGAL
+
+
+
+
+#endif
+
diff --git a/src/detail/transform/AffineTransform3.cpp b/src/detail/transform/AffineTransform3.cpp
new file mode 100644
index 0000000..a25f8bb
--- /dev/null
+++ b/src/detail/transform/AffineTransform3.cpp
@@ -0,0 +1,135 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/transform/AffineTransform3.h>
+
+#include <CGAL/Aff_transformation_3.h>
+#include <SFCGAL/Transform.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/PolyhedralSurface.h>
+
+namespace SFCGAL {
+namespace transform {
+
+///
+///
+///
+AffineTransform3::AffineTransform3( CGAL::Aff_transformation_3< Kernel > transform ):
+ _transform( transform )
+{
+
+}
+
+///
+///
+///
+void AffineTransform3::transform( Point& p )
+{
+ if ( ! p.isEmpty() ) {
+ p = Point( p.toPoint_3().transform( _transform ) ) ;
+ }
+}
+
+
+///
+///
+///
+void AffineTransform3::transform( LineString& ls )
+{
+ for ( size_t i = 0; i < ls.numPoints(); ++i ) {
+ transform( ls.pointN( i ) );
+ }
+}
+
+///
+///
+///
+void AffineTransform3::transform( Triangle& tri )
+{
+ transform( tri.vertex( 0 ) );
+ transform( tri.vertex( 1 ) );
+ transform( tri.vertex( 2 ) );
+}
+
+
+///
+///
+///
+void AffineTransform3::transform( Polygon& poly )
+{
+ transform( poly.exteriorRing() );
+
+ for ( size_t i = 0; i < poly.numInteriorRings(); ++i ) {
+ transform( poly.interiorRingN( i ) );
+ }
+}
+
+
+///
+///
+///
+void AffineTransform3::transform( PolyhedralSurface& surf )
+{
+ for ( size_t i = 0; i < surf.numPolygons(); ++i ) {
+ transform( surf.polygonN( i ) );
+ }
+}
+
+
+///
+///
+///
+void AffineTransform3::transform( TriangulatedSurface& surf )
+{
+ for ( size_t i = 0; i < surf.numGeometries(); ++i ) {
+ transform( surf.geometryN( i ) );
+ }
+}
+
+
+///
+///
+///
+void AffineTransform3::transform( Solid& solid )
+{
+ transform( solid.exteriorShell() );
+
+ for ( size_t i = 0; i < solid.numInteriorShells(); ++i ) {
+ transform( solid.interiorShellN( i ) );
+ }
+}
+
+
+}//transform
+}//SFCGAL
+
+
+
diff --git a/src/detail/transform/AffineTransform3.h b/src/detail/transform/AffineTransform3.h
new file mode 100644
index 0000000..8171336
--- /dev/null
+++ b/src/detail/transform/AffineTransform3.h
@@ -0,0 +1,71 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_TRANSFORM_AFFINETRANSFORM3_H_
+#define _SFCGAL_TRANSFORM_AFFINETRANSFORM3_H_
+
+#include <SFCGAL/config.h>
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Transform.h>
+
+#include <CGAL/Aff_transformation_3.h>
+
+namespace SFCGAL {
+namespace transform {
+
+/**
+ * Wrapper for CGAL::Aff_transform_3
+ * @todo unittest
+ */
+class SFCGAL_API AffineTransform3 : public Transform {
+public:
+ /**
+ * Constructor with a transform
+ */
+ AffineTransform3( CGAL::Aff_transformation_3< Kernel > transform ) ;
+
+ /*
+ * [SFCGAL::Transform]
+ */
+ virtual void transform( Point& p ) ;
+
+ virtual void transform( LineString& ls ) ;
+ virtual void transform( Triangle& tri ) ;
+ virtual void transform( Polygon& poly ) ;
+
+ virtual void transform( PolyhedralSurface& surf ) ;
+
+ virtual void transform( TriangulatedSurface& surf ) ;
+
+ virtual void transform( Solid& solid ) ;
+
+private:
+ CGAL::Aff_transformation_3< Kernel > _transform ;
+};
+
+
+}//transform
+}//SFCGAL
+
+
+
+
+#endif
+
diff --git a/src/detail/transform/Force2D.cpp b/src/detail/transform/Force2D.cpp
new file mode 100644
index 0000000..21c832c
--- /dev/null
+++ b/src/detail/transform/Force2D.cpp
@@ -0,0 +1,43 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/transform/Force2D.h>
+#include <SFCGAL/Point.h>
+
+
+namespace SFCGAL {
+namespace transform {
+
+///
+///
+///
+void Force2D::transform( Point& p )
+{
+ if ( ! p.isEmpty() && p.is3D() ) {
+ p = Point( p.x(), p.y() );
+ }
+}
+
+
+}//transform
+}//SFCGAL
+
+
+
diff --git a/src/detail/transform/Force2D.h b/src/detail/transform/Force2D.h
new file mode 100644
index 0000000..efc169b
--- /dev/null
+++ b/src/detail/transform/Force2D.h
@@ -0,0 +1,50 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_TRANSFORM_FORCE2D_H_
+#define _SFCGAL_TRANSFORM_FORCE2D_H_
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Transform.h>
+
+namespace SFCGAL {
+namespace transform {
+
+/**
+ * Force 2D definitions
+ */
+class SFCGAL_API Force2D : public Transform {
+public:
+ /*
+ * [SFCGAL::Transform]
+ */
+ virtual void transform( Point& p ) ;
+};
+
+}//transform
+}//SFCGAL
+
+
+
+
+#endif
+
diff --git a/src/detail/transform/ForceOrderPoints.cpp b/src/detail/transform/ForceOrderPoints.cpp
new file mode 100644
index 0000000..1b95886
--- /dev/null
+++ b/src/detail/transform/ForceOrderPoints.cpp
@@ -0,0 +1,112 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/transform/ForceOrderPoints.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/algorithm/orientation.h>
+
+namespace SFCGAL {
+namespace transform {
+
+///
+///
+///
+ForceOrderPoints::ForceOrderPoints( bool orientCCW ) :
+ _orientCCW( orientCCW )
+{
+
+}
+
+///
+///
+///
+void ForceOrderPoints::transform( Point& )
+{
+}
+
+
+///
+///
+///
+void ForceOrderPoints::visit( Triangle& t )
+{
+ if ( ! t.is3D() ) {
+ if ( ! algorithm::isCounterClockWiseOriented( t ) ) {
+ // not pointing up, reverse
+ if ( _orientCCW ) {
+ t.reverse();
+ }
+ }
+ else {
+ if ( ! _orientCCW ) {
+ t.reverse();
+ }
+ }
+
+ Transform::visit( t );
+ }
+
+}
+
+void ForceOrderPoints::visit( Polygon& p )
+{
+ if ( ! p.is3D() ) {
+ LineString& ext = p.exteriorRing();
+
+ if ( ! algorithm::isCounterClockWiseOriented( p.exteriorRing() ) ) {
+ // exterior ring not pointing up, reverse
+ if ( _orientCCW ) {
+ ext.reverse();
+ }
+ }
+ else {
+ if ( ! _orientCCW ) {
+ ext.reverse();
+ }
+ }
+
+ for ( size_t i = 0; i < p.numInteriorRings(); ++i ) {
+ LineString inter = p.interiorRingN( i );
+
+ if ( algorithm::isCounterClockWiseOriented( inter ) ) {
+ // interior ring is pointing up, reverse
+ if ( _orientCCW ) {
+ inter.reverse();
+ }
+ }
+ else {
+ if ( ! _orientCCW ) {
+ inter.reverse();
+ }
+ }
+ }
+
+ Transform::visit( p );
+ }
+
+}
+
+}//transform
+}//SFCGAL
+
+
+
diff --git a/src/detail/transform/ForceOrderPoints.h b/src/detail/transform/ForceOrderPoints.h
new file mode 100644
index 0000000..7ef6275
--- /dev/null
+++ b/src/detail/transform/ForceOrderPoints.h
@@ -0,0 +1,65 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_TRANSFORM_FORCE_ORDER_POINTS_H_
+#define _SFCGAL_TRANSFORM_FORCE_ORDER_POINTS_H_
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Transform.h>
+
+namespace SFCGAL {
+
+namespace transform {
+
+/**
+ * If the 2D surface is pointing down, reverse its points
+ * @todo unittest
+ * @todo move outside (it's not a coordinate transform)?
+ */
+class SFCGAL_API ForceOrderPoints : public Transform {
+public:
+ /**
+ * Pass the forced orientation as parameter
+ */
+ ForceOrderPoints( bool orientCCW = true ) ;
+
+ /*
+ * [SFCGAL::Transform]
+ */
+ virtual void transform( Point& p ) ;
+
+ virtual void visit( Triangle& );
+ virtual void visit( Polygon& );
+
+private:
+ bool _orientCCW;
+};
+
+
+}//transform
+}//SFCGAL
+
+
+
+
+#endif
+
diff --git a/src/detail/transform/ForceZ.cpp b/src/detail/transform/ForceZ.cpp
new file mode 100644
index 0000000..c00aa87
--- /dev/null
+++ b/src/detail/transform/ForceZ.cpp
@@ -0,0 +1,52 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/transform/ForceZ.h>
+#include <SFCGAL/Point.h>
+
+
+namespace SFCGAL {
+namespace transform {
+
+///
+///
+///
+ForceZ::ForceZ( const Kernel::FT& defaultZ ):
+ _defaultZ( defaultZ )
+{
+
+}
+
+///
+///
+///
+void ForceZ::transform( Point& p )
+{
+ if ( ! p.isEmpty() && ! p.is3D() ) {
+ p = Point( p.x(), p.y(), _defaultZ );
+ }
+}
+
+
+}//transform
+}//SFCGAL
+
+
+
diff --git a/src/detail/transform/ForceZ.h b/src/detail/transform/ForceZ.h
new file mode 100644
index 0000000..e22f314
--- /dev/null
+++ b/src/detail/transform/ForceZ.h
@@ -0,0 +1,58 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_TRANSFORM_FORCEZ_H_
+#define _SFCGAL_TRANSFORM_FORCEZ_H_
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Transform.h>
+
+namespace SFCGAL {
+namespace transform {
+
+/**
+ * Force Z definitions
+ */
+class SFCGAL_API ForceZ : public Transform {
+public:
+ /**
+ * Constructor with a default Z value
+ */
+ ForceZ( const Kernel::FT& defaultZ = 0 ) ;
+
+ /*
+ * [SFCGAL::Transform]
+ */
+ virtual void transform( Point& p ) ;
+
+private:
+ Kernel::FT _defaultZ ;
+};
+
+}//transform
+}//SFCGAL
+
+
+
+
+#endif
+
diff --git a/src/detail/transform/ForceZOrderPoints.cpp b/src/detail/transform/ForceZOrderPoints.cpp
new file mode 100644
index 0000000..673f783
--- /dev/null
+++ b/src/detail/transform/ForceZOrderPoints.cpp
@@ -0,0 +1,94 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/transform/ForceZOrderPoints.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/algorithm/orientation.h>
+
+namespace SFCGAL {
+namespace transform {
+
+///
+///
+///
+ForceZOrderPoints::ForceZOrderPoints( const Kernel::FT& defaultZ ):
+ _defaultZ( defaultZ )
+{
+
+}
+
+///
+///
+///
+void ForceZOrderPoints::transform( Point& p )
+{
+ if ( ! p.is3D() ) {
+ p = Point( p.x(), p.y(), _defaultZ );
+ }
+}
+
+
+///
+///
+///
+void ForceZOrderPoints::visit( Triangle& t )
+{
+ if ( ! t.is3D() ) {
+ if ( ! algorithm::isCounterClockWiseOriented( t ) ) {
+ // not pointing up, reverse
+ t.reverse();
+ }
+
+ Transform::visit( t );
+ }
+
+}
+
+void ForceZOrderPoints::visit( Polygon& p )
+{
+ if ( ! p.is3D() ) {
+ LineString& ext = p.exteriorRing();
+
+ if ( ! algorithm::isCounterClockWiseOriented( p.exteriorRing() ) ) {
+ // exterior ring not pointing up, reverse
+ ext.reverse();
+ }
+
+ for ( size_t i = 0; i < p.numInteriorRings(); ++i ) {
+ LineString& inter = p.interiorRingN( i );
+
+ if ( algorithm::isCounterClockWiseOriented( inter ) ) {
+ // interior ring is pointing up, reverse
+ inter.reverse();
+ }
+ }
+
+ Transform::visit( p );
+ }
+
+}
+
+}//transform
+}//SFCGAL
+
+
+
diff --git a/src/detail/transform/ForceZOrderPoints.h b/src/detail/transform/ForceZOrderPoints.h
new file mode 100644
index 0000000..c1ffa21
--- /dev/null
+++ b/src/detail/transform/ForceZOrderPoints.h
@@ -0,0 +1,66 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_TRANSFORM_FORCEZ_ORDER_POINTS_H_
+#define _SFCGAL_TRANSFORM_FORCEZ_ORDER_POINTS_H_
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Transform.h>
+
+namespace SFCGAL {
+
+namespace transform {
+
+/**
+ * Force Z. If the 2D surface is pointing down, reverse its points
+ *
+ * @todo unittest
+ * @todo move outside (it's not a coordinate transform)?
+ */
+class SFCGAL_API ForceZOrderPoints : public Transform {
+public:
+ /**
+ * Constructor with a default Z value
+ */
+ ForceZOrderPoints( const Kernel::FT& defaultZ = 0 ) ;
+
+ /*
+ * [SFCGAL::Transform]
+ */
+ virtual void transform( Point& p ) ;
+
+ virtual void visit( Triangle& );
+ virtual void visit( Polygon& );
+
+private:
+ Kernel::FT _defaultZ ;
+};
+
+
+}//transform
+}//SFCGAL
+
+
+
+
+#endif
+
diff --git a/src/detail/transform/RoundTransform.cpp b/src/detail/transform/RoundTransform.cpp
new file mode 100644
index 0000000..fb455c0
--- /dev/null
+++ b/src/detail/transform/RoundTransform.cpp
@@ -0,0 +1,49 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/transform/RoundTransform.h>
+
+#include <SFCGAL/Point.h>
+
+namespace SFCGAL {
+namespace transform {
+
+///
+///
+///
+RoundTransform::RoundTransform( const long& scale ):
+ _scale( scale )
+{
+
+}
+
+///
+///
+///
+void RoundTransform::transform( Point& p )
+{
+ p.coordinate().round( _scale ) ;
+}
+
+}//transform
+}//SFCGAL
+
+
+
diff --git a/src/detail/transform/RoundTransform.h b/src/detail/transform/RoundTransform.h
new file mode 100644
index 0000000..391f757
--- /dev/null
+++ b/src/detail/transform/RoundTransform.h
@@ -0,0 +1,59 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_TRANSFORM_ROUNDTRANSFORM_H_
+#define _SFCGAL_TRANSFORM_ROUNDTRANSFORM_H_
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Transform.h>
+
+namespace SFCGAL {
+namespace transform {
+
+/**
+ * Round the coordinates of a Geometry
+ */
+class SFCGAL_API RoundTransform : public Transform {
+public:
+ /**
+ * Constructor with a scale factor (default is nearest integer)
+ */
+ RoundTransform( const long& scale = 1 ) ;
+
+ /*
+ * [SFCGAL::Transform]
+ */
+ virtual void transform( Point& p ) ;
+
+private:
+ long _scale ;
+};
+
+
+}//transform
+}//SFCGAL
+
+
+
+
+#endif
+
diff --git a/src/detail/triangulate/ConstraintDelaunayTriangulation.cpp b/src/detail/triangulate/ConstraintDelaunayTriangulation.cpp
new file mode 100644
index 0000000..e12c89d
--- /dev/null
+++ b/src/detail/triangulate/ConstraintDelaunayTriangulation.cpp
@@ -0,0 +1,172 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/triangulate/ConstraintDelaunayTriangulation.h>
+
+#include <SFCGAL/Exception.h>
+#include <SFCGAL/TriangulatedSurface.h>
+
+
+#include <SFCGAL/detail/triangulate/markDomains.h>
+
+namespace SFCGAL {
+namespace triangulate {
+
+///
+///
+///
+ConstraintDelaunayTriangulation::ConstraintDelaunayTriangulation():
+ _cdt()
+{
+
+}
+
+
+///
+///
+///
+ConstraintDelaunayTriangulation::Vertex_handle ConstraintDelaunayTriangulation::addVertex( const Coordinate& position )
+{
+ if ( position.isEmpty() ) {
+ BOOST_THROW_EXCEPTION( Exception(
+ "try to add empty position to ConstraintDelaunayTriangulation"
+ ) );
+ }
+
+ Vertex_handle vertex = _projectionPlane
+ ? _cdt.insert( _projectionPlane->to_2d( position.toPoint_3() ) )
+ : _cdt.insert( position.toPoint_2() );
+ vertex->info().original = position ;
+ return vertex ;
+}
+
+///
+///
+///
+void ConstraintDelaunayTriangulation::addConstraint( Vertex_handle source, Vertex_handle target )
+{
+ if ( source == target ) {
+ return ;
+ }
+
+ _cdt.insert_constraint( source, target );
+}
+
+///
+///
+///
+void ConstraintDelaunayTriangulation::clear()
+{
+ _cdt.clear();
+}
+
+///
+///
+///
+size_t ConstraintDelaunayTriangulation::numVertices() const
+{
+ return _cdt.number_of_vertices() ;
+}
+
+///
+///
+///
+size_t ConstraintDelaunayTriangulation::numTriangles() const
+{
+ return _cdt.number_of_faces() ;
+}
+
+///
+///
+///
+void ConstraintDelaunayTriangulation::setProjectionPlane( const Kernel::Plane_3& projectionPlane )
+{
+ BOOST_ASSERT( ! projectionPlane.is_degenerate() ) ;
+ _projectionPlane = projectionPlane ;
+}
+
+///
+///
+///
+Kernel::Plane_3 ConstraintDelaunayTriangulation::projectionPlane() const
+{
+ if ( _projectionPlane ) {
+ return *_projectionPlane ;
+ }
+ else {
+ return Kernel::Plane_3( Kernel::RT( 0 ), Kernel::RT( 0 ), Kernel::RT( 1 ), Kernel::RT( 0 ) );
+ }
+}
+
+
+///
+/// adapted from CGAL example
+///
+void ConstraintDelaunayTriangulation::markDomains()
+{
+ detail::markDomains( _cdt );
+}
+
+
+
+
+///
+///
+///
+void ConstraintDelaunayTriangulation::getTriangles( TriangulatedSurface& triangulatedSurface, bool filterExteriorParts ) const
+{
+ triangulatedSurface.reserve( triangulatedSurface.numTriangles() + numTriangles() );
+
+ for ( Finite_faces_iterator it = finite_faces_begin(); it != finite_faces_end(); ++it ) {
+ if ( filterExteriorParts && ( it->info().nestingLevel % 2 == 0 ) ) {
+ continue ;
+ }
+
+ const Coordinate& a = it->vertex( 0 )->info().original ;
+
+ const Coordinate& b = it->vertex( 1 )->info().original ;
+
+ const Coordinate& c = it->vertex( 2 )->info().original ;
+
+ // check that vertex has an original vertex
+ if ( a.isEmpty() || b.isEmpty() || c.isEmpty() ) {
+ BOOST_THROW_EXCEPTION( Exception(
+ ( boost::format( "Can't convert Triangulation to TriangulatedSurface (constraint intersection found)" ) ).str()
+ ) ) ;
+ }
+
+ triangulatedSurface.addTriangle( new Triangle( Point( a ), Point( b ), Point( c ) ) );
+ }
+}
+
+///
+///
+///
+std::auto_ptr< TriangulatedSurface > ConstraintDelaunayTriangulation::getTriangulatedSurface() const
+{
+ std::auto_ptr< TriangulatedSurface > result( new TriangulatedSurface );
+ getTriangles( *result, false );
+ return result ;
+}
+
+
+} // namespace triangulate
+} // namespace SFCGAL
+
diff --git a/src/detail/triangulate/ConstraintDelaunayTriangulation.h b/src/detail/triangulate/ConstraintDelaunayTriangulation.h
new file mode 100644
index 0000000..a3529cf
--- /dev/null
+++ b/src/detail/triangulate/ConstraintDelaunayTriangulation.h
@@ -0,0 +1,209 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_TRIANGULATE_CONSTRAINTDELAUNAYTRIANGULATION_H_
+#define _SFCGAL_TRIANGULATE_CONSTRAINTDELAUNAYTRIANGULATION_H_
+
+#include <boost/optional.hpp>
+
+#include <SFCGAL/config.h>
+#include <SFCGAL/Coordinate.h>
+
+#include <CGAL/Constrained_Delaunay_triangulation_2.h>
+#include <CGAL/Triangulation_vertex_base_with_info_2.h>
+#include <CGAL/Triangulation_face_base_with_info_2.h>
+
+namespace SFCGAL {
+class TriangulatedSurface ;
+}
+
+
+namespace SFCGAL {
+namespace triangulate {
+
+/**
+ * @brief 2DZ constraint Delaunay triangulation
+ */
+class SFCGAL_API ConstraintDelaunayTriangulation {
+public:
+ /**
+ * @brief vertex info in triangulation
+ */
+ struct VertexInfo {
+ VertexInfo() :
+ original() {
+ }
+ Coordinate original ;
+ };
+
+ /**
+ * face information (depth)
+ */
+ struct FaceInfo {
+ FaceInfo():
+ nestingLevel( -1 ) {
+ }
+ int nestingLevel;
+
+ bool in_domain() {
+ return nestingLevel % 2 == 1;
+ }
+ };
+
+ typedef CGAL::Triangulation_vertex_base_with_info_2< VertexInfo, Kernel > Triangulation_vertex_base ;
+ typedef CGAL::Triangulation_face_base_with_info_2<FaceInfo, Kernel> Triangulation_face_base;
+ typedef CGAL::Constrained_triangulation_face_base_2<Kernel, Triangulation_face_base> Constrained_triangulation_face_base;
+ typedef CGAL::Triangulation_data_structure_2< Triangulation_vertex_base,
+ Constrained_triangulation_face_base > Triangulation_data_structure ;
+
+ typedef CGAL::Constrained_Delaunay_triangulation_2< Kernel, Triangulation_data_structure, CGAL::Exact_predicates_tag > CDT;
+
+ typedef CDT::Vertex_handle Vertex_handle ;
+ typedef CDT::Face_handle Face_handle ;
+ typedef CDT::All_faces_iterator All_faces_iterator ;
+ typedef CDT::Finite_faces_iterator Finite_faces_iterator ;
+
+ /**
+ * @brief default constructor
+ */
+ ConstraintDelaunayTriangulation();
+
+ /**
+ * @brief add a vertex to the triangulation
+ */
+ Vertex_handle addVertex( const Coordinate& position ) ;
+ /**
+ * @brief add a vertex to the triangulation
+ */
+ void addConstraint( Vertex_handle source, Vertex_handle target ) ;
+
+
+ /**
+ * @brief clear the triangulation
+ */
+ void clear() ;
+
+ /**
+ * @brief Returns the number of finite vertices.
+ */
+ size_t numVertices() const ;
+ /**
+ * @brief Returns the number of finite faces.
+ */
+ size_t numTriangles() const ;
+
+
+ /**
+ * @brief test if a projection plane is defined
+ */
+ inline bool hasProjectionPlane() const {
+ return _projectionPlane.is_initialized() ;
+ }
+ /**
+ * @brief define projection plane
+ */
+ void setProjectionPlane( const Kernel::Plane_3& projectionPlane ) ;
+ /**
+ * @brief get the projection plane (OXY if not defined)
+ */
+ Kernel::Plane_3 projectionPlane() const ;
+
+ /**
+ * @brief test if the vertex is infinite
+ */
+ inline bool isInfinite( Vertex_handle vertex ) const {
+ return _cdt.is_infinite( vertex ) ;
+ }
+ /**
+ * @brief test if the face has infinite vertex
+ */
+ inline bool isInfinite( Face_handle face ) const {
+ return _cdt.is_infinite( face ) ;
+ }
+
+ /**
+ * @brief Append Triangles to a TriangulatedSurface
+ */
+ void getTriangles( TriangulatedSurface& triangulatedSurface, bool filterExteriorParts = false ) const ;
+ /**
+ * get the resulting TriangulatedSurface
+ */
+ std::auto_ptr< TriangulatedSurface > getTriangulatedSurface() const ;
+
+ /**
+ * @brief get finite face iterator
+ */
+ inline Finite_faces_iterator finite_faces_begin() const {
+ return _cdt.finite_faces_begin() ;
+ }
+ /**
+ * @brief get finite face iterator
+ */
+ inline Finite_faces_iterator finite_faces_end() const {
+ return _cdt.finite_faces_end() ;
+ }
+
+ /**
+ * @brief get all face iterator
+ */
+ inline All_faces_iterator all_faces_begin() const {
+ return _cdt.all_faces_begin() ;
+ }
+ /**
+ * @brief get all face iterator
+ */
+ inline All_faces_iterator all_faces_end() const {
+ return _cdt.all_faces_end() ;
+ }
+
+
+ /**
+ * @brief fill nesting_level info in face info
+ */
+ void markDomains() ;
+
+
+ /**
+ * @brief [advanced]get the CGAL object
+ */
+ inline CDT& cdt() {
+ return _cdt ;
+ }
+ /**
+ * @brief [advanced]get the CGAL object
+ */
+ inline const CDT& cdt() const {
+ return _cdt ;
+ }
+private:
+ /**
+ * @brief wrapped triangulation
+ */
+ CDT _cdt ;
+ /**
+ * @brief plan in which the triangulation is done
+ */
+ boost::optional< Kernel::Plane_3 > _projectionPlane ;
+};
+
+} // namespace triangulate
+} // namespace SFCGAL
+
+#endif
diff --git a/src/detail/triangulate/markDomains.h b/src/detail/triangulate/markDomains.h
new file mode 100644
index 0000000..f83ea98
--- /dev/null
+++ b/src/detail/triangulate/markDomains.h
@@ -0,0 +1,112 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_TRIANGULATE_DETAIL_MARKDOMAINS_H_
+#define _SFCGAL_TRIANGULATE_DETAIL_MARKDOMAINS_H_
+
+
+namespace SFCGAL {
+namespace triangulate {
+namespace detail {
+
+/**
+ * @brief fill nestingLevel
+ *
+ * Adapted from CGAL-4.1/examples/Triangulation_2/polygon_triangulation.cpp
+ */
+template < typename CDT >
+void markDomains(
+ CDT& cdt,
+ typename CDT::Face_handle start,
+ int index,
+ std::list< typename CDT::Edge >& border
+)
+{
+ typedef typename CDT::Face_handle Face_handle ;
+ typedef typename CDT::Edge Edge ;
+
+ if ( start->info().nestingLevel != -1 ) {
+ return;
+ }
+
+ std::list< Face_handle > queue;
+ queue.push_back( start );
+
+ while ( !queue.empty() ) {
+ Face_handle fh = queue.front();
+ queue.pop_front();
+
+ if ( fh->info().nestingLevel == -1 ) {
+ fh->info().nestingLevel = index;
+
+ for ( int i = 0; i < 3; i++ ) {
+ Edge e( fh, i );
+ Face_handle n = fh->neighbor( i );
+
+ if ( n->info().nestingLevel == -1 ) {
+ if ( cdt.is_constrained( e ) ) {
+ border.push_back( e );
+ }
+ else {
+ queue.push_back( n );
+ }
+ }
+ }
+ }
+ }
+}
+
+/**
+ * @brief fill nestingLevel
+ *
+ * Adapted from CGAL-4.1/examples/Triangulation_2/polygon_triangulation.cpp
+ */
+template < typename CDT >
+void markDomains( CDT& cdt )
+{
+ typedef typename CDT::All_faces_iterator All_faces_iterator ;
+ typedef typename CDT::Face_handle Face_handle ;
+ typedef typename CDT::Edge Edge ;
+
+ for ( All_faces_iterator it = cdt.all_faces_begin(); it != cdt.all_faces_end(); ++it ) {
+ it->info().nestingLevel = -1;
+ }
+
+ int index = 0;
+ std::list< Edge > border;
+ markDomains( cdt, cdt.infinite_face(), index++, border );
+
+ while ( ! border.empty() ) {
+ Edge e = border.front();
+ border.pop_front();
+ Face_handle n = e.first->neighbor( e.second );
+
+ if ( n->info().nestingLevel == -1 ) {
+ markDomains( cdt, n, e.first->info().nestingLevel + 1, border );
+ }
+ }
+}
+
+}//namespace detail
+}//namespace triangulate
+}//namespace SFCGAL
+
+
+#endif
diff --git a/src/detail/triangulate/triangulateInGeometrySet.cpp b/src/detail/triangulate/triangulateInGeometrySet.cpp
new file mode 100644
index 0000000..8e30faf
--- /dev/null
+++ b/src/detail/triangulate/triangulateInGeometrySet.cpp
@@ -0,0 +1,134 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/detail/triangulate/triangulateInGeometrySet.h>
+#include <SFCGAL/triangulate/triangulatePolygon.h>
+#include <SFCGAL/detail/triangulate/ConstraintDelaunayTriangulation.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/TriangulatedSurface.h>
+
+#include <CGAL/Delaunay_triangulation_2.h>
+#include <CGAL/Triangulation_vertex_base_with_info_2.h>
+
+using namespace SFCGAL::detail;
+
+namespace SFCGAL {
+namespace triangulate {
+
+/**
+ * vertex information with original coordinates
+ */
+struct VertexInfo2 {
+ VertexInfo2() :
+ original( NULL ) {
+ }
+
+ const CGAL::Point_3<Kernel>* original ;
+};
+
+
+
+typedef CGAL::Triangulation_vertex_base_with_info_2< VertexInfo2, Kernel > triangulation_vertex_base ;
+typedef CGAL::Triangulation_data_structure_2<
+triangulation_vertex_base> triangulation_data_structure;
+
+typedef CGAL::Delaunay_triangulation_2<
+Kernel,
+triangulation_data_structure> Triangulation;
+
+///
+/// input polyhedron must have its planes computed
+///
+void triangulate( const MarkedPolyhedron& polyhedron, GeometrySet<3>& geometry )
+{
+ if ( polyhedron.is_pure_triangle() ) {
+ for ( MarkedPolyhedron::Facet_const_iterator fit = polyhedron.facets_begin(); fit != polyhedron.facets_end(); ++fit ) {
+ MarkedPolyhedron::Facet::Halfedge_around_facet_const_circulator pit;
+
+ pit = fit->facet_begin();
+ const CGAL::Point_3<Kernel>& pt1 = pit->vertex()->point();
+ ++pit;
+ const CGAL::Point_3<Kernel>& pt2 = pit->vertex()->point();
+ ++pit;
+ const CGAL::Point_3<Kernel>& pt3 = pit->vertex()->point();
+
+ CGAL::Triangle_3<Kernel> tri( pt1, pt2, pt3 );
+ geometry.addPrimitive( tri );
+ }
+
+ return;
+
+ }
+
+ Triangulation triangulation;
+
+ for ( MarkedPolyhedron::Facet_const_iterator fit = polyhedron.facets_begin(); fit != polyhedron.facets_end(); ++fit ) {
+ MarkedPolyhedron::Facet::Halfedge_around_facet_const_circulator pit;
+
+ triangulation.clear();
+
+ CGAL::Plane_3<Kernel> plane = fit->plane();
+ BOOST_ASSERT( ! plane.is_degenerate() );
+
+ pit = fit->facet_begin();
+
+ do {
+ const CGAL::Point_3<Kernel>& pt3 = pit->vertex()->point();
+ CGAL::Point_2<Kernel> pt2 = plane.to_2d( pt3 );
+
+ Triangulation::Vertex_handle vh = triangulation.insert( pt2 );
+ vh->info().original = &pt3;
+
+ pit ++;
+ }
+ while ( pit != fit->facet_begin() );
+
+
+ for ( Triangulation::Finite_faces_iterator tit = triangulation.finite_faces_begin();
+ tit != triangulation.finite_faces_end();
+ ++tit ) {
+ const CGAL::Point_3<Kernel>* a = tit->vertex( 0 )->info().original ;
+ const CGAL::Point_3<Kernel>* b = tit->vertex( 1 )->info().original ;
+ const CGAL::Point_3<Kernel>* c = tit->vertex( 2 )->info().original ;
+
+ CGAL::Triangle_3<Kernel> tri( *a, *b, *c );
+ geometry.addPrimitive( tri );
+ }
+
+ }
+}
+
+///
+///
+///
+void triangulate( const CGAL::Polygon_with_holes_2<Kernel>& polygon, GeometrySet<2>& output )
+{
+ // FIXME: lots of copies here, can we avoid this ?
+ Polygon poly( polygon );
+ TriangulatedSurface surf;
+ triangulatePolygon3D( poly, surf );
+
+ for ( size_t i = 0; i < surf.numTriangles(); ++i ) {
+ output.addGeometry( surf.triangleN( i ) );
+ }
+}
+
+}
+}
diff --git a/src/detail/triangulate/triangulateInGeometrySet.h b/src/detail/triangulate/triangulateInGeometrySet.h
new file mode 100644
index 0000000..5df9221
--- /dev/null
+++ b/src/detail/triangulate/triangulateInGeometrySet.h
@@ -0,0 +1,44 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_TRIANGULATE_IN_GEOMETRY_SET_H_
+#define _SFCGAL_TRIANGULATE_IN_GEOMETRY_SET_H_
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/detail/GeometrySet.h>
+
+namespace SFCGAL {
+namespace triangulate {
+
+/**
+ * Populate the GeometrySet<3> geometry with the triangulation (list of triangles) of a polyhedron
+ */
+SFCGAL_API void triangulate( const detail::MarkedPolyhedron& polyhedron, detail::GeometrySet<3>& geometry );
+/**
+ * Populate the GeometrySet<2> geometry with the triangulation (list of polygons) of a polygon
+ */
+SFCGAL_API void triangulate( const CGAL::Polygon_with_holes_2<Kernel>& polygon, detail::GeometrySet<2>& geometry );
+
+}//algorithm
+}//SFCGAL
+
+#endif
+
diff --git a/src/detail/ublas.h b/src/detail/ublas.h
new file mode 100644
index 0000000..e6c2c83
--- /dev/null
+++ b/src/detail/ublas.h
@@ -0,0 +1,33 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_UBLAS_H_
+#define _SFCGAL_UBLAS_H_
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+
+namespace SFCGAL {
+namespace detail {
+namespace ublas = boost::numeric::ublas ;
+} // namespace detail
+} // namespace SFCGAL
+
+#endif
diff --git a/src/export.h b/src/export.h
new file mode 100644
index 0000000..00784e3
--- /dev/null
+++ b/src/export.h
@@ -0,0 +1,57 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_EXPORT_H_
+#define _SFCGAL_EXPORT_H_
+
+//----- DLL MANAGEMENT ------------------
+
+#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined( __BCPLUSPLUS__) || defined( __MWERKS__)
+#define SFCGAL_API_IMPORT __declspec(dllimport)
+#define SFCGAL_API_EXPORT __declspec(dllexport)
+
+#define SFCGAL_API_TEMPLATE_EXPORT extern
+#define SFCGAL_API_TEMPLATE_IMPORT
+#else
+#define SFCGAL_API_IMPORT
+#define SFCGAL_API_EXPORT
+#define SFCGAL_API_TEMPLATE_EXPORT
+#define SFCGAL_API_TEMPLATE_IMPORT
+#endif
+
+
+//TODO : split cxx api and capi?
+
+#ifdef SFCGAL_USE_STATIC_LIBS
+// static libraries
+# define SFCGAL_API
+# define SFCGAL_API_TEMPLATE
+#else
+// shared libraries
+# ifdef SFCGAL_BUILD_SHARED
+# define SFCGAL_API SFCGAL_API_EXPORT
+# define SFCGAL_API_TEMPLATE SFCGAL_API_TEMPLATE_EXPORT
+# else
+# define SFCGAL_API SFCGAL_API_IMPORT
+# define SFCGAL_API_TEMPLATE SFCGAL_API_TEMPLATE_IMPORT
+# endif
+#endif
+
+#endif // _SFCGAL_EXPORT_H_
diff --git a/src/io/GeometryStreams.cpp b/src/io/GeometryStreams.cpp
new file mode 100644
index 0000000..93e53d3
--- /dev/null
+++ b/src/io/GeometryStreams.cpp
@@ -0,0 +1,44 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/io/GeometryStreams.h>
+#include <SFCGAL/Envelope.h>
+#include <SFCGAL/Geometry.h>
+
+namespace SFCGAL {
+
+///
+///
+///
+std::ostream& operator<<( std::ostream& ostr, const Envelope& env )
+{
+ return env.print( ostr );
+}
+
+///
+///
+///
+std::ostream& operator<<( std::ostream& ostr, const Geometry& g )
+{
+ ostr << g.asText();
+ return ostr;
+}
+
+}
diff --git a/src/io/GeometryStreams.h b/src/io/GeometryStreams.h
new file mode 100644
index 0000000..4555d7a
--- /dev/null
+++ b/src/io/GeometryStreams.h
@@ -0,0 +1,44 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_GEOMETRY_STREAMS_H_
+#define _SFCGAL_GEOMETRY_STREAMS_H_
+
+#include <ostream>
+
+#include <SFCGAL/config.h>
+
+namespace SFCGAL {
+
+class Envelope;
+class Geometry;
+
+/**
+ * Ostream operator for Envelope;
+ */
+SFCGAL_API std::ostream& operator<< ( std::ostream&, const Envelope& );
+
+/**
+ * Ostream operator for Geometry;
+ */
+SFCGAL_API std::ostream& operator<< ( std::ostream&, const Geometry& );
+}
+
+#endif
diff --git a/src/io/asc.cpp b/src/io/asc.cpp
new file mode 100644
index 0000000..991a250
--- /dev/null
+++ b/src/io/asc.cpp
@@ -0,0 +1,125 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/io/asc.h>
+
+#include <boost/format.hpp>
+
+#include <SFCGAL/Exception.h>
+#include <SFCGAL/detail/tools/InputStreamReader.h>
+
+using namespace SFCGAL::detail;
+
+namespace SFCGAL {
+namespace io {
+
+///
+///
+///
+std::auto_ptr< Grid > readASC( std::istream& s )
+{
+ tools::InputStreamReader reader( s );
+
+ //ncols 4
+ size_t ncols ;
+
+ if ( ! reader.match( "ncols" ) || ! reader.read( ncols ) ) {
+ BOOST_THROW_EXCEPTION( Exception( "expecting ncols <ncols>" ) );
+ }
+
+ //nrows 6
+ size_t nrows ;
+
+ if ( ! reader.match( "nrows" ) || ! reader.read( nrows ) ) {
+ BOOST_THROW_EXCEPTION( Exception( "expecting nrows <nrows>" ) );
+ }
+
+ //xllcorner 0.0
+ double xllcorner ;
+
+ if ( ! reader.match( "xllcorner" ) || ! reader.read( xllcorner ) ) {
+ BOOST_THROW_EXCEPTION( Exception( "expecting xllcorner <xllcorner>" ) );
+ }
+
+ //yllcorner 0.0
+ double yllcorner ;
+
+ if ( ! reader.match( "yllcorner" ) || ! reader.read( yllcorner ) ) {
+ BOOST_THROW_EXCEPTION( Exception( "expecting yllcorner <yllcorner>" ) );
+ }
+
+ //cellsize 50.0
+ double cellsize ;
+
+ if ( ! reader.match( "cellsize" ) || ! reader.read( cellsize ) ) {
+ BOOST_THROW_EXCEPTION( Exception( "expecting cellsize <cellsize>" ) );
+ }
+
+ //NODATA_value -9999
+ double NODATA_value ;
+
+ if ( ! reader.match( "NODATA_value" ) || ! reader.read( NODATA_value ) ) {
+ BOOST_THROW_EXCEPTION( Exception( "expecting NODATA_value <NODATA_value>" ) );
+ }
+
+ /*
+ * a matrix and read data
+ */
+ ublas::matrix< double > data( nrows, ncols );
+
+ //-9999 -9999 5 2
+ //-9999 20 100 36
+ //3 8 35 10
+ //32 42 50 6
+ //88 75 27 9
+ //13 5 1 -9999
+ for ( size_t i = 0; i < nrows; i++ ) {
+ for ( size_t j = 0; j < ncols; j++ ) {
+ double value ;
+
+ if ( ! reader.read( value ) ) {
+ BOOST_THROW_EXCEPTION( Exception(
+ ( boost::format( "fail to read data(%s,%s) value" ) % i % j ).str()
+ ) );
+ }
+
+ if ( value == NODATA_value ) {
+ data( i,j ) = NaN() ;
+ }
+ else {
+ data( i,j ) = value ;
+ }
+ }
+ }
+
+ /*
+ * produce the resulting grid
+ */
+ Envelope limits(
+ xllcorner, xllcorner + cellsize * ncols,
+ yllcorner, yllcorner + cellsize * nrows
+ );
+ return std::auto_ptr< Grid >( new Grid( data, limits, PIXEL_IS_AREA ) ) ;
+}
+
+
+} // namespace io
+} // namespace SFCGAL
+
diff --git a/src/io/asc.h b/src/io/asc.h
new file mode 100644
index 0000000..5153219
--- /dev/null
+++ b/src/io/asc.h
@@ -0,0 +1,43 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_IO_ASC_H_
+#define _SFCGAL_IO_ASC_H_
+
+#include <SFCGAL/config.h>
+
+#include <sstream>
+
+#include <SFCGAL/Grid.h>
+
+namespace SFCGAL {
+namespace io {
+
+/**
+ * @brief read ASC grid from input stream
+ * @see http://en.wikipedia.org/wiki/Esri_grid
+ */
+SFCGAL_API std::auto_ptr< Grid > readASC( std::istream& s ) ;
+
+
+} // namespace io
+} // namespace SFCGAL
+
+#endif
diff --git a/src/io/ewkt.cpp b/src/io/ewkt.cpp
new file mode 100644
index 0000000..a0642a1
--- /dev/null
+++ b/src/io/ewkt.cpp
@@ -0,0 +1,71 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/io/ewkt.h>
+
+#include <SFCGAL/detail/io/WktReader.h>
+#include <SFCGAL/detail/io/WktWriter.h>
+#include <SFCGAL/detail/tools/CharArrayBuffer.h>
+
+using namespace SFCGAL::detail::io;
+
+namespace SFCGAL {
+namespace io {
+
+///
+///
+///
+std::auto_ptr< PreparedGeometry > readEwkt( std::istream& s )
+{
+ WktReader wktReader( s );
+ srid_t srid = wktReader.readSRID();
+ std::auto_ptr< Geometry > g( wktReader.readGeometry() );
+ return std::auto_ptr<PreparedGeometry>( new PreparedGeometry( g, srid ) );
+}
+
+///
+///
+///
+std::auto_ptr< PreparedGeometry > readEwkt( const std::string& s )
+{
+ std::istringstream iss( s );
+ WktReader wktReader( iss );
+ srid_t srid = wktReader.readSRID();
+ std::auto_ptr< Geometry > g( wktReader.readGeometry() );
+ return std::auto_ptr<PreparedGeometry>( new PreparedGeometry( g, srid ) );
+}
+
+///
+///
+///
+std::auto_ptr< PreparedGeometry > readEwkt( const char* str, size_t len )
+{
+ CharArrayBuffer buf( str, str + len );
+ std::istream istr( &buf );
+ WktReader wktReader( istr );
+ srid_t srid = wktReader.readSRID();
+ std::auto_ptr< Geometry > g( wktReader.readGeometry() );
+ return std::auto_ptr<PreparedGeometry>( new PreparedGeometry( g, srid ) );
+}
+
+}//io
+}//SFCGAL
+
+
diff --git a/src/io/ewkt.h b/src/io/ewkt.h
new file mode 100644
index 0000000..5d96ca9
--- /dev/null
+++ b/src/io/ewkt.h
@@ -0,0 +1,52 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_IO_EWKT_H_
+#define _SFCGAL_IO_EWKT_H_
+
+#include <SFCGAL/config.h>
+
+#include <sstream>
+#include <string>
+#include <memory>
+
+namespace SFCGAL {
+class Geometry ;
+class PreparedGeometry ;
+}
+
+namespace SFCGAL {
+namespace io {
+/**
+ * Read a EWKT prepared geometry from an input stream
+ */
+SFCGAL_API std::auto_ptr< PreparedGeometry > readEwkt( std::istream& s ) ;
+/**
+ * Read a EWKT geometry from a string
+ */
+SFCGAL_API std::auto_ptr< PreparedGeometry > readEwkt( const std::string& s ) ;
+/**
+ * Read a EWKT geometry from a char*
+ */
+SFCGAL_API std::auto_ptr< PreparedGeometry > readEwkt( const char*, size_t );
+}
+}
+
+#endif
diff --git a/src/io/osg.cpp b/src/io/osg.cpp
new file mode 100644
index 0000000..2461c3b
--- /dev/null
+++ b/src/io/osg.cpp
@@ -0,0 +1,64 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/config.h>
+#ifdef SFCGAL_WITH_OSG
+
+#include <SFCGAL/io/osg.h>
+#include <SFCGAL/detail/io/OsgFactory.h>
+
+#include <osg/Geometry>
+#include <osg/Group>
+#include <osg/Geode>
+
+#include <osgDB/WriteFile>
+
+namespace SFCGAL {
+namespace io {
+
+///
+///
+///
+void osgWriteFile( const Geometry& g, const std::string& filepath )
+{
+ SFCGAL::detail::io::OsgFactory factory ;
+ osg::ref_ptr< osg::Geometry > osgGeometry = factory.createGeometry( g );
+ osg::ref_ptr< osg::Geode > geode = new osg::Geode;
+ geode->setName( g.geometryType() );
+ geode->addDrawable( osgGeometry );
+ osgDB::writeNodeFile( *geode, filepath ) ;
+}
+
+
+///
+///
+///
+osg::Geometry* toOsgGeometry( const Geometry& g )
+{
+ SFCGAL::detail::io::OsgFactory factory ;
+ return factory.createGeometry( g ) ;
+}
+
+
+} // namespace io
+} // namespace SFCGAL
+
+
+#endif //SFCGAL_WITH_OSG
diff --git a/src/io/osg.h b/src/io/osg.h
new file mode 100644
index 0000000..db470d0
--- /dev/null
+++ b/src/io/osg.h
@@ -0,0 +1,63 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_IO_OSG_H_
+#define _SFCGAL_IO_OSG_H_
+
+#include <SFCGAL/config.h>
+
+#ifndef SFCGAL_WITH_OSG
+#error "SFCGAL is not build with OpenSceneGraph support (see SFCGAL_BUILD_OSG in cmake)"
+#endif
+
+#include <string>
+
+namespace osg {
+class Geometry ;
+}
+
+namespace SFCGAL {
+class Geometry ;
+}
+
+
+namespace SFCGAL {
+namespace io {
+
+/**
+ * @brief [helper] write an OSG geometry in a file. The format depends on the extension (http://www.openscenegraph.org/projects/osg/wiki/Support/UserGuides/Plugins)
+ * Note that osgviewer command line executable allows the visualization of the resulting files, screenshots and co
+ * @warning requires OpenSceneGraph
+ * @todo list of geometries?
+ */
+SFCGAL_API void osgWriteFile( const Geometry& g, const std::string& filepath ) ;
+
+/**
+ * @brief [helper] converts a SFCGAL::Geometry to an OSG geometry
+ */
+SFCGAL_API osg::Geometry* toOsgGeometry( const Geometry& g ) ;
+
+
+} // namespace io
+} // namespace SFCGAL
+
+
+
+#endif
diff --git a/src/io/vtk.h b/src/io/vtk.h
new file mode 100644
index 0000000..bf633a3
--- /dev/null
+++ b/src/io/vtk.h
@@ -0,0 +1,205 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_IO_VTK_H_
+#define _SFCGAL_IO_VTK_H_
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+using namespace SFCGAL ;
+
+namespace SFCGAL {
+namespace io {
+// print each ring has a different polygon
+inline
+void vtk( const Polygon& poly, const std::string& file )
+{
+ std::stringstream pointStr;
+ std::stringstream polyStr;
+ size_t numPoints=0;
+ size_t numData=0;
+
+ for ( size_t r=0; r!=poly.numRings(); ++r ) {
+ polyStr << poly.ringN( r ).numPoints();
+
+ for ( size_t p=0; p!=poly.ringN( r ).numPoints(); ++p ) {
+ pointStr << poly.ringN( r ).pointN( p ).x() << " " << poly.ringN( r ).pointN( p ).y() << " " << poly.ringN( r ).pointN( p ).z() << "\n";
+ polyStr << " " << numPoints;
+ ++numPoints;
+ ++numData;
+ }
+
+ ++numData;
+ polyStr << "\n";
+ }
+
+ std::ofstream out( file.c_str() );
+ out << "# vtk DataFile Version 1.0\n"
+ << "Polygon output\n"
+ << "ASCII\n"
+ << "\n"
+ << "DATASET POLYDATA\n"
+ << "POINTS " << numPoints << " float\n"
+ << pointStr.str()
+ << "POLYGONS " << poly.numRings() << " " << numData << "\n"
+ << polyStr.str();
+}
+
+template< typename MultiPolygonOrPolyhedraSurface >
+void vtk( const MultiPolygonOrPolyhedraSurface& multiPoly, const std::string& file )
+{
+ std::stringstream pointStr;
+ std::stringstream polyStr;
+ size_t numPoints=0;
+ size_t numRings=0;
+ size_t numData=0;
+
+ for ( size_t i=0; i!=multiPoly.numGeometries(); ++i ) {
+ const Polygon& poly = multiPoly.polygonN( i );
+
+ for ( size_t r=0; r!=poly.numRings(); ++r ) {
+ polyStr << poly.ringN( r ).numPoints();
+
+ for ( size_t p=0; p!=poly.ringN( r ).numPoints(); ++p ) {
+ pointStr << poly.ringN( r ).pointN( p ).x() << " " << poly.ringN( r ).pointN( p ).y() << " " << poly.ringN( r ).pointN( p ).z() << "\n";
+ polyStr << " " << numPoints;
+ ++numPoints;
+ ++numData;
+ }
+
+ ++numData;
+ ++numRings;
+ polyStr << "\n";
+ }
+ }
+
+ std::ofstream out( file.c_str() );
+ out << "# vtk DataFile Version 1.0\n"
+ << "Polygon output\n"
+ << "ASCII\n"
+ << "\n"
+ << "DATASET POLYDATA\n"
+ << "POINTS " << numPoints << " float\n"
+ << pointStr.str()
+ << "POLYGONS " << numRings << " " << numData << "\n"
+ << polyStr.str();
+}
+
+inline
+void vtk( const Triangle& tri, const std::string& file )
+{
+ vtk( tri.toPolygon(), file );
+}
+
+inline
+void vtk( const TriangulatedSurface& s, const std::string& file )
+{
+ std::stringstream pointStr;
+ std::stringstream polyStr;
+ size_t numPoints=0;
+ size_t numTri=0;
+ size_t numData=0;
+
+ for ( size_t i=0; i!=s.numTriangles(); ++i ) {
+ const Triangle& tri = s.triangleN( i );
+ polyStr << 3;
+
+ for ( size_t p=0; p!=3; ++p ) {
+ pointStr << tri.vertex( p ).x() << " " << tri.vertex( p ).y() << " " << tri.vertex( p ).z() << "\n";
+ polyStr << " " << numPoints;
+ ++numPoints;
+ ++numData;
+ }
+
+ ++numData;
+ ++numTri;
+ polyStr << "\n";
+ }
+
+ std::ofstream out( file.c_str() );
+ out << "# vtk DataFile Version 1.0\n"
+ << "Polygon output\n"
+ << "ASCII\n"
+ << "\n"
+ << "DATASET POLYDATA\n"
+ << "POINTS " << numPoints << " float\n"
+ << pointStr.str()
+ << "POLYGONS " << numTri << " " << numData << "\n"
+ << polyStr.str();
+}
+
+inline
+void vtk( const Geometry& g, const std::string& file )
+{
+ switch ( g.geometryTypeId() ) {
+ case TYPE_POLYGON:
+ vtk( g.as<Polygon>(), file ) ;
+ return ;
+
+ case TYPE_MULTIPOLYGON:
+ vtk( g.as<MultiPolygon>(), file ) ;
+ return ;
+
+ case TYPE_TRIANGLE:
+ vtk( g.as<Triangle>(), file ) ;
+ return ;
+
+ case TYPE_TRIANGULATEDSURFACE:
+ vtk( g.as<TriangulatedSurface>(), file ) ;
+ return ;
+
+ case TYPE_POLYHEDRALSURFACE:
+ vtk( g.as<PolyhedralSurface>(), file ) ;
+ return ;
+
+ case TYPE_SOLID:
+ vtk( g.as<Solid>().exteriorShell(), file ) ;
+ return ;
+
+ case TYPE_POINT:
+ case TYPE_LINESTRING:
+ case TYPE_MULTIPOINT:
+ case TYPE_MULTILINESTRING:
+ case TYPE_MULTISOLID:
+ case TYPE_GEOMETRYCOLLECTION:
+ BOOST_THROW_EXCEPTION( NotImplementedException(
+ ( boost::format( "vtk(%s, file) is not implemented" ) % g.geometryType() ).str()
+ ) );
+ }
+}
+}
+}
+
+#endif
diff --git a/src/io/wkt.cpp b/src/io/wkt.cpp
new file mode 100644
index 0000000..a61305d
--- /dev/null
+++ b/src/io/wkt.cpp
@@ -0,0 +1,65 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/io/wkt.h>
+
+#include <SFCGAL/detail/io/WktReader.h>
+#include <SFCGAL/detail/io/WktWriter.h>
+#include <SFCGAL/detail/tools/CharArrayBuffer.h>
+
+using namespace SFCGAL::detail::io;
+
+namespace SFCGAL {
+namespace io {
+
+///
+///
+///
+std::auto_ptr< Geometry > readWkt( std::istream& s )
+{
+ WktReader wktReader( s );
+ return std::auto_ptr< Geometry >( wktReader.readGeometry() );
+}
+
+///
+///
+///
+std::auto_ptr< Geometry > readWkt( const std::string& s )
+{
+ std::istringstream iss( s );
+ WktReader wktReader( iss );
+ return std::auto_ptr< Geometry >( wktReader.readGeometry() );
+}
+
+///
+///
+///
+std::auto_ptr< Geometry > readWkt( const char* str, size_t len )
+{
+ CharArrayBuffer buf( str, str + len );
+ std::istream istr( &buf );
+ WktReader wktReader( istr );
+ return std::auto_ptr< Geometry >( wktReader.readGeometry() );
+}
+
+}//io
+}//SFCGAL
+
+
diff --git a/src/io/wkt.h b/src/io/wkt.h
new file mode 100644
index 0000000..3391caa
--- /dev/null
+++ b/src/io/wkt.h
@@ -0,0 +1,51 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_IO_WKT_H_
+#define _SFCGAL_IO_WKT_H_
+
+#include <SFCGAL/config.h>
+
+#include <sstream>
+#include <string>
+#include <memory>
+
+namespace SFCGAL {
+class Geometry ;
+}
+
+namespace SFCGAL {
+namespace io {
+/**
+ * Read a WKT geometry from an input stream
+ */
+SFCGAL_API std::auto_ptr< Geometry > readWkt( std::istream& s ) ;
+/**
+ * Read a WKT geometry from a string
+ */
+SFCGAL_API std::auto_ptr< Geometry > readWkt( const std::string& s ) ;
+/**
+ * Read a WKT geometry from a char*
+ */
+SFCGAL_API std::auto_ptr< Geometry > readWkt( const char*, size_t );
+}
+}
+
+#endif
diff --git a/src/numeric.cpp b/src/numeric.cpp
new file mode 100644
index 0000000..db65cf8
--- /dev/null
+++ b/src/numeric.cpp
@@ -0,0 +1,63 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/numeric.h>
+
+namespace SFCGAL {
+
+///
+///
+///
+CGAL::Gmpz floor( const CGAL::Gmpq& v )
+{
+ return v.numerator() / v.denominator() ;
+}
+
+///
+///
+///
+CGAL::Gmpz ceil( const CGAL::Gmpq& v )
+{
+ CGAL::Gmpz result( 0 ) ;
+ mpz_cdiv_q( result.mpz(), v.numerator().mpz(), v.denominator().mpz() ) ;
+ return result ;
+}
+
+///
+///
+///
+CGAL::Gmpz round( const CGAL::Gmpq& v )
+{
+ if ( v < 0 ) {
+ //ceil( v - 0.5 ) ;
+ return ceil( v - CGAL::Gmpq( 1,2 ) );
+ }
+ else if ( v == 0 ) {
+ return 0 ;
+ }
+ else {
+ //floor( v + 0.5 ) ;
+ return floor( v + CGAL::Gmpq( 1,2 ) );
+ }
+}
+
+}//SFCGAL
+
+
diff --git a/src/numeric.h b/src/numeric.h
new file mode 100644
index 0000000..0b6f5ed
--- /dev/null
+++ b/src/numeric.h
@@ -0,0 +1,76 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_NUMERIC_H_
+#define _SFCGAL_NUMERIC_H_
+
+#include <limits>
+#include <cmath>
+
+#include <SFCGAL/export.h>
+
+#include <SFCGAL/Kernel.h>
+
+namespace SFCGAL {
+/**
+ * shortcut to get NaN for double
+ */
+inline double NaN()
+{
+ return std::numeric_limits< double >::quiet_NaN();
+}
+/**
+ * shortcut to test NaN for double
+ */
+inline bool isNaN( const double& value )
+{
+ return value != value ;
+}
+
+/**
+ * @brief round a double to the nearest integer
+ */
+inline double round( const double& v )
+{
+ if ( v < 0.0 ) {
+ return ::ceil( v - 0.5 ) ;
+ }
+ else {
+ return ::floor( v + 0.5 ) ;
+ }
+}
+
+
+/**
+ * @brief floor a rational to an integer
+ */
+SFCGAL_API CGAL::Gmpz floor( const CGAL::Gmpq& v ) ;
+/**
+ * @brief ceil a rational to an integer
+ */
+SFCGAL_API CGAL::Gmpz ceil( const CGAL::Gmpq& v ) ;
+/**
+ * @brief round a rational to an integer
+ */
+SFCGAL_API CGAL::Gmpz round( const CGAL::Gmpq& v ) ;
+
+}//SFCGAL
+
+#endif
diff --git a/src/triangulate/triangulate2DZ.cpp b/src/triangulate/triangulate2DZ.cpp
new file mode 100644
index 0000000..a412997
--- /dev/null
+++ b/src/triangulate/triangulate2DZ.cpp
@@ -0,0 +1,169 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/triangulate/triangulate2DZ.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+
+#include <SFCGAL/Exception.h>
+#include <SFCGAL/algorithm/isValid.h>
+
+namespace SFCGAL {
+namespace triangulate {
+
+typedef ConstraintDelaunayTriangulation::Vertex_handle Vertex_handle ;
+
+///
+///
+///
+void triangulate2DZ( const Point& g, ConstraintDelaunayTriangulation& triangulation )
+{
+ triangulation.addVertex( g.coordinate() );
+}
+///
+///
+///
+void triangulate2DZ( const LineString& g, ConstraintDelaunayTriangulation& triangulation )
+{
+ Vertex_handle last ;
+
+ for ( size_t i = 0; i < g.numPoints(); i++ ) {
+ Vertex_handle vertex = triangulation.addVertex( g.pointN( i ).coordinate() );
+
+ if ( i != 0 ) {
+ triangulation.addConstraint( last, vertex ) ;
+ }
+
+ last = vertex ;
+ }
+}
+///
+///
+///
+void triangulate2DZ( const Polygon& g, ConstraintDelaunayTriangulation& triangulation )
+{
+ for ( size_t i = 0; i < g.numRings(); i++ ) {
+ triangulate2DZ( g.ringN( i ), triangulation ) ;
+ }
+}
+///
+///
+///
+void triangulate2DZ( const Triangle& g, ConstraintDelaunayTriangulation& triangulation )
+{
+ Vertex_handle last ;
+
+ for ( size_t i = 0; i < 4; i++ ) {
+ Vertex_handle vertex = triangulation.addVertex( g.vertex( i ).coordinate() );
+
+ if ( i != 0 ) {
+ triangulation.addConstraint( last, vertex ) ;
+ }
+
+ last = vertex ;
+ }
+}
+///
+///
+///
+void triangulateCollection2DZ( const Geometry& g, ConstraintDelaunayTriangulation& triangulation )
+{
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ triangulate2DZ( g.geometryN( i ), triangulation ) ;
+ }
+}
+
+
+
+///
+///
+///
+void triangulate2DZ( const Geometry& g, ConstraintDelaunayTriangulation& triangulation )
+{
+
+ if ( g.isEmpty() ) {
+ return;
+ }
+
+ if ( triangulation.hasProjectionPlane() ) {
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_ON_PLANE( g, triangulation.projectionPlane() );
+ }
+ else {
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY_2D( g );
+ }
+
+
+ switch ( g.geometryTypeId() ) {
+ case TYPE_POINT:
+ triangulate2DZ( g.as< Point >(), triangulation );
+ return ;
+
+ case TYPE_LINESTRING:
+ triangulate2DZ( g.as< LineString >(), triangulation );
+ return ;
+
+ case TYPE_POLYGON:
+ triangulate2DZ( g.as< Polygon >(), triangulation );
+ return ;
+
+ case TYPE_TRIANGLE:
+ triangulate2DZ( g.as< Triangle >(), triangulation );
+ return ;
+
+ case TYPE_MULTIPOINT:
+ case TYPE_MULTILINESTRING:
+ case TYPE_MULTIPOLYGON:
+ case TYPE_POLYHEDRALSURFACE:
+ case TYPE_TRIANGULATEDSURFACE:
+ case TYPE_GEOMETRYCOLLECTION:
+ triangulateCollection2DZ( g, triangulation );
+ return ;
+
+ case TYPE_SOLID:
+ case TYPE_MULTISOLID:
+ // note: we can't have à valid geom in 2D that comes from à solid
+ // since a solid closed and thus self-intersects once projected
+ BOOST_THROW_EXCEPTION(
+ InappropriateGeometryException(
+ ( boost::format( "can't process 2DZ triangulation for type '%1%'" ) % g.geometryType() ).str()
+ )
+ );
+ }
+}
+
+
+///
+///
+///
+ConstraintDelaunayTriangulation triangulate2DZ( const Geometry& g )
+{
+ ConstraintDelaunayTriangulation triangulation ;
+ triangulate2DZ( g,triangulation );
+ return triangulation ;
+}
+
+
+}//triangulate
+}//SFCGAL
+
+
diff --git a/src/triangulate/triangulate2DZ.h b/src/triangulate/triangulate2DZ.h
new file mode 100644
index 0000000..3d59382
--- /dev/null
+++ b/src/triangulate/triangulate2DZ.h
@@ -0,0 +1,44 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_TRIANGULATE_TRIANGULATE2DZ_H_
+#define _SFCGAL_TRIANGULATE_TRIANGULATE2DZ_H_
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Geometry.h>
+#include <SFCGAL/detail/triangulate/ConstraintDelaunayTriangulation.h>
+
+namespace SFCGAL {
+namespace triangulate {
+/**
+ * @brief Constraint 2DZ Delaunay Triangulation (keep Z if defined, a projectionPlane may be provided)
+ */
+SFCGAL_API void triangulate2DZ( const Geometry& g, ConstraintDelaunayTriangulation& triangulate );
+/**
+ * @brief Constraint 2DZ Delaunay Triangulation (keep Z if defined, project points in OXY plane)
+ */
+SFCGAL_API ConstraintDelaunayTriangulation triangulate2DZ( const Geometry& g );
+
+}//algorithm
+}//SFCGAL
+
+#endif
+
diff --git a/src/triangulate/triangulatePolygon.cpp b/src/triangulate/triangulatePolygon.cpp
new file mode 100644
index 0000000..3ed8d4f
--- /dev/null
+++ b/src/triangulate/triangulatePolygon.cpp
@@ -0,0 +1,230 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/triangulate/triangulatePolygon.h>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+
+#include <SFCGAL/detail/triangulate/ConstraintDelaunayTriangulation.h>
+
+#include <SFCGAL/algorithm/plane.h>
+#include <SFCGAL/algorithm/normal.h>
+#include <SFCGAL/algorithm/isValid.h>
+
+#include <iostream>
+
+
+namespace SFCGAL {
+namespace triangulate {
+
+typedef ConstraintDelaunayTriangulation::Vertex_handle Vertex_handle ;
+
+///
+///
+///
+void triangulatePolygon3D(
+ const Geometry& g,
+ TriangulatedSurface& triangulatedSurface
+)
+{
+ if ( g.isEmpty() ) {
+ return;
+ }
+
+ SFCGAL_ASSERT_GEOMETRY_VALIDITY( g );
+
+ switch ( g.geometryTypeId() ) {
+ case TYPE_TRIANGLE:
+ return triangulatePolygon3D( g.as< Triangle >(), triangulatedSurface );
+
+ case TYPE_POLYGON:
+ return triangulatePolygon3D( g.as< Polygon >(), triangulatedSurface );
+
+ case TYPE_TRIANGULATEDSURFACE:
+ return triangulatePolygon3D( g.as< TriangulatedSurface >(), triangulatedSurface );
+
+ case TYPE_POLYHEDRALSURFACE:
+ return triangulatePolygon3D( g.as< PolyhedralSurface >(), triangulatedSurface );
+
+ case TYPE_SOLID:
+ return triangulatePolygon3D( g.as< Solid >(), triangulatedSurface );
+
+ case TYPE_MULTIPOLYGON:
+ case TYPE_MULTISOLID:
+ case TYPE_GEOMETRYCOLLECTION: {
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ triangulatePolygon3D( g.geometryN( i ), triangulatedSurface ) ;
+ }
+
+ return ;
+ }
+
+ default:
+ BOOST_THROW_EXCEPTION(
+ InappropriateGeometryException(
+ ( boost::format( "can't triangulate 3d polygons for type '%1%'" ) % g.geometryType() ).str()
+ )
+ );
+ }
+}
+
+///
+///
+///
+void triangulatePolygon3D(
+ const Triangle& triangle,
+ TriangulatedSurface& triangulatedSurface
+)
+{
+ /*
+ * filter empty polygon
+ */
+ if ( triangle.isEmpty() ) {
+ return ;
+ }
+
+ triangulatedSurface.addTriangle( triangle ) ;
+}
+
+///
+///
+///
+void triangulatePolygon3D(
+ const TriangulatedSurface& g,
+ TriangulatedSurface& triangulatedSurface
+)
+{
+ triangulatedSurface.addTriangles( g ) ;
+}
+
+///
+///
+///
+void triangulatePolygon3D(
+ const GeometryCollection& g,
+ TriangulatedSurface& triangulatedSurface
+)
+{
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ triangulatePolygon3D( g.geometryN( i ), triangulatedSurface );
+ }
+}
+
+///
+///
+///
+void triangulatePolygon3D(
+ const Polygon& polygon,
+ TriangulatedSurface& triangulatedSurface
+)
+{
+ /*
+ * filter empty polygon
+ */
+ if ( polygon.isEmpty() ) {
+ return ;
+ }
+
+ /*
+ * Prepare a Constraint Delaunay Triangulation
+ */
+ ConstraintDelaunayTriangulation cdt;
+
+ /*
+ * find polygon plane
+ */
+ Kernel::Plane_3 polygonPlane = algorithm::plane3D< Kernel >( polygon, false ) ;
+
+ if ( polygonPlane.is_degenerate() ) {
+ BOOST_THROW_EXCEPTION( Exception(
+ ( boost::format( "can't find plane for polygon %s" ) % polygon.asText() ).str()
+ ) );
+ }
+
+ cdt.setProjectionPlane( polygonPlane );
+
+ /*
+ * insert each ring in the triangulation
+ */
+ for ( size_t i = 0; i < polygon.numRings(); i++ ) {
+ const LineString& ring = polygon.ringN( i );
+
+ /*
+ * note, we do not include the last point, since it's equal to the last and that
+ */
+ if ( !ring.numPoints() ) {
+ continue;
+ }
+
+ Vertex_handle v_prev = cdt.addVertex( ring.pointN( 0 ).coordinate() );
+ Vertex_handle v_0 = v_prev;
+
+ for ( size_t j = 1; j < ring.numPoints()-1; j++ ) {
+ Vertex_handle vh = cdt.addVertex( ring.pointN( j ).coordinate() );
+ cdt.addConstraint( v_prev, vh );
+ v_prev = vh;
+ }
+
+ cdt.addConstraint( v_prev, v_0 );
+ }
+
+ /*
+ * Mark facets that are inside the domain bounded by the polygon
+ */
+ cdt.markDomains() ;
+ cdt.getTriangles( triangulatedSurface, true ) ;
+}
+
+///
+///
+///
+void triangulatePolygon3D(
+ const PolyhedralSurface& g,
+ TriangulatedSurface& triangulatedSurface
+)
+{
+ for ( size_t i = 0; i < g.numGeometries(); i++ ) {
+ triangulatePolygon3D( g.polygonN( i ), triangulatedSurface );
+ }
+}
+
+
+///
+///
+///
+void triangulatePolygon3D(
+ const Solid& g,
+ TriangulatedSurface& triangulatedSurface
+)
+{
+ for ( size_t i = 0; i < g.numShells(); i++ ) {
+ triangulatePolygon3D( g.shellN( i ), triangulatedSurface );
+ }
+}
+
+
+}//triangulate
+}//SFCGAL
+
+
+
diff --git a/src/triangulate/triangulatePolygon.h b/src/triangulate/triangulatePolygon.h
new file mode 100644
index 0000000..75e11fd
--- /dev/null
+++ b/src/triangulate/triangulatePolygon.h
@@ -0,0 +1,106 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_TRIANGULATE_TRIANGULATEPOLYGON_H_
+#define _SFCGAL_TRIANGULATE_TRIANGULATEPOLYGON_H_
+
+#include <SFCGAL/config.h>
+
+#include <SFCGAL/Geometry.h>
+
+namespace SFCGAL {
+namespace triangulate {
+
+/**
+ * @brief Triangulate 3D polygons in a Geometry.
+ *
+ * @param g input geometry
+ * @param triangulatedSurface resulting TriangulatedSurface
+ * @param usePolygonPlanes use polygon plane or Triangulate in OXY plane
+ * @todo unittest
+ * @ingroup detail
+ */
+SFCGAL_API void triangulatePolygon3D(
+ const Geometry& g,
+ TriangulatedSurface& triangulatedSurface
+);
+/**
+ * @brief Triangulate a 3D Polygon
+ * @todo unittest
+ * @ingroup detail
+ */
+SFCGAL_API void triangulatePolygon3D(
+ const Polygon& g,
+ TriangulatedSurface& triangulatedSurface
+);
+/**
+ * @brief Triangulate a 3D Triangle (copy triangle)
+ * @todo unittest
+ * @ingroup detail
+ */
+SFCGAL_API void triangulatePolygon3D(
+ const Triangle& g,
+ TriangulatedSurface& triangulatedSurface
+);
+/**
+ * @brief Triangulate a 3D TriangulatedSurface (copy triangles)
+ *
+ * @todo unittest
+ * @ingroup detail
+ */
+SFCGAL_API void triangulatePolygon3D(
+ const TriangulatedSurface& g,
+ TriangulatedSurface& triangulatedSurface
+);
+/**
+ * @brief Triangulate a 3D MultiPolygon
+ * @todo unittest
+ * @ingroup detail
+ */
+SFCGAL_API void opentriangulatePolygon3D(
+ const GeometryCollection& g,
+ TriangulatedSurface& triangulatedSurface
+);
+/**
+ * @brief Triangulate 3D polygons in a PolyhedralSurface.
+ *
+ * @todo unittest
+ * @ingroup detail
+ */
+SFCGAL_API void triangulatePolygon3D(
+ const PolyhedralSurface& polyhedralSurface,
+ TriangulatedSurface& triangulatedSurface
+);
+/**
+ * @brief Triangulate a Solid
+ *
+ * @todo unittest
+ * @ingroup detail
+ */
+SFCGAL_API void triangulatePolygon3D(
+ const Solid& g,
+ TriangulatedSurface& triangulatedSurface
+);
+
+}//algorithm
+}//SFCGAL
+
+#endif
+
diff --git a/src/version.cpp b/src/version.cpp
new file mode 100644
index 0000000..bcd8ab1
--- /dev/null
+++ b/src/version.cpp
@@ -0,0 +1,33 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/version.h>
+
+namespace SFCGAL {
+
+const char _sfcgal_version[] = SFCGAL_VERSION;
+
+const char* Version()
+{
+ return _sfcgal_version;
+}
+
+}//SFCGAL
+
diff --git a/src/version.h.cmake b/src/version.h.cmake
new file mode 100644
index 0000000..7eb264d
--- /dev/null
+++ b/src/version.h.cmake
@@ -0,0 +1,37 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SFCGAL_VERSION_H_
+#define _SFCGAL_VERSION_H_
+
+#include <SFCGAL/export.h>
+
+#define SFCGAL_VERSION_MAJOR @SFCGAL_VERSION_MAJOR@
+#define SFCGAL_VERSION_MINOR @SFCGAL_VERSION_MINOR@
+#define SFCGAL_VERSION_PATCH @SFCGAL_VERSION_PATCH@
+
+#define SFCGAL_VERSION "@SFCGAL_VERSION@"
+
+namespace SFCGAL {
+ SFCGAL_API const char* Version();
+}
+
+#endif
+
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 0000000..67469fc
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,28 @@
+#-- configure tests
+set( SFCGAL_TEST_DIRECTORY "${CMAKE_SOURCE_DIR}/test" )
+configure_file( ${SFCGAL_TEST_DIRECTORY}/test_config.h.cmake ${SFCGAL_TEST_DIRECTORY}/test_config.h )
+
+if(CMAKE_COMPILER_IS_GNUCXX)
+ add_definitions( "-frounding-math" )
+
+endif(CMAKE_COMPILER_IS_GNUCXX)
+
+#-- build regression tests
+if( SFCGAL_BUILD_TESTS )
+ add_subdirectory( unit )
+ add_subdirectory( regress )
+ add_subdirectory( garden )
+endif()
+
+if( SFCGAL_BUILD_BENCH )
+ add_subdirectory( bench )
+endif()
+
+if(CMAKE_SYSTEM_NAME MATCHES "Linux")
+ add_test( style-test ${CMAKE_SOURCE_DIR}/script/test-style-SFCGAL.sh )
+endif()
+
+
+
+
+
diff --git a/test/bench/Bench.cpp b/test/bench/Bench.cpp
new file mode 100644
index 0000000..55ba68c
--- /dev/null
+++ b/test/bench/Bench.cpp
@@ -0,0 +1,89 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "Bench.h"
+
+
+namespace SFCGAL {
+
+///
+///
+///
+Bench::~Bench()
+{
+
+}
+
+///
+///
+///
+void Bench::start( const std::string& description )
+{
+ _timers.push( std::make_pair( description, timer_t() ) );
+ _timers.top().second.start();
+}
+
+///
+///
+///
+void Bench::start( const boost::basic_format<char>& description )
+{
+ start( description.str() );
+}
+
+///
+///
+///
+void Bench::stop()
+{
+ BOOST_ASSERT( ! _timers.empty() ) ;
+ _timers.top().second.stop();
+ s() << _timers.top().first << "\t" << ( _timers.top().second.elapsed().wall * 1.0e-9 ) << std::endl ;
+ _timers.pop() ;
+}
+
+///
+///
+///
+Bench& Bench::instance()
+{
+ static Bench bench ;
+ return bench ;
+}
+
+///
+///
+///
+std::ostream& Bench::s()
+{
+ return *_s ;
+}
+
+///
+///
+///
+Bench::Bench():
+ _s( &std::cout )
+{
+
+}
+
+
+} // namespace SFCGAL
+
diff --git a/test/bench/Bench.h b/test/bench/Bench.h
new file mode 100644
index 0000000..50fee5a
--- /dev/null
+++ b/test/bench/Bench.h
@@ -0,0 +1,97 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _SFCGAL_BENCH_H_
+#define _SFCGAL_BENCH_H_
+
+#include <iostream>
+#include <stack>
+
+#include <boost/timer/timer.hpp>
+
+#include <boost/format.hpp>
+
+namespace SFCGAL {
+
+/**
+ * @brief helper class to write formated benchs
+ */
+class Bench {
+public:
+ typedef boost::timer::cpu_timer timer_t ;
+
+ /**
+ * destructor
+ */
+ ~Bench();
+
+ /**
+ * start a bench
+ */
+ void start( const std::string& description ) ;
+ /**
+ * start a bench
+ */
+ void start( const boost::basic_format<char>& description ) ;
+ /**
+ * stop a bench
+ */
+ void stop() ;
+
+ /**
+ * get bench instance
+ */
+ static Bench& instance() ;
+
+ /**
+ * Get output stream
+ */
+ std::ostream& s() ;
+private:
+ /**
+ * default constructor
+ */
+ Bench();
+ /**
+ * copy constructor
+ */
+ Bench( const Bench& bench );
+
+ /**
+ * output stream to write bench result (default is std::cout)
+ */
+ std::ostream* _s ;
+ /**
+ * timer stack with description
+ */
+ std::stack< std::pair< std::string, timer_t > > _timers ;
+};
+
+/**
+ * @Get bench instance
+ */
+inline Bench& bench()
+{
+ return Bench::instance() ;
+}
+
+} // namespace SFCGAL
+
+#endif
+
diff --git a/test/bench/BenchArea.cpp b/test/bench/BenchArea.cpp
new file mode 100644
index 0000000..b4cc7a0
--- /dev/null
+++ b/test/bench/BenchArea.cpp
@@ -0,0 +1,82 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <fstream>
+
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+#include "../test_config.h"
+#include "Bench.h"
+
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/detail/generator/sierpinski.h>
+
+#include <SFCGAL/algorithm/area.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_BenchArea )
+
+
+BOOST_AUTO_TEST_CASE( testAreaSierpinski )
+{
+ std::auto_ptr< MultiPolygon > fractal( generator::sierpinski( 9 ) ) ;
+
+ bench().start( "area sierpinski" ) ;
+
+ for ( int i = 0; i < 10; i++ ) {
+ algorithm::area( *fractal ) ;
+ }
+
+ bench().stop();
+}
+
+BOOST_AUTO_TEST_CASE( testAreaSierpinski3D )
+{
+ std::auto_ptr< MultiPolygon > fractal( generator::sierpinski( 9 ) ) ;
+
+ bench().start( "area sierpinski" ) ;
+
+ for ( int i = 0; i < 10; i++ ) {
+ algorithm::area3D( *fractal ) ;
+ }
+
+ bench().stop() ;
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/bench/BenchContainer.cpp b/test/bench/BenchContainer.cpp
new file mode 100644
index 0000000..2f00c87
--- /dev/null
+++ b/test/bench/BenchContainer.cpp
@@ -0,0 +1,179 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+
+#include "../test_config.h"
+
+#include "Bench.h"
+
+#include <boost/test/unit_test.hpp>
+
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_BenchContainer )
+
+#if 0
+
+//
+// Test limit case
+BOOST_AUTO_TEST_CASE( testVectorOfPoint2 )
+{
+ const int N = 100000 ;
+
+ // create points
+ bench().start( "std::vector< Kernel::Point_2 > create" ) ;
+ std::vector< Kernel::Point_2 > points ;
+ points.reserve( N ) ;
+
+ for ( int i = 0; i < N; i++ ) {
+ points.push_back( Kernel::Point_2( i,i ) ) ;
+ }
+
+ bench().stop();
+
+ // centroid
+ bench().start( "std::vector< Kernel::Point_2 > access" ) ;
+ Kernel::FT x = 0 , y = 0 ;
+
+ for ( std::vector< Kernel::Point_2 >::const_iterator it = points.begin(); it != points.end(); ++it ) {
+ x += it->x() ;
+ y += it->y() ;
+ }
+
+ Kernel::Point_2 centroid( x / Kernel::FT( ( int )points.size() ), y / Kernel::FT( ( int )points.size() ) );
+ bench().stop() ;
+
+ // reverse
+ bench().start( "std::vector< Kernel::Point_2 > reverse" ) ;
+ std::reverse( points.begin(), points.end() ) ;
+ bench().stop();
+
+ // clear
+ bench().start( "std::vector< Kernel::Point_2 > clear" ) ;
+ points.clear() ;
+ bench().stop() ;
+}
+
+//
+// Test limit case
+BOOST_AUTO_TEST_CASE( testVectorOfPoint )
+{
+ const int N = 100000 ;
+
+ // create points
+ bench().start( "std::vector< Point > create" );
+ std::vector< Point > points ;
+ points.reserve( N ) ;
+
+ for ( int i = 0; i < N; i++ ) {
+ points.push_back( Point( i,i ) ) ;
+ }
+
+ bench().stop();
+
+ // centroid
+ bench().start( "std::vector< Point > access" );
+ Kernel::FT x = 0 , y = 0 ;
+
+ for ( std::vector< Point >::const_iterator it = points.begin(); it != points.end(); ++it ) {
+ x += it->x() ;
+ y += it->y() ;
+ }
+
+ Point centroid( x / Kernel::FT( ( int )points.size() ), y / Kernel::FT( ( int )points.size() ) );
+ bench().stop();
+
+
+ // reverse
+ bench().start( "std::vector< Point > reverse" ) ;
+ std::reverse( points.begin(), points.end() ) ;
+ bench().stop() ;
+
+ // clear
+ bench().start( "std::vector< Point > clear" ) ;
+ points.clear() ;
+ bench().stop() ;
+}
+
+
+//
+// Test limit case
+BOOST_AUTO_TEST_CASE( testPtrVectorOfPoint )
+{
+ const int N = 100000 ;
+
+ boost::timer::cpu_timer timer;
+
+ // create points
+ bench().start( "boost::ptr_vector< Point > create" ) ;
+ boost::ptr_vector< Point > points ;
+ points.reserve( N ) ;
+
+ for ( int i = 0; i < N; i++ ) {
+ points.push_back( new Point( i,i ) ) ;
+ }
+
+ bench().stop() ;
+
+ // centroid
+ bench().start( "boost::ptr_vector< Point > access" ) ;
+ Kernel::FT x = 0 , y = 0 ;
+
+ for ( boost::ptr_vector< Point >::const_iterator it = points.begin(); it != points.end(); ++it ) {
+ x += it->x() ;
+ y += it->y() ;
+ }
+
+ Point centroid( x / Kernel::FT( ( int )points.size() ), y / Kernel::FT( ( int )points.size() ) );
+ bench().stop();
+
+
+ // reverse
+ bench().start( "boost::ptr_vector< Point > reverse" );
+ std::reverse( points.begin(), points.end() ) ;
+ bench().stop();
+
+ // clear
+ bench().start( "boost::ptr_vector< Point > clear" );
+ points.clear() ;
+ bench().stop();
+}
+
+#endif
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/bench/BenchMinkowski.cpp b/test/bench/BenchMinkowski.cpp
new file mode 100644
index 0000000..fc79f65
--- /dev/null
+++ b/test/bench/BenchMinkowski.cpp
@@ -0,0 +1,76 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/minkowskiSum.h>
+
+#include "../test_config.h"
+#include "Bench.h"
+
+#include <boost/test/unit_test.hpp>
+
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_BenchMinkowskiSum )
+
+
+BOOST_AUTO_TEST_CASE( testPolygonWithHoles )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "MULTIPOLYGON(((11.795461 32.713032,11.381695 35.857648,15.188336 38.091981,28.428825 38.257487,30.994170 33.788822,30.580405 29.816675,26.773764 22.617159,11.050683 18.562259,-0.534745 21.044851,-3.513855 26.837565,3.520155 26.506553,4.099426 24.685985,4.678698 22.782665,6.582018 21.541369,8.899104 21.458616,16.098620 21.706875,18.332952 25.016998,17.919187 27.499589,16.429632 27.830601,14.360805 26.175540,13.036756 24.520479,10.885177 23.5 [...]
+ std::auto_ptr< Geometry > gB( io::readWkt( "POLYGON((-1 0,0 -1,1 0,0 1,-1 0))" ) );
+
+ bench().start( "minkowski polygon with hole" ) ;
+
+ for ( int i = 0; i < 1000; i++ ) {
+ std::auto_ptr< Geometry > sum( algorithm::minkowskiSum( *gA, gB->as< Polygon >() ) );
+ }
+
+ bench().stop();
+}
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
+
+
+//BOOST_AUTO_TEST_CASE( testTemp ){
+// std::auto_ptr< Geometry > gA( io::readWkt("MULTIPOLYGON(((11.795461 32.713032,11.381695 35.857648,15.188336 38.091981,28.428825 38.257487,30.994170 33.788822,30.580405 29.816675,26.773764 22.617159,11.050683 18.562259,-0.534745 21.044851,-3.513855 26.837565,3.520155 26.506553,4.099426 24.685985,4.678698 22.782665,6.582018 21.541369,8.899104 21.458616,16.098620 21.706875,18.332952 25.016998,17.919187 27.499589,16.429632 27.830601,14.360805 26.175540,13.036756 24.520479,10.885177 23.527 [...]
+// std::auto_ptr< Geometry > gB( io::readWkt( "POLYGON((-1 0,0 -1,1 0,0 1,-1 0))" ) );
+//
+// std::auto_ptr< Geometry > sum( algorithm::minkowskiSum( *gA, gB->as< Polygon >() ) );
+// std::cout << sum->asText(6) << std::endl ;
+//}
diff --git a/test/bench/BenchTriangulation.cpp b/test/bench/BenchTriangulation.cpp
new file mode 100644
index 0000000..98be31e
--- /dev/null
+++ b/test/bench/BenchTriangulation.cpp
@@ -0,0 +1,192 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <fstream>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/detail/generator/hoch.h>
+#include <SFCGAL/detail/generator/disc.h>
+#include <SFCGAL/triangulate/triangulate2DZ.h>
+#include <SFCGAL/triangulate/triangulatePolygon.h>
+
+#include "../test_config.h"
+#include "Bench.h"
+
+#include <boost/test/unit_test.hpp>
+#include <boost/format.hpp>
+
+#include <CGAL/point_generators_2.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+using namespace SFCGAL::triangulate ;
+
+#define N_POINTS 100000
+
+typedef CGAL::Creator_uniform_2< double, Kernel::Point_2 > Creator ;
+
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_BenchTriangulation )
+
+BOOST_AUTO_TEST_CASE( testMultiPointTriangulation )
+{
+ CGAL::Random_points_in_disc_2< Kernel::Point_2, Creator > g( 150.0 );
+
+ MultiPoint multiPoint ;
+
+ for ( int i = 0; i < N_POINTS; i++ ) {
+ Kernel::Point_2 p = *( ++g ) ;
+ multiPoint.addGeometry( new Point( p ) ) ;
+ }
+
+ bench().start( boost::format( "triangulate2DZ %s points" ) % N_POINTS );
+ ConstraintDelaunayTriangulation cdt = triangulate2DZ( multiPoint ) ;
+ bench().stop();
+}
+
+
+BOOST_AUTO_TEST_CASE( testPolygonTriangulationHoch )
+{
+ const int N = 7 ;
+ std::auto_ptr< Polygon > fractal( generator::hoch( N ) );
+ BOOST_CHECK_EQUAL( fractal->exteriorRing().numPoints(), 49153U );
+
+ bench().start( boost::format( "triangulate hoch(%s)" ) % N );
+ TriangulatedSurface triangulatedSurface ;
+ SFCGAL::triangulate::triangulatePolygon3D( *fractal, triangulatedSurface ) ;
+ bench().stop() ;
+}
+
+BOOST_AUTO_TEST_CASE( testPolygonTriangulationHoch_roundingSixDecimal )
+{
+ const int N = 7 ;
+ std::auto_ptr< Polygon > fractal( generator::hoch( N ) );
+ BOOST_CHECK_EQUAL( fractal->exteriorRing().numPoints(), 49153U );
+
+ fractal->round( 100000 ) ;
+
+ bench().start( boost::format( "triangulate hoch(%s) (round 6 six decimals)" ) % N );
+ TriangulatedSurface triangulatedSurface ;
+ SFCGAL::triangulate::triangulatePolygon3D( *fractal, triangulatedSurface ) ;
+ bench().stop() ;
+}
+
+
+
+BOOST_AUTO_TEST_CASE( testPolygonTriangulationDisc )
+{
+ const int N = 20000 ;
+
+ std::auto_ptr< Polygon > disc( generator::disc( Point( 0.0,0.0 ), 1.0, 8U ) );
+// std::cout << fractal->asText(5) << std::endl ;
+
+ bench().start( boost::format( "triangulate disc x %s" ) % N );
+
+ for ( int i = 0; i < N; i++ ) {
+ TriangulatedSurface triangulatedSurface ;
+ SFCGAL::triangulate::triangulatePolygon3D( *disc, triangulatedSurface ) ;
+ }
+
+ bench().stop();
+}
+
+
+
+
+BOOST_AUTO_TEST_CASE( testMultiPointTriangulation2D )
+{
+ CGAL::Random_points_in_disc_2< Kernel::Point_2, Creator > g( 150.0 );
+
+ MultiPoint multiPoint ;
+
+ for ( int i = 0; i < N_POINTS; i++ ) {
+ Kernel::Point_2 p = *( ++g ) ;
+ multiPoint.addGeometry( new Point( p ) ) ;
+ }
+
+ bench().start( boost::format( "triangulate2D %s points" ) % N_POINTS );
+ SFCGAL::triangulate::ConstraintDelaunayTriangulation cdt;
+ SFCGAL::triangulate::triangulate2DZ( multiPoint, cdt ) ;
+ bench().stop();
+}
+
+BOOST_AUTO_TEST_CASE( testPolygonTriangulationHoch2D )
+{
+ const int N = 7 ;
+ std::auto_ptr< Polygon > fractal( generator::hoch( N ) );
+// std::cout << fractal->asText(5) << std::endl ;
+
+ bench().start( boost::format( "triangulate2D hoch(%s)" ) % N );
+ SFCGAL::triangulate::ConstraintDelaunayTriangulation cdt;
+ SFCGAL::triangulate::triangulate2DZ( *fractal, cdt ) ;
+ bench().stop();
+}
+
+BOOST_AUTO_TEST_CASE( testPolygonTriangulationDisc2D )
+{
+ const int N = 20000 ;
+
+ std::auto_ptr< Polygon > disc( generator::disc( Point( 0.0,0.0 ), 1.0, 8U ) ) ;
+// std::cout << fractal->asText(5) << std::endl ;
+
+ bench().start( boost::format( "triangulate2D disc x %s" ) % N ) ;
+
+ for ( int i = 0; i < N; i++ ) {
+ SFCGAL::triangulate::ConstraintDelaunayTriangulation cdt;
+ SFCGAL::triangulate::triangulate2DZ( *disc, cdt ) ;
+ }
+
+ bench().stop() ;
+}
+
+BOOST_AUTO_TEST_CASE( testPolygonTriangulationDisc2D_roundingSixDecimal )
+{
+ const int N = 20000 ;
+
+ std::auto_ptr< Polygon > disc( generator::disc( Point( 0.0,0.0 ), 1.0, 8U ) ) ;
+ disc->round( 100000 ) ;
+
+ bench().start( boost::format( "triangulate2D disc x %s (round 6 six decimals)" ) % N ) ;
+
+ for ( int i = 0; i < N; i++ ) {
+ SFCGAL::triangulate::ConstraintDelaunayTriangulation cdt;
+ SFCGAL::triangulate::triangulate2DZ( *disc, cdt ) ;
+ }
+
+ bench().stop() ;
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/bench/BenchWKT.cpp b/test/bench/BenchWKT.cpp
new file mode 100644
index 0000000..3ec8f2f
--- /dev/null
+++ b/test/bench/BenchWKT.cpp
@@ -0,0 +1,130 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <fstream>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+
+#include "../test_config.h"
+#include "Bench.h"
+
+#include <boost/test/unit_test.hpp>
+#include <boost/format.hpp>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_BenchWKT )
+
+//
+// Test limit case
+BOOST_AUTO_TEST_CASE( testReadPoints )
+{
+ const int N = 100000 ;
+
+ bench().start( boost::format( "READ WKT POINTS" ) );
+
+ for ( int i = 0; i < N; i++ ) {
+ io::readWkt( "POINT(50000 50000)" ) ;
+ }
+
+ bench().stop() ;
+}
+
+
+//
+// Test limit case
+BOOST_AUTO_TEST_CASE( testReadLineString )
+{
+ const int N = 100000 ;
+
+ bench().start( boost::format( "READ WKT LINESTRING" ) ) ;
+
+ for ( int i = 0; i < N; i++ ) {
+ io::readWkt( "LINESTRING(0 0,0 1000,1000 1000)" ) ;
+ }
+
+ bench().stop() ;
+}
+
+//
+// Test limit case
+BOOST_AUTO_TEST_CASE( testReadPolygon )
+{
+ const int N = 100000 ;
+
+ bench().start( boost::format( "READ WKT POLYGON" ) ) ;
+
+ for ( int i = 0; i < N; i++ ) {
+ io::readWkt( "POLYGON((0 0,0 1000,1000 1000,1000 0,0 0))" ) ;
+ }
+
+ bench().stop();
+}
+
+//
+// Test limit case
+BOOST_AUTO_TEST_CASE( testReadTriangle )
+{
+ const int N = 100000 ;
+
+ bench().start( boost::format( "READ WKT TRIANGLE" ) ) ;
+
+ for ( int i = 0; i < N; i++ ) {
+ io::readWkt( "TRIANGLE((0 0,0 1000,1000 1000,1000 0,0 0))" ) ;
+ }
+
+ bench().stop();
+}
+
+//
+// Test limit case
+BOOST_AUTO_TEST_CASE( testReadSolid )
+{
+ const int N = 10000 ;
+
+ bench().start( boost::format( "READ WKT SOLID" ) ) ;
+
+ for ( int i = 0; i < N; i++ ) {
+ io::readWkt( "SOLID((((0.0 0.0 0.0,0.0 1.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0,0.0 0.0 0.0),(0.2 0.2 0.0,0.8 0.2 0.0,0.8 0.8 0.0,0.2 0.8 0.0,0.2 0.2 0.0)),((0.0 0.0 1.0,1.0 0.0 1.0,1.0 1.0 1.0,0.0 1.0 1.0,0.0 0.0 1.0),(0.2 0.2 1.0,0.2 0.8 1.0,0.8 0.8 1.0,0.8 0.2 1.0,0.2 0.2 1.0)),((0.0 0.0 0.0,0.0 0.0 1.0,0.0 1.0 1.0,0.0 1.0 0.0,0.0 0.0 0.0)),((0.0 1.0 0.0,0.0 1.0 1.0,1.0 1.0 1.0,1.0 1.0 0.0,0.0 1.0 0.0)),((1.0 1.0 0.0,1.0 1.0 1.0,1.0 0.0 1.0,1.0 0.0 0.0,1.0 1.0 0.0)),((1.0 0.0 0.0,1.0 0 [...]
+ }
+
+ bench().stop();
+}
+
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/bench/CMakeLists.txt b/test/bench/CMakeLists.txt
new file mode 100644
index 0000000..48b01b4
--- /dev/null
+++ b/test/bench/CMakeLists.txt
@@ -0,0 +1,13 @@
+file( GLOB SFCGAL_BENCHS_SOURCES *.cpp )
+add_executable( bench-SFCGAL ${SFCGAL_BENCHS_SOURCES} )
+target_link_libraries( bench-SFCGAL
+ SFCGAL
+ ${Boost_LIBRARIES}
+ ${CGAL_LIBRARIES}
+)
+if( SFCGAL_WITH_MPFR )
+ target_link_libraries( bench-SFCGAL ${MPFR_LIBRARIES} ${GMP_LIBRARIES} )
+endif()
+set_target_properties( bench-SFCGAL PROPERTIES DEBUG_POSTFIX "d" )
+install( TARGETS bench-SFCGAL DESTINATION bin )
+
diff --git a/test/bench/IntersectionPerfTest.cpp b/test/bench/IntersectionPerfTest.cpp
new file mode 100644
index 0000000..8b58069
--- /dev/null
+++ b/test/bench/IntersectionPerfTest.cpp
@@ -0,0 +1,89 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <fstream>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/intersection.h>
+#include <SFCGAL/algorithm/intersects.h>
+#include <SFCGAL/algorithm/convexHull.h>
+
+#include "../test_config.h"
+#include "Bench.h"
+
+#include <boost/test/unit_test.hpp>
+#include <boost/format.hpp>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_IntersectionPerfTest )
+
+
+#define N_POLYGONS 10000
+#define N_POINTS 50
+
+//
+// Test limit case
+BOOST_AUTO_TEST_CASE( testIntersectionPerf )
+{
+
+ //
+ // generate polygons
+ std::vector<Geometry*> polygons;
+
+ for ( size_t i = 0; i < N_POLYGONS; ++i ) {
+ MultiPoint mp;
+
+ for ( size_t j = 0; j < N_POINTS; ++j ) {
+ double x = ( rand() +.0 ) / RAND_MAX * 10.0;
+ double y = ( rand() +.0 ) / RAND_MAX * 10.0;
+ mp.addGeometry( Point( x, y ) );
+ }
+
+ std::auto_ptr<Geometry> g( algorithm::convexHull( mp ) );
+ polygons.push_back( g.release() );
+ }
+
+ bench().start( "intersects convex hull" );
+
+ for ( size_t i = 0; i < N_POLYGONS / 2; ++i ) {
+ algorithm::intersects( *polygons[2*i], *polygons[2*i+1] );
+ }
+
+ bench().stop();
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/bench/KernelPerfTest.cpp b/test/bench/KernelPerfTest.cpp
new file mode 100644
index 0000000..e49dba6
--- /dev/null
+++ b/test/bench/KernelPerfTest.cpp
@@ -0,0 +1,85 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <fstream>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+
+#include "../test_config.h"
+#include "Bench.h"
+
+#include <boost/test/unit_test.hpp>
+#include <boost/format.hpp>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+typedef CGAL::Exact_predicates_exact_constructions_kernel ExactKernel;
+typedef CGAL::Exact_predicates_inexact_constructions_kernel InexactKernel;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_KernelPerfTest )
+
+#define N_POINTS 10000000
+//
+// Test limit case
+BOOST_AUTO_TEST_CASE( testPointCopyPerf )
+{
+ bench().start( "Inexact kernel copy" );
+ InexactKernel::Point_2 ip2;
+
+ for ( size_t i = 0; i < N_POINTS; ++i ) {
+ // test copy
+ InexactKernel::Point_2 p( ( double )rand() / RAND_MAX, ( double )rand() / RAND_MAX );
+ ip2 = p;
+ }
+
+ bench().stop();
+
+ bench().start( "Exact kernel copy" );
+ ExactKernel::Point_2 ep2;
+
+ for ( size_t i = 0; i < N_POINTS; ++i ) {
+ // test copy
+ ExactKernel::Point_2 p( ( double )rand() / RAND_MAX, ( double )rand() / RAND_MAX );
+ ep2 = p;
+ }
+
+ bench().stop();
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/bench/TestModule.cpp b/test/bench/TestModule.cpp
new file mode 100644
index 0000000..087b322
--- /dev/null
+++ b/test/bench/TestModule.cpp
@@ -0,0 +1,29 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#define BOOST_TEST_MODULE BenchTestSFCGAL
+
+#include <boost/test/unit_test.hpp>
+using namespace boost::unit_test ;
+
+
+
+
+
+
diff --git a/test/data/AreaTest.txt b/test/data/AreaTest.txt
new file mode 100644
index 0000000..b4a6106
--- /dev/null
+++ b/test/data/AreaTest.txt
@@ -0,0 +1,1001 @@
+#some 2D buildings with <id> ST_Area(<geometry>) geometry
+BATIMENT0000000043414173 61.57470703125 MULTIPOLYGON(((969243.8 6768272.7,969250.1 6768274.4,969246.5 6768282.3,969239.1 6768280.9,969243.8 6768272.7)))
+BATIMENT0000000043414170 70.47021484375 MULTIPOLYGON(((969222.6 6768284.1,969229.5 6768286.2,969226.8 6768295.5,969219.9 6768293.7,969222.6 6768284.1)))
+BATIMENT0000000043414164 33.44091796875 MULTIPOLYGON(((969352.3 6768345.3,969347.9 6768347.6,969352.8 6768353.5,969356.3 6768351.6,969352.3 6768345.3)))
+BATIMENT0000000023319515 388.30517578125 MULTIPOLYGON(((184816.2 6865889,184815.2 6865882.3,184809.6 6865881.8,184810 6865869.6,184806.2 6865869.8,184806.2 6865864.2,184790.4 6865864.1,184789.2 6865880.5,184803.1 6865881,184802.2 6865885.4,184816.2 6865889)))
+BATIMENT0000000043414159 214.125 MULTIPOLYGON(((970402.8 6768517.6,970408.4 6768503.9,970395.8 6768498.5,970389.9 6768514.6,970402.8 6768517.6)))
+BATIMENT0000000043414158 208.20556640625 MULTIPOLYGON(((970777.5 6768466.7,970789 6768457.6,970794.1 6768466.7,970790.1 6768469.2,970795.4 6768477,970788.7 6768480.9,970777.5 6768466.7)))
+BATIMENT0000000023316787 398.10009765625 MULTIPOLYGON(((186386.2 6866604.6,186391 6866616.9,186418.1 6866606.7,186410.7 6866594.2,186392.2 6866600.8,186386.2 6866604.6)))
+BATIMENT0000000023316791 283.5 MULTIPOLYGON(((186276.8 6866706.9,186257.8 6866706.2,186258.2 6866691.3,186276.5 6866691.4,186276.8 6866706.9)))
+BATIMENT0000000043414151 77.97509765625 MULTIPOLYGON(((970435.8 6768262,970445.4 6768259.8,970447.8 6768268.5,970439.5 6768269.6,970435.8 6768262)))
+BATIMENT0000000223445499 164.97998046875 MULTIPOLYGON(((987920.4 6716933.6,987928.1 6716938.2,987923.1 6716946.6,987922.3 6716946.1,987919.3 6716951.2,987907.3 6716943.8,987909.8 6716939.5,987915.1 6716942.6,987920.4 6716933.6)))
+BATIMENT0000000014667724 91.83544921875 MULTIPOLYGON(((990303 6714463.2,990300.5 6714454.8,990290.7 6714457,990292.5 6714465.7,990303 6714463.2)))
+BATIMENT0000000043414149 61.67041015625 MULTIPOLYGON(((971228.6 6768472.2,971219.2 6768473.8,971220.6 6768480.4,971231.9 6768476.2,971228.6 6768472.2)))
+BATIMENT0000000043414148 291.22021484375 MULTIPOLYGON(((971632.3 6768310.4,971641.5 6768297.3,971651.4 6768302.3,971649.5 6768306.7,971654.8 6768310.6,971646.5 6768321.7,971632.3 6768310.4)))
+BATIMENT0000000043414147 237.61572265625 MULTIPOLYGON(((971271.5 6768626,971258.5 6768623.8,971258.9 6768643.1,971272.1 6768642.4,971273.1 6768633.3,971271.2 6768633.1,971271.5 6768626)))
+BATIMENT0000000043414146 312.8994140625 MULTIPOLYGON(((971276.8 6768626,971296.8 6768626.1,971297 6768639.5,971289.3 6768639.4,971289.8 6768644.9,971280.4 6768645,971280.9 6768637.7,971276.5 6768637.5,971276.8 6768626)))
+BATIMENT0000000039301933 3256.525390625 MULTIPOLYGON(((650686.1 6913382.7,650681.3 6913398.2,650676.2 6913396.7,650673.2 6913406.8,650658.8 6913401.2,650648.8 6913438,650660.6 6913441.6,650669.8 6913441.4,650683.9 6913445.1,650681.7 6913451.1,650670.4 6913446.9,650667.3 6913457.2,650693.5 6913467.1,650697.7 6913457.2,650687.9 6913453.3,650689.2 6913450.3,650699.4 6913452.9,650720.3 6913396.1,650686.1 6913382.7)))
+BATIMENT0000000222666367 32.64990234375 MULTIPOLYGON(((879677.2 6558431.2,879683.4 6558430.7,879682.4 6558424.6,879676.5 6558426.9,879677.2 6558431.2)))
+BATIMENT0000000075020418 117.849609375 MULTIPOLYGON(((963507.6 6230245.7,963502 6230245.5,963503 6230224.3,963508.5 6230224.5,963507.6 6230245.7)))
+BATIMENT0000000014190515 89.835205078125 MULTIPOLYGON(((505099.1 6885698.9,505115.1 6885696.2,505113.9 6885690.8,505098.4 6885693.2,505099.1 6885698.9)))
+BATIMENT0000000076313748 120.615112304688 MULTIPOLYGON(((245256.3 6856304.4,245257.1 6856298,245236.2 6856295,245235.5 6856299.9,245256.3 6856304.4)))
+BATIMENT0000000223445500 104.91015625 MULTIPOLYGON(((987885.4 6716896.7,987888.4 6716898.3,987884 6716906.4,987873.4 6716900.5,987877.5 6716893.1,987885.1 6716897.3,987885.4 6716896.7)))
+BATIMENT0000000223445501 73.16015625 MULTIPOLYGON(((987783.2 6716923.9,987786.8 6716918.6,987793.1 6716922.7,987790.5 6716926.5,987793.5 6716928.6,987791.2 6716931.9,987787.5 6716929.3,987784.3 6716927.1,987785.4 6716925.5,987783.2 6716923.9)))
+BATIMENT0000000223445502 76.1357421875 MULTIPOLYGON(((987778.7 6716934.1,987779.2 6716933.5,987778.6 6716933.1,987779.6 6716931.6,987780.5 6716932.3,987784.3 6716927.1,987787.5 6716929.3,987779.8 6716940.2,987779 6716941.3,987773.2 6716939.1,987777.6 6716933.2,987778.7 6716934.1)))
+BATIMENT0000000043850089 462.6201171875 MULTIPOLYGON(((895059.1 6689136.3,895054.2 6689125.7,895018.3 6689143.7,895023.2 6689154,895059.1 6689136.3)))
+BATIMENT0000000043413724 75.64501953125 MULTIPOLYGON(((923926.3 6769385.3,923927.1 6769377.7,923935.9 6769378,923935.2 6769387.3,923926.3 6769385.3)))
+BATIMENT0000000043413723 179 MULTIPOLYGON(((924477.1 6769125.3,924472.2 6769116.8,924486.5 6769107.7,924491.9 6769118,924477.1 6769125.3)))
+BATIMENT0000000043413722 166.705078125 MULTIPOLYGON(((924703.3 6769154.4,924710.3 6769149,924721.5 6769162.9,924712.4 6769168.3,924703.3 6769154.4)))
+BATIMENT0000000043842996 230.08984375 MULTIPOLYGON(((886755.1 6702797.6,886755.6 6702813.1,886740.5 6702812.9,886740.6 6702797.3,886755.1 6702797.6)))
+BATIMENT0000000014190524 104.954833984375 MULTIPOLYGON(((505137 6885764.4,505144.8 6885763.8,505143.4 6885750.5,505135.5 6885751.2,505137 6885764.4)))
+BATIMENT0000000043413474 155.42041015625 MULTIPOLYGON(((970808.1 6768816.2,970806.1 6768827.9,970792.9 6768825.7,970796.1 6768813.7,970808.1 6768816.2)))
+BATIMENT0000000043413473 160.92041015625 MULTIPOLYGON(((970811.9 6768827,970821.2 6768827.7,970817.9 6768844.6,970808.3 6768843.5,970811.9 6768827)))
+BATIMENT0000000043413471 183.02001953125 MULTIPOLYGON(((970791.7 6768835.5,970790.8 6768842.6,970792.3 6768851.1,970802.1 6768852.1,970803.6 6768835.7,970791.7 6768835.5)))
+BATIMENT0000000043413470 440.85986328125 MULTIPOLYGON(((970850.2 6768862.4,970836.2 6768862,970836.9 6768831.4,970851.6 6768831.6,970850.2 6768862.4)))
+BATIMENT0000000043413469 356.50048828125 MULTIPOLYGON(((970503.9 6768885.9,970488.6 6768886.1,970488.4 6768863.3,970504.1 6768862.7,970503.9 6768885.9)))
+BATIMENT0000000043413466 138.580078125 MULTIPOLYGON(((970673.7 6768924.5,970665.5 6768927.2,970671.5 6768942.3,970679.6 6768939.1,970673.7 6768924.5)))
+BATIMENT0000000043413465 174.57080078125 MULTIPOLYGON(((970552.6 6768988,970549 6769001.3,970535.6 6768996.8,970541.2 6768984.8,970552.6 6768988)))
+BATIMENT0000000043413464 49.77978515625 MULTIPOLYGON(((970555.1 6768971.4,970549.2 6768972,970550.5 6768979.9,970556.8 6768979.6,970555.1 6768971.4)))
+BATIMENT0000000043413463 246.74951171875 MULTIPOLYGON(((970571 6768944.2,970568.6 6768960.6,970583.6 6768962.1,970585.4 6768945.3,970571 6768944.2)))
+BATIMENT0000000043413462 132.400390625 MULTIPOLYGON(((970576.5 6768930.8,970575.3 6768942.5,970564.3 6768942,970565.6 6768929.7,970576.5 6768930.8)))
+BATIMENT0000000043413461 93.92431640625 MULTIPOLYGON(((970225.3 6769054.2,970224.8 6769045,970234.7 6769045.1,970234.7 6769055.4,970225.3 6769054.2)))
+BATIMENT0000000043413460 270.27978515625 MULTIPOLYGON(((970661.6 6768946.1,970649.8 6768953.6,970661.6 6768969.4,970673 6768963.5,970661.6 6768946.1)))
+BATIMENT0000000076243094 41.510009765625 MULTIPOLYGON(((238257.9 6875576.9,238258.7 6875582.5,238265.6 6875581.8,238264.8 6875575.6,238257.9 6875576.9)))
+BATIMENT0000000076243108 1498.66015625 MULTIPOLYGON(((237608 6875691.2,237611.8 6875595.2,237602.9 6875593.5,237595.7 6875594.2,237593.2 6875690.7,237608 6875691.2)))
+BATIMENT0000000008783893 391.2197265625 MULTIPOLYGON(((862939.9 6577948.2,862929.6 6577949,862929.8 6577947.1,862918.8 6577947.6,862918.2 6577960,862920.2 6577960.3,862921 6577966.5,862926.1 6577965.9,862926.2 6577966.6,862941.4 6577965.7,862939.9 6577948.2)))
+BATIMENT0000000076243132 181.864990234375 MULTIPOLYGON(((238022.1 6875459.5,238036.8 6875453.9,238033 6875442.9,238018.5 6875448.4,238022.1 6875459.5)))
+BATIMENT0000000076243198 1536.61511230469 MULTIPOLYGON(((237616.7 6875615,237613.8 6875715.7,237629.2 6875715.8,237631.9 6875615.8,237616.7 6875615)))
+BATIMENT0000000076243222 1343.1201171875 MULTIPOLYGON(((237198 6875599.4,237224.8 6875606.8,237237.9 6875560.8,237210.2 6875553.6,237198 6875599.4)))
+BATIMENT0000000043413116 65.4453125 MULTIPOLYGON(((924596.5 6769568.2,924596.8 6769560,924588.7 6769559.7,924588.1 6769567.3,924596.5 6769568.2)))
+BATIMENT0000000075021879 1448.8349609375 MULTIPOLYGON(((947669.9 6230067.6,947685.7 6230090,947644.1 6230121.3,947627.8 6230098.2,947669.9 6230067.6)))
+BATIMENT0000000044716091 154.46484375 MULTIPOLYGON(((726650.1 6245520.4,726654.5 6245515.8,726652.2 6245513.6,726655.6 6245508.1,726647.1 6245501.2,726640.4 6245510.9,726650.1 6245520.4)))
+BATIMENT0000000012671500 93.6298828125 MULTIPOLYGON(((925714.7 6507600,925723.1 6507598.3,925722.8 6507587.7,925714 6507589,925714.7 6507600)))
+BATIMENT0000000023592979 408.729858398438 MULTIPOLYGON(((184708.6 6796910.9,184697 6796927.6,184685.8 6796921.1,184682.7 6796927,184678.2 6796923.3,184695.1 6796900.3,184708.6 6796910.9)))
+BATIMENT0000000014190522 98.094970703125 MULTIPOLYGON(((505107.6 6885459.2,505121 6885454.8,505119.1 6885448.3,505104.9 6885453,505107.6 6885459.2)))
+BATIMENT0000000222666445 71.97509765625 MULTIPOLYGON(((879659.6 6559392,879669.3 6559392.3,879669.3 6559385.2,879659.4 6559384.4,879659.6 6559392)))
+BATIMENT0000000075027740 2833.8193359375 MULTIPOLYGON(((957306.6 6229563.4,957210.9 6229591.9,957199 6229567.4,957297.7 6229536,957306.6 6229563.4)))
+BATIMENT0000000075025579 140.95458984375 MULTIPOLYGON(((932117 6230332,932122.8 6230331.6,932124.9 6230354.9,932118.7 6230355.4,932117 6230332)))
+BATIMENT0000000075699182 93.8603515625 MULTIPOLYGON(((945238.2 6389749.6,945223.6 6389740.6,945226.1 6389735.9,945241.1 6389744.9,945238.2 6389749.6)))
+BATIMENT0000000047042232 326.744873046875 MULTIPOLYGON(((378452.3 6827020.1,378432.7 6826996.8,378424.4 6827004.5,378445 6827027.1,378452.3 6827020.1)))
+BATIMENT0000000008783896 561.0947265625 MULTIPOLYGON(((862999.5 6577949.6,862998.9 6577958.3,862996.9 6577958.2,862996.2 6577961.8,862989.7 6577961.9,862989.4 6577964.8,862970.4 6577961.2,862960.7 6577959.8,862949.1 6577958.5,862948.6 6577949.4,862990.7 6577951,862990.8 6577949.1,862999.5 6577949.6)))
+BATIMENT0000000008783987 294.19970703125 MULTIPOLYGON(((862673.1 6577831.2,862684.2 6577833.1,862680.2 6577858.7,862669 6577857.1,862673.1 6577831.2)))
+BATIMENT0000000222666384 274.175537109375 MULTIPOLYGON(((554845.2 6463889,554841.7 6463889,554841.9 6463893.3,554830.8 6463894.1,554832.5 6463904.1,554843.3 6463903,554843.5 6463906.7,554847.6 6463906.3,554847.4 6463903,554857.4 6463901.8,554856.3 6463892.5,554846 6463893.9,554845.2 6463889)))
+BATIMENT0000000075028598 816.06005859375 MULTIPOLYGON(((952820.5 6229728,952821.1 6229710.8,952865.7 6229696.8,952869.5 6229713.5,952820.5 6229728)))
+BATIMENT0000000075033393 8290.91943359375 MULTIPOLYGON(((958715.2 6229347.5,958788.2 6229405.9,958752.8 6229478.7,958671.3 6229439,958715.2 6229347.5)))
+BATIMENT0000000039627613 167.35546875 MULTIPOLYGON(((1001501.7 6719234.5,1001511.2 6719235.1,1001512.8 6719217.4,1001503.7 6719216.5,1001501.7 6719234.5)))
+BATIMENT0000000219248062 78.14013671875 MULTIPOLYGON(((927588 6501043.6,927586.7 6501046.5,927586.4 6501046.3,927586.1 6501046.7,927584.8 6501047.5,927571.3 6501040.8,927571 6501040.1,927571.2 6501039.3,927572.7 6501036.5,927584.3 6501041.9,927588 6501043.6)))
+BATIMENT0000000219248049 248.49072265625 MULTIPOLYGON(((927585.1 6501030.3,927583 6501035.2,927586.6 6501036.8,927584.3 6501041.9,927572.7 6501036.5,927571.2 6501039.3,927568.1 6501037.8,927569.3 6501034.9,927569.1 6501034.7,927562.7 6501031.8,927566.9 6501021.8,927574.2 6501025.4,927585.1 6501030.3)))
+BATIMENT0000000039627614 133.31982421875 MULTIPOLYGON(((1001523.7 6719178.1,1001526.1 6719187.8,1001512.9 6719191.7,1001511.1 6719182,1001523.7 6719178.1)))
+BATIMENT0000000039627616 308.98046875 MULTIPOLYGON(((1001328.3 6719227.7,1001330.2 6719236,1001309.4 6719242.8,1001310.7 6719247.8,1001298.4 6719251.6,1001295.8 6719244,1001307.1 6719239.1,1001305.8 6719235,1001328.3 6719227.7)))
+BATIMENT0000000039627590 296.744140625 MULTIPOLYGON(((1001451 6719202.6,1001451.8 6719206.1,1001437.7 6719211.8,1001440.7 6719222.5,1001448.9 6719220,1001448.5 6719215.5,1001461.2 6719211.3,1001460.4 6719206.5,1001467.8 6719204,1001466.3 6719197.4,1001451 6719202.6)))
+BATIMENT0000000039627591 305.60546875 MULTIPOLYGON(((1001453.5 6719192.6,1001460.7 6719190.5,1001456.7 6719175.6,1001450.7 6719177.1,1001445.7 6719164.8,1001434.6 6719168.3,1001436.7 6719174.7,1001440.7 6719173.3,1001445.3 6719186.7,1001450.1 6719185.5,1001453.5 6719192.6)))
+BATIMENT0000000039597786 252.22509765625 MULTIPOLYGON(((993771.3 6742962.5,993774.4 6742952.2,993797.4 6742959.3,993794.2 6742969.1,993771.3 6742962.5)))
+BATIMENT0000000216548147 1180.5048828125 MULTIPOLYGON(((913957.4 6496368.2,913960.5 6496364.7,913983.1 6496383.8,913975.5 6496393.2,913976 6496393.7,913960.8 6496411.5,913936.8 6496391.7,913939.9 6496388,913947.9 6496377.5,913944.3 6496370.3,913947.4 6496367.7,913948 6496366,913957.4 6496368.2)))
+BATIMENT0000000039627592 266.24462890625 MULTIPOLYGON(((1001355.9 6719164.4,1001352.4 6719165.8,1001354.3 6719173.1,1001364.9 6719170,1001360.8 6719154.8,1001364 6719153.7,1001360 6719140.4,1001353.4 6719142.8,1001355.3 6719150.2,1001351.7 6719151.6,1001355.9 6719164.4)))
+BATIMENT0000000039627593 255.12548828125 MULTIPOLYGON(((1001376.9 6719165.5,1001381.6 6719163.6,1001384.4 6719173.7,1001390 6719171.5,1001394.8 6719184.9,1001398.4 6719182.7,1001400.6 6719189.4,1001390.2 6719193.4,1001385.7 6719180.8,1001381.5 6719182,1001376.9 6719165.5)))
+BATIMENT0000000039597810 116.10009765625 MULTIPOLYGON(((993559 6742920.4,993562.9 6742908.1,993571.9 6742911.7,993567.2 6742923.2,993559 6742920.4)))
+BATIMENT0000000014190527 63.710205078125 MULTIPOLYGON(((505100.6 6885473.6,505106.5 6885473.7,505105.5 6885462.9,505099.4 6885463.2,505100.6 6885473.6)))
+BATIMENT0000000060111648 432.1943359375 MULTIPOLYGON(((1005998.4 6853680.1,1006010.4 6853678.5,1006011.2 6853685.1,1006015.1 6853684.6,1006018.1 6853706.5,1006012.4 6853707.2,1006002.3 6853708.6,1005998.4 6853680.1)))
+BATIMENT0000000110046541 188.83447265625 MULTIPOLYGON(((853479.4 6957440.8,853479.6 6957451.2,853489.1 6957450.9,853498.1 6957450,853498.1 6957440.4,853489.6 6957440.6,853479.4 6957440.8)))
+BATIMENT0000000014190558 96.604736328125 MULTIPOLYGON(((501445.2 6885596.2,501454 6885586.1,501459.3 6885590.3,501450.9 6885601.1,501445.2 6885596.2)))
+BATIMENT0000000075701932 179.58984375 MULTIPOLYGON(((944000.4 6388834.8,943985.9 6388844.4,943980.2 6388835.7,943995.3 6388826.2,944000.4 6388834.8)))
+BATIMENT0000000075034328 1019.54052734375 MULTIPOLYGON(((952232.5 6229274,952225.3 6229252.8,952268.2 6229237,952275.2 6229258.2,952232.5 6229274)))
+BATIMENT0000000049588631 1242.2607421875 MULTIPOLYGON(((554844.3 6463877.5,554845.2 6463889,554841.7 6463889,554841.9 6463893.3,554830.8 6463894.1,554832.5 6463904.1,554843.3 6463903,554843.5 6463906.7,554847.6 6463906.3,554848.6 6463917.6,554859.7 6463916.7,554858.7 6463906.5,554861.1 6463905,554861 6463901,554869.4 6463900.2,554869.4 6463905,554870.3 6463904.9,554872.1 6463919.5,554870.4 6463919.6,554871.1 6463927.7,554874.8 6463927.3,554874.9 6463929.2,554882.1 6463928.9,554881.5 6463 [...]
+BATIMENT0000000104790821 1424.63989257812 MULTIPOLYGON(((573209 6601600.4,573256.6 6601627,573269 6601604,573221.4 6601577.4,573209 6601600.4)))
+BATIMENT0000000223445503 60.875 MULTIPOLYGON(((987779.8 6716940.2,987787.5 6716929.3,987791.2 6716931.9,987787.4 6716937.2,987788 6716937.6,987787 6716939,987786.5 6716938.7,987783.9 6716942.5,987779.8 6716940.2)))
+BATIMENT0000000223445504 145.81982421875 MULTIPOLYGON(((987848.4 6716850.5,987846 6716848.8,987846.7 6716847.8,987838.8 6716841.8,987844 6716834.5,987850 6716838.9,987856.7 6716843.8,987851.4 6716851.1,987849.1 6716849.5,987848.4 6716850.5)))
+BATIMENT0000000223445505 149.64990234375 MULTIPOLYGON(((987950.1 6716914.5,987954.7 6716906.3,987968.8 6716914.1,987964.3 6716922.1,987950.1 6716914.5)))
+BATIMENT0000000043840034 104.26513671875 MULTIPOLYGON(((938649.8 6704069.3,938643.7 6704060.9,938652 6704054.4,938657.4 6704062.9,938649.8 6704069.3)))
+BATIMENT0000000023592977 332.369873046875 MULTIPOLYGON(((184701.3 6796956.5,184706.5 6796962.8,184736.7 6796936.4,184731.9 6796929.6,184701.3 6796956.5)))
+BATIMENT0000000075034359 914.8701171875 MULTIPOLYGON(((951916.4 6229159.1,951924.9 6229184.6,951893.4 6229195.5,951884.3 6229169.3,951916.4 6229159.1)))
+BATIMENT0000000044716090 128.35400390625 MULTIPOLYGON(((726941.8 6245237.4,726940.7 6245227.3,726928.6 6245228.1,726928 6245237.8,726941.8 6245237.4)))
+BATIMENT0000000075034923 323.79931640625 MULTIPOLYGON(((949537.5 6229425.3,949539.4 6229416.5,949575 6229423.9,949573.4 6229432.5,949537.5 6229425.3)))
+BATIMENT0000000012627147 32.19970703125 MULTIPOLYGON(((931577.2 6520222.9,931583.4 6520220.4,931582.2 6520216.1,931575.4 6520218.4,931577.2 6520222.9)))
+BATIMENT0000000216556059 104.455078125 MULTIPOLYGON(((910023.5 6506726.7,910014.2 6506727.8,910014.3 6506729.2,910009.1 6506729.8,910008.2 6506721.8,910013.8 6506721.1,910022.5 6506720.1,910023.5 6506726.7)))
+BATIMENT0000000107196701 456.60546875 MULTIPOLYGON(((459686.7 6520600.8,459676.4 6520604.7,459678.4 6520611.4,459677.1 6520611.8,459681.2 6520633.9,459704 6520628.8,459702.1 6520620.5,459690.5 6520623.3,459688.9 6520615.3,459693.3 6520614.7,459692.3 6520608.9,459688.3 6520610.2,459686.7 6520600.8)))
+BATIMENT0000000075037483 986.36962890625 MULTIPOLYGON(((931738.8 6229593.2,931696.5 6229603.5,931691.1 6229581.2,931732.9 6229571.3,931738.8 6229593.2)))
+BATIMENT0000000075038797 522.830078125 MULTIPOLYGON(((955863.9 6228972.1,955854.5 6228973.1,955847.7 6228918.6,955857.3 6228917.8,955863.9 6228972.1)))
+BATIMENT0000000075706483 3071.0400390625 MULTIPOLYGON(((943024.2 6386921.5,942965.3 6386973.9,942939.5 6386944.4,942998.9 6386892.3,943024.2 6386921.5)))
+BATIMENT0000000075038796 1044.35986328125 MULTIPOLYGON(((955978.4 6228881.1,955895.4 6228899.6,955895 6228887.1,955975.4 6228868.8,955978.4 6228881.1)))
+BATIMENT0000000075038795 932.5849609375 MULTIPOLYGON(((955889.1 6228938,955888.2 6228927.9,955980.4 6228912.4,955982.1 6228922,955889.1 6228938)))
+BATIMENT0000000075365625 1329.3447265625 MULTIPOLYGON(((927374.9 6890742.3,927341.2 6890777.8,927321.8 6890759.1,927357.1 6890722.7,927374.9 6890742.3)))
+BATIMENT0000000008783974 177.36962890625 MULTIPOLYGON(((862694.8 6577851.3,862695.3 6577846.9,862696.4 6577846.9,862698.7 6577831.9,862707.4 6577833.9,862704.4 6577852.9,862694.8 6577851.3)))
+BATIMENT0000000099156422 53.0999755859375 MULTIPOLYGON(((141778.8 6834111,141781.8 6834113.9,141790.3 6834105,141787.1 6834101.9,141778.8 6834111)))
+BATIMENT0000000076250122 225.419921875 MULTIPOLYGON(((226851.8 6874037.5,226858.5 6874041,226868.3 6874024.7,226874.2 6874014.6,226867.4 6874011.9,226851.8 6874037.5)))
+BATIMENT0000000075048527 709.625 MULTIPOLYGON(((947418.1 6228214,947415.1 6228229.6,947370.6 6228218.5,947373.1 6228203.7,947418.1 6228214)))
+BATIMENT0000000075048560 1184.7294921875 MULTIPOLYGON(((947075.7 6228283.6,947060.1 6228347.4,947042.4 6228343.4,947058.9 6228278.4,947075.7 6228283.6)))
+BATIMENT0000000076251010 395.025024414062 MULTIPOLYGON(((247986.4 6873400.5,247992.6 6873392.7,247959.9 6873368.9,247954.6 6873377.2,247986.4 6873400.5)))
+BATIMENT0000000075049043 860.91943359375 MULTIPOLYGON(((944525 6227995.4,944562 6227983.4,944568.8 6228004.6,944531 6228016.2,944525 6227995.4)))
+BATIMENT0000000075053130 738.8544921875 MULTIPOLYGON(((951029 6227824.9,951072 6227848.9,951063.8 6227862.8,951021.9 6227836.8,951029 6227824.9)))
+BATIMENT0000000075053336 1001.00048828125 MULTIPOLYGON(((949129.2 6227503.7,949137.1 6227518.5,949084.6 6227544.9,949076.6 6227529.5,949129.2 6227503.7)))
+BATIMENT0000000006204488 279.300048828125 MULTIPOLYGON(((615101.1 6757996.3,615125.3 6757982.4,615121.1 6757973.5,615095.8 6757988.1,615101.1 6757996.3)))
+BATIMENT0000000075056810 1157.26953125 MULTIPOLYGON(((955267.9 6227353.2,955267.8 6227396.3,955241 6227395.6,955241 6227352.5,955267.9 6227353.2)))
+BATIMENT0000000075057568 4513.61962890625 MULTIPOLYGON(((949038.1 6227460.1,949094.9 6227435.4,949126.9 6227502.7,949073.1 6227526.6,949038.1 6227460.1)))
+BATIMENT0000000014190557 61.734619140625 MULTIPOLYGON(((501498.2 6885654.3,501502.6 6885649.5,501509.3 6885655.7,501504 6885660.8,501498.2 6885654.3)))
+BATIMENT0000000014190554 203.76513671875 MULTIPOLYGON(((501542.8 6885619.7,501554.5 6885634,501556.8 6885631.9,501561.7 6885637.2,501554.6 6885644.2,501537 6885624.1,501542.8 6885619.7)))
+BATIMENT0000000006181091 176.690185546875 MULTIPOLYGON(((617296.3 6760860.2,617307.4 6760861.5,617309.3 6760845.6,617298.6 6760844.2,617296.3 6760860.2)))
+BATIMENT0000000006181131 1891.2001953125 MULTIPOLYGON(((617256.5 6760679.5,617286 6760686.4,617284.5 6760685.3,617288.5 6760686.4,617289.9 6760684,617329.5 6760692.3,617334.5 6760667,617295.2 6760659.2,617294.5 6760662.4,617290.9 6760661.2,617261.1 6760654.6,617256.5 6760679.5)))
+BATIMENT0000000006183688 111.494873046875 MULTIPOLYGON(((617317 6760282.3,617320.1 6760273.4,617308.9 6760269.3,617306 6760278.3,617317 6760282.3)))
+BATIMENT0000000006183699 128.190185546875 MULTIPOLYGON(((617333.3 6760291,617336.7 6760281.1,617324.7 6760277.2,617321.3 6760286.2,617333.3 6760291)))
+BATIMENT0000000006180397 225.000244140625 MULTIPOLYGON(((620888.8 6760527.7,620884.7 6760519.6,620863 6760531.7,620868.2 6760539.6,620888.8 6760527.7)))
+BATIMENT0000000075057566 993.474609375 MULTIPOLYGON(((949166.4 6227444.5,949174.5 6227460.1,949123.3 6227485.1,949115.9 6227469.2,949166.4 6227444.5)))
+BATIMENT0000000075069721 1315.009765625 MULTIPOLYGON(((955152.7 6225434.9,955193.7 6225424.2,955201.7 6225454.1,955161.1 6225465.1,955152.7 6225434.9)))
+BATIMENT0000000076253506 138.720092773438 MULTIPOLYGON(((220985.9 6873217.1,220993 6873220.5,221001.1 6873204.8,220993.8 6873201.6,220985.9 6873217.1)))
+BATIMENT0000000075075166 1293.98046875 MULTIPOLYGON(((929104.2 6225263.4,929147.7 6225255.1,929154.8 6225281.8,929111 6225292.9,929104.2 6225263.4)))
+BATIMENT0000000075084749 843.77978515625 MULTIPOLYGON(((929278.5 6223449.3,929316.3 6223426.2,929326 6223443.5,929289.5 6223465,929278.5 6223449.3)))
+BATIMENT0000000076325705 37.6951904296875 MULTIPOLYGON(((306034 6852930.1,306039.3 6852928.6,306041 6852935,306035.2 6852936.5,306034 6852930.1)))
+BATIMENT0000000076253756 202.619995117188 MULTIPOLYGON(((216884.5 6873075.3,216876.6 6873065.7,216888.3 6873054.2,216896.4 6873062.4,216884.5 6873075.3)))
+BATIMENT0000000076253765 39.2449951171875 MULTIPOLYGON(((216999.3 6873033.8,216998.9 6873028.7,217006.4 6873027.5,217006.4 6873033.1,216999.3 6873033.8)))
+BATIMENT0000000023591520 690.56005859375 MULTIPOLYGON(((184539.2 6797446,184531.5 6797444,184535.4 6797428.1,184517.4 6797424.3,184511.5 6797456,184536.1 6797461,184539.2 6797446)))
+BATIMENT0000000014190559 113.9853515625 MULTIPOLYGON(((501463.2 6885626,501469.6 6885631.1,501461.7 6885642.1,501454.9 6885636.9,501463.2 6885626)))
+BATIMENT0000000014187451 208.919921875 MULTIPOLYGON(((445635 6887219.6,445657.4 6887228,445655.2 6887237.2,445633.2 6887227.6,445635 6887219.6)))
+BATIMENT0000000069853077 94.0499267578125 MULTIPOLYGON(((126880.8 6848498.1,126879.3 6848505.6,126890.8 6848507.8,126892.3 6848499.4,126880.8 6848498.1)))
+BATIMENT0000000069853078 168.535034179688 MULTIPOLYGON(((126864.1 6849720.5,126866.1 6849727.8,126881.9 6849722.4,126881.1 6849720,126888.5 6849717.2,126886.6 6849712.3,126864.1 6849720.5)))
+BATIMENT0000000069853079 54.2999877929688 MULTIPOLYGON(((126983.4 6849409.3,126985.7 6849413.3,126984.6 6849413.9,126986.1 6849416.4,126993.1 6849412.3,126989.3 6849406,126983.4 6849409.3)))
+BATIMENT0000000069853080 657.889892578125 MULTIPOLYGON(((127631.7 6851344.9,127633.2 6851342.3,127635.2 6851339.6,127637.3 6851337.8,127640.6 6851335.4,127645.2 6851333.8,127649.8 6851333.5,127665.3 6851337.2,127665.1 6851339.8,127669.2 6851340.9,127665.4 6851358.3,127659.9 6851359.4,127659.3 6851357.7,127652.8 6851358.8,127652.3 6851354,127647.4 6851353.2,127645.7 6851360.3,127639.6 6851358.9,127641.9 6851347.8,127631.7 6851344.9)))
+BATIMENT0000000069853081 192.309997558594 MULTIPOLYGON(((126710 6849113.4,126708.5 6849122.1,126703.4 6849120.9,126701.9 6849127.7,126693.5 6849126.1,126693.7 6849123.1,126692.7 6849122.2,126692.1 6849120.8,126692.1 6849119.2,126692.7 6849117.4,126693.8 6849116.7,126695.5 6849116.7,126696.7 6849111,126710 6849113.4)))
+BATIMENT0000000069853082 161.124938964844 MULTIPOLYGON(((127747.6 6851424.9,127749 6851432.5,127743.6 6851433.5,127744.1 6851434.9,127740.5 6851435.8,127740.9 6851438.6,127733.6 6851439.9,127731.4 6851428.7,127747.6 6851424.9)))
+BATIMENT0000000069853083 54.1299438476562 MULTIPOLYGON(((127794.3 6850976.3,127787.7 6850980.4,127786 6850977.1,127783.2 6850978.8,127786.3 6850984.6,127789.4 6850982.4,127790.2 6850984.1,127796.1 6850980.6,127794.3 6850976.3)))
+BATIMENT0000000069853084 272.579956054688 MULTIPOLYGON(((126958.5 6848239.1,126959.6 6848243.5,126964.5 6848241.8,126964.3 6848240.3,126968.1 6848239,126969.2 6848242.4,126975.3 6848239.3,126973.4 6848233.4,126982.3 6848230,126983.2 6848232.5,126987.8 6848230.5,126992.6 6848228.5,126989.9 6848219.9,126967.2 6848228.7,126969.4 6848233.9,126958.5 6848239.1)))
+BATIMENT0000000069853085 189.574829101562 MULTIPOLYGON(((127801.4 6851406.8,127803.4 6851415.3,127801.1 6851415.8,127801.7 6851419.3,127793 6851421.1,127792.2 6851417.5,127785.3 6851418.8,127783.7 6851411.2,127789 6851410.1,127790 6851408.8,127798.1 6851407.1,127798.7 6851407.5,127801.4 6851406.8)))
+BATIMENT0000000069853086 169.809936523438 MULTIPOLYGON(((127177.2 6851103.3,127181.7 6851100.7,127183.4 6851103.4,127189.9 6851099.2,127194.4 6851106.1,127191.8 6851107.8,127195.5 6851113.3,127188.6 6851117.7,127184.1 6851109.9,127182.3 6851110.8,127177.2 6851103.3)))
+BATIMENT0000000069853087 84.6600952148438 MULTIPOLYGON(((127453.4 6849511.1,127455.8 6849518.3,127444.8 6849520.8,127442.6 6849513.5,127453.4 6849511.1)))
+BATIMENT0000000069853088 106.1650390625 MULTIPOLYGON(((129488.3 6850672.7,129490.8 6850677.3,129508 6850669.1,129504.6 6850664,129488.3 6850672.7)))
+BATIMENT0000000069853089 203.825012207031 MULTIPOLYGON(((127077.2 6848231.7,127077.6 6848236.4,127073.4 6848236.9,127074.9 6848249,127085.8 6848247.8,127084.6 6848240.1,127089.2 6848239.1,127088.1 6848230.5,127077.2 6848231.7)))
+BATIMENT0000000069853090 101.390014648438 MULTIPOLYGON(((128125.9 6852081.8,128126.8 6852085.5,128130.3 6852084.8,128131.9 6852090.2,128120.3 6852093.1,128117.9 6852083.2,128125.9 6852081.8)))
+BATIMENT0000000069853091 203.625 MULTIPOLYGON(((128160.6 6848598.5,128159.8 6848590.9,128181.1 6848589.5,128181.8 6848595.8,128175.3 6848596.2,128176.2 6848606.3,128170.3 6848606.7,128170 6848601.6,128169.8 6848597.5,128160.6 6848598.5)))
+BATIMENT0000000075088111 273.67041015625 MULTIPOLYGON(((961016.5 6216370.7,961011.9 6216341.4,961021.1 6216339.5,961025.3 6216369.5,961016.5 6216370.7)))
+BATIMENT0000000006183694 1119.35009765625 MULTIPOLYGON(((617268.2 6760312.3,617273.3 6760300.1,617268.6 6760297.7,617271.2 6760291.6,617326.1 6760315.8,617323 6760324.2,617319.4 6760323.1,617314.8 6760332.8,617311.6 6760332.2,617268.2 6760312.3)))
+BATIMENT0000000006183734 98.68505859375 MULTIPOLYGON(((617305.1 6760228.9,617301.3 6760240.5,617309 6760243.1,617312.7 6760231.4,617305.1 6760228.9)))
+BATIMENT0000000006183723 88.450439453125 MULTIPOLYGON(((617286.5 6760239,617292.5 6760241.3,617296.9 6760226.7,617291.9 6760225,617286.5 6760239)))
+BATIMENT0000000006183753 169.33447265625 MULTIPOLYGON(((617295.4 6760194.2,617290.8 6760192.3,617289.6 6760195.2,617281.1 6760191.9,617280.2 6760194.1,617278.2 6760193.3,617276 6760198.6,617277.7 6760199.1,617277 6760200.8,617290.5 6760206.4,617295.4 6760194.2)))
+BATIMENT0000000074038925 45.80029296875 MULTIPOLYGON(((1052659.6 6313425,1052648.1 6313426.5,1052647.6 6313422.5,1052659.3 6313421.2,1052659.6 6313425)))
+BATIMENT0000000069853092 142.914978027344 MULTIPOLYGON(((127052 6849667.4,127057.4 6849671.2,127062.7 6849663.3,127059.7 6849660.9,127062.2 6849656.6,127056.8 6849653.3,127054.3 6849656.4,127052.1 6849655,127048.3 6849661.8,127053.5 6849664.8,127052 6849667.4)))
+BATIMENT0000000069853093 209.5 MULTIPOLYGON(((127426.3 6851076.1,127429.7 6851083,127427.7 6851083.7,127432 6851093.5,127425.2 6851096.1,127421.8 6851087.8,127414.9 6851090.8,127411.9 6851083.9,127415.5 6851082.3,127414.7 6851080.3,127426.3 6851076.1)))
+BATIMENT0000000069853094 319.555053710938 MULTIPOLYGON(((127715.2 6852374.3,127718.7 6852379.5,127714.4 6852383.1,127714.8 6852383.7,127708.7 6852390,127706.7 6852388.3,127702.1 6852392.4,127699.9 6852390.3,127695.8 6852394,127690 6852387.9,127695.8 6852381.9,127693.7 6852379.9,127696.6 6852377.1,127694.9 6852374.9,127699.4 6852371.2,127707.4 6852379.5,127708.8 6852378.1,127710.3 6852379.4,127715.2 6852374.3)))
+BATIMENT0000000069853096 47.0750732421875 MULTIPOLYGON(((128736.7 6848262,128731.2 6848264.4,128734.2 6848271.5,128739.9 6848269,128736.7 6848262)))
+BATIMENT0000000069853097 44.135009765625 MULTIPOLYGON(((127438.2 6851329.8,127440.7 6851334.3,127447.6 6851330.3,127445.4 6851325.5,127439.8 6851328.4,127438.2 6851329.8)))
+BATIMENT0000000069853098 124.690124511719 MULTIPOLYGON(((127456.6 6850548,127455.8 6850540.2,127465.5 6850538.8,127465.7 6850540.3,127471.9 6850539.6,127472.6 6850546.8,127456.6 6850548)))
+BATIMENT0000000069853099 25.300048828125 MULTIPOLYGON(((126916.1 6849168.2,126915.8 6849172.1,126922.2 6849172.7,126922.3 6849168.6,126916.1 6849168.2)))
+BATIMENT0000000069853100 168.160034179688 MULTIPOLYGON(((127714.1 6852178.5,127720.3 6852180,127715 6852200.8,127704.1 6852198.6,127704.9 6852193.5,127709.7 6852194,127714.1 6852178.5)))
+BATIMENT0000000069853101 55.6500244140625 MULTIPOLYGON(((126849.6 6848605,126848.5 6848601.7,126849.6 6848601.1,126849.2 6848599.3,126854.6 6848598,126855.3 6848600,126860.1 6848598.7,126861.2 6848602.4,126849.6 6848605)))
+BATIMENT0000000069853102 35.7999877929688 MULTIPOLYGON(((126924.8 6848498.1,126924.1 6848503,126931.5 6848503.5,126931.9 6848498.6,126924.8 6848498.1)))
+BATIMENT0000000069853103 52.5850219726562 MULTIPOLYGON(((126811.8 6849550,126816.4 6849558,126811.3 6849560.7,126806.8 6849553.1,126811.8 6849550)))
+BATIMENT0000000069853104 74.7999267578125 MULTIPOLYGON(((127992.4 6852408.7,127995.2 6852416,127986.6 6852419.9,127983.5 6852412.8,127992.4 6852408.7)))
+BATIMENT0000000069853105 80.43994140625 MULTIPOLYGON(((127285.3 6851035.9,127292.1 6851046.2,127289.1 6851046.6,127281.8 6851045.7,127278.4 6851040.2,127285.3 6851035.9)))
+BATIMENT0000000069853106 58.2600708007812 MULTIPOLYGON(((126667.8 6849546.9,126658.4 6849550,126660.2 6849556,126669.2 6849552.4,126667.8 6849546.9)))
+BATIMENT0000000069853107 25.3700561523438 MULTIPOLYGON(((126781.6 6849801,126783.9 6849805.9,126780.3 6849808.4,126777.5 6849803.3,126781.6 6849801)))
+BATIMENT0000000076255586 162.019897460938 MULTIPOLYGON(((216860.7 6872988.7,216855.2 6872981.7,216852.3 6872984.4,216846.4 6872977.1,216854.4 6872969.7,216865.8 6872984.3,216860.7 6872988.7)))
+BATIMENT0000000069853109 50.1600341796875 MULTIPOLYGON(((127396.4 6851435.4,127395 6851431.7,127407.4 6851426.8,127408.2 6851430.5,127396.4 6851435.4)))
+BATIMENT0000000069853110 78.5399780273438 MULTIPOLYGON(((127964.3 6848399.9,127967.7 6848406.7,127958.9 6848411.9,127955.6 6848404.5,127964.3 6848399.9)))
+BATIMENT0000000069853111 259.074951171875 MULTIPOLYGON(((127215.2 6848308.9,127204.6 6848310.7,127204.9 6848313.3,127203.2 6848315,127204.1 6848321.5,127207.1 6848322.9,127207.8 6848328.4,127223.7 6848326.8,127222.8 6848318.2,127216.4 6848319.1,127215.2 6848308.9)))
+BATIMENT0000000069853112 48.905029296875 MULTIPOLYGON(((127693.6 6851759.4,127695.8 6851765.9,127689.3 6851768.4,127686.7 6851762.2,127693.6 6851759.4)))
+BATIMENT0000000069853113 125.120056152344 MULTIPOLYGON(((127215.9 6850053.3,127208.9 6850056.3,127214.2 6850070.3,127222.5 6850067.5,127215.9 6850053.3)))
+BATIMENT0000000069853114 28.6799926757812 MULTIPOLYGON(((126727.2 6849808.3,126723.7 6849808.8,126724.8 6849816.6,126728.5 6849816.1,126727.2 6849808.3)))
+BATIMENT0000000069853115 136.709899902344 MULTIPOLYGON(((127485.1 6851460.2,127476.6 6851462,127479.3 6851478.6,127486.7 6851477.1,127485.1 6851460.2)))
+BATIMENT0000000069853116 86.1348876953125 MULTIPOLYGON(((127260.7 6850793.8,127258.5 6850793,127259.9 6850789.7,127254.2 6850787.4,127250.1 6850798.2,127257.6 6850801,127260.7 6850793.8)))
+BATIMENT0000000069853117 170.764892578125 MULTIPOLYGON(((128488.4 6851155.2,128492.3 6851169.7,128476.7 6851174.3,128474.9 6851166.9,128479.5 6851165.6,128480 6851167.8,128485 6851166.5,128484 6851161.1,128480.8 6851161.5,128479.8 6851156.7,128488.4 6851155.2)))
+BATIMENT0000000069853118 55.489990234375 MULTIPOLYGON(((127124 6850426.4,127124.3 6850428.9,127130.8 6850428.3,127130.1 6850420.3,127122.5 6850421.1,127124 6850426.4)))
+BATIMENT0000000069853119 43.2901000976562 MULTIPOLYGON(((126586.9 6850290.1,126583.1 6850290.1,126582.9 6850282.7,126588.9 6850282.8,126589.1 6850289.3,126586.9 6850290.1)))
+BATIMENT0000000069853120 97.8450317382812 MULTIPOLYGON(((127684.1 6851182.5,127676.7 6851183.8,127678.1 6851196.6,127685.6 6851195.5,127684.1 6851182.5)))
+BATIMENT0000000069853121 121.1650390625 MULTIPOLYGON(((127249.6 6850121.2,127242.7 6850123.6,127244 6850129.9,127242.6 6850130.1,127244.4 6850138.5,127252.6 6850136.6,127249.6 6850121.2)))
+BATIMENT0000000069853122 73.8900146484375 MULTIPOLYGON(((127758.4 6851469.4,127750.6 6851471.2,127752.7 6851480.4,127760.2 6851478.6,127758.4 6851469.4)))
+BATIMENT0000000069853123 90.5800170898438 MULTIPOLYGON(((127789.3 6851448.2,127782 6851450,127784.4 6851461.5,127791.9 6851460.1,127789.3 6851448.2)))
+BATIMENT0000000069853124 27.4100952148438 MULTIPOLYGON(((129355.9 6850603.1,129363.3 6850600.4,129361.8 6850597,129354.7 6850600,129355.9 6850603.1)))
+BATIMENT0000000069853125 60.135009765625 MULTIPOLYGON(((127420.2 6851316,127424.4 6851323,127419.8 6851327.9,127414.3 6851322.8,127420.2 6851316)))
+BATIMENT0000000006183747 127.97509765625 MULTIPOLYGON(((617333.8 6760243.1,617323.9 6760239.3,617322.6 6760240.9,617320.2 6760240.2,617317.7 6760246.8,617331.8 6760252.3,617333.8 6760243.1)))
+BATIMENT0000000006187154 417.335205078125 MULTIPOLYGON(((617291 6760040.7,617296.9 6760020,617303.2 6760022,617310.2 6760007.8,617321.6 6760012.1,617314.1 6760028.1,617304.3 6760024.1,617299.8 6760034.6,617304.3 6760036.2,617300.7 6760045.8,617291 6760040.7)))
+BATIMENT0000000211695811 7.699951171875 MULTIPOLYGON(((620164.5 6759934.9,620164.3 6759933.6,620168 6759933.2,620167.9 6759932.5,620169.5 6759932.2,620169.8 6759934.1,620164.5 6759934.9)))
+BATIMENT0000000117904687 112.43017578125 MULTIPOLYGON(((634599.8 6751212.3,634603 6751220,634615.6 6751213.9,634612.2 6751206.7,634599.8 6751212.3)))
+BATIMENT0000000006183689 2510.63549804688 MULTIPOLYGON(((617336 6760410,617338.8 6760407,617341.6 6760402.6,617343.3 6760397.6,617344.1 6760391.7,617343.4 6760387.3,617342.3 6760383.8,617340.9 6760380,617339.3 6760377.3,617337.1 6760379.4,617321.3 6760361.4,617275.1 6760402.2,617282.7 6760410.5,617299.6 6760428.9,617314 6760416.1,617317.6 6760416.9,617321.1 6760416.7,617324.7 6760416.2,617328.1 6760415.1,617331.5 6760413.6,617335 6760411.2,617336 6760410)))
+BATIMENT0000000006186100 125.35009765625 MULTIPOLYGON(((621034.4 6759989.4,621035 6759980.7,621020.6 6759980.2,621019.9 6759988.8,621034.4 6759989.4)))
+BATIMENT0000000006181129 309.63037109375 MULTIPOLYGON(((617338.1 6760659.7,617338.8 6760656,617340.4 6760656.5,617342 6760647.9,617315.8 6760641.5,617313.3 6760654.6,617326.1 6760657.4,617327.9 6760649.2,617331.8 6760650.4,617330.1 6760658.4,617338.1 6760659.7)))
+BATIMENT0000000006181097 93.235107421875 MULTIPOLYGON(((617302.6 6760827.9,617311.4 6760829.4,617312.9 6760819.2,617303.7 6760817.8,617302.6 6760827.9)))
+BATIMENT0000000006181100 35.22998046875 MULTIPOLYGON(((617293.8 6760841.7,617298.9 6760842.3,617299.8 6760835.9,617294.2 6760835.1,617293.8 6760841.7)))
+BATIMENT0000000006144578 122.224609375 MULTIPOLYGON(((680118.1 6767545.3,680127.2 6767552.2,680133 6767543.2,680122.9 6767536.4,680118.1 6767545.3)))
+BATIMENT0000000074195828 117.96484375 MULTIPOLYGON(((1028581 6283593.2,1028580.2 6283591.2,1028586.3 6283580.2,1028588.5 6283580.2,1028595.2 6283590.5,1028594.4 6283592.2,1028581 6283593.2)))
+BATIMENT0000000008783975 107.08056640625 MULTIPOLYGON(((862753.1 6577858.9,862754.4 6577849.9,862765.9 6577851.6,862764.8 6577860.7,862753.1 6577858.9)))
+BATIMENT0000000008783976 198.28955078125 MULTIPOLYGON(((862753.8 6577877.6,862766.3 6577879.5,862769.3 6577864.2,862756.6 6577862.3,862753.8 6577877.6)))
+BATIMENT0000000012671026 93.1494140625 MULTIPOLYGON(((922192.3 6511282.3,922183 6511291.6,922189.4 6511296.5,922197.1 6511286.8,922192.3 6511282.3)))
+BATIMENT0000000023591523 88.6700439453125 MULTIPOLYGON(((184529.7 6797396.1,184523.3 6797396.2,184522.1 6797409.1,184529.4 6797409.1,184529.7 6797396.1)))
+BATIMENT0000000008783978 417.04052734375 MULTIPOLYGON(((862759.9 6577942,862760.3 6577947,862759.2 6577947.1,862760.2 6577960.4,862761.4 6577960,862762 6577979.1,862749.2 6577979.7,862748.7 6577960.6,862751.9 6577960.3,862751.2 6577948,862748 6577948.3,862747.6 6577942.1,862759.9 6577942)))
+BATIMENT0000000008783979 274.43505859375 MULTIPOLYGON(((862713 6577902.2,862711.9 6577921.3,862710.4 6577921.3,862710.4 6577924.7,862700.2 6577924.3,862700.7 6577920.5,862699.1 6577920,862700.8 6577901.6,862713 6577902.2)))
+BATIMENT0000000008783981 21.90087890625 MULTIPOLYGON(((862723.3 6577929.4,862722.8 6577933.2,862717.1 6577932,862717.4 6577928.4,862723.3 6577929.4)))
+BATIMENT0000000213615069 97.324951171875 MULTIPOLYGON(((624303.2 6756710.4,624307.1 6756717.1,624296.7 6756723.6,624292.6 6756716.6,624303.2 6756710.4)))
+BATIMENT0000000006938192 2045.7353515625 MULTIPOLYGON(((889192.5 6379004.7,889198.7 6379005,889210.9 6379007.2,889218.3 6379011.9,889219.6 6379009.5,889238.1 6379020.8,889249.2 6379033.4,889259.8 6379050.7,889250.6 6379056.3,889230.3 6379030.4,889227.5 6379028.5,889223.9 6379025.5,889221.8 6379044,889227.2 6379043,889225.8 6379035.8,889231.2 6379035.4,889232.8 6379040.9,889235.7 6379040.3,889248.7 6379057.3,889234.2 6379065.6,889229.4 6379058.3,889226.4 6379053.9,889222 6379054.2,889221. [...]
+BATIMENT0000000213687181 3.205078125 MULTIPOLYGON(((675629.7 6726428.6,675628.5 6726429.4,675627.2 6726427.7,675628.4 6726426.8,675629.7 6726428.6)))
+BATIMENT0000000012670334 188.55029296875 MULTIPOLYGON(((925472.7 6510109.5,925484.1 6510109.4,925484.4 6510103,925485.2 6510103,925485.2 6510094.6,925471.4 6510094.7,925472.7 6510109.5)))
+BATIMENT0000000008783984 376.7392578125 MULTIPOLYGON(((862667.5 6577878.9,862679.5 6577880.7,862676 6577911.6,862664.1 6577910.1,862667.5 6577878.9)))
+BATIMENT0000000008787942 37.0400390625 MULTIPOLYGON(((862849.7 6577656.8,862849.8 6577662.3,862856.5 6577662,862856.2 6577656.3,862849.7 6577656.8)))
+BATIMENT0000000069853126 45.0599975585938 MULTIPOLYGON(((127409.7 6851413.8,127408.1 6851407.5,127414.1 6851404.8,127416.5 6851410.8,127409.7 6851413.8)))
+BATIMENT0000000069853127 57.2999267578125 MULTIPOLYGON(((127474.1 6851527.6,127469.6 6851527.9,127469.6 6851520.4,127465.1 6851520.4,127464.8 6851530.3,127473.6 6851530.4,127474.1 6851527.6)))
+BATIMENT0000000069853128 97.2199096679688 MULTIPOLYGON(((126963.7 6849244.8,126962.8 6849254.8,126972.5 6849255.6,126972.9 6849245.1,126963.7 6849244.8)))
+BATIMENT0000000069853129 104.535217285156 MULTIPOLYGON(((127238.7 6851287.5,127241.4 6851295,127245.5 6851293.5,127246.6 6851296.2,127254 6851292.3,127251.4 6851285.9,127247.7 6851287.8,127246.8 6851285.6,127243.9 6851286.8,127243.2 6851285.3,127238.7 6851287.5)))
+BATIMENT0000000069853130 75.1849365234375 MULTIPOLYGON(((127412.1 6850869.7,127418.9 6850875.2,127413.2 6850881.8,127406.6 6850876.6,127412.1 6850869.7)))
+BATIMENT0000000069853131 54.5499267578125 MULTIPOLYGON(((127325.7 6850202.5,127327.3 6850210.8,127328.8 6850210.4,127330.6 6850216.2,127326.5 6850217.6,127322.1 6850203.8,127325.7 6850202.5)))
+BATIMENT0000000069853132 41.820068359375 MULTIPOLYGON(((128041.7 6850460.4,128041.7 6850466,128049.2 6850466.1,128049.4 6850460.7,128041.7 6850460.4)))
+BATIMENT0000000069853133 162.885009765625 MULTIPOLYGON(((127014.5 6848543.2,127021.2 6848556,127019.8 6848556.8,127021.6 6848560.8,127014.7 6848563.9,127006.7 6848547.5,127014.5 6848543.2)))
+BATIMENT0000000069853134 69.1900024414062 MULTIPOLYGON(((128323.1 6851760.9,128316.8 6851764.5,128322 6851773,128327.8 6851769.3,128323.1 6851760.9)))
+BATIMENT0000000069853135 131.97998046875 MULTIPOLYGON(((128242.1 6851907.3,128252.1 6851918.8,128245.2 6851924.6,128236 6851914.1,128242.1 6851907.3)))
+BATIMENT0000000069853136 194.654968261719 MULTIPOLYGON(((128791.1 6848520.3,128809 6848510,128813.6 6848518.6,128795.8 6848528.3,128791.1 6848520.3)))
+BATIMENT0000000069853137 40.10498046875 MULTIPOLYGON(((127433.5 6848628.7,127435.2 6848635.1,127441.1 6848633.8,127439.9 6848627.7,127433.5 6848628.7)))
+BATIMENT0000000069853138 49.2800903320312 MULTIPOLYGON(((126643.2 6849839.9,126648.4 6849843.8,126653 6849837.7,126647.7 6849833.9,126643.2 6849839.9)))
+BATIMENT0000000069853139 80.7050170898438 MULTIPOLYGON(((127631.1 6851809.4,127624 6851811.2,127626.4 6851821.4,127634.2 6851819.5,127631.1 6851809.4)))
+BATIMENT0000000069853140 66.51513671875 MULTIPOLYGON(((127246.8 6850806.7,127254.4 6850809.6,127251.5 6850817.3,127244.2 6850814.9,127246.8 6850806.7)))
+BATIMENT0000000069853141 43.530029296875 MULTIPOLYGON(((127958.5 6850826.3,127966.5 6850822.9,127961.6 6850818.5,127955.1 6850823.5,127958.5 6850826.3)))
+BATIMENT0000000069853142 51.2749633789062 MULTIPOLYGON(((127776.6 6851387.6,127770.5 6851389.8,127772.1 6851397.1,127778.5 6851395.7,127776.6 6851387.6)))
+BATIMENT0000000069853143 45.8300170898438 MULTIPOLYGON(((126719.4 6848611.3,126719.9 6848614.9,126706.6 6848617.2,126706.1 6848614.1,126719.4 6848611.3)))
+BATIMENT0000000006181109 321.439697265625 MULTIPOLYGON(((617325.8 6760492,617309.4 6760501.5,617309.9 6760502.7,617306.6 6760504.6,617311 6760512.9,617314.8 6760510.7,617316.6 6760513.5,617332.8 6760503.8,617330.8 6760501.9,617333.6 6760500.5,617329.3 6760493,617326.9 6760494.6,617325.8 6760492)))
+BATIMENT0000000076256928 56.3199462890625 MULTIPOLYGON(((221608.4 6872241.7,221609.8 6872242,221609.5 6872244.2,221615.8 6872245.1,221616.7 6872237.4,221608.9 6872236.5,221608.4 6872241.7)))
+BATIMENT0000000006181071 301.8203125 MULTIPOLYGON(((617329.4 6760779.6,617298.4 6760776.2,617299.8 6760766.4,617330.9 6760770.3,617329.4 6760779.6)))
+BATIMENT0000000076257127 29.8299560546875 MULTIPOLYGON(((220199.4 6872406.2,220202.4 6872406.8,220203.1 6872405.1,220205.5 6872405.9,220207.1 6872402.5,220200.8 6872400.4,220199.4 6872406.2)))
+BATIMENT0000000073249974 12.664794921875 MULTIPOLYGON(((570264.2 6275375.8,570267.1 6275381.9,570268.4 6275375.9,570264.2 6275375.8)))
+BATIMENT0000000074062963 102.70556640625 MULTIPOLYGON(((1013403.8 6306733.5,1013409.2 6306733.1,1013409.9 6306750.9,1013403.6 6306750.8,1013403.8 6306733.5)))
+BATIMENT0000000006204490 82.585205078125 MULTIPOLYGON(((615067.3 6757952.2,615072.8 6757960.3,615079.7 6757954.3,615074.1 6757947.2,615067.3 6757952.2)))
+BATIMENT0000000075364604 1546.62548828125 MULTIPOLYGON(((926347.5 6890451.5,926400.2 6890462.7,926406.2 6890434.3,926353.8 6890423.6,926347.5 6890451.5)))
+BATIMENT0000000006168239 65.0791015625 MULTIPOLYGON(((682198.6 6762933.6,682194.7 6762940.6,682202.7 6762944.9,682205.7 6762939.8,682202 6762938.1,682203.1 6762935.6,682198.6 6762933.6)))
+BATIMENT0000000076257633 130.97509765625 MULTIPOLYGON(((216901.3 6872311.9,216899.9 6872295,216907.4 6872294.5,216909.1 6872311.7,216901.3 6872311.9)))
+BATIMENT0000000006181075 210.580322265625 MULTIPOLYGON(((617304.3 6760714.3,617307.9 6760696.6,617296 6760695,617292.4 6760711.3,617304.3 6760714.3)))
+BATIMENT0000000006183658 42.449951171875 MULTIPOLYGON(((617805.1 6760262,617805.3 6760255.6,617812.1 6760256.5,617811.7 6760262.7,617805.1 6760262)))
+BATIMENT0000000006183621 369.125244140625 MULTIPOLYGON(((617800.6 6760224.4,617802.7 6760205.2,617817.5 6760207,617824.4 6760208,617823.7 6760216.9,617818 6760216.3,617816.6 6760226.7,617800.6 6760224.4)))
+BATIMENT0000000006178715 52.395263671875 MULTIPOLYGON(((617823.4 6760924.4,617821.5 6760917.6,617814.3 6760920.9,617816 6760927,617823.4 6760924.4)))
+BATIMENT0000000006183712 2452.90478515625 MULTIPOLYGON(((617581.7 6760252.3,617567.1 6760298.3,617518.7 6760283.5,617533.1 6760237.8,617533.4 6760237.2,617581.7 6760252.3)))
+BATIMENT0000000006183774 116.264892578125 MULTIPOLYGON(((617335.9 6760252.8,617348.1 6760256.1,617350.2 6760246.9,617338.5 6760243.8,617335.9 6760252.8)))
+BATIMENT0000000006183678 105.7099609375 MULTIPOLYGON(((617349.8 6760296.7,617353.3 6760288.3,617342.4 6760283.7,617339.2 6760292.1,617349.8 6760296.7)))
+BATIMENT0000000006181130 1084.03955078125 MULTIPOLYGON(((617358.1 6760570.2,617360.3 6760554,617351.8 6760553.4,617352.5 6760550.9,617313.3 6760534,617305.3 6760553.5,617343.6 6760570.7,617344.8 6760568.1,617358.1 6760570.2)))
+BATIMENT0000000006181116 116.259765625 MULTIPOLYGON(((617341.1 6760623,617342.7 6760610.7,617333.5 6760609,617331.9 6760621.4,617341.1 6760623)))
+BATIMENT0000000073655373 307.885070800781 MULTIPOLYGON(((157161.4 6852472.2,157167.7 6852477.2,157191 6852448.1,157184.4 6852442.8,157161.4 6852472.2)))
+BATIMENT0000000073652670 300.960021972656 MULTIPOLYGON(((154539.2 6841926.9,154575.7 6841935.6,154578 6841927.9,154541.3 6841919.2,154539.2 6841926.9)))
+BATIMENT0000000006181117 103.909912109375 MULTIPOLYGON(((617358 6760583.5,617358.6 6760577.6,617341.5 6760575.3,617340.5 6760581.2,617358 6760583.5)))
+BATIMENT0000000014192077 106.994873046875 MULTIPOLYGON(((501463.4 6885213.1,501464 6885208.2,501478.8 6885208.6,501477.8 6885218.5,501471.4 6885218,501471.5 6885213.8,501463.4 6885213.1)))
+BATIMENT0000000074069451 294.39990234375 MULTIPOLYGON(((1037091 6304698.2,1037059.7 6304709.3,1037056.2 6304701,1037086.8 6304690.2,1037091 6304698.2)))
+BATIMENT0000000076259180 57.795166015625 MULTIPOLYGON(((232759.7 6871869.3,232754.3 6871864.3,232748.9 6871869.4,232754.6 6871875,232759.7 6871869.3)))
+BATIMENT0000000065171852 214.6005859375 MULTIPOLYGON(((778798.4 6907155.9,778811 6907151.2,778817.4 6907165.1,778804 6907170.4,778798.4 6907155.9)))
+BATIMENT0000000014237425 258.650146484375 MULTIPOLYGON(((448575.2 6871891.6,448559 6871893.2,448560.1 6871909.3,448575.6 6871908,448575.2 6871891.6)))
+BATIMENT0000000065198756 596.49951171875 MULTIPOLYGON(((783661.1 6896075,783646 6896083.5,783628.3 6896055.2,783643.8 6896045.8,783661.1 6896075)))
+BATIMENT0000000065202270 193.82080078125 MULTIPOLYGON(((799034.8 6894070.7,799035.2 6894061.8,799056.7 6894062.5,799056.3 6894071.6,799034.8 6894070.7)))
+BATIMENT0000000073652671 264.804992675781 MULTIPOLYGON(((154536.3 6841957.9,154569.3 6841966.3,154571 6841958.6,154537.7 6841950.4,154536.3 6841957.9)))
+BATIMENT0000000076260014 166.550048828125 MULTIPOLYGON(((216873.4 6872179.2,216867.9 6872173,216881.6 6872158.9,216887.5 6872165.1,216873.4 6872179.2)))
+BATIMENT0000000074073480 1735.3798828125 MULTIPOLYGON(((1037014.5 6303811.4,1036974.3 6303752.1,1036994.9 6303739,1037034.8 6303798.5,1037014.5 6303811.4)))
+BATIMENT0000000065258070 855.83935546875 MULTIPOLYGON(((777181.7 6868466.9,777168.7 6868462,777190.1 6868404.2,777203.1 6868409,777181.7 6868466.9)))
+BATIMENT0000000117913575 38.10009765625 MULTIPOLYGON(((621064.6 6760535.9,621068.1 6760542,621072.6 6760539.3,621069.1 6760532.9,621064.6 6760535.9)))
+BATIMENT0000000014192081 83.355224609375 MULTIPOLYGON(((501832.9 6885029.9,501839.7 6885022.2,501846.1 6885027.4,501838.8 6885035,501832.9 6885029.9)))
+BATIMENT0000000023591503 639.889892578125 MULTIPOLYGON(((186266.5 6797398.4,186249.2 6797370.4,186232.4 6797381.8,186247.7 6797407.2,186266.5 6797398.4)))
+BATIMENT0000000014192079 35.36962890625 MULTIPOLYGON(((501912.8 6885007.9,501916.4 6885003.4,501921 6885007.1,501917.7 6885011.9,501912.8 6885007.9)))
+BATIMENT0000000014192078 59.08984375 MULTIPOLYGON(((501902.5 6885017.9,501909.4 6885010.9,501913.7 6885014.6,501907.2 6885022.1,501902.5 6885017.9)))
+BATIMENT0000000074075147 306.39990234375 MULTIPOLYGON(((1053264.3 6302761.6,1053302.6 6302797.1,1053298.7 6302802.4,1053260.6 6302765.1,1053264.3 6302761.6)))
+BATIMENT0000000076262116 4984.63500976562 MULTIPOLYGON(((254852.9 6870788.8,254888.7 6870699.2,254936.9 6870717.9,254901 6870807.5,254852.9 6870788.8)))
+BATIMENT0000000074076822 412.0498046875 MULTIPOLYGON(((1043041.5 6302755.4,1043039.6 6302726.2,1043054.4 6302725.4,1043054.6 6302755.2,1043041.5 6302755.4)))
+BATIMENT0000000074077009 196.48974609375 MULTIPOLYGON(((1041957.6 6303010.3,1041950.6 6302984.8,1041958.3 6302983.4,1041964.6 6303008.2,1041957.6 6303010.3)))
+BATIMENT0000000014190572 56.1103515625 MULTIPOLYGON(((501803.2 6885730.8,501812.2 6885724.1,501815.4 6885727.8,501806.5 6885734.7,501803.2 6885730.8)))
+BATIMENT0000000014190568 651.75 MULTIPOLYGON(((501811.7 6885704,501830.3 6885685.8,501847.7 6885704.2,501828.8 6885722,501811.7 6885704)))
+BATIMENT0000000076263300 61.5399169921875 MULTIPOLYGON(((217632.4 6871288.7,217626 6871284.6,217630 6871277.7,217636.6 6871281.9,217632.4 6871288.7)))
+BATIMENT0000000074077265 266.3701171875 MULTIPOLYGON(((1039700.1 6302830.8,1039707 6302834.2,1039690.4 6302868,1039684.7 6302864.8,1039700.1 6302830.8)))
+BATIMENT0000000008787948 475.6650390625 MULTIPOLYGON(((862827 6577615.1,862841.2 6577611.9,862847.4 6577644.4,862833.1 6577646.9,862827 6577615.1)))
+BATIMENT0000000008787931 215.125 MULTIPOLYGON(((862861.3 6577638.1,862864.3 6577659.2,862874.6 6577657.6,862871.7 6577637.7,862861.3 6577638.1)))
+BATIMENT0000000014190529 98.3251953125 MULTIPOLYGON(((505012.9 6885458.5,505025.7 6885464.2,505029.2 6885457.9,505015.8 6885452.5,505012.9 6885458.5)))
+BATIMENT0000000023591509 558.219970703125 MULTIPOLYGON(((186078.4 6797616.3,186051.5 6797573.3,186043.2 6797579.1,186068.8 6797623.3,186078.4 6797616.3)))
+BATIMENT0000000076264279 159.074829101562 MULTIPOLYGON(((233993 6870640.5,233983 6870629.7,233975.9 6870636.9,233984.4 6870648.6,233993 6870640.5)))
+BATIMENT0000000014190520 83.820068359375 MULTIPOLYGON(((505132.9 6885449.2,505146.7 6885445,505145 6885439.1,505131.3 6885444,505132.9 6885449.2)))
+BATIMENT0000000130898037 68.654296875 MULTIPOLYGON(((813529 6486801.3,813533 6486797.3,813525 6486788.2,813520.9 6486792,813529 6486801.3)))
+BATIMENT0000000130898036 24.0244140625 MULTIPOLYGON(((813456.9 6486529.1,813457.9 6486525.5,813451.6 6486523.9,813450.8 6486527.6,813456.9 6486529.1)))
+BATIMENT0000000014186778 101.02490234375 MULTIPOLYGON(((505038.7 6886665,505044.2 6886659.1,505053 6886667.9,505048 6886674,505038.7 6886665)))
+BATIMENT0000000026842922 391.44873046875 MULTIPOLYGON(((828860.9 7005318.2,828862.1 7005322,828863.9 7005324.7,828866.9 7005326.5,828870.3 7005327.2,828873.9 7005327.4,828876.5 7005326.8,828878.2 7005325.9,828881.4 7005323.2,828883.9 7005321.3,828885.8 7005319.8,828886.5 7005317.9,828886.1 7005314.5,828881.6 7005308.7,828879.9 7005307.9,828878.3 7005308.2,828876 7005309.5,828874.4 7005308.8,828871.8 7005306.7,828870.3 7005305.6,828868.3 7005305.8,828865.6 7005308.3,828860.9 7005318.2)))
+BATIMENT0000000000469132 50.525146484375 MULTIPOLYGON(((639368.9 6859136.4,639372.1 6859127.4,639377.2 6859129.2,639373.8 6859138.1,639368.9 6859136.4)))
+BATIMENT0000000075364607 980.85009765625 MULTIPOLYGON(((926198.4 6890995.7,926198 6890956.6,926223.4 6890956.7,926223.3 6890995.6,926198.4 6890995.7)))
+BATIMENT0000000073128437 673.139892578125 MULTIPOLYGON(((568870.1 6294014.3,568864.3 6294023.4,568917.6 6294055.4,568924.1 6294046.8,568870.1 6294014.3)))
+BATIMENT0000000008787941 197.60498046875 MULTIPOLYGON(((862861.8 6577579.1,862872.1 6577577.6,862874.1 6577591.9,862871.8 6577592.3,862873 6577598.7,862865.4 6577599.9,862861.8 6577579.1)))
+BATIMENT0000000006204493 133.570068359375 MULTIPOLYGON(((615102 6757871.7,615096.8 6757863.8,615107.4 6757855.9,615113.4 6757864.7,615102 6757871.7)))
+BATIMENT0000000006938200 517.0732421875 MULTIPOLYGON(((889178.5 6379017.7,889179.7 6379004.3,889178.8 6379000.8,889171.3 6379001.3,889171.1 6379005,889164.3 6379006.3,889153 6379011.2,889149.3 6379006.2,889138.4 6379013.5,889144.4 6379019.3,889150.7 6379016.8,889160.4 6379021.4,889163.3 6379019.4,889168.5 6379027,889173.3 6379023.6,889171.3 6379020.3,889178.5 6379017.7)))
+BATIMENT0000000006204479 1430.505859375 MULTIPOLYGON(((615054.9 6757968.2,615061.5 6757978.4,615065 6757975.9,615067.3 6757980.2,615073.8 6757976.6,615077.3 6757982.8,615100.9 6757969.2,615142.9 6757946.5,615137.7 6757938.7,615132.9 6757941.4,615126.4 6757930.7,615120.8 6757933.4,615126.9 6757946,615123 6757948.5,615120.7 6757945.7,615114 6757947.9,615101.6 6757956.1,615091.6 6757940,615100.1 6757934.1,615093.2 6757925,615078.6 6757935.4,615092.6 6757957.9,615090 6757959.4,615091.3 67579 [...]
+BATIMENT0000000006204283 154.229248046875 MULTIPOLYGON(((615872.2 6757977.1,615861.9 6757977.2,615861.4 6757979.2,615857.5 6757979.2,615859.2 6757988.6,615873.3 6757988,615872.2 6757977.1)))
+BATIMENT0000000006204281 182.274658203125 MULTIPOLYGON(((615896.3 6757970.8,615891.5 6757971.4,615891.7 6757973.7,615878.8 6757975.7,615880.3 6757985,615893.8 6757982.7,615893.7 6757981.8,615899.3 6757981.2,615896.3 6757970.8)))
+BATIMENT0000000006224709 155.405029296875 MULTIPOLYGON(((620286.4 6755093.9,620283.9 6755089.2,620276.9 6755093.6,620270.6 6755075.1,620267.6 6755075.7,620268.8 6755082.8,620274.1 6755101.1,620286.4 6755093.9)))
+BATIMENT0000000006204275 203.82958984375 MULTIPOLYGON(((615896.6 6757870.8,615894.1 6757870.2,615895.1 6757864.6,615886.9 6757862.4,615887.2 6757860.5,615881.9 6757861,615879 6757848.9,615884.3 6757847.9,615884.6 6757852,615888.8 6757851.4,615889.4 6757852.6,615892.8 6757853.8,615893.1 6757851.5,615898.2 6757853.4,615896 6757863.9,615898 6757864.3,615896.6 6757870.8)))
+BATIMENT0000000006204301 114.509765625 MULTIPOLYGON(((615889.1 6758012.8,615887.4 6758004.5,615899.7 6758000.5,615902.4 6758008.7,615889.1 6758012.8)))
+BATIMENT0000000023591510 463.7802734375 MULTIPOLYGON(((184822.9 6797355.4,184825.3 6797350.4,184830.6 6797352.5,184835.2 6797335.3,184856 6797343.7,184850.3 6797359.3,184843.2 6797356.7,184841.4 6797360.9,184822.9 6797355.4)))
+BATIMENT0000000076266669 172.4150390625 MULTIPOLYGON(((243064.2 6869791.8,243066.9 6869797.3,243091.6 6869784.9,243088.8 6869779.2,243064.2 6869791.8)))
+BATIMENT0000000076266817 155.420166015625 MULTIPOLYGON(((232323 6869950.4,232331.1 6869955.4,232327.5 6869962.9,232328.5 6869963.7,232326.7 6869967,232324.1 6869965.3,232322.7 6869968.3,232316.1 6869965.4,232317.4 6869962.5,232316.3 6869961.6,232323 6869950.4)))
+BATIMENT0000000076266816 48.570068359375 MULTIPOLYGON(((232813.5 6869829.4,232822 6869825.9,232824.2 6869830.2,232815.6 6869834.5,232813.5 6869829.4)))
+BATIMENT0000000076266815 123.505126953125 MULTIPOLYGON(((232594.9 6869695,232605.1 6869697.7,232604.8 6869699,232608.2 6869700.5,232605.2 6869708.1,232591.3 6869701.5,232594.9 6869695)))
+BATIMENT0000000076266814 156.98974609375 MULTIPOLYGON(((232812.4 6869797.1,232818.5 6869794.4,232815.4 6869783.3,232819.3 6869782,232817.6 6869775.8,232806.3 6869779.9,232812.4 6869797.1)))
+BATIMENT0000000076266813 119.134887695312 MULTIPOLYGON(((232751.3 6869803,232751.8 6869795.5,232758.3 6869796.1,232758.1 6869794.6,232761.1 6869794.6,232761.4 6869796.8,232767.6 6869797.2,232767.3 6869802.8,232761.6 6869802.5,232761.6 6869804.7,232754.5 6869804.4,232754.6 6869802.6,232751.3 6869803)))
+BATIMENT0000000076266812 133.200073242188 MULTIPOLYGON(((232633.6 6869680.9,232620 6869675,232616.5 6869683.6,232630 6869689,232633.6 6869680.9)))
+BATIMENT0000000076266807 102.415161132812 MULTIPOLYGON(((232786 6869886.3,232792.2 6869879,232782.3 6869871.9,232779.2 6869875.7,232781.1 6869877.1,232778.3 6869880.1,232786 6869886.3)))
+BATIMENT0000000076266805 122.940063476562 MULTIPOLYGON(((232770.2 6869903.6,232779.6 6869909.2,232784.9 6869899,232776 6869893.6,232770.2 6869903.6)))
+BATIMENT0000000076266834 86.8648681640625 MULTIPOLYGON(((232035.1 6869883.3,232031 6869882,232037.3 6869866,232041.5 6869867.8,232038.3 6869880.5,232036 6869879.9,232035.1 6869883.3)))
+BATIMENT0000000076266833 252.1298828125 MULTIPOLYGON(((232039.1 6869885.5,232069.3 6869904.4,232066.1 6869909.6,232033.7 6869891.3,232039.1 6869885.5)))
+BATIMENT0000000076266832 91.699951171875 MULTIPOLYGON(((232380.6 6869875.1,232379.8 6869886.3,232371.6 6869886,232372.8 6869874.4,232380.6 6869875.1)))
+BATIMENT0000000076266831 84.925048828125 MULTIPOLYGON(((232356.7 6870004.7,232347.3 6869999.5,232343.6 6870006.4,232353.2 6870011.7,232356.7 6870004.7)))
+BATIMENT0000000076266829 80.3699951171875 MULTIPOLYGON(((232393.3 6870002,232396.3 6869996,232407.4 6870002,232404.5 6870007.4,232393.3 6870002)))
+BATIMENT0000000076266827 133.154907226562 MULTIPOLYGON(((232342.5 6869929.4,232325.4 6869923.7,232323.6 6869930.7,232339.8 6869936.8,232342.5 6869929.4)))
+BATIMENT0000000076266825 278.194946289062 MULTIPOLYGON(((232072.1 6869887.3,232078 6869873.2,232092 6869879,232095.5 6869880.6,232090.6 6869892.6,232086.9 6869892.4,232072.1 6869887.3)))
+BATIMENT0000000076266824 137.080200195312 MULTIPOLYGON(((232347.4 6869945.1,232348.4 6869940,232354 6869942.4,232356.5 6869934.9,232365 6869937,232361.6 6869948.8,232347.4 6869945.1)))
+BATIMENT0000000076266823 113.029907226562 MULTIPOLYGON(((232370.1 6869895.2,232378.9 6869896.3,232377.2 6869908.9,232368.1 6869907.3,232370.1 6869895.2)))
+BATIMENT0000000076266822 122.9599609375 MULTIPOLYGON(((232306.6 6869985.5,232302.9 6869995.7,232312.4 6870000.3,232317.4 6869990.3,232306.6 6869985.5)))
+BATIMENT0000000076266821 71.1798095703125 MULTIPOLYGON(((232300.6 6869981.1,232294.6 6869978.1,232298.9 6869968.3,232304 6869970.8,232302.9 6869973.2,232304.2 6869974.3,232300.6 6869981.1)))
+BATIMENT0000000076266820 39.079833984375 MULTIPOLYGON(((232388.5 6869976.8,232383.3 6869972.7,232383.9 6869968.8,232391.8 6869970.3,232391.8 6869972.4,232390.1 6869972.3,232388.5 6869976.8)))
+BATIMENT0000000076266819 165.175170898438 MULTIPOLYGON(((232394.7 6869954.5,232392.3 6869968.9,232400.2 6869970.7,232401.9 6869961.6,232407.4 6869962.7,232408.3 6869954.4,232402.8 6869953.2,232401.7 6869956.6,232394.7 6869954.5)))
+BATIMENT0000000076266849 413.18505859375 MULTIPOLYGON(((232408.6 6869725.5,232423.4 6869730,232431.4 6869705,232416.9 6869699.6,232408.6 6869725.5)))
+BATIMENT0000000076266848 69.3499755859375 MULTIPOLYGON(((232515.9 6869794.3,232519.8 6869789.1,232512.3 6869782.1,232507.9 6869787.3,232515.9 6869794.3)))
+BATIMENT0000000076266847 29.6500244140625 MULTIPOLYGON(((232492.5 6869723.5,232487.1 6869719.8,232489.4 6869716,232494.8 6869719.3,232492.5 6869723.5)))
+BATIMENT0000000076266846 101.000122070312 MULTIPOLYGON(((232449.4 6869755.6,232449.3 6869763.3,232438 6869762.9,232438.7 6869759.1,232434.2 6869758.9,232434.2 6869755.5,232438.5 6869755.7,232438.8 6869754.8,232449.4 6869755.6)))
+BATIMENT0000000076266845 198.949951171875 MULTIPOLYGON(((232402.2 6869672.8,232427.2 6869675.6,232432.2 6869675.9,232432.7 6869669.8,232403.4 6869665.9,232402.2 6869672.8)))
+BATIMENT0000000076266844 116.399780273438 MULTIPOLYGON(((232219.4 6869636.4,232223.3 6869629,232235.3 6869635.5,232231.1 6869643.2,232219.4 6869636.4)))
+BATIMENT0000000076266843 296.049926757812 MULTIPOLYGON(((232439.2 6869657.2,232441.5 6869660.3,232445.1 6869657.8,232456.3 6869669.5,232460.3 6869666.4,232455.2 6869660.4,232461.6 6869655.9,232464.8 6869653.9,232467.2 6869646.4,232461.1 6869644.3,232459 6869651.5,232452.8 6869645.1,232444.6 6869653.7,232439.2 6869657.2)))
+BATIMENT0000000076266842 141.195190429688 MULTIPOLYGON(((232350.5 6869854.8,232339.1 6869853.1,232337.4 6869862.1,232338.9 6869865.5,232347.8 6869867.5,232348.8 6869863.9,232350.5 6869854.8)))
+BATIMENT0000000076266841 135.159912109375 MULTIPOLYGON(((232532 6869714,232535 6869700.5,232543.7 6869701.5,232542 6869709.7,232544.8 6869710.7,232544.2 6869713.5,232541.5 6869713.4,232541.5 6869715.7,232532 6869714)))
+BATIMENT0000000076266840 113.030029296875 MULTIPOLYGON(((232476.5 6869736.8,232479.2 6869733.2,232496.7 6869738.4,232493.7 6869744.6,232482.1 6869741.4,232483 6869739.2,232476.5 6869736.8)))
+BATIMENT0000000076266839 245.754638671875 MULTIPOLYGON(((232469.6 6869719.6,232464.8 6869719.4,232464.3 6869724.4,232460.1 6869724.1,232460.4 6869721.4,232456.3 6869721.4,232456.8 6869724.2,232451 6869724.1,232451.2 6869730.1,232456.6 6869730,232456.5 6869734,232462.3 6869734.1,232461.8 6869731.1,232466.4 6869731.2,232466.3 6869734.8,232471.9 6869734.9,232472 6869731.3,232476.7 6869731.4,232476.8 6869724.8,232474.5 6869724.4,232474.3 6869721.4,232472.2 6869721.5,232472.3 6869724.8,232469 [...]
+BATIMENT0000000076266838 210.655029296875 MULTIPOLYGON(((232519 6869764,232511.8 6869773.2,232517.9 6869777.9,232521.9 6869774.5,232532.5 6869784.7,232538.1 6869778.2,232526.4 6869767.7,232523.1 6869771.3,232519.8 6869767.9,232521.7 6869766.3,232519 6869764)))
+BATIMENT0000000076266837 209.219848632812 MULTIPOLYGON(((232448.7 6869683.8,232454.8 6869685.1,232451.2 6869698.5,232443.5 6869711.1,232440.2 6869717,232437.5 6869723,232434.1 6869721.3,232436.8 6869715.1,232435.8 6869714,232440.1 6869707.9,232446.2 6869696.1,232448.7 6869683.8)))
+BATIMENT0000000076266862 181.050048828125 MULTIPOLYGON(((231951.4 6869725,231975.4 6869742.2,231972.4 6869747.5,231948.2 6869730.3,231951.4 6869725)))
+BATIMENT0000000076266861 103.110107421875 MULTIPOLYGON(((231953 6869706,231948.7 6869703.5,231940.1 6869719.8,231944.2 6869724.3,231953 6869706)))
+BATIMENT0000000076266859 64.0499267578125 MULTIPOLYGON(((232412.1 6869983.6,232417.5 6869986.5,232423.3 6869978.5,232416.1 6869975.7,232412.1 6869983.6)))
+BATIMENT0000000076266856 122.594970703125 MULTIPOLYGON(((232008.4 6869806.7,231988.1 6869805.7,231988.2 6869810.3,231997.4 6869810.7,231997.3 6869814.8,232004.5 6869814.5,232004.8 6869811.3,232009.4 6869811.3,232008.4 6869806.7)))
+BATIMENT0000000076266855 121.079956054688 MULTIPOLYGON(((232342.9 6869840.1,232345.2 6869824.6,232351 6869824.7,232352.2 6869830.1,232350.3 6869841.8,232342.9 6869840.1)))
+BATIMENT0000000076266854 75.5850830078125 MULTIPOLYGON(((232385.6 6869821.8,232374.8 6869824.6,232376.4 6869831.1,232386.9 6869828.8,232385.6 6869821.8)))
+BATIMENT0000000076266853 64.594970703125 MULTIPOLYGON(((232381.6 6869850.3,232375.6 6869849.3,232374.5 6869859.9,232380.7 6869860.6,232381.6 6869850.3)))
+BATIMENT0000000076266852 222.1103515625 MULTIPOLYGON(((232460.2 6869781.2,232430.9 6869771.5,232428.8 6869779,232451.1 6869785.6,232457.4 6869787.6,232460.2 6869781.2)))
+BATIMENT0000000076266851 93.8349609375 MULTIPOLYGON(((232499.9 6869700.2,232490 6869691.4,232485.3 6869696.5,232496.1 6869705.8,232499.9 6869700.2)))
+BATIMENT0000000076266850 117.219970703125 MULTIPOLYGON(((232414.4 6869692.4,232416.6 6869683.7,232428.6 6869687.4,232426 6869696.9,232414.4 6869692.4)))
+BATIMENT0000000076266874 79.4051513671875 MULTIPOLYGON(((232452.9 6869640.4,232440.3 6869633.3,232437.4 6869638.1,232450.1 6869645,232452.9 6869640.4)))
+BATIMENT0000000076266873 854.869995117188 MULTIPOLYGON(((232359.2 6869707.6,232303.2 6869678.5,232296.7 6869690.5,232353.8 6869719.7,232359.2 6869707.6)))
+BATIMENT0000000076266872 94.56494140625 MULTIPOLYGON(((232429.8 6869684.7,232428.3 6869690.6,232442.9 6869695,232444.5 6869688.9,232429.8 6869684.7)))
+BATIMENT0000000076266871 122.034912109375 MULTIPOLYGON(((232381.1 6869783.9,232381.1 6869773.9,232393 6869773.2,232392.9 6869783.8,232381.1 6869783.9)))
+BATIMENT0000000014190567 117.9248046875 MULTIPOLYGON(((501485.8 6885664.6,501495.8 6885674,501490.5 6885680.3,501479.7 6885670.4,501485.8 6885664.6)))
+BATIMENT0000000014102308 74.800048828125 MULTIPOLYGON(((448753.5 6903712.6,448761.1 6903711,448759 6903701.6,448751.6 6903702.8,448753.5 6903712.6)))
+BATIMENT0000000076266867 12.1099853515625 MULTIPOLYGON(((232516.2 6869761.7,232516.4 6869758.2,232513.4 6869757.9,232512.9 6869762.1,232516.2 6869761.7)))
+BATIMENT0000000012633731 30.11572265625 MULTIPOLYGON(((925344.3 6515433.3,925347.5 6515434.8,925351.6 6515428.2,925348 6515426.2,925344.3 6515433.3)))
+BATIMENT0000000012633730 275.23486328125 MULTIPOLYGON(((925348.3 6515319.8,925355.6 6515297.8,925353.2 6515296.9,925344.1 6515293.8,925337.3 6515315.4,925348.3 6515319.8)))
+BATIMENT0000000076266949 134.53515625 MULTIPOLYGON(((226236.4 6869809.1,226250.6 6869814.2,226255 6869806.4,226240.5 6869801.2,226236.4 6869809.1)))
+BATIMENT0000000008787922 555.4853515625 MULTIPOLYGON(((862902 6577646.9,862901.3 6577683.8,862915.1 6577684.4,862915.2 6577686,862922.9 6577686.5,862923.6 6577677.6,862914.2 6577676.9,862915.2 6577647.9,862902 6577646.9)))
+BATIMENT0000000076267392 1034.27502441406 MULTIPOLYGON(((255072.1 6869351.8,255026.3 6869338.2,255032.6 6869317.3,255077.9 6869330.9,255072.1 6869351.8)))
+BATIMENT0000000076267401 110.98486328125 MULTIPOLYGON(((255036.9 6869350.4,255027.4 6869347.8,255024.7 6869358.7,255034.3 6869361.3,255036.9 6869350.4)))
+BATIMENT0000000006204295 146.114990234375 MULTIPOLYGON(((615873 6757857.1,615871 6757848,615864.1 6757849.6,615864.7 6757852.9,615856 6757855.6,615855.3 6757854,615851.9 6757855,615853.4 6757861.8,615873 6757857.1)))
+BATIMENT0000000006204288 97.644775390625 MULTIPOLYGON(((615862.3 6757883,615873 6757879.7,615870.3 6757870.9,615860.1 6757874.8,615862.3 6757883)))
+BATIMENT0000000076267453 228.119995117188 MULTIPOLYGON(((254996.5 6869339.4,255002.5 6869319.6,254992 6869316.3,254986.1 6869336.8,254996.5 6869339.4)))
+BATIMENT0000000006204286 82.6796875 MULTIPOLYGON(((615867.9 6757870,615876.6 6757867.8,615873.7 6757858.6,615865.3 6757861.5,615867.9 6757870)))
+BATIMENT0000000074082403 235.5947265625 MULTIPOLYGON(((1040254.1 6302171.9,1040262.5 6302200.6,1040255.1 6302202.8,1040246.4 6302174.3,1040254.1 6302171.9)))
+BATIMENT0000000006204303 68.360107421875 MULTIPOLYGON(((615860.7 6757831.4,615859.9 6757839.6,615868.4 6757840.3,615868.6 6757831.9,615860.7 6757831.4)))
+BATIMENT0000000006204386 134.56494140625 MULTIPOLYGON(((615854.7 6757773.1,615857.1 6757788.5,615863.5 6757788.4,615865.2 6757772,615854.7 6757773.1)))
+BATIMENT0000000006204383 60.125 MULTIPOLYGON(((615878.5 6757798.5,615889.4 6757799,615889.5 6757794.9,615886.4 6757795.1,615886 6757793,615877.3 6757792.9,615878.5 6757798.5)))
+BATIMENT0000000006204381 112.77978515625 MULTIPOLYGON(((615880.3 6757755.6,615880.1 6757765.6,615897.6 6757766.6,615897.5 6757762.7,615888.4 6757762.7,615888.4 6757756.7,615880.3 6757755.6)))
+BATIMENT0000000006204379 73.800048828125 MULTIPOLYGON(((615881.8 6757766.6,615882.1 6757776.6,615888.5 6757776.9,615888.3 6757773.1,615891.3 6757773.4,615890.6 6757768.4,615881.8 6757766.6)))
+BATIMENT0000000006204378 193.685302734375 MULTIPOLYGON(((615850.1 6757659.2,615851.4 6757675,615850.1 6757675,615850.6 6757678.7,615860.2 6757678.6,615859.9 6757673.2,615861.3 6757673,615860.1 6757658.8,615850.1 6757659.2)))
+BATIMENT0000000130694379 260.98486328125 MULTIPOLYGON(((790612 6983113.4,790598.3 6983124.7,790607.3 6983136,790621.5 6983124.2,790612 6983113.4)))
+BATIMENT0000000006204402 97.10009765625 MULTIPOLYGON(((615848.7 6757789.2,615840.3 6757790.6,615842.6 6757801.7,615851.2 6757800.1,615848.7 6757789.2)))
+BATIMENT0000000076267690 415.625 MULTIPOLYGON(((245518.7 6869405.8,245537.8 6869413.7,245545.7 6869395.5,245526.3 6869387.3,245518.7 6869405.8)))
+BATIMENT0000000076267689 177.72509765625 MULTIPOLYGON(((245489.6 6869407.4,245496.3 6869410,245507.1 6869388,245500.8 6869384.7,245489.6 6869407.4)))
+BATIMENT0000000076267687 378.125 MULTIPOLYGON(((245437.5 6869423.8,245469.2 6869436.5,245472.8 6869426.2,245441.6 6869413.2,245437.5 6869423.8)))
+BATIMENT0000000076267686 330.670043945312 MULTIPOLYGON(((245480.4 6869421.9,245488.4 6869424.2,245503.8 6869428.8,245516.9 6869432.3,245521.7 6869414.4,245514.6 6869412.6,245511 6869424.5,245505.5 6869422.8,245490.9 6869418,245483 6869416,245480.4 6869421.9)))
+BATIMENT0000000026852242 280.205078125 MULTIPOLYGON(((811183.1 6979497.9,811183.6 6979528.9,811192.4 6979528.6,811192.1 6979496.7,811183.1 6979497.9)))
+BATIMENT0000000076267712 365.775146484375 MULTIPOLYGON(((245533.8 6869439.1,245561.4 6869451.4,245565.7 6869440.6,245538.7 6869427.4,245533.8 6869439.1)))
+BATIMENT0000000074082402 445.86962890625 MULTIPOLYGON(((1040437.2 6302196.2,1040432.1 6302202.8,1040392.1 6302171.8,1040397.3 6302164.2,1040437.2 6302196.2)))
+BATIMENT0000000076267959 180.260131835938 MULTIPOLYGON(((233108.5 6869615.6,233111.6 6869616.4,233116.8 6869617.1,233116.2 6869620.2,233120.9 6869621.2,233121.5 6869618.5,233132.4 6869623.4,233134 6869620.5,233136.6 6869621.4,233137.8 6869619,233134.6 6869617.2,233124 6869612.8,233112.3 6869610.7,233109.3 6869610.5,233108.5 6869615.6)))
+BATIMENT0000000076267975 273.385009765625 MULTIPOLYGON(((232535.2 6869564.6,232564.6 6869579.6,232562.8 6869585.6,232560.7 6869584.7,232559 6869588,232554.2 6869586.3,232555.3 6869583.3,232548.2 6869579,232546.6 6869583.3,232539 6869578.8,232540.8 6869575.6,232538.7 6869573.8,232539.7 6869572.1,232532.7 6869569,232535.2 6869564.6)))
+BATIMENT0000000076267974 36.1051025390625 MULTIPOLYGON(((232685.8 6869339.9,232680.9 6869339.7,232679.5 6869346.5,232684.3 6869347.6,232685.8 6869339.9)))
+BATIMENT0000000076267973 408.670043945312 MULTIPOLYGON(((232744 6869352.4,232723.6 6869349,232721.7 6869369.7,232742.1 6869371.3,232744 6869352.4)))
+BATIMENT0000000076267972 40.43994140625 MULTIPOLYGON(((233098.9 6869613.8,233104.3 6869616,233106.8 6869609.4,233101 6869607.6,233098.9 6869613.8)))
+BATIMENT0000000076267970 261.605102539062 MULTIPOLYGON(((232724.1 6869322.4,232737.9 6869327.3,232736.5 6869329.7,232739.8 6869332.1,232737.3 6869340.8,232732.5 6869338.7,232731.7 6869340.8,232718.1 6869336.6,232718.1 6869331.8,232721.3 6869330.4,232724.1 6869322.4)))
+BATIMENT0000000076267969 103.739990234375 MULTIPOLYGON(((232788.5 6869353.6,232777.9 6869351.6,232776.5 6869361.3,232786.3 6869363.5,232788.5 6869353.6)))
+BATIMENT0000000076267968 29.93994140625 MULTIPOLYGON(((232807.9 6869266.3,232801.4 6869264.7,232800.8 6869269.7,232806.9 6869270.5,232807.9 6869266.3)))
+BATIMENT0000000076267967 240.570190429688 MULTIPOLYGON(((232720.2 6869360.4,232720.6 6869354.2,232681.8 6869349.5,232682.8 6869356,232720.2 6869360.4)))
+BATIMENT0000000076267966 47.639892578125 MULTIPOLYGON(((232712.4 6869311.7,232705.8 6869307.2,232702.1 6869311.9,232708.4 6869316.4,232712.4 6869311.7)))
+BATIMENT0000000076267965 93.5699462890625 MULTIPOLYGON(((232788.9 6869350.3,232790.8 6869342.5,232778.6 6869340.1,232777.3 6869347.3,232788.9 6869350.3)))
+BATIMENT0000000076267964 148.289916992188 MULTIPOLYGON(((233133.9 6869445.8,233135.4 6869434.8,233119 6869431.8,233117.9 6869439.8,233129.5 6869441.8,233128.8 6869444.5,233133.9 6869445.8)))
+BATIMENT0000000076267963 692.85009765625 MULTIPOLYGON(((232609.8 6869627.6,232618 6869610.6,232585.3 6869594.6,232576.9 6869611.8,232609.8 6869627.6)))
+BATIMENT0000000076267962 101.140258789062 MULTIPOLYGON(((232590.9 6869568.7,232586.2 6869565.6,232577.5 6869580,232582.4 6869583.9,232590.9 6869568.7)))
+BATIMENT0000000076267961 69.5599365234375 MULTIPOLYGON(((233068.7 6869599.3,233081.8 6869602.8,233080 6869607.9,233067.2 6869604,233068.7 6869599.3)))
+BATIMENT0000000076267960 458.16015625 MULTIPOLYGON(((233143.9 6869612.8,233135.7 6869609.3,233128.7 6869608.3,233128.6 6869606.6,233120.5 6869603.6,233120.1 6869605.5,233114.3 6869604.6,233097.3 6869597.6,233101.6 6869587.4,233120 6869593.7,233120.1 6869592.5,233130 6869597.2,233128.7 6869599.4,233136.9 6869603.4,233146 6869608,233143.9 6869612.8)))
+BATIMENT0000000076267985 749.470092773438 MULTIPOLYGON(((232369.9 6869370.5,232357.8 6869392.3,232332.1 6869378.1,232344.1 6869355.4,232369.9 6869370.5)))
+BATIMENT0000000076267984 72.760009765625 MULTIPOLYGON(((232310 6869384.8,232316.8 6869366,232320.3 6869367.8,232313 6869386.4,232310 6869384.8)))
+BATIMENT0000000076267983 116.769897460938 MULTIPOLYGON(((232210.5 6869344.2,232198.2 6869330.9,232193.8 6869336.2,232207 6869349.1,232210.5 6869344.2)))
+BATIMENT0000000076267982 550.244995117188 MULTIPOLYGON(((232398 6869434.6,232385.9 6869452.3,232364.1 6869438,232376.3 6869420.8,232398 6869434.6)))
+BATIMENT0000000076267981 23.084716796875 MULTIPOLYGON(((232363 6869413.2,232360.6 6869418.3,232356.7 6869415.9,232359.6 6869411.4,232363 6869413.2)))
+BATIMENT0000000076267979 221.420043945312 MULTIPOLYGON(((232465.1 6869640.8,232467.3 6869634.2,232451.3 6869626.8,232453 6869620.3,232445.6 6869618.6,232443.7 6869624.8,232446.2 6869625.8,232443.8 6869632.3,232465.1 6869640.8)))
+BATIMENT0000000076267978 237.089965820312 MULTIPOLYGON(((232557.6 6869550.7,232576.8 6869559.8,232569.1 6869580,232563.6 6869577.1,232568.6 6869563.8,232554.9 6869556.6,232557.6 6869550.7)))
+BATIMENT0000000076267977 67.8150634765625 MULTIPOLYGON(((232423.7 6869599.6,232425.2 6869582.1,232421.1 6869581.1,232420.3 6869599.4,232423.7 6869599.6)))
+BATIMENT0000000076267976 237.76025390625 MULTIPOLYGON(((232568.6 6869614.5,232560.8 6869608.1,232562.6 6869606,232554.4 6869599.7,232549.1 6869605.9,232557.2 6869612.2,232550.9 6869619.7,232559 6869625.9,232568.6 6869614.5)))
+BATIMENT0000000076268003 38.1600341796875 MULTIPOLYGON(((232340.6 6869388,232335.1 6869396.3,232338.2 6869398.6,232343.5 6869391,232340.6 6869388)))
+BATIMENT0000000076268002 311.465087890625 MULTIPOLYGON(((232349.7 6869432.3,232352.3 6869427.3,232308.2 6869396.2,232305.5 6869401.6,232349.7 6869432.3)))
+BATIMENT0000000076268001 105.900024414062 MULTIPOLYGON(((232190.6 6869576,232195.2 6869572.6,232205.7 6869588.7,232200.4 6869591,232190.6 6869576)))
+BATIMENT0000000076268000 100.170043945312 MULTIPOLYGON(((232432.9 6869589.2,232444.6 6869588.8,232444.8 6869597.6,232433.5 6869597.8,232432.9 6869589.2)))
+BATIMENT0000000076267999 1549.05480957031 MULTIPOLYGON(((232528.2 6869654.6,232547.2 6869631.1,232536 6869622.6,232536.6 6869622.1,232517 6869605.4,232533.6 6869584.6,232529.1 6869580.5,232510.1 6869602.4,232511.5 6869604.4,232493.6 6869626.8,232528.2 6869654.6)))
+BATIMENT0000000026929220 67.5947265625 MULTIPOLYGON(((815980.6 6924224.9,815988.3 6924228.3,815991.5 6924221.2,815982.4 6924217.9,815980.6 6924224.9)))
+BATIMENT0000000076268215 205.035034179688 MULTIPOLYGON(((226218.4 6869486.2,226236.7 6869485,226239.6 6869471.6,226230.7 6869470.7,226229 6869477.7,226219.2 6869478.1,226218.4 6869486.2)))
+BATIMENT0000000026931457 47.84033203125 MULTIPOLYGON(((820696.4 6922587.4,820696.5 6922580.8,820689.1 6922580.6,820689.3 6922587.2,820696.4 6922587.4)))
+BATIMENT0000000076268827 55.3900146484375 MULTIPOLYGON(((253897.3 6868837.1,253902.5 6868829,253897.7 6868825.6,253892.7 6868833.8,253897.3 6868837.1)))
+BATIMENT0000000076269015 121.574951171875 MULTIPOLYGON(((245210.5 6868898.7,245217.7 6868899.8,245220.1 6868883.4,245212.6 6868882.6,245210.5 6868898.7)))
+BATIMENT0000000023332044 100.545043945312 MULTIPOLYGON(((209752.9 6862809.5,209750.3 6862816.2,209737.2 6862810.2,209738.9 6862803.9,209752.9 6862809.5)))
+BATIMENT0000000207661477 28.83935546875 MULTIPOLYGON(((736669.5 6243531.6,736664.2 6243534.6,736661.9 6243530.4,736667.3 6243527.5,736669.5 6243531.6)))
+BATIMENT0000000076269164 216.27001953125 MULTIPOLYGON(((238187.5 6868913.4,238188.4 6868905.5,238214.9 6868907.1,238214 6868915.4,238187.5 6868913.4)))
+BATIMENT0000000076269239 133.915161132812 MULTIPOLYGON(((233473.9 6868819.1,233474.5 6868824.6,233451.7 6868829.2,233450.4 6868823.5,233473.9 6868819.1)))
+BATIMENT0000000076269238 88.22998046875 MULTIPOLYGON(((233583.4 6868803.1,233571.1 6868800,233570.8 6868808.3,233582.5 6868809.3,233583.4 6868803.1)))
+BATIMENT0000000076269237 498.664672851562 MULTIPOLYGON(((233565.7 6868843.7,233571.1 6868831.3,233542.6 6868819.2,233537.1 6868818.1,233533.4 6868829.8,233537.5 6868832.8,233565.7 6868843.7)))
+BATIMENT0000000076269236 124.680053710938 MULTIPOLYGON(((233635.7 6868798.9,233632.4 6868806.7,233646.3 6868812.9,233649 6868805.1,233635.7 6868798.9)))
+BATIMENT0000000076269235 350.040161132812 MULTIPOLYGON(((233505 6868853.2,233468.7 6868851.1,233469.3 6868841.1,233506.2 6868844.2,233505 6868853.2)))
+BATIMENT0000000076269234 151.255004882812 MULTIPOLYGON(((233482.7 6868820.9,233484.2 6868826.1,233499.4 6868820.2,233509 6868820.1,233509.2 6868825,233511.9 6868825.2,233511.3 6868815.6,233499 6868815.6,233482.7 6868820.9)))
+BATIMENT0000000076269233 722.75 MULTIPOLYGON(((233453.3 6868871.6,233464.2 6868850,233455.6 6868845.4,233456.9 6868842.1,233449.1 6868838.2,233446.9 6868841.7,233438 6868837.9,233428.3 6868859.8,233453.3 6868871.6)))
+BATIMENT0000000076269256 171.860107421875 MULTIPOLYGON(((233372.5 6868962.8,233399.7 6868951.2,233397 6868945.7,233370 6868957.9,233372.5 6868962.8)))
+BATIMENT0000000076269255 27.8851318359375 MULTIPOLYGON(((233177.3 6868838.3,233173.4 6868835.1,233170.2 6868839.4,233174.4 6868842.8,233177.3 6868838.3)))
+BATIMENT0000000076269254 132.804931640625 MULTIPOLYGON(((233351.7 6868963,233358.7 6868951.8,233349.7 6868939.2,233345.3 6868942.8,233352.4 6868951.4,233347.3 6868960.1,233351.7 6868963)))
+BATIMENT0000000076269253 135.255004882812 MULTIPOLYGON(((232796.5 6869190.4,232790.7 6869182.4,232780 6869191.8,232787.1 6869199.1,232796.5 6869190.4)))
+BATIMENT0000000076269252 66.85009765625 MULTIPOLYGON(((232833.1 6869204.9,232832 6869209.5,232844.7 6869214,232845.8 6869208.8,232833.1 6869204.9)))
+BATIMENT0000000076269251 342.205078125 MULTIPOLYGON(((232816.1 6869226.4,232818.4 6869215.9,232777 6869205,232776 6869210.3,232798.6 6869216.6,232797.3 6869222,232816.1 6869226.4)))
+BATIMENT0000000076269250 111.000244140625 MULTIPOLYGON(((232910.8 6869169.1,232906.2 6869173.2,232894.3 6869158.6,232898.9 6869155.1,232910.8 6869169.1)))
+BATIMENT0000000076269249 107.43017578125 MULTIPOLYGON(((233250.9 6869080.6,233235.4 6869079,233235.1 6869085.9,233250.6 6869087.5,233250.9 6869080.6)))
+BATIMENT0000000076269248 42.0550537109375 MULTIPOLYGON(((233240.3 6869052.7,233227.7 6869055.7,233228.8 6869058.8,233241.3 6869055.8,233240.3 6869052.7)))
+BATIMENT0000000076269247 85.9100341796875 MULTIPOLYGON(((233235.9 6869045.2,233234.5 6869037.2,233226.2 6869039.9,233226.7 6869042.5,233222.6 6869043.6,233223 6869048,233235.9 6869045.2)))
+BATIMENT0000000076269244 43.2451171875 MULTIPOLYGON(((233671.7 6868808.6,233672.4 6868804.5,233663.8 6868801.5,233663 6868807,233671.7 6868808.6)))
+BATIMENT0000000076269240 648.300170898438 MULTIPOLYGON(((233554.8 6868872.5,233560.3 6868858,233533.1 6868847,233536.7 6868837.5,233530.3 6868834.5,233520.7 6868859.2,233554.8 6868872.5)))
+BATIMENT0000000076269261 97.3402099609375 MULTIPOLYGON(((233300.2 6868809.1,233308.9 6868810.7,233310.5 6868799.8,233301.7 6868798.3,233300.2 6868809.1)))
+BATIMENT0000000076269260 39.3302001953125 MULTIPOLYGON(((232646.6 6868961.4,232646.2 6868955.5,232639.6 6868955.6,232640 6868961.6,232646.6 6868961.4)))
+BATIMENT0000000076269259 293.690063476562 MULTIPOLYGON(((232601.8 6868988.8,232604.8 6868976.1,232583.1 6868972,232580.3 6868985.5,232601.8 6868988.8)))
+BATIMENT0000000076269258 299.979858398438 MULTIPOLYGON(((232610 6868983.1,232649.6 6868992.7,232648.1 6868999.2,232635.4 6868995.9,232633.2 6868998.1,232619.9 6868995.9,232620.6 6868991.5,232608.8 6868988.7,232610 6868983.1)))
+BATIMENT0000000076269257 219.579956054688 MULTIPOLYGON(((232608.3 6868967.2,232614 6868968.2,232616 6868958.3,232634.8 6868961.1,232635.6 6868954.5,232610.8 6868951.4,232608.3 6868967.2)))
+BATIMENT0000000074773074 92.31005859375 MULTIPOLYGON(((991985.4 6299665.9,991990.3 6299660.7,991999.6 6299668.8,991994.7 6299674.6,991985.4 6299665.9)))
+BATIMENT0000000006204401 110.5703125 MULTIPOLYGON(((615879.2 6757632.3,615868.3 6757634.2,615869.8 6757643.8,615880.5 6757642.8,615879.2 6757632.3)))
+BATIMENT0000000006204396 131.309814453125 MULTIPOLYGON(((615853.2 6757748,615843.9 6757748.7,615845 6757763,615853.7 6757762.8,615853.2 6757748)))
+BATIMENT0000000076269926 190.315185546875 MULTIPOLYGON(((221301 6869090.6,221312.9 6869096,221319.2 6869083.1,221309 6869077.6,221308.1 6869077,221301 6869090.6)))
+BATIMENT0000000074772640 100.4609375 MULTIPOLYGON(((961118.4 6302912.3,961121.5 6302906.5,961107.4 6302899.6,961104.9 6302905.6,961118.4 6302912.3)))
+BATIMENT0000000208501226 64.484375 MULTIPOLYGON(((725938.8 6293316.8,725933.3 6293323.2,725930.6 6293321.1,725927.4 6293318.3,725933 6293312,725938.8 6293316.8)))
+BATIMENT0000000208501227 66.8896484375 MULTIPOLYGON(((725926 6293339.2,725919.9 6293333.9,725924.8 6293327.5,725931.2 6293332.7,725927.3 6293337.6,725926 6293339.2)))
+BATIMENT0000000208501228 101.25537109375 MULTIPOLYGON(((725726.5 6293885.7,725725.9 6293878.6,725726.3 6293875,725732.8 6293874.3,725734 6293883.9,725734.8 6293883.8,725735.1 6293887.8,725728.2 6293888.8,725727.7 6293885.6,725726.5 6293885.7)))
+BATIMENT0000000076270451 215.319702148438 MULTIPOLYGON(((245041.2 6868620,245044 6868616.2,245046.8 6868617.9,245049.9 6868613.6,245047.1 6868611.7,245048.5 6868609.3,245041.6 6868605.4,245040.3 6868608.3,245037.5 6868606.6,245028.9 6868621.6,245032.4 6868624.1,245034.4 6868622.2,245038.8 6868625.2,245042.9 6868621.1,245041.2 6868620)))
+BATIMENT0000000076270470 155.10498046875 MULTIPOLYGON(((244388.6 6868397.9,244384.2 6868396.8,244372.3 6868421.7,244378.4 6868424.3,244388.6 6868397.9)))
+BATIMENT0000000076270469 99.9097900390625 MULTIPOLYGON(((244457.5 6868402,244449 6868400.4,244447.7 6868405.1,244449.8 6868405.3,244447.9 6868413.9,244454.2 6868415.4,244457.5 6868402)))
+BATIMENT0000000076270468 44.2550048828125 MULTIPOLYGON(((244366.9 6868388.1,244360.5 6868386.5,244362 6868379.6,244367.8 6868381.1,244366.9 6868388.1)))
+BATIMENT0000000076270467 42.4449462890625 MULTIPOLYGON(((244404.1 6868359.2,244402.9 6868354.6,244394 6868357.2,244395.3 6868361.5,244404.1 6868359.2)))
+BATIMENT0000000076270466 41.739990234375 MULTIPOLYGON(((244423.6 6868400.4,244419.4 6868399.9,244417.1 6868408.8,244421.6 6868409.9,244423.6 6868400.4)))
+BATIMENT0000000076270465 136.72509765625 MULTIPOLYGON(((244744.6 6868517,244745.1 6868509.5,244727 6868507.3,244725.8 6868514.4,244744.6 6868517)))
+BATIMENT0000000076270464 184.170043945312 MULTIPOLYGON(((244435.3 6868384.1,244434.2 6868389.8,244407.2 6868383.3,244407.8 6868378.1,244405.5 6868377.5,244406.1 6868372.8,244411.1 6868374.6,244410.8 6868378.2,244435.3 6868384.1)))
+BATIMENT0000000076270463 809.47998046875 MULTIPOLYGON(((244551.3 6868535.9,244556.5 6868521.1,244550.6 6868518.7,244558.3 6868494.2,244544.8 6868489.3,244539.2 6868509,244533.8 6868507.6,244526.4 6868527.3,244551.3 6868535.9)))
+BATIMENT0000000076270462 178.674926757812 MULTIPOLYGON(((244734 6868527.7,244726.8 6868528.4,244729.1 6868550.8,244738.9 6868550.2,244738.5 6868543.9,244735.5 6868544.4,244734 6868527.7)))
+BATIMENT0000000076270461 58.610107421875 MULTIPOLYGON(((244789.2 6868477.2,244789.3 6868480.4,244788.7 6868481.5,244786.5 6868483.1,244783.8 6868483.1,244783.2 6868482.7,244780.7 6868480.5,244780.8 6868476.1,244786.8 6868474.4,244789.2 6868477.2)))
+BATIMENT0000000076270460 681.164794921875 MULTIPOLYGON(((244526.7 6868555.1,244520.5 6868553.6,244518.1 6868561.7,244522.2 6868563.6,244521.9 6868570.9,244576.6 6868582.3,244579.4 6868573.3,244578.6 6868563.9,244574.7 6868564,244575 6868571.8,244525.9 6868560.6,244526.7 6868555.1)))
+BATIMENT0000000076270484 56.43994140625 MULTIPOLYGON(((244409.7 6868349,244404.2 6868349.9,244404.9 6868358.8,244411.8 6868357.9,244409.7 6868349)))
+BATIMENT0000000076270483 166.769897460938 MULTIPOLYGON(((244299.5 6868490.1,244298.5 6868482.6,244276.1 6868484.5,244277.8 6868491.9,244299.5 6868490.1)))
+BATIMENT0000000076270482 231.125 MULTIPOLYGON(((244516.9 6868537.9,244509.2 6868535.1,244519.8 6868507.5,244526.8 6868510,244516.9 6868537.9)))
+BATIMENT0000000076270481 100.420043945312 MULTIPOLYGON(((244714.6 6868553.3,244713.1 6868543.5,244702.9 6868544.4,244704.6 6868554.2,244714.6 6868553.3)))
+BATIMENT0000000076270480 30.070068359375 MULTIPOLYGON(((244549.7 6868552.4,244544.7 6868551.5,244544.3 6868557.6,244549.1 6868558.4,244549.7 6868552.4)))
+BATIMENT0000000076270479 437.625 MULTIPOLYGON(((244197.8 6868365.4,244198.9 6868361,244201.6 6868362,244207.8 6868341.5,244198.7 6868337.1,244191 6868357.6,244167.5 6868353,244166.5 6868359.8,244197.8 6868365.4)))
+BATIMENT0000000076270478 252.044921875 MULTIPOLYGON(((244273.3 6868485.7,244274.9 6868487.2,244272.4 6868494.2,244269.5 6868492.9,244267 6868496.5,244253.6 6868492,244255.5 6868486.9,244250.8 6868485.4,244253.6 6868478.1,244273.3 6868485.7)))
+BATIMENT0000000076270477 74.5799560546875 MULTIPOLYGON(((244372.6 6868350.5,244367.6 6868352.1,244369.6 6868365.2,244375.4 6868363.6,244372.6 6868350.5)))
+BATIMENT0000000076270476 137.130004882812 MULTIPOLYGON(((244390.2 6868433,244383.7 6868431.9,244388.9 6868412.9,244396.2 6868414.2,244390.2 6868433)))
+BATIMENT0000000076270475 103.4951171875 MULTIPOLYGON(((244400 6868446.2,244397.5 6868454.5,244386.3 6868451.3,244387 6868443.3,244400 6868446.2)))
+BATIMENT0000000076270474 38.780029296875 MULTIPOLYGON(((244344.7 6868431.4,244341.8 6868428.6,244335.7 6868434.8,244339.2 6868438.2,244344.7 6868431.4)))
+BATIMENT0000000076270473 89.1597900390625 MULTIPOLYGON(((244378.8 6868425.8,244370.4 6868425.4,244369.7 6868431.1,244373.7 6868431.1,244372.4 6868439.6,244377.7 6868439.5,244378.8 6868425.8)))
+BATIMENT0000000076270472 93.7899169921875 MULTIPOLYGON(((244777.5 6868512.3,244776.1 6868504.6,244763.6 6868505.9,244764.6 6868512.8,244777.5 6868512.3)))
+BATIMENT0000000076270471 440.68505859375 MULTIPOLYGON(((244774.3 6868534.3,244769.7 6868559.8,244755.3 6868557.3,244761 6868523.8,244766.1 6868525.1,244765.2 6868528.5,244769.4 6868529.5,244769 6868532.8,244774.3 6868534.3)))
+BATIMENT0000000074773106 37.35546875 MULTIPOLYGON(((990959 6299782.9,990967.7 6299782.5,990967.5 6299787.3,990959.8 6299787.2,990959 6299782.9)))
+BATIMENT0000000014190566 159.13525390625 MULTIPOLYGON(((501291.3 6885724.7,501302 6885738.5,501293.3 6885745.9,501288 6885739.5,501291 6885735.6,501286.5 6885729.1,501291.3 6885724.7)))
+BATIMENT0000000014102309 107.69482421875 MULTIPOLYGON(((448843.1 6903736.3,448831.1 6903738.7,448833.7 6903747.4,448845 6903745.2,448843.1 6903736.3)))
+BATIMENT0000000076270651 322.859985351562 MULTIPOLYGON(((238699.4 6868740,238717.7 6868726.3,238709 6868714.8,238691.2 6868728.6,238699.4 6868740)))
+BATIMENT0000000014190564 154.8046875 MULTIPOLYGON(((501733.6 6885695.1,501718.3 6885687.1,501719.7 6885685.3,501715.7 6885682.7,501719.8 6885677.6,501736.4 6885689.1,501733.6 6885695.1)))
+BATIMENT0000000076270803 195.56494140625 MULTIPOLYGON(((232927.9 6868626.6,232930.4 6868619.2,232952 6868629.8,232947.5 6868637.7,232927.9 6868626.6)))
+BATIMENT0000000023332031 161.340087890625 MULTIPOLYGON(((209770.4 6862755.1,209766.8 6862759.1,209762.1 6862755.9,209756.7 6862751.5,209754.3 6862752.8,209747.9 6862746.7,209749.3 6862744.9,209752.9 6862739.9,209770.4 6862755.1)))
+BATIMENT0000000076270801 260.669677734375 MULTIPOLYGON(((232670.7 6868715.2,232654.3 6868707.3,232632.3 6868699.2,232630.4 6868704.6,232645.8 6868710.7,232644.6 6868713.7,232650.3 6868716.6,232651.5 6868712.3,232668.4 6868720,232670.7 6868715.2)))
+BATIMENT0000000076270800 48.0550537109375 MULTIPOLYGON(((233001.9 6868659.6,232993.7 6868654.4,232991.1 6868658.5,232999.6 6868663.9,233001.9 6868659.6)))
+BATIMENT0000000023527949 566.400024414062 MULTIPOLYGON(((213043.9 6820306.2,213072.3 6820334,213077.9 6820329.2,213079.9 6820331.3,213084 6820327.1,213054 6820296.2,213043.9 6820306.2)))
+BATIMENT0000000076270809 91.4600830078125 MULTIPOLYGON(((233291.9 6868767.7,233282.5 6868765.3,233282.7 6868776.5,233289.8 6868778.2,233291.9 6868767.7)))
+BATIMENT0000000076271440 95.5347900390625 MULTIPOLYGON(((224141.7 6868669,224143.5 6868675.8,224157.2 6868671.4,224155.3 6868665.3,224141.7 6868669)))
+BATIMENT0000000074082657 798.7744140625 MULTIPOLYGON(((1037953 6301855.8,1037943.4 6301845.3,1037990.6 6301809.5,1037999.1 6301819.2,1037953 6301855.8)))
+BATIMENT0000000076271580 97.9849853515625 MULTIPOLYGON(((220314.4 6868901,220326.8 6868896.5,220323.8 6868889.3,220312.3 6868893.7,220314.4 6868901)))
+BATIMENT0000000073165432 960.295166015625 MULTIPOLYGON(((576526.7 6286172.9,576512.4 6286183,576546.2 6286229.1,576559.1 6286219.1,576526.7 6286172.9)))
+BATIMENT0000000074082737 1521.04052734375 MULTIPOLYGON(((1036623.4 6301864.9,1036616 6301930.6,1036593.6 6301928.7,1036599.8 6301863.2,1036623.4 6301864.9)))
+BATIMENT0000000074092411 308.45556640625 MULTIPOLYGON(((1041454 6300495.6,1041450.2 6300489.6,1041485.8 6300469.9,1041489.3 6300477.4,1041454 6300495.6)))
+BATIMENT0000000076272164 99.9600830078125 MULTIPOLYGON(((244067.2 6868147.9,244062.1 6868149.3,244058 6868140,244051.9 6868142.1,244050.2 6868138.9,244058.9 6868135.2,244063.6 6868138.3,244067.2 6868147.9)))
+BATIMENT0000000076272163 679.664916992188 MULTIPOLYGON(((244079.3 6868161.3,244041 6868176.4,244030.6 6868145.2,244045.7 6868141.9,244047.1 6868147.2,244040.5 6868148.8,244044.5 6868162,244075.4 6868151,244079.3 6868161.3)))
+BATIMENT0000000076272179 128.26513671875 MULTIPOLYGON(((243925.2 6868202.1,243921.7 6868209.5,243906 6868201,243908.8 6868195.4,243925.2 6868202.1)))
+BATIMENT0000000076272178 51.4100341796875 MULTIPOLYGON(((243895.6 6868148.3,243893.8 6868154,243885.6 6868149.7,243887.5 6868144.6,243895.6 6868148.3)))
+BATIMENT0000000076272175 193.155151367188 MULTIPOLYGON(((243919.8 6868170.9,243922.9 6868164.6,243901.9 6868156,243897.1 6868168.7,243902.1 6868170.8,243904.1 6868164.7,243919.8 6868170.9)))
+BATIMENT0000000076272174 331.699951171875 MULTIPOLYGON(((243988.4 6868204.6,243987.2 6868212.2,243978.7 6868209.1,243976.9 6868212.9,243962.6 6868207.8,243963.9 6868204.7,243951.4 6868198.5,243953.7 6868193,243988.4 6868204.6)))
+BATIMENT0000000076272173 103.989990234375 MULTIPOLYGON(((244111.8 6868164.5,244104.1 6868163.1,244101.1 6868175.5,244109 6868177.5,244111.8 6868164.5)))
+BATIMENT0000000076272172 380.339965820312 MULTIPOLYGON(((244076.8 6868132.7,244097.3 6868127,244102 6868144.7,244082 6868149.9,244076.8 6868132.7)))
+BATIMENT0000000076272171 77.8299560546875 MULTIPOLYGON(((244283.2 6868044.9,244282.2 6868037.7,244271 6868039.8,244271.6 6868044.7,244271.8 6868046.1,244283.2 6868044.9)))
+BATIMENT0000000076272170 131.39013671875 MULTIPOLYGON(((244787.6 6867925.9,244786.7 6867918.4,244770.5 6867918.5,244770.6 6867926.8,244787.6 6867925.9)))
+BATIMENT0000000076272169 45 MULTIPOLYGON(((244583.5 6867962.9,244581.8 6867956,244575.5 6867957,244577.8 6867964.3,244583.5 6867962.9)))
+BATIMENT0000000076272168 55.965087890625 MULTIPOLYGON(((244786.8 6867963.7,244786.6 6867956.1,244779.3 6867956.8,244779.4 6867964.4,244786.8 6867963.7)))
+BATIMENT0000000076272167 201.85986328125 MULTIPOLYGON(((244593.2 6867986.5,244592.3 6867977.6,244571.6 6867977.8,244571.4 6867989.8,244579.1 6867989.7,244579.1 6867985.1,244593.2 6867986.5)))
+BATIMENT0000000076272166 283.4697265625 MULTIPOLYGON(((244815.8 6867958.6,244809.1 6867961.7,244805.7 6867960.4,244805.3 6867948.4,244789.2 6867951.1,244788.4 6867944,244811 6867940.8,244812.4 6867948,244814.8 6867947.4,244815.8 6867958.6)))
+BATIMENT0000000076272165 623.599731445312 MULTIPOLYGON(((244078.8 6868165.2,244071.3 6868167.3,244073.7 6868176.4,244068.7 6868178.4,244071.3 6868188.6,244077.6 6868187.8,244086.7 6868219.1,244099 6868214.7,244078.8 6868165.2)))
+BATIMENT0000000014190561 119.520263671875 MULTIPOLYGON(((501704.4 6885486.8,501705.3 6885474.5,501715.2 6885475.1,501714.1 6885487.1,501704.4 6885486.8)))
+BATIMENT0000000076273091 117.359741210938 MULTIPOLYGON(((225206.8 6868287.9,225207.8 6868300.6,225201.9 6868300.8,225201 6868296.7,225197 6868297.2,225196.1 6868288.3,225206.8 6868287.9)))
+BATIMENT0000000076274122 218.949951171875 MULTIPOLYGON(((244820.5 6867884.1,244805.6 6867884,244805.2 6867898.6,244820.5 6867898.5,244820.5 6867884.1)))
+BATIMENT0000000076274121 70.3798828125 MULTIPOLYGON(((245168.9 6867622.1,245167.2 6867614.9,245158.1 6867617.4,245160 6867624.8,245168.9 6867622.1)))
+BATIMENT0000000076274120 930.790161132812 MULTIPOLYGON(((245148.1 6867598.7,245151.2 6867621.9,245132.4 6867626.3,245129.6 6867618.3,245113.3 6867621.1,245110.6 6867614,245095.5 6867616.5,245094.8 6867607.3,245148.1 6867598.7)))
+BATIMENT0000000076274128 253.33984375 MULTIPOLYGON(((243760.6 6867568.7,243754.7 6867567.6,243751.1 6867582.2,243747.6 6867581.4,243742.1 6867611.4,243748.2 6867612.3,243752 6867583.6,243755.8 6867584.5,243760.6 6867568.7)))
+BATIMENT0000000076274127 528.23486328125 MULTIPOLYGON(((243755 6867592.6,243793.3 6867598.9,243789.8 6867613.4,243765.2 6867610.2,243765.3 6867605.2,243753.8 6867603.9,243755 6867592.6)))
+BATIMENT0000000073171664 400.820068359375 MULTIPOLYGON(((574542.4 6285219.9,574514.3 6285244.7,574520.2 6285253.4,574548.7 6285228.9,574542.4 6285219.9)))
+BATIMENT0000000107196702 123.955078125 MULTIPOLYGON(((459699.3 6520597.1,459695 6520598.1,459686.7 6520600.8,459688.3 6520610.2,459692.3 6520608.9,459701.1 6520605.8,459699.3 6520597.1)))
+BATIMENT0000000074773104 77.75439453125 MULTIPOLYGON(((991030.1 6299599.4,991019.9 6299600,991018.7 6299593.5,991030.8 6299592,991030.1 6299599.4)))
+BATIMENT0000000073171814 1191.294921875 MULTIPOLYGON(((574512 6285243.7,574496.1 6285226.2,574459.1 6285260.9,574475 6285278.1,574512 6285243.7)))
+BATIMENT0000000006204394 302.190185546875 MULTIPOLYGON(((615851.4 6757807.2,615844.5 6757808.4,615846.1 6757821,615839.9 6757822.2,615841.6 6757833.1,615839.4 6757833.4,615840.1 6757838.7,615842.5 6757838.5,615843.3 6757846.6,615849.5 6757845.9,615847 6757826.1,615854.8 6757824.7,615851.4 6757807.2)))
+BATIMENT0000000074773103 191.3203125 MULTIPOLYGON(((991005.3 6299556.9,990982.1 6299558.9,990981.4 6299550.6,991004.9 6299548.9,991005.3 6299556.9)))
+BATIMENT0000000076275284 24.68994140625 MULTIPOLYGON(((264132.4 6867087.4,264126.7 6867088.9,264127.8 6867093,264133.3 6867091.6,264132.4 6867087.4)))
+BATIMENT0000000074773102 77.48486328125 MULTIPOLYGON(((990960.4 6299759.7,990960.8 6299769.3,990953 6299769.4,990952.3 6299759.5,990960.4 6299759.7)))
+BATIMENT0000000074092868 169.740234375 MULTIPOLYGON(((1038894.2 6300779.2,1038903.2 6300760.3,1038910.7 6300764.3,1038901.4 6300782.5,1038894.2 6300779.2)))
+BATIMENT0000000074092999 599.09033203125 MULTIPOLYGON(((1037603.5 6300916.6,1037588.7 6300912.8,1037600.5 6300871.7,1037612.9 6300875.6,1037603.5 6300916.6)))
+BATIMENT0000000076276007 295.31982421875 MULTIPOLYGON(((244499.2 6867394,244497.4 6867405.9,244524 6867411,244526.6 6867402.7,244514.8 6867401.2,244514.8 6867396.3,244499.2 6867394)))
+BATIMENT0000000076276006 261.849975585938 MULTIPOLYGON(((244776.4 6867346.6,244772 6867357.6,244749.9 6867350.6,244753.7 6867340.6,244776.4 6867346.6)))
+BATIMENT0000000076276005 123.929931640625 MULTIPOLYGON(((244738.5 6867355.4,244736.4 6867363.8,244720.7 6867359.2,244722.7 6867352.8,244738.5 6867355.4)))
+BATIMENT0000000076276004 52.85009765625 MULTIPOLYGON(((244711.8 6867347.9,244710.3 6867353.2,244701.4 6867350.9,244702.8 6867345.2,244711.8 6867347.9)))
+BATIMENT0000000076276003 193.744995117188 MULTIPOLYGON(((244353.3 6867367.7,244352.5 6867376.5,244341.5 6867374.1,244340.4 6867376.9,244326.2 6867374.6,244326.8 6867369.5,244338.8 6867371.4,244340.1 6867364.7,244353.3 6867367.7)))
+BATIMENT0000000076276002 236.06494140625 MULTIPOLYGON(((244363.9 6867372.7,244366.8 6867367.1,244392.6 6867379.5,244389.7 6867385.8,244391.5 6867386.9,244390 6867390.4,244380.5 6867385.5,244381.7 6867382.1,244363.9 6867372.7)))
+BATIMENT0000000076276001 163.4150390625 MULTIPOLYGON(((244571.2 6867461.6,244569.3 6867471.4,244557 6867468.8,244557.8 6867465,244552.1 6867463.8,244553.3 6867457.5,244571.2 6867461.6)))
+BATIMENT0000000076276000 413.14990234375 MULTIPOLYGON(((244739.7 6867385,244738.5 6867388.7,244736 6867395.7,244717.9 6867390.3,244689 6867381.1,244690.5 6867375.4,244708 6867380.9,244708.5 6867379.1,244720.2 6867383.2,244720.9 6867379.9,244739.7 6867385)))
+BATIMENT0000000076275997 135.954956054688 MULTIPOLYGON(((245011.7 6867312.5,245004.1 6867312.2,245006.4 6867291.7,245012 6867291.9,245011.7 6867312.5)))
+BATIMENT0000000076275994 128.045043945312 MULTIPOLYGON(((245046.6 6867366.7,245046.6 6867370.9,245028.5 6867370.4,245027.7 6867357.3,245031.2 6867357.3,245031.4 6867363.9,245038.9 6867363.9,245038.8 6867365.7,245046.6 6867366.7)))
+BATIMENT0000000076276021 461.715087890625 MULTIPOLYGON(((244763.6 6867110.9,244765.4 6867122.7,244772.2 6867122,244772.7 6867126.7,244783.5 6867125.5,244785.6 6867134.5,244762.3 6867138,244761 6867129.2,244754.4 6867130.2,244751.5 6867113.3,244763.6 6867110.9)))
+BATIMENT0000000076276020 155.304931640625 MULTIPOLYGON(((244770.2 6867085.8,244772.2 6867092.5,244766.7 6867094.4,244767.1 6867096.8,244750 6867103,244748 6867096.8,244762.9 6867093.1,244761.5 6867089.7,244770.2 6867085.8)))
+BATIMENT0000000076276019 364.554931640625 MULTIPOLYGON(((244502.2 6867295.5,244503.7 6867280,244479.1 6867278.6,244478.6 6867293.2,244502.2 6867295.5)))
+BATIMENT0000000076276018 108.325073242188 MULTIPOLYGON(((244593.2 6867244.6,244591.6 6867252.6,244578.8 6867249.5,244580.3 6867241.4,244593.2 6867244.6)))
+BATIMENT0000000076276017 385.06982421875 MULTIPOLYGON(((244549.6 6867222.4,244530 6867216.4,244523.4 6867240,244530.5 6867242.5,244532.8 6867234.4,244544.1 6867237.4,244549.6 6867222.4)))
+BATIMENT0000000076276016 106.130249023438 MULTIPOLYGON(((244765.6 6867254.6,244765.2 6867259,244742.9 6867256.2,244743.2 6867251.2,244765.6 6867254.6)))
+BATIMENT0000000076276015 42.0001220703125 MULTIPOLYGON(((244673 6867128.1,244673.6 6867134.4,244666.8 6867134.9,244666.9 6867128.2,244673 6867128.1)))
+BATIMENT0000000076276014 1677.85498046875 MULTIPOLYGON(((244420.1 6867106.2,244418.7 6867083.8,244456.5 6867081.3,244456.3 6867084.4,244470.9 6867083.7,244470.7 6867076.8,244483.7 6867077.1,244483.7 6867092.9,244477.4 6867093.2,244478.1 6867110.6,244440.6 6867111.9,244439.4 6867105.5,244420.1 6867106.2)))
+BATIMENT0000000076276013 323.07470703125 MULTIPOLYGON(((244695.7 6867118.2,244688.6 6867117.8,244689 6867113.2,244680.5 6867112.7,244681.3 6867107.9,244684.2 6867108.4,244685.1 6867095.5,244687.4 6867095.4,244688 6867090.5,244690.5 6867090.8,244690.6 6867085.1,244695.8 6867086.3,244695.1 6867088.4,244696.6 6867088.8,244695.7 6867118.2)))
+BATIMENT0000000076276012 1001.78503417969 MULTIPOLYGON(((244666.8 6867168.3,244667 6867177.3,244696.8 6867167.6,244710.6 6867167.2,244711.3 6867157.6,244713.4 6867157.8,244709.5 6867109.3,244702.2 6867110,244701.1 6867120.2,244698.6 6867120.7,244699.4 6867135.5,244699.5 6867142.9,244690.1 6867143.3,244690 6867151.8,244699.9 6867151.5,244699.9 6867160.7,244688.3 6867160.4,244688 6867164.2,244666.8 6867168.3)))
+BATIMENT0000000076276011 425.10986328125 MULTIPOLYGON(((244739.4 6867174.6,244739.5 6867177,244737.7 6867177.2,244736.4 6867184.4,244738.5 6867184.8,244737.2 6867188.9,244752.2 6867189.1,244752.3 6867192.7,244761.2 6867193.9,244761.4 6867189.3,244767.8 6867189.4,244768.3 6867181.8,244762.8 6867181.1,244762.9 6867175,244754.7 6867174.2,244754.5 6867176.9,244739.4 6867174.6)))
+BATIMENT0000000076276010 333.684814453125 MULTIPOLYGON(((244766.4 6867221.9,244765.7 6867228.4,244752.8 6867227.3,244752.4 6867234.2,244761.7 6867234.6,244760.8 6867242.1,244744.8 6867240,244745.5 6867232.9,244743.6 6867232.3,244744.2 6867225.5,244746 6867225.5,244747.1 6867218.5,244755.1 6867219.5,244755.2 6867217.8,244761.1 6867218.7,244760.7 6867221,244766.4 6867221.9)))
+BATIMENT0000000076276009 557.514892578125 MULTIPOLYGON(((244274.7 6867319.6,244273.8 6867327.4,244245.5 6867322.1,244237.5 6867354,244229.7 6867351.9,244231.3 6867345.8,244228.9 6867345.2,244229.8 6867338.1,244232.5 6867338.5,244239.8 6867313.7,244274.7 6867319.6)))
+BATIMENT0000000076276008 231.119873046875 MULTIPOLYGON(((244645.2 6867451.6,244642.7 6867458.4,244632.8 6867454.6,244630.1 6867463.1,244623 6867460,244625.2 6867452.8,244622.3 6867451.5,244624.5 6867443.5,244645.2 6867451.6)))
+BATIMENT0000000076276038 632.849853515625 MULTIPOLYGON(((244229.1 6867304.5,244217.5 6867322.4,244192.2 6867308.4,244203.3 6867289.6,244229.1 6867304.5)))
+BATIMENT0000000076276037 65.170166015625 MULTIPOLYGON(((244676.7 6867101.4,244675.7 6867107.3,244664.8 6867105.2,244665.2 6867099.7,244676.7 6867101.4)))
+BATIMENT0000000076276036 362.580200195312 MULTIPOLYGON(((244520.7 6867303.1,244520.2 6867316.5,244493.4 6867314.7,244494.4 6867300.9,244520.7 6867303.1)))
+BATIMENT0000000076276035 243.919799804688 MULTIPOLYGON(((244550.9 6867299.2,244547.6 6867306.6,244531.6 6867300.7,244529.6 6867304.8,244521.3 6867301.1,244525 6867290.7,244550.9 6867299.2)))
+BATIMENT0000000076276034 133.910034179688 MULTIPOLYGON(((244777.6 6867092.4,244770.6 6867095,244774.1 6867111.3,244782.4 6867107.8,244777.6 6867092.4)))
+BATIMENT0000000076276033 1057.97534179688 MULTIPOLYGON(((244540.6 6867247.7,244531.4 6867244.7,244524.8 6867271,244559.1 6867280.7,244557.8 6867286,244563.1 6867287.3,244572.1 6867263.1,244562.5 6867259.9,244564.1 6867255.9,244546.1 6867248.9,244542.9 6867259.5,244538 6867257.7,244540.6 6867247.7)))
+BATIMENT0000000076276032 235.880004882812 MULTIPOLYGON(((244743.9 6867215.5,244744 6867224.1,244728.9 6867223.1,244728.5 6867237.6,244722.3 6867237.1,244722.8 6867222,244726.5 6867221.9,244726.5 6867215.1,244743.9 6867215.5)))
+BATIMENT0000000076276031 61.6650390625 MULTIPOLYGON(((244748.7 6867341.8,244743.9 6867339.5,244748 6867329.5,244753.5 6867332,244748.7 6867341.8)))
+BATIMENT0000000076276030 239.394897460938 MULTIPOLYGON(((244285.9 6867350.8,244286.6 6867359,244281 6867359.1,244255.2 6867358,244255 6867351.1,244285.9 6867350.8)))
+BATIMENT0000000076276029 51.300048828125 MULTIPOLYGON(((244523.7 6867381.7,244522.9 6867388.6,244515 6867387.1,244515.5 6867381.4,244523.7 6867381.7)))
+BATIMENT0000000076276028 720.465087890625 MULTIPOLYGON(((244767 6867388.3,244740.6 6867383.1,244746 6867357.2,244773.9 6867363.8,244767 6867388.3)))
+BATIMENT0000000076276027 227.149780273438 MULTIPOLYGON(((244778.5 6867396.7,244779 6867389.6,244808.3 6867390.1,244808.1 6867398.4,244778.5 6867396.7)))
+BATIMENT0000000076276026 500.039916992188 MULTIPOLYGON(((244379 6867083.4,244378.1 6867095.3,244338.5 6867090.3,244339.4 6867077.2,244379 6867083.4)))
+BATIMENT0000000076276025 134.150024414062 MULTIPOLYGON(((244636.2 6867108.4,244636.7 6867099.1,244623.8 6867097.8,244621.8 6867108,244636.2 6867108.4)))
+BATIMENT0000000076276024 237.89013671875 MULTIPOLYGON(((244520.8 6867088.3,244521.6 6867081.5,244548.9 6867084.5,244548.3 6867094.4,244537.5 6867094.4,244537.6 6867091.2,244520.8 6867088.3)))
+BATIMENT0000000076276023 375.60009765625 MULTIPOLYGON(((244510.4 6867089,244491.1 6867089.8,244492.2 6867110,244510.2 6867109,244510.3 6867102.3,244510.4 6867089)))
+BATIMENT0000000076276022 178.6748046875 MULTIPOLYGON(((244510.2 6867109,244537 6867108.5,244536.4 6867101.7,244510.3 6867102.3,244510.2 6867109)))
+BATIMENT0000000076276041 260.404907226562 MULTIPOLYGON(((243896.6 6867210.4,243890.1 6867210.6,243890.1 6867221.5,243873.4 6867218.5,243871.7 6867227.9,243892.5 6867230.7,243893.1 6867222.8,243896 6867223.1,243896.6 6867210.4)))
+BATIMENT0000000076276040 162.934936523438 MULTIPOLYGON(((243896.9 6867188.2,243888.7 6867188.2,243888.6 6867205.3,243888.6 6867207.6,243897.1 6867207.8,243896.9 6867188.2)))
+BATIMENT0000000076276039 251.89013671875 MULTIPOLYGON(((243915.1 6867225.1,243907.2 6867226.2,243905.4 6867205.3,243906.2 6867192.1,243911.8 6867191.2,243915.1 6867225.1)))
+BATIMENT0000000076276081 148.655151367188 MULTIPOLYGON(((241351.9 6867300,241325.8 6867314.4,241328.3 6867318.5,241354.5 6867304.5,241351.9 6867300)))
+BATIMENT0000000074773246 56.1044921875 MULTIPOLYGON(((992148.6 6299108.6,992140.3 6299109,992140.2 6299102.1,992148 6299101.6,992148.6 6299108.6)))
+BATIMENT0000000008783989 226.77099609375 MULTIPOLYGON(((862828.2 6577856.2,862814.5 6577855.6,862813.7 6577871.8,862827.4 6577873,862828.2 6577856.2)))
+BATIMENT0000000008783990 432.890625 MULTIPOLYGON(((862794.1 6577915.7,862790.8 6577940.6,862793.7 6577941.1,862792.6 6577950,862803.1 6577950.9,862805.8 6577925.1,862807.8 6577925.2,862808.7 6577917.8,862794.1 6577915.7)))
+BATIMENT0000000008783968 170.60009765625 MULTIPOLYGON(((862882.4 6577747.9,862893.3 6577748.1,862892.8 6577757.3,862898.1 6577757.7,862897.4 6577762.1,862881.2 6577760.8,862882.4 6577747.9)))
+BATIMENT0000000008783973 234.560546875 MULTIPOLYGON(((862829.3 6577779.7,862828.6 6577787.7,862827.2 6577787.8,862826.6 6577800.3,862815.6 6577799.8,862817.2 6577779.1,862829.3 6577779.7)))
+BATIMENT0000000043385423 68.18994140625 MULTIPOLYGON(((984170.3 6781502.8,984172.4 6781510.3,984180.9 6781507.2,984178.1 6781499.8,984170.3 6781502.8)))
+BATIMENT0000000074773378 149.06005859375 MULTIPOLYGON(((992529.3 6298334.3,992526.4 6298321.4,992537.7 6298319.1,992540.1 6298332.1,992529.3 6298334.3)))
+BATIMENT0000000043410370 62.2705078125 MULTIPOLYGON(((923203.4 6771233.7,923209.8 6771232.5,923212.8 6771241.1,923205.8 6771242.6,923203.4 6771233.7)))
+BATIMENT0000000074773409 33.2509765625 MULTIPOLYGON(((987834.6 6298676.4,987841.9 6298675.9,987842.6 6298680.3,987834.9 6298680.8,987834.6 6298676.4)))
+BATIMENT0000000074099660 228.89990234375 MULTIPOLYGON(((1038581.7 6299944.4,1038574 6299917.6,1038582.4 6299915.8,1038589.4 6299942.4,1038581.7 6299944.4)))
+BATIMENT0000000074773487 19.92431640625 MULTIPOLYGON(((991566.1 6298055.7,991563.2 6298053.9,991567.6 6298049.2,991570 6298051,991566.1 6298055.7)))
+BATIMENT0000000074773537 107.0107421875 MULTIPOLYGON(((984214 6298204.9,984211.5 6298197.8,984226.3 6298195,984227.9 6298202,984214 6298204.9)))
+BATIMENT0000000202574988 199.30517578125 MULTIPOLYGON(((417127.8 6866903.4,417127.7 6866910.3,417108.1 6866910,417098.4 6866909.7,417098.5 6866903.1,417127.8 6866903.4)))
+BATIMENT0000000014204695 80.030029296875 MULTIPOLYGON(((480736.1 6882291.2,480734.5 6882277.3,480729.1 6882277.4,480729.8 6882290.9,480736.1 6882291.2)))
+BATIMENT0000000202574989 98.205078125 MULTIPOLYGON(((417208.8 6866932.1,417208.8 6866922.2,417208.8 6866915.6,417214.9 6866915.8,417214.6 6866932.3,417208.8 6866932.1)))
+BATIMENT0000000202140330 18.239990234375 MULTIPOLYGON(((442658.7 6877991.9,442660.3 6877985.2,442662.9 6877985.9,442661.2 6877992.6,442658.7 6877991.9)))
+BATIMENT0000000076277872 41.2349853515625 MULTIPOLYGON(((252748 6866656.1,252751.9 6866658.6,252756.9 6866651.4,252753.1 6866648.7,252748 6866656.1)))
+BATIMENT0000000074773567 70.41015625 MULTIPOLYGON(((998669.7 6297598.3,998669.2 6297604.3,998657.7 6297603.6,998657.8 6297597.6,998669.7 6297598.3)))
+BATIMENT0000000076277943 286.650146484375 MULTIPOLYGON(((244695.8 6866992.9,244690 6866991.7,244690.1 6866981.8,244679 6866977.1,244678.1 6866980.6,244668.4 6866977.6,244668.9 6866974.4,244665.3 6866973.2,244667.5 6866965.8,244693.7 6866976,244695.8 6866992.9)))
+BATIMENT0000000023591500 152.839965820312 MULTIPOLYGON(((186232.6 6797400,186224.6 6797385.3,186216.5 6797389.9,186225.1 6797404.6,186232.6 6797400)))
+BATIMENT0000000076277960 349.979858398438 MULTIPOLYGON(((244057 6866875.8,244048.7 6866875.2,244049.2 6866871.7,244026.8 6866869.7,244027.1 6866862.1,244054.6 6866864.9,244055.5 6866857,244048.3 6866855.8,244048.5 6866851.4,244058.3 6866853,244060.6 6866858.4,244057 6866875.8)))
+BATIMENT0000000076277959 473.570068359375 MULTIPOLYGON(((244036 6866855.1,244035.2 6866842.2,243998.7 6866842.4,243998.6 6866848.8,244002.2 6866848.7,244001.9 6866855,244013.7 6866854.8,244013.6 6866857.5,244023.7 6866858.6,244023.9 6866854.2,244036 6866855.1)))
+BATIMENT0000000076277958 38.945068359375 MULTIPOLYGON(((244351.5 6866828.3,244347.3 6866826.4,244351.7 6866818,244355 6866819.3,244351.5 6866828.3)))
+BATIMENT0000000076277957 70.159912109375 MULTIPOLYGON(((244346.5 6866842.1,244339.6 6866838.5,244344.5 6866829.9,244350.2 6866833,244346.5 6866842.1)))
+BATIMENT0000000076277955 62.16015625 MULTIPOLYGON(((244662.2 6866962.9,244654 6866958.3,244651.4 6866965.3,244659.9 6866968.5,244662.2 6866962.9)))
+BATIMENT0000000076277954 127.364990234375 MULTIPOLYGON(((244731.5 6867025.4,244726.2 6867025.8,244725.5 6867008.9,244722.3 6867008.8,244721.9 6867002.6,244729 6867002.1,244731.5 6867025.4)))
+BATIMENT0000000076277953 119.7099609375 MULTIPOLYGON(((244702.4 6866959.5,244687.1 6866955.9,244685.2 6866962.5,244700.4 6866967.5,244702.4 6866959.5)))
+BATIMENT0000000076277952 143.984985351562 MULTIPOLYGON(((244679.6 6866946.5,244671.4 6866942.6,244674.7 6866931.3,244669.9 6866929.4,244666.1 6866947.4,244677.9 6866953.3,244679.6 6866946.5)))
+BATIMENT0000000076277951 32.760009765625 MULTIPOLYGON(((244672.7 6867052.5,244670.3 6867048.5,244664.5 6867051.5,244667.1 6867056.1,244672.7 6867052.5)))
+BATIMENT0000000076277950 88.0599365234375 MULTIPOLYGON(((244655.9 6866984.2,244653.5 6866979,244645 6866986.9,244651.6 6866994,244656.4 6866989.8,244654.1 6866986.5,244655.9 6866984.2)))
+BATIMENT0000000076277949 638.93994140625 MULTIPOLYGON(((244520.8 6867088.3,244521.6 6867081.5,244523.7 6867066.6,244492.9 6867064.2,244492.1 6867083.1,244497.3 6867083,244497.5 6867086.8,244520.8 6867088.3)))
+BATIMENT0000000076277948 58.39990234375 MULTIPOLYGON(((244707.6 6866919,244698.4 6866916.8,244699.4 6866910.6,244708.4 6866912.8,244707.6 6866919)))
+BATIMENT0000000076277947 85.3499755859375 MULTIPOLYGON(((244676.9 6866993.3,244676.9 6866988,244662.9 6866986.8,244662.7 6866993.6,244676.9 6866993.3)))
+BATIMENT0000000076277946 54.4200439453125 MULTIPOLYGON(((244809.2 6867069.4,244809.1 6867069,244805.2 6867065.4,244799.3 6867073,244803.2 6867077,244809.2 6867069.4)))
+BATIMENT0000000076277945 259.114868164062 MULTIPOLYGON(((244694.9 6867037.4,244687.6 6867037,244688.8 6867004.5,244688.9 6867000.5,244695.8 6867000.8,244694.9 6867037.4)))
+BATIMENT0000000076277944 176.52001953125 MULTIPOLYGON(((244715.7 6867031.5,244708.2 6867032.1,244706.9 6867012,244714.6 6867011.4,244714.8 6867020.9,244719 6867021.2,244719.5 6867027.6,244714.2 6867028.3,244715.7 6867031.5)))
+BATIMENT0000000076277964 645.59521484375 MULTIPOLYGON(((244032.1 6866884.4,244030.6 6866891.3,244020.7 6866889.8,244019.3 6866894.2,244005 6866892.3,244005.3 6866890.2,243998.1 6866888.9,243997.5 6866891.7,243985 6866889.5,243987.8 6866869.6,244000.3 6866870.8,243999.5 6866877.5,244006.9 6866878.9,244007.2 6866876.4,244020.7 6866879,244019.4 6866882.9,244032.1 6866884.4)))
+BATIMENT0000000076277962 96.6800537109375 MULTIPOLYGON(((244357.9 6866834.3,244361.1 6866828.1,244373.6 6866835.8,244371.4 6866841.4,244357.9 6866834.3)))
+BATIMENT0000000076277961 114.049926757812 MULTIPOLYGON(((244443.4 6866803.6,244440.7 6866810.6,244425.3 6866804.7,244427.5 6866798.8,244443.4 6866803.6)))
+BATIMENT0000000074773566 111.60986328125 MULTIPOLYGON(((1001328.8 6297635.6,1001332.6 6297630.3,1001346.1 6297640.1,1001342.2 6297645.7,1001328.8 6297635.6)))
+BATIMENT0000000014186987 32.85986328125 MULTIPOLYGON(((501355.6 6886711.5,501360.3 6886708.2,501356.2 6886702.7,501353.6 6886704.5,501355.2 6886706.4,501353 6886708.2,501355.6 6886711.5)))
+BATIMENT0000000076278453 252.574951171875 MULTIPOLYGON(((226596.5 6867100.7,226587 6867103.8,226579 6867080.1,226588.5 6867076.7,226596.5 6867100.7)))
+BATIMENT0000000006938240 283.82470703125 MULTIPOLYGON(((889179.7 6379004.3,889178.5 6379017.7,889179.6 6379025.5,889191.7 6379027,889192.5 6379004.7,889188.9 6379004.5,889179.7 6379004.3)))
+BATIMENT0000000098452629 137.9599609375 MULTIPOLYGON(((441843.8 6442245.8,441841.3 6442238.3,441857.8 6442230.9,441860.1 6442238,441843.8 6442245.8)))
+BATIMENT0000000026931394 33.1201171875 MULTIPOLYGON(((822388.4 6922713.7,822387.9 6922704.1,822384.5 6922704.1,822384.9 6922713.7,822388.4 6922713.7)))
+BATIMENT0000000076278640 372.385009765625 MULTIPOLYGON(((226401.4 6866952.8,226401.1 6866963.3,226368.1 6866961.7,226369.8 6866949.3,226401.4 6866952.8)))
+BATIMENT0000000041261250 689.715576171875 MULTIPOLYGON(((459699.3 6520597.1,459695 6520598.1,459691 6520585.4,459683.7 6520587.8,459686.7 6520600.8,459676.4 6520604.7,459678.4 6520611.4,459677.1 6520611.8,459681.2 6520633.9,459704 6520628.8,459702.1 6520620.5,459690.5 6520623.3,459688.9 6520615.3,459693.3 6520614.7,459692.3 6520608.9,459701.1 6520605.8,459699.3 6520597.1)))
+BATIMENT0000000125441261 9.02490234375 MULTIPOLYGON(((669145.4 6547324.4,669146.5 6547326.9,669143.5 6547328.2,669142.2 6547326,669145.4 6547324.4)))
+BATIMENT0000000008783977 257.94970703125 MULTIPOLYGON(((862813.7 6577871.8,862812.9 6577890.6,862826.7 6577891.6,862827.4 6577873,862813.7 6577871.8)))
+BATIMENT0000000008783980 215.59423828125 MULTIPOLYGON(((862827.3 6577825.6,862822.7 6577825.1,862823.6 6577818.6,862811.4 6577816.8,862809.3 6577831.2,862826.4 6577833.4,862827.3 6577825.6)))
+BATIMENT0000000074773583 66.58447265625 MULTIPOLYGON(((988452.2 6297576.5,988441.8 6297573.6,988443.4 6297567.6,988453.5 6297570.3,988452.2 6297576.5)))
+BATIMENT0000000069853144 76.175048828125 MULTIPOLYGON(((127713.2 6851463.6,127712.9 6851470.3,127724.1 6851471.3,127724.9 6851464.8,127713.2 6851463.6)))
+BATIMENT0000000069853145 42.4900512695312 MULTIPOLYGON(((126758.7 6848944.6,126760.9 6848949.6,126768 6848946.9,126765.5 6848941.6,126758.7 6848944.6)))
+BATIMENT0000000069853146 134.809997558594 MULTIPOLYGON(((127823.1 6851340.6,127823.1 6851348.6,127829.5 6851348.6,127829.7 6851350.4,127837.8 6851350.4,127838 6851340.4,127823.1 6851340.6)))
+BATIMENT0000000069853147 37.6849975585938 MULTIPOLYGON(((127259.7 6849793.4,127258.6 6849798.4,127265.4 6849799.9,127266.6 6849794.3,127259.7 6849793.4)))
+BATIMENT0000000069853148 160.754943847656 MULTIPOLYGON(((127082.7 6848287.7,127083.8 6848296.5,127103.3 6848294,127102.7 6848288.3,127097.9 6848288.9,127097.7 6848285.7,127082.7 6848287.7)))
+BATIMENT0000000069853149 111.549987792969 MULTIPOLYGON(((127179.3 6851014.9,127181.2 6851020.8,127197.7 6851014.8,127195 6851008.6,127179.3 6851014.9)))
+BATIMENT0000000069853150 59.9500122070312 MULTIPOLYGON(((127741.2 6851407.8,127743.4 6851414.6,127735.7 6851417.3,127733.5 6851409.9,127741.2 6851407.8)))
+BATIMENT0000000069853151 36.260009765625 MULTIPOLYGON(((127865.1 6851018.4,127870.4 6851015.7,127867.6 6851010.5,127861.6 6851014.5,127865.1 6851018.4)))
+BATIMENT0000000069853152 83.8800048828125 MULTIPOLYGON(((127787.7 6851427.3,127790.8 6851438,127784 6851440.3,127780.4 6851429.2,127787.7 6851427.3)))
+BATIMENT0000000069853153 151.660034179688 MULTIPOLYGON(((127222.6 6848339.5,127223.4 6848344.5,127221.1 6848344.8,127222.3 6848356.2,127214 6848356.8,127212.7 6848345.4,127211.4 6848345.7,127210.7 6848341.5,127222.6 6848339.5)))
+BATIMENT0000000069853154 147.349914550781 MULTIPOLYGON(((127020 6849657,127022.7 6849658.7,127024.5 6849656.7,127028.2 6849660,127025.6 6849662.5,127028.2 6849675,127022.1 6849676.4,127021.1 6849670.6,127018.7 6849671,127016.6 6849661.6,127020 6849657)))
+BATIMENT0000000069853155 126.840087890625 MULTIPOLYGON(((127677 6851460.4,127676 6851468.7,127679.6 6851468.9,127679.4 6851471.1,127684.1 6851471.4,127684.2 6851469.4,127687.9 6851469.6,127688.1 6851468.6,127691 6851468.9,127691.2 6851461.8,127677 6851460.4)))
+BATIMENT0000000069853156 84.5150146484375 MULTIPOLYGON(((127816.9 6852392.7,127814.5 6852386.6,127827 6852381.6,127829 6852387.4,127816.9 6852392.7)))
+BATIMENT0000000069853157 117.535034179688 MULTIPOLYGON(((127800.7 6851375.1,127800 6851383.2,127813.9 6851384.4,127814.7 6851376.9,127809.7 6851377,127810 6851373.8,127806.4 6851373.5,127806.3 6851375.5,127800.7 6851375.1)))
+BATIMENT0000000069853158 105.9150390625 MULTIPOLYGON(((127209.6 6851290.6,127215.4 6851299.3,127206.5 6851304.6,127201 6851296,127209.6 6851290.6)))
+BATIMENT0000000069853159 24.7000732421875 MULTIPOLYGON(((126705.2 6849154.6,126704.3 6849159.1,126709.6 6849159.8,126710.5 6849155.2,126705.2 6849154.6)))
+BATIMENT0000000069853160 158.304870605469 MULTIPOLYGON(((127731.4 6851317,127720.3 6851317.7,127720.4 6851315,127715.1 6851315.7,127715.3 6851318.5,127708.9 6851319.1,127709 6851324.2,127715.8 6851323.6,127716.2 6851325.7,127721.3 6851325.5,127721.2 6851324.5,127731.7 6851323.3,127731.4 6851317)))
+BATIMENT0000000069853161 177.179931640625 MULTIPOLYGON(((126656.2 6850259.4,126657.8 6850268,126653.1 6850268.4,126653.2 6850270.8,126645.6 6850271.7,126644.8 6850267.4,126639.1 6850268.4,126639 6850267.3,126634.4 6850267.9,126633.9 6850263.4,126656.2 6850259.4)))
+BATIMENT0000000069853162 93.0249633789062 MULTIPOLYGON(((127158 6850705.7,127153.4 6850704.6,127152.6 6850708.4,127146.3 6850707.2,127145.1 6850713.9,127156.4 6850715.6,127158 6850705.7)))
+BATIMENT0000000069853163 297.760009765625 MULTIPOLYGON(((129821.7 6850639.4,129833.5 6850641.7,129829 6850665.6,129816.9 6850663.7,129821.7 6850639.4)))
+BATIMENT0000000069853164 59.010009765625 MULTIPOLYGON(((127152.8 6848220.1,127153.7 6848226.7,127163 6848225.1,127161.8 6848219.1,127152.8 6848220.1)))
+BATIMENT0000000069853165 48.5 MULTIPOLYGON(((126674.3 6849177.3,126673.3 6849182.4,126679.7 6849183.5,126679.8 6849182.6,126683 6849183.2,126683.4 6849178.4,126674.3 6849177.3)))
+BATIMENT0000000069853166 164.934875488281 MULTIPOLYGON(((127645.9 6851462.3,127645.8 6851470.1,127651 6851470.7,127650.4 6851475.3,127660.9 6851476.1,127661.5 6851468.2,127656.8 6851462.7,127645.9 6851462.3)))
+BATIMENT0000000069853167 146.690063476562 MULTIPOLYGON(((127207.8 6851264.8,127209 6851269,127212.6 6851268.2,127214.4 6851274.2,127212.8 6851275.9,127203.6 6851278.6,127201.6 6851272.3,127196.7 6851273.8,127195.7 6851268.9,127207.8 6851264.8)))
+BATIMENT0000000069853168 361.739868164062 MULTIPOLYGON(((127084.5 6849609.4,127087.5 6849617.7,127094.3 6849615.8,127095.8 6849621,127107.7 6849617.4,127106 6849611,127111 6849609.6,127108.6 6849600.1,127105 6849601.3,127103.8 6849598.2,127100.2 6849599.5,127099.2 6849596.7,127093.7 6849598.7,127095.7 6849605.9,127084.5 6849609.4)))
+BATIMENT0000000069853169 197.960083007812 MULTIPOLYGON(((127448.6 6850707.8,127447.6 6850717.1,127450.9 6850717.5,127450.1 6850722.6,127458.5 6850723.6,127458.9 6850718.4,127464.6 6850718.8,127465.2 6850710,127448.6 6850707.8)))
+BATIMENT0000000069853170 126.070007324219 MULTIPOLYGON(((126609.5 6850182.5,126617 6850186.2,126614.1 6850191.7,126617.9 6850193.1,126620.5 6850186.7,126622.6 6850187.8,126627.8 6850176.9,126624.6 6850175.3,126621.3 6850181.8,126612.7 6850177.7,126609.5 6850182.5)))
+BATIMENT0000000023393948 92.0599975585938 MULTIPOLYGON(((127479.6 6851455.2,127485.4 6851455.1,127486.6 6851462.5,127485.3 6851462.7,127486.3 6851473.7,127482.5 6851474.4,127479.6 6851455.2)))
+BATIMENT0000000023397979 26.4600219726562 MULTIPOLYGON(((129891.5 6850622.1,129895.4 6850618.7,129898.4 6850622.9,129894.8 6850626.3,129891.5 6850622.1)))
+BATIMENT0000000023397977 47.830078125 MULTIPOLYGON(((129898.3 6850612.9,129903.7 6850610,129906.9 6850617.3,129901.7 6850620.1,129898.3 6850612.9)))
+BATIMENT0000000023398017 46.8699951171875 MULTIPOLYGON(((129343.7 6850562.8,129348.2 6850558.4,129353 6850564.2,129349 6850568.6,129343.7 6850562.8)))
+BATIMENT0000000023397991 77.5400390625 MULTIPOLYGON(((129407.2 6850542.5,129414.5 6850537.7,129418.6 6850546.9,129411.9 6850550.3,129407.2 6850542.5)))
+BATIMENT0000000023401927 43.4249877929688 MULTIPOLYGON(((127341.7 6849566.5,127341.6 6849559.7,127347.8 6849559.2,127348.4 6849565.8,127341.7 6849566.5)))
+BATIMENT0000000023401964 187.469970703125 MULTIPOLYGON(((127183 6849480.9,127200.5 6849476,127202.9 6849485.4,127183 6849490.9,127181.7 6849487.1,127184.1 6849485.9,127183 6849480.9)))
+BATIMENT0000000023406001 52.0499877929688 MULTIPOLYGON(((126835.2 6848603.1,126832.2 6848599.1,126840.1 6848593.1,126843.1 6848598.1,126835.2 6848603.1)))
+BATIMENT0000000023405889 354.964782714844 MULTIPOLYGON(((128179.8 6848589.7,128180.2 6848596,128173.1 6848596.7,128173.7 6848606.8,128164.5 6848607.6,128164.2 6848602.6,128168.5 6848602.4,128168.2 6848597.5,128160.3 6848598.4,128161.2 6848608.4,128153.3 6848609.3,128151.7 6848591,128179.8 6848589.7)))
+BATIMENT0000000023405917 36.2050170898438 MULTIPOLYGON(((127672 6848796.1,127677 6848799.5,127673.3 6848808.5,127670.9 6848806.8,127673.8 6848800.4,127670.3 6848798.3,127672 6848796.1)))
+BATIMENT0000000023403745 28.52001953125 MULTIPOLYGON(((127354.1 6848946.4,127358.1 6848943.8,127360.9 6848949.7,127357.3 6848951.8,127354.1 6848946.4)))
+BATIMENT0000000023408221 288.450012207031 MULTIPOLYGON(((126988.9 6848219.8,126995.5 6848241.6,126990.3 6848243.9,126985.5 6848228.2,126971.5 6848234.3,126973.8 6848239.5,126969.2 6848241.9,126965 6848230,126988.9 6848219.8)))
+BATIMENT0000000023408148 55.550048828125 MULTIPOLYGON(((128734.8 6848265.2,128729.8 6848267.2,128724.7 6848259.3,128729.8 6848256.2,128734.8 6848265.2)))
+BATIMENT0000000023403730 68.4550170898438 MULTIPOLYGON(((129044.8 6848968.1,129053.6 6848969.4,129052.8 6848977,129043.7 6848975.5,129044.8 6848968.1)))
+BATIMENT0000000023403728 44.8300170898438 MULTIPOLYGON(((129092 6848965.7,129096.9 6848965.8,129096.1 6848975.1,129091.2 6848974.6,129092 6848965.7)))
+BATIMENT0000000023403823 19.4500122070312 MULTIPOLYGON(((126683 6849179.2,126689.1 6849180.5,126688.4 6849183.6,126682.1 6849182,126683 6849179.2)))
+BATIMENT0000000023403808 62.9249267578125 MULTIPOLYGON(((126605.2 6849197.1,126605.7 6849201.2,126599.6 6849201.6,126599.6 6849203.2,126593.4 6849203.8,126592.4 6849198,126605.2 6849197.1)))
+BATIMENT0000000023400516 8.48004150390625 MULTIPOLYGON(((127837.2 6849975.7,127840.2 6849974.5,127841.3 6849976.7,127838 6849978.1,127837.2 6849975.7)))
+BATIMENT0000000023396352 100.820007324219 MULTIPOLYGON(((127681.2 6851177.4,127686.1 6851188.7,127679.6 6851192.2,127673.2 6851182,127681.2 6851177.4)))
+BATIMENT0000000023396311 41.0750122070312 MULTIPOLYGON(((127938.3 6851132.5,127941.1 6851130.4,127947.6 6851138.7,127944.5 6851141.5,127938.3 6851132.5)))
+BATIMENT0000000023391148 29.8949584960938 MULTIPOLYGON(((128042.9 6852085,128040.5 6852078.4,128044.6 6852076.7,128046.7 6852083.3,128042.9 6852085)))
+BATIMENT0000000023388574 58.9149780273438 MULTIPOLYGON(((126835.3 6852209.8,126839.7 6852213.3,126835 6852221.6,126829.6 6852217.8,126835.3 6852209.8)))
+BATIMENT0000000023388520 120.470092773438 MULTIPOLYGON(((127684.6 6852420.5,127672.9 6852408.4,127677.8 6852403.2,127689.5 6852415.2,127684.6 6852420.5)))
+BATIMENT0000000023398018 160.720092773438 MULTIPOLYGON(((129310.1 6850676.4,129301.2 6850670.9,129312.5 6850659.2,129320.6 6850665.8,129310.1 6850676.4)))
+BATIMENT0000000023398025 162.414916992188 MULTIPOLYGON(((129332 6850641.2,129338.1 6850641.8,129340.7 6850646.1,129339.2 6850655.4,129324 6850652.1,129324.3 6850644.8,129330.9 6850646.3,129332 6850641.2)))
+BATIMENT0000000023398052 33.5950317382812 MULTIPOLYGON(((127977.3 6850737.1,127976.7 6850733.1,127985.2 6850731.8,127985.8 6850735.5,127977.3 6850737.1)))
+BATIMENT0000000023398149 30.4949951171875 MULTIPOLYGON(((127217.4 6850788.2,127218.7 6850784.5,127226 6850786.3,127225 6850790.2,127217.4 6850788.2)))
+BATIMENT0000000023405996 19.7100219726562 MULTIPOLYGON(((126788.7 6848768.6,126794 6848767.8,126794.4 6848771.3,126788.9 6848772.3,126788.7 6848768.6)))
+BATIMENT0000000064251984 303.6201171875 MULTIPOLYGON(((558976.5 6930408.4,558959.8 6930400.9,558959.9 6930399.4,558948.2 6930396.4,558930.5 6930392.3,558928.8 6930399.1,558952.1 6930405,558975.6 6930411.4,558976.5 6930408.4)))
+BATIMENT0000000016868547 960.82373046875 MULTIPOLYGON(((673567.7 6653609.3,673573.6 6653611.3,673574.1 6653609.6,673577.5 6653611.1,673581.2 6653602.6,673580.1 6653602.3,673584.8 6653584.5,673586 6653584.8,673587.6 6653578.5,673595.2 6653580.5,673595 6653581.4,673600.7 6653582.9,673600.9 6653582.1,673607.2 6653583.8,673600.7 6653608.8,673597.3 6653607.9,673595.9 6653612.8,673599.5 6653613.7,673598 6653618.3,673605.6 6653620,673608.6 6653611,673606.9 6653610.5,673613.3 6653585.9,673619.8 [...]
+BATIMENT0000000070446605 113.7998046875 MULTIPOLYGON(((672946.7 6653989.2,672937.8 6653989.4,672937.6 6654000.8,672940.9 6654000.8,672940.9 6654002.4,672946.9 6654002.3,672946.7 6653989.2)))
+BATIMENT0000000070446606 103.2001953125 MULTIPOLYGON(((672937.8 6653989.4,672929.4 6653989.5,672929.6 6654002.6,672935.5 6654002.4,672935.4 6654000.8,672937.6 6654000.8,672937.8 6653989.4)))
+BATIMENT0000000016868501 217.39501953125 MULTIPOLYGON(((672946.7 6653989.2,672929.4 6653989.5,672929.6 6654002.6,672935.5 6654002.4,672935.4 6654000.8,672940.9 6654000.8,672940.9 6654002.4,672946.9 6654002.3,672946.7 6653989.2)))
+BATIMENT0000000023432980 129.349975585938 MULTIPOLYGON(((126057.5 6843372.2,126060.1 6843362.6,126050 6843360,126049.5 6843364.1,126045.7 6843363.6,126045.9 6843372.4,126050.4 6843373.6,126051.9 6843369.7,126057.5 6843372.2)))
+BATIMENT0000000023432971 51.1600952148438 MULTIPOLYGON(((125756.5 6843166.4,125747.3 6843167.2,125747.4 6843171.8,125750.3 6843172.4,125757.8 6843171.4,125756.5 6843166.4)))
+BATIMENT0000000023432970 126.659973144531 MULTIPOLYGON(((125688.4 6843215.1,125693.9 6843214.9,125698.4 6843217.4,125701.8 6843225.1,125696.7 6843230,125694.7 6843225,125686.4 6843222.2,125688.4 6843215.1)))
+BATIMENT0000000023432938 362.809936523438 MULTIPOLYGON(((126699.8 6843228.8,126719.9 6843226.9,126721.2 6843245,126701 6843246.5,126699.8 6843228.8)))
+BATIMENT0000000023432935 200.239929199219 MULTIPOLYGON(((126783.5 6843118.3,126786.3 6843125.3,126789.5 6843125,126791.3 6843130.8,126793.8 6843130.5,126794.5 6843137.1,126785.2 6843139.8,126783.6 6843133.5,126780.6 6843134,126776.7 6843120.2,126783.5 6843118.3)))
+BATIMENT0000000044633043 31.9453125 MULTIPOLYGON(((755901.3 6269873.4,755898.6 6269876.5,755904.2 6269881.8,755907 6269878.8,755901.3 6269873.4)))
+BATIMENT0000000216994006 93.30029296875 MULTIPOLYGON(((837446.2 6754709.7,837436.2 6754714.2,837431.5 6754708.2,837443 6754702.2,837446.2 6754709.7)))
+BATIMENT0000000070446632 145.42041015625 MULTIPOLYGON(((679394 6650539.8,679403.4 6650551.7,679411.1 6650545.9,679400.9 6650533.8,679394 6650539.8)))
+BATIMENT0000000016873415 308.4404296875 MULTIPOLYGON(((679402.3 6650527.7,679385.2 6650540.6,679386.9 6650552.5,679388.3 6650558.5,679390.3 6650561.3,679394.9 6650558.1,679387.6 6650547.7,679389.1 6650547.1,679388.7 6650543.6,679393.8 6650539.5,679403.4 6650551.7,679411.1 6650545.9,679400.8 6650533.7,679406.1 6650529.6,679402.3 6650527.7)))
+BATIMENT0000000023432934 20.8049926757812 MULTIPOLYGON(((126814.3 6843185.1,126819.4 6843184.8,126819.4 6843188.7,126814.5 6843189.5,126814.3 6843185.1)))
+BATIMENT0000000023432928 1094.24499511719 MULTIPOLYGON(((126722.7 6843220.7,126764.1 6843214.7,126765.9 6843242.2,126725 6843245.9,126722.7 6843220.7)))
+BATIMENT0000000023432875 1061.84497070312 MULTIPOLYGON(((130330.6 6843168.7,130353.5 6843158.6,130357.5 6843166.9,130361.8 6843165.4,130366.3 6843176.4,130362 6843178.6,130365.5 6843186.2,130342.5 6843196.5,130337 6843190,130316.1 6843199.1,130303.8 6843202.4,130303.2 6843196.9,130317.1 6843193.1,130326.4 6843187.2,130335.5 6843182.2,130330.6 6843168.7)))
+BATIMENT0000000023432869 68.2350463867188 MULTIPOLYGON(((131096.4 6843250.6,131104.9 6843249.7,131105.3 6843257.8,131096.7 6843258.4,131096.4 6843250.6)))
+BATIMENT0000000023430930 217.785034179688 MULTIPOLYGON(((130262 6843529.6,130251.9 6843528.9,130252.1 6843525.2,130248.1 6843524.9,130250.2 6843508.3,130261.2 6843509.1,130258.6 6843525.7,130262.4 6843526,130262 6843529.6)))
+BATIMENT0000000023430924 38.4149169921875 MULTIPOLYGON(((133715.6 6843478.1,133716.4 6843471.7,133722.3 6843472.2,133721.7 6843478.5,133715.6 6843478.1)))
+BATIMENT0000000023432974 173.844909667969 MULTIPOLYGON(((125936.9 6843439.7,125943.1 6843439,125942.8 6843436.6,125953.3 6843435.1,125953.5 6843437.2,125958 6843436.7,125959.1 6843441.8,125942.5 6843444.9,125943.5 6843452.4,125939.9 6843452.9,125938.1 6843445.1,125936.9 6843439.7)))
+BATIMENT0000000023432965 250.910034179688 MULTIPOLYGON(((125806.5 6843397.5,125822 6843376.7,125830 6843383.3,125824.3 6843392.6,125822.4 6843390.8,125813.4 6843403.2,125806.5 6843397.5)))
+BATIMENT0000000023432963 90.8550415039062 MULTIPOLYGON(((125983.3 6843413.5,125972 6843411.8,125971 6843419.5,125982.4 6843421.5,125983.3 6843413.5)))
+BATIMENT0000000006190032 316.425048828125 MULTIPOLYGON(((619741.5 6759384.6,619737.9 6759375.1,619709.4 6759386.4,619713.2 6759396.2,619741.5 6759384.6)))
+BATIMENT0000000064252018 823.190673828125 MULTIPOLYGON(((558967.8 6930354.8,558962.8 6930354.1,558959.4 6930367.6,558948.6 6930364.9,558947.1 6930372.4,558955.1 6930374.7,558954.1 6930379.3,558940.8 6930377.3,558940.6 6930386.9,558942.5 6930387.2,558942.3 6930389.7,558952.1 6930390.1,558952.2 6930391.9,558957.2 6930392,558957.3 6930393.8,558963.5 6930393.2,558963.8 6930396.3,558974.6 6930398,558974.7 6930378.8,558970.7 6930377.8,558971.1 6930373.2,558970.8 6930371.9,558968 6930370.1,5589 [...]
+BATIMENT0000000016892915 146.59033203125 MULTIPOLYGON(((673236.3 6633926.4,673231.3 6633923.8,673235.1 6633916.9,673249.5 6633924.1,673250.3 6633933.1,673236.3 6633926.4)))
+BATIMENT0000000016892930 184.740234375 MULTIPOLYGON(((673210.1 6633913,673199.6 6633933.7,673206.7 6633937.1,673217.4 6633916.2,673210.1 6633913)))
+BATIMENT0000000023432962 94.7550048828125 MULTIPOLYGON(((125961.1 6843399.4,125962.5 6843387.3,125953.6 6843385.7,125953.1 6843394.4,125956.3 6843394.2,125957.2 6843400.4,125961.1 6843399.4)))
+BATIMENT0000000023432958 143.200012207031 MULTIPOLYGON(((126025.3 6843425.7,126035.1 6843425.6,126035.4 6843422.2,126040.2 6843422.6,126040.4 6843433.9,126025.3 6843434.3,126025.3 6843425.7)))
+BATIMENT0000000023432925 89.7949829101562 MULTIPOLYGON(((127206.1 6843507.9,127212.3 6843509.4,127209.8 6843523,127203.2 6843520.8,127206.1 6843507.9)))
+BATIMENT0000000023432924 690.945007324219 MULTIPOLYGON(((126965.8 6843477.6,126952.2 6843497.7,126979.6 6843516.3,126989.2 6843497.9,126973 6843488.1,126975.1 6843483.9,126965.8 6843477.6)))
+BATIMENT0000000023432918 139.409973144531 MULTIPOLYGON(((127391.3 6843398.3,127375.9 6843410.8,127371.3 6843405.7,127386.6 6843392.9,127391.3 6843398.3)))
+BATIMENT0000000023430933 2790.34515380859 MULTIPOLYGON(((129129 6843593.6,129130.5 6843619.3,129108.5 6843620.3,129107 6843566.5,129127.8 6843567.7,129140.5 6843566.4,129141 6843571.5,129158.2 6843571,129158.8 6843584.7,129142.4 6843585.1,129142.6 6843592.5,129154.3 6843591.7,129154.9 6843596.4,129162.8 6843596.9,129162.9 6843601.1,129154.1 6843601.8,129154.3 6843607.7,129159.2 6843607.5,129160.3 6843612.7,129162.7 6843612.7,129162.8 6843618.2,129155.5 6843618.7,129157.4 6843641.6,129149 [...]
+BATIMENT0000000023430958 12 MULTIPOLYGON(((127211.5 6843553.9,127209.5 6843551.9,127212.5 6843548.9,127214.5 6843550.9,127211.5 6843553.9)))
+BATIMENT0000000023430962 79.6250610351562 MULTIPOLYGON(((127231.3 6843571,127242 6843567.4,127243.3 6843574.5,127232.5 6843577.9,127231.3 6843571)))
+BATIMENT0000000023431021 33.4400024414062 MULTIPOLYGON(((126174.6 6843610,126179.7 6843606.5,126182.5 6843611.7,126178 6843614.6,126174.6 6843610)))
+BATIMENT0000000023431071 68.9349975585938 MULTIPOLYGON(((125778.4 6843546.1,125782.7 6843545.6,125788.2 6843544.5,125788.9 6843551.6,125779 6843553,125778.4 6843546.1)))
+BATIMENT0000000023431072 71.5399169921875 MULTIPOLYGON(((125817.3 6843585,125821 6843583.4,125825.9 6843582.3,125826.9 6843591.1,125818.8 6843592.3,125817.3 6843585)))
+BATIMENT0000000044633042 22.09423828125 MULTIPOLYGON(((755302.3 6269674,755306.1 6269672.6,755303.8 6269667.7,755299.8 6269669.6,755302.3 6269674)))
+BATIMENT0000000044633051 41.2998046875 MULTIPOLYGON(((755252.6 6269606.6,755255.1 6269610,755262.6 6269602.6,755260.2 6269599.7,755252.6 6269606.6)))
+BATIMENT0000000064252278 226.795166015625 MULTIPOLYGON(((558930.4 6930383.2,558931.5 6930378.1,558938.9 6930379.7,558940.2 6930369.5,558927.8 6930367.4,558923 6930366.6,558920.6 6930381.1,558925 6930382,558930.4 6930383.2)))
+BATIMENT0000000016866238 1002.68896484375 MULTIPOLYGON(((686125.2 6654849.8,686119.8 6654836,686114.3 6654838.1,686107.9 6654820.5,686113.4 6654818.4,686110.5 6654810.6,686130.4 6654803.2,686145.1 6654842.3,686125.2 6654849.8)))
+BATIMENT0000000016868425 977.51025390625 MULTIPOLYGON(((685469.8 6653569.5,685476.9 6653566,685474.7 6653550.9,685482.6 6653549.7,685486.2 6653568.8,685499.5 6653567.2,685501.3 6653574.3,685479.6 6653579.4,685480.5 6653584.6,685494 6653582.4,685497.1 6653596.8,685486.1 6653599.3,685490.5 6653617.3,685481.5 6653618.3,685476.8 6653596.7,685474.3 6653596.8,685469.8 6653569.5)))
+BATIMENT0000000023431075 152.114990234375 MULTIPOLYGON(((125793.9 6843617.5,125782.5 6843618.5,125782.4 6843613.6,125776.5 6843615.3,125776.8 6843620.8,125777.8 6843626.9,125793.8 6843624.7,125793.9 6843617.5)))
+BATIMENT0000000023431076 88.919921875 MULTIPOLYGON(((125889.9 6843577.6,125888.9 6843582.5,125888.7 6843590.2,125895.9 6843590.7,125895.9 6843577.4,125889.9 6843577.6)))
+BATIMENT0000000023431100 197.600036621094 MULTIPOLYGON(((125495.3 6843620.8,125509.9 6843613.5,125513 6843620.1,125505.8 6843623.9,125509 6843628.8,125506.2 6843630.2,125510.6 6843637.4,125505.9 6843639.6,125499.7 6843625.6,125497.9 6843626.8,125495.3 6843620.8)))
+BATIMENT0000000023431035 223.31494140625 MULTIPOLYGON(((125740.6 6843688.8,125740 6843673.3,125737 6843673.5,125736.3 6843665.7,125752.1 6843667.4,125752.1 6843674.3,125746.9 6843677.3,125747.7 6843688.5,125740.6 6843688.8)))
+BATIMENT0000000023431095 90.75 MULTIPOLYGON(((125687.1 6843644.3,125681.8 6843644.8,125677.4 6843645.9,125680.2 6843654.9,125690.6 6843651.4,125687.1 6843644.3)))
+BATIMENT0000000023431107 79.6500244140625 MULTIPOLYGON(((125667 6843672.3,125671.4 6843669.7,125672.1 6843672.3,125676.6 6843669.5,125679.3 6843676,125671.5 6843681,125667 6843672.3)))
+BATIMENT0000000023431112 60.7998657226562 MULTIPOLYGON(((125645 6843689,125651.8 6843690.7,125649.7 6843699.4,125643 6843697.1,125645 6843689)))
+BATIMENT0000000023431052 98.8800659179688 MULTIPOLYGON(((125904.4 6843795.1,125905.9 6843804.1,125916.3 6843802,125914.9 6843792.7,125904.4 6843795.1)))
+BATIMENT0000000023429514 67.510009765625 MULTIPOLYGON(((125660 6843947.6,125666.5 6843942.4,125670.9 6843949.6,125663.3 6843954.2,125660 6843947.6)))
+BATIMENT0000000023431096 78.919921875 MULTIPOLYGON(((125868.5 6843932.1,125880.7 6843932.1,125880.4 6843938.6,125868.5 6843938.7,125868.5 6843932.1)))
+BATIMENT0000000023427407 86.2799682617188 MULTIPOLYGON(((132780.6 6844431.1,132782.5 6844436.6,132776.9 6844439.6,132777.7 6844441,132771.4 6844442.8,132768.9 6844436.1,132780.6 6844431.1)))
+BATIMENT0000000014186997 50.054931640625 MULTIPOLYGON(((501272.9 6886804,501280.9 6886802.1,501279.3 6886795.7,501272 6886798,501272.9 6886804)))
+BATIMENT0000000014188072 50.86474609375 MULTIPOLYGON(((501241.6 6886538.3,501247.3 6886533.1,501242.2 6886528.4,501237 6886533.5,501241.6 6886538.3)))
+BATIMENT0000000076280185 104.344848632812 MULTIPOLYGON(((244052.3 6866564.4,244051.6 6866558.4,244034.4 6866559.7,244035 6866565.7,244052.3 6866564.4)))
+BATIMENT0000000076280184 126.779907226562 MULTIPOLYGON(((244076.7 6866551.4,244066.5 6866552.6,244064.6 6866541.4,244078.4 6866540.2,244079.1 6866544.1,244074.8 6866544.7,244076.7 6866551.4)))
+BATIMENT0000000076280183 82.0799560546875 MULTIPOLYGON(((244103.6 6866576.2,244102.5 6866570.7,244089.2 6866573.8,244090.5 6866580.1,244103.6 6866576.2)))
+BATIMENT0000000076280182 102.579833984375 MULTIPOLYGON(((244244.6 6866670,244240.8 6866675.7,244228.8 6866668.8,244232.7 6866662.1,244244.6 6866670)))
+BATIMENT0000000076280181 42.599853515625 MULTIPOLYGON(((244039.8 6866544.1,244038.2 6866539,244030.5 6866541.1,244031.5 6866546,244039.8 6866544.1)))
+BATIMENT0000000076280180 22.7099609375 MULTIPOLYGON(((244064.7 6866497.5,244060.6 6866498.6,244059.1 6866493.4,244062.8 6866492.1,244064.7 6866497.5)))
+BATIMENT0000000076280179 118.6650390625 MULTIPOLYGON(((244260.3 6866644,244255.1 6866649.9,244257.3 6866652.7,244254.2 6866656.1,244245.3 6866645.4,244248.3 6866642.1,244249.7 6866643.6,244254 6866639.5,244260.3 6866644)))
+BATIMENT0000000076280178 46.4898681640625 MULTIPOLYGON(((244704.9 6866621.1,244698.8 6866620.9,244697.5 6866628.3,244703.8 6866628.6,244704.9 6866621.1)))
+BATIMENT0000000076280176 156.520141601562 MULTIPOLYGON(((244511.4 6866574.3,244510.4 6866568.3,244486.7 6866570,244487 6866576.9,244511.4 6866574.3)))
+BATIMENT0000000076280175 206.464965820312 MULTIPOLYGON(((244497.2 6866558.4,244490.3 6866559.6,244488.5 6866551.3,244484.2 6866551.7,244482.6 6866542.9,244499.8 6866540.1,244501.5 6866545.2,244495.5 6866547.8,244497.2 6866558.4)))
+BATIMENT0000000076280174 697.610107421875 MULTIPOLYGON(((244550.3 6866589.9,244548.3 6866581.1,244487.5 6866589.9,244488.4 6866597.8,244492.6 6866597.3,244493 6866600,244503.4 6866598.4,244503.5 6866596.6,244513.9 6866594.7,244514.6 6866601.1,244536 6866597.7,244535.5 6866592.4,244550.3 6866589.9)))
+BATIMENT0000000076280173 121.47021484375 MULTIPOLYGON(((244691.3 6866544.2,244682.8 6866545.9,244683.6 6866552.5,244685.5 6866552.2,244687.7 6866562.1,244693.3 6866561.2,244691.3 6866544.2)))
+BATIMENT0000000076280171 93.13525390625 MULTIPOLYGON(((244710.2 6866556.7,244709.1 6866550.6,244701.1 6866551.8,244700.4 6866545,244697 6866545.5,244698.7 6866558.3,244710.2 6866556.7)))
+BATIMENT0000000076280204 140.76513671875 MULTIPOLYGON(((244685.2 6866562.7,244685.4 6866573,244672.2 6866573.8,244672.1 6866562.7,244685.2 6866562.7)))
+BATIMENT0000000076280203 57.6600341796875 MULTIPOLYGON(((244690.4 6866539.9,244689.4 6866534.1,244680.6 6866535.3,244681.8 6866542.3,244690.4 6866539.9)))
+BATIMENT0000000076280202 112.400024414062 MULTIPOLYGON(((244091.1 6866309.7,244090.8 6866302.2,244075.1 6866302.7,244075.6 6866309.6,244091.1 6866309.7)))
+BATIMENT0000000076280201 184.259765625 MULTIPOLYGON(((244267.2 6866300.8,244266.3 6866293.1,244256.2 6866293.5,244253.1 6866279.3,244248.4 6866280.4,244252.5 6866301.2,244267.2 6866300.8)))
+BATIMENT0000000076280200 73.2100830078125 MULTIPOLYGON(((244027.6 6866323.7,244020.9 6866325.2,244023.8 6866335.8,244030.3 6866333.8,244027.6 6866323.7)))
+BATIMENT0000000076280199 121.2099609375 MULTIPOLYGON(((244088.3 6866316.5,244086 6866323.6,244068.2 6866318.7,244069 6866313.4,244088.3 6866316.5)))
+BATIMENT0000000076280198 120.570068359375 MULTIPOLYGON(((244062.5 6866327.7,244061.7 6866322.4,244041.8 6866325.1,244042.2 6866331.6,244062.5 6866327.7)))
+BATIMENT0000000076280197 115.404907226562 MULTIPOLYGON(((244492.9 6866263.6,244485.9 6866263.8,244485.6 6866279.5,244493.3 6866279.3,244492.9 6866263.6)))
+BATIMENT0000000076280196 108.77490234375 MULTIPOLYGON(((244330.1 6866274.2,244330 6866266,244313.6 6866267.7,244314.3 6866273,244330.1 6866274.2)))
+BATIMENT0000000076280195 169.549926757812 MULTIPOLYGON(((244546.4 6866275,244543.6 6866284.9,244528.4 6866280,244530.5 6866269.7,244546.4 6866275)))
+BATIMENT0000000076280193 173.240112304688 MULTIPOLYGON(((244337 6866318.3,244333 6866312.8,244319.6 6866321.5,244324.7 6866337.1,244329.4 6866335.7,244326.6 6866326.2,244337 6866318.3)))
+BATIMENT0000000076280190 124.845092773438 MULTIPOLYGON(((244461.3 6866261.7,244451.7 6866260.9,244450.8 6866275,244459.5 6866274.8,244461.3 6866261.7)))
+BATIMENT0000000076280189 239.585083007812 MULTIPOLYGON(((244331.4 6866335.2,244329.4 6866335.7,244324.7 6866337.1,244319.6 6866338.4,244326.6 6866357.8,244337.3 6866355,244331.4 6866335.2)))
+BATIMENT0000000076280208 25.6201171875 MULTIPOLYGON(((243586.9 6866562.1,243583.5 6866560.9,243582.1 6866567.5,243586.5 6866568.2,243586.9 6866562.1)))
+BATIMENT0000000076280207 232.614990234375 MULTIPOLYGON(((243606.6 6866576.4,243604.5 6866584.4,243590.5 6866583.4,243583.6 6866580.9,243586.2 6866569.9,243591.4 6866572.4,243591.9 6866570,243606.6 6866576.4)))
+BATIMENT0000000076280206 67.1600341796875 MULTIPOLYGON(((243605.4 6866632.3,243597.1 6866635.2,243594.2 6866625.9,243598.8 6866624.7,243599.7 6866628.2,243603.7 6866627.2,243605.4 6866632.3)))
+BATIMENT0000000076280205 58.4000244140625 MULTIPOLYGON(((244066.9 6866516.1,244062.5 6866516.4,244060.5 6866502.3,244064.1 6866501.6,244066.9 6866516.1)))
+BATIMENT0000000074773720 23.05029296875 MULTIPOLYGON(((985569.2 6297259.8,985568.3 6297256.3,985574.3 6297254.6,985575.4 6297258.1,985569.2 6297259.8)))
+BATIMENT0000000074773719 21.91943359375 MULTIPOLYGON(((985417.1 6297463.7,985417.7 6297459.7,985423.1 6297460.5,985422.4 6297464.5,985417.1 6297463.7)))
+BATIMENT0000000074773752 63.57958984375 MULTIPOLYGON(((983968.2 6297288.1,983958.7 6297286.7,983959.4 6297280.3,983969.7 6297282,983968.2 6297288.1)))
+BATIMENT0000000074773751 52.38037109375 MULTIPOLYGON(((983977.9 6297286.7,983978.9 6297280.3,983986 6297281.9,983985.2 6297289.5,983977.9 6297286.7)))
+BATIMENT0000000074773801 11.7802734375 MULTIPOLYGON(((988813.7 6296783.9,988818.3 6296782.9,988818.9 6296785.3,988814.1 6296786.3,988813.7 6296783.9)))
+BATIMENT0000000074773800 10.71533203125 MULTIPOLYGON(((989365.1 6296848.3,989364.4 6296851.6,989361.2 6296851.1,989361.9 6296847.9,989365.1 6296848.3)))
+BATIMENT0000000044633032 37.68017578125 MULTIPOLYGON(((755313 6269623.4,755317.3 6269628.6,755321.5 6269626.7,755318.5 6269620.2,755313 6269623.4)))
+BATIMENT0000000035151700 489.9208984375 MULTIPOLYGON(((870034.8 6612599.1,870044.5 6612597.9,870050.1 6612637.4,870031.9 6612640.1,870031 6612629.9,870038.1 6612628.9,870034.8 6612599.1)))
+BATIMENT0000000070446729 176.0400390625 MULTIPOLYGON(((475026.4 6245226,475013.7 6245225.2,475012.8 6245238.8,475014.7 6245239.3,475025 6245240.2,475026.4 6245226)))
+BATIMENT0000000023427410 167.349975585938 MULTIPOLYGON(((132870.8 6844520.3,132873.6 6844537.3,132883.8 6844534.8,132879.2 6844517.8,132870.8 6844520.3)))
+BATIMENT0000000023427426 1358.41998291016 MULTIPOLYGON(((131737.4 6844692.8,131686.5 6844692.9,131685.8 6844676.2,131692.8 6844675.7,131693 6844657.9,131719.6 6844658,131719.7 6844675.3,131737.3 6844675.3,131737.4 6844692.8)))
+BATIMENT0000000023427421 1531.70013427734 MULTIPOLYGON(((131775.9 6844617.5,131776.8 6844630.4,131761.1 6844631.4,131762.1 6844671.8,131731.6 6844670.7,131732.8 6844661,131726.8 6844661,131727 6844653,131730.7 6844652.6,131731.3 6844647.9,131736.5 6844647,131737.6 6844629.1,131744.1 6844628.4,131745.2 6844622,131761.2 6844621.2,131761.4 6844617.1,131775.9 6844617.5)))
+BATIMENT0000000023423768 98.2298583984375 MULTIPOLYGON(((127856.1 6845558.7,127853.6 6845552.6,127857.8 6845552.1,127856.8 6845548.2,127863.4 6845546.4,127866.5 6845556.9,127856.1 6845558.7)))
+BATIMENT0000000023421730 279.559936523438 MULTIPOLYGON(((127832.5 6845577.5,127879.4 6845564.7,127880.6 6845569.6,127835.1 6845583.6,127832.5 6845577.5)))
+BATIMENT0000000023423751 137.239990234375 MULTIPOLYGON(((130672 6845191.3,130657.1 6845196.2,130653.7 6845188.2,130668.9 6845183.2,130672 6845191.3)))
+BATIMENT0000000023423738 190.119995117188 MULTIPOLYGON(((130974.4 6845291.6,130974.8 6845299.6,130964.4 6845300.3,130964.6 6845304.5,130955.9 6845305.1,130955 6845293.1,130974.4 6845291.6)))
+BATIMENT0000000023417587 340.2900390625 MULTIPOLYGON(((128425.3 6846539.7,128424.3 6846549,128409.7 6846544.1,128415.4 6846526.7,128439.8 6846532.3,128437.8 6846539.1,128426.1 6846535.5,128425.3 6846539.7)))
+BATIMENT0000000023417582 305.664978027344 MULTIPOLYGON(((128425.3 6846539.7,128454.2 6846549.6,128451 6846563.5,128444.8 6846561.3,128445.4 6846556,128424.3 6846549,128425.3 6846539.7)))
+BATIMENT0000000023417553 185.345092773438 MULTIPOLYGON(((129621.7 6846529,129622.1 6846534.1,129595.9 6846543.2,129593.9 6846535.7,129615 6846530.2,129621.7 6846529)))
+BATIMENT0000000023417562 253.680053710938 MULTIPOLYGON(((129675.4 6846600.4,129668.3 6846602.9,129669.4 6846612,129661.5 6846612.5,129660.8 6846603.6,129652.7 6846605.5,129651.2 6846597.8,129674.1 6846593.1,129675.4 6846600.4)))
+BATIMENT0000000023417572 413.930053710938 MULTIPOLYGON(((128925.4 6846639.3,128921.7 6846619.6,128939.4 6846614.8,128943.3 6846630.6,128947.1 6846630.3,128947.8 6846635.4,128925.4 6846639.3)))
+BATIMENT0000000073181915 105.695068359375 MULTIPOLYGON(((569316 6283667.6,569319.9 6283676.1,569330.2 6283670.5,569326.2 6283662.5,569316 6283667.6)))
+BATIMENT0000000044633026 91.08447265625 MULTIPOLYGON(((755689.8 6269594.4,755698.3 6269598.6,755701.3 6269592.8,755696.2 6269590.2,755698 6269586.6,755691.9 6269583.6,755690.2 6269587.9,755692.4 6269589.1,755689.8 6269594.4)))
+BATIMENT0000000044633029 51.1259765625 MULTIPOLYGON(((755694.4 6269605.7,755695.7 6269603.1,755690.1 6269599.1,755691.1 6269597,755686.3 6269594.7,755683.8 6269599.2,755694.4 6269605.7)))
+BATIMENT0000000044633038 44.78955078125 MULTIPOLYGON(((755655.9 6269561.2,755661.2 6269565,755665.3 6269560,755659.4 6269555.7,755655.9 6269561.2)))
+BATIMENT0000000064252520 57.955078125 MULTIPOLYGON(((558913.8 6930348.2,558911.4 6930356.9,558917.7 6930358.9,558919.9 6930350.5,558913.8 6930348.2)))
+BATIMENT0000000064252028 1812.66918945312 MULTIPOLYGON(((558828.6 6930972.5,558833.6 6930973.8,558837.1 6930964.1,558840.3 6930964.7,558841.3 6930961.1,558847 6930961.9,558845.1 6930967.6,558851.6 6930969.2,558854.6 6930962.9,558867.8 6930919.5,558875.9 6930893.9,558881.9 6930873,558884.4 6930864.9,558877.5 6930863,558875.3 6930871.2,558870.8 6930885.9,558864.8 6930885.1,558864.3 6930886.8,558847.5 6930883.1,558846.8 6930885.9,558842.9 6930885.4,558837.3 6930907,558843.3 6930908.4,558844 [...]
+BATIMENT0000000044633048 33.8349609375 MULTIPOLYGON(((755101.5 6269730.2,755105.1 6269730.1,755104.6 6269720.4,755101.2 6269720.6,755101.5 6269730.2)))
+BATIMENT0000000044633050 43.80029296875 MULTIPOLYGON(((755101.8 6269764.1,755103.5 6269755.9,755098.5 6269754.8,755096.6 6269763,755101.8 6269764.1)))
+BATIMENT0000000064251806 800.06982421875 MULTIPOLYGON(((558150.2 6931520.3,558172.8 6931524.6,558176.5 6931525.3,558189.5 6931527.8,558188.7 6931533.4,558187.3 6931533.4,558185.5 6931546.6,558192 6931547.7,558192.5 6931543.4,558195.4 6931543.4,558197.3 6931529.4,558201.8 6931529.2,558202.2 6931526.7,558207.4 6931527.5,558208.8 6931520.5,558199.7 6931518.1,558200.7 6931506.2,558198.7 6931505.9,558199.6 6931497.4,558194.8 6931496.5,558190.6 6931519.1,558157.5 6931514,558151.6 6931513.1,558 [...]
+BATIMENT0000000064252370 762.459228515625 MULTIPOLYGON(((558822.3 6931131.5,558831.3 6931133.4,558831.6 6931132.5,558834.6 6931122.4,558840.7 6931102,558853.3 6931105.8,558855.8 6931099.3,558843.6 6931096.1,558845.3 6931089.3,558849.7 6931090.1,558851 6931087,558858.6 6931088.8,558861.4 6931089.8,558860.8 6931092,558865.5 6931093.3,558869.1 6931077.3,558864.2 6931076.2,558863.6 6931080.4,558862.1 6931085.1,558859.8 6931084.8,558852.1 6931083.1,558837.9 6931079.1,558822.3 6931131.5)))
+BATIMENT0000000064252007 379.78515625 MULTIPOLYGON(((558828.6 6931514,558822.7 6931512.7,558816.9 6931511.5,558815.3 6931521.4,558813.8 6931521.1,558811.2 6931531.3,558812.2 6931531.7,558810.5 6931541.3,558822.2 6931544.1,558827.5 6931519.2,558828.6 6931514)))
+BATIMENT0000000220019322 176.419921875 MULTIPOLYGON(((602102.8 6937206.9,602084.9 6937198.4,602088.9 6937190.4,602106.2 6937198.3,602102.8 6937206.9)))
+BATIMENT0000000215899768 215.1455078125 MULTIPOLYGON(((862137 6747949,862144.2 6747936.3,862131.3 6747929.5,862123.8 6747942,862137 6747949)))
+BATIMENT0000000044492526 100.67919921875 MULTIPOLYGON(((757919.2 6314203,757926.8 6314197.7,757933 6314206.6,757925.3 6314211.9,757919.2 6314203)))
+BATIMENT0000000023415618 192.130065917969 MULTIPOLYGON(((129665.8 6847025.3,129668.6 6847017.4,129688.1 6847023.1,129684.7 6847033.5,129679.3 6847032.4,129679.1 6847029.8,129665.8 6847025.3)))
+BATIMENT0000000044633791 61.705078125 MULTIPOLYGON(((756096 6269245.9,756100.2 6269248,756106.6 6269237.8,756102.5 6269234.6,756096 6269245.9)))
+BATIMENT0000000076281102 109.809814453125 MULTIPOLYGON(((224982.3 6866624,224976.6 6866630.1,224967.5 6866621.8,224973.5 6866614.8,224982.3 6866624)))
+BATIMENT0000000042304145 84.860107421875 MULTIPOLYGON(((475098.6 6248896.5,475095.9 6248904,475085.8 6248901.1,475088.5 6248893.4,475098.6 6248896.5)))
+BATIMENT0000000220003765 24.2998046875 MULTIPOLYGON(((558179.2 6931558.4,558179.9 6931553.3,558175.4 6931552.6,558174.6 6931558,558179.2 6931558.4)))
+BATIMENT0000000220003764 34.704833984375 MULTIPOLYGON(((558830.6 6931423.4,558839 6931425.6,558840 6931421.7,558831.9 6931419.5,558830.6 6931423.4)))
+BATIMENT0000000010209104 134.02587890625 MULTIPOLYGON(((929027.8 6928527.2,929028.9 6928539.9,929019.1 6928541.2,929016.9 6928528.4,929027.8 6928527.2)))
+BATIMENT0000000217447617 276.1591796875 MULTIPOLYGON(((782942.6 6703217.2,782949.8 6703209.2,782962.7 6703220.7,782963.3 6703222.1,782947.2 6703233.9,782941.4 6703227.1,782946.9 6703222.1,782942.6 6703217.2)))
+BATIMENT0000000217447618 59.3056640625 MULTIPOLYGON(((782946.9 6703222.1,782941.4 6703227.1,782947.2 6703233.9,782936.4 6703224.2,782942.6 6703217.2,782946.9 6703222.1)))
+BATIMENT0000000217447619 189.13525390625 MULTIPOLYGON(((782955.6 6703241.7,782954 6703240.3,782947.2 6703233.9,782963.3 6703222.1,782963.5 6703222.7,782964.3 6703222.3,782969.1 6703226.8,782955.6 6703241.7)))
+BATIMENT0000000217447620 301.2646484375 MULTIPOLYGON(((782964.3 6703222.3,782962.7 6703220.7,782961 6703216.2,782962.4 6703215.4,782961.4 6703212.9,782960.2 6703213.6,782959.5 6703212.2,782961 6703211.6,782961.3 6703212.3,782983.1 6703202.6,782987.2 6703200.9,782987.3 6703201.2,782989.9 6703208.4,782990.6 6703210.3,782964.3 6703222.3)))
+BATIMENT0000000217447622 23.64013671875 MULTIPOLYGON(((782992.4 6703214.3,782990.6 6703210.3,782989.9 6703208.4,782991.7 6703207.5,782993.3 6703212.1,782999.1 6703209.2,783000 6703210.9,782992.4 6703214.3)))
+BATIMENT0000000217447624 15.71044921875 MULTIPOLYGON(((782991.7 6703207.5,782989.9 6703208.4,782987.3 6703201.2,782989.3 6703200.4,782991.7 6703207.5)))
+BATIMENT0000000217448189 533.66064453125 MULTIPOLYGON(((783971.6 6703322.7,783964.7 6703309.1,783989 6703296.3,783993.1 6703303.1,784001.8 6703298.7,784005.9 6703306.9,783971.6 6703322.7)))
+BATIMENT0000000018638048 56.364990234375 MULTIPOLYGON(((354203.6 6280152.6,354200.5 6280146.9,354208.7 6280143.1,354211.4 6280148.7,354203.6 6280152.6)))
+BATIMENT0000000217448193 18.5302734375 MULTIPOLYGON(((783975 6703212.4,783972.1 6703213.1,783970.4 6703207.2,783973.3 6703206.4,783975 6703212.4)))
+BATIMENT0000000217448098 796.18994140625 MULTIPOLYGON(((783394.4 6703171.8,783395.6 6703175.3,783380.1 6703181.9,783369.4 6703186.3,783359.2 6703160.1,783385.6 6703149.6,783390.8 6703162.3,783394.4 6703171.8)))
+BATIMENT0000000217448099 33.20947265625 MULTIPOLYGON(((783393 6703161.4,783390.8 6703162.3,783385.6 6703149.6,783387.9 6703148.7,783393 6703161.4)))
+BATIMENT0000000217448100 49.060546875 MULTIPOLYGON(((783398.5 6703176.6,783380.9 6703183.7,783380.1 6703181.9,783395.6 6703175.3,783394.4 6703171.8,783396.4 6703171,783398.5 6703176.6)))
+BATIMENT0000000217448159 4.64990234375 MULTIPOLYGON(((783428.6 6703139,783429.1 6703136.9,783431.2 6703137.3,783430.9 6703139.3,783428.6 6703139)))
+BATIMENT0000000217448104 55.63037109375 MULTIPOLYGON(((783275.6 6703360.8,783272.2 6703356.7,783280.8 6703349.9,783283.6 6703354.2,783275.6 6703360.8)))
+BATIMENT0000000217448230 6.8994140625 MULTIPOLYGON(((783848.9 6703242.3,783845.9 6703242.3,783845.9 6703240,783846.5 6703240,783848.9 6703240,783848.9 6703242.3)))
+BATIMENT0000000217448130 5.7998046875 MULTIPOLYGON(((783327.1 6703227.4,783325.8 6703225.8,783328.1 6703224,783329.3 6703225.5,783327.1 6703227.4)))
+BATIMENT0000000223445506 127.8154296875 MULTIPOLYGON(((987989 6716942.2,987994.6 6716931.4,987998.5 6716933.4,987999.2 6716932.2,988001.5 6716933.4,988000.9 6716934.6,988004.2 6716936.4,987999.8 6716944.7,987997.1 6716943.4,987995.7 6716946,987989 6716942.2)))
+BATIMENT0000000220003768 82.044921875 MULTIPOLYGON(((558681.4 6931509.7,558687.7 6931511.6,558685.5 6931523.1,558678.3 6931520.9,558681.4 6931509.7)))
+BATIMENT0000000073181914 98.22998046875 MULTIPOLYGON(((569287.9 6283681.1,569277.9 6283686.4,569281.8 6283694,569291.9 6283689,569287.9 6283681.1)))
+BATIMENT0000000041277519 48.224853515625 MULTIPOLYGON(((484771.1 6515334.5,484758.4 6515330.6,484767.5 6515325.8,484771.1 6515334.5)))
+BATIMENT0000000074773799 109.44482421875 MULTIPOLYGON(((998703.5 6296649.7,998697.5 6296652.6,998690.4 6296637.9,998696.4 6296634.9,998703.5 6296649.7)))
+BATIMENT0000000044635784 28.25048828125 MULTIPOLYGON(((756146.1 6268489.9,756150.8 6268496.3,756153.6 6268493.9,756148.8 6268487.7,756146.1 6268489.9)))
+BATIMENT0000000217450219 24.83544921875 MULTIPOLYGON(((793408.7 6705384.6,793408.7 6705386.1,793400.8 6705386.7,793400.4 6705383.7,793408.7 6705383,793408.7 6705384.6)))
+BATIMENT0000000217450223 188.49951171875 MULTIPOLYGON(((793408.2 6705374.5,793408.7 6705383,793400.4 6705383.7,793389.8 6705384.5,793389.9 6705387.5,793388.1 6705387.6,793387.7 6705384.6,793386.9 6705376.1,793393.9 6705375.5,793408.2 6705374.5)))
+BATIMENT0000000217450228 32.4501953125 MULTIPOLYGON(((793400.4 6705383.7,793400.8 6705386.7,793389.9 6705387.5,793389.8 6705384.5,793400.4 6705383.7)))
+BATIMENT0000000217450234 292.5302734375 MULTIPOLYGON(((793466.5 6705446.4,793466.3 6705449,793463.4 6705471.1,793453.5 6705470.2,793457 6705441.9,793457.1 6705441.2,793466.8 6705442,793466.5 6705446.4)))
+BATIMENT0000000217450243 239.06494140625 MULTIPOLYGON(((793437.9 6705271.8,793435.9 6705277.9,793433 6705278.1,793423.9 6705278.9,793412 6705283.3,793418.2 6705265.7,793437.9 6705271.8)))
+BATIMENT0000000217450244 341.90478515625 MULTIPOLYGON(((793417.6 6705296.1,793409.1 6705292.8,793412 6705283.3,793423.9 6705278.9,793433 6705278.1,793429.9 6705293.5,793428.5 6705300.6,793417.6 6705296.1)))
+BATIMENT0000000217450245 341.77490234375 MULTIPOLYGON(((793446.7 6705300.8,793443.9 6705306.9,793428.5 6705300.6,793429.9 6705293.5,793433 6705278.1,793435.9 6705277.9,793439.8 6705277.6,793446.7 6705300.8)))
+BATIMENT0000000217450246 344.755859375 MULTIPOLYGON(((793437.9 6705271.8,793458.8 6705278.3,793451.4 6705302.1,793446.7 6705300.8,793439.8 6705277.6,793435.9 6705277.9,793437.9 6705271.8)))
+BATIMENT0000000217450247 131.4306640625 MULTIPOLYGON(((793411 6705308.9,793402.3 6705304.8,793409.1 6705292.8,793417.6 6705296.1,793411 6705308.9)))
+BATIMENT0000000217450248 322.59033203125 MULTIPOLYGON(((793424.2 6705322.4,793428.5 6705300.6,793443.9 6705306.9,793435.3 6705328,793424.2 6705322.4)))
+BATIMENT0000000074773942 50.625 MULTIPOLYGON(((1003417.7 6296449,1003411.1 6296441.3,1003415.2 6296437.9,1003421.1 6296445.2,1003417.7 6296449)))
+BATIMENT0000000074773941 30.8095703125 MULTIPOLYGON(((1003503.8 6296345.3,1003501.4 6296338.3,1003505 6296336.8,1003508 6296342.9,1003503.8 6296345.3)))
+BATIMENT0000000219854336 111.544921875 MULTIPOLYGON(((851692.7 6687302.3,851699.4 6687297.8,851702.5 6687302.4,851702.7 6687302.3,851702.9 6687302.2,851707.2 6687308.7,851700.1 6687313.4,851692.7 6687302.3)))
+BATIMENT0000000035054342 2365.25341796875 MULTIPOLYGON(((854085.9 6646188.4,854091.5 6646195.3,854112.7 6646221.6,854107.9 6646229.1,854085 6646201.4,854079.8 6646206,854084.9 6646211.6,854081.5 6646215,854087.5 6646222.2,854080.4 6646227.5,854075.1 6646221.4,854071.7 6646225.1,854072.6 6646226.6,854067.1 6646230.3,854061.2 6646223.7,854058.7 6646226,854067.3 6646235,854062.1 6646239,854059 6646235.3,854050.6 6646241.6,854042 6646231.5,854044.3 6646225.6,854079.5 6646195.2,854078.5 66461 [...]
+BATIMENT0000000217450249 268.53466796875 MULTIPOLYGON(((793424.2 6705322.4,793414.7 6705317.8,793417.4 6705312,793411 6705308.9,793417.6 6705296.1,793428.5 6705300.6,793424.2 6705322.4)))
+BATIMENT0000000217450251 664.2705078125 MULTIPOLYGON(((793354.8 6705170.9,793358.7 6705128.9,793374.4 6705130.4,793370.5 6705172.3,793354.8 6705170.9)))
+BATIMENT0000000217450265 147.21044921875 MULTIPOLYGON(((793407.5 6705589.1,793397.8 6705589.4,793397.7 6705575.3,793400.1 6705575.2,793400.1 6705573.7,793407.4 6705573.7,793407.5 6705589.1)))
+BATIMENT0000000035054334 22.3349609375 MULTIPOLYGON(((854345 6646148.8,854342 6646145,854345.5 6646142.1,854348.6 6646145.9,854345 6646148.8)))
+BATIMENT0000000004340656 1962.10205078125 MULTIPOLYGON(((664296.3 6854779.7,664298.4 6854784.6,664311 6854814.2,664325.8 6854809.3,664331.3 6854807,664339.7 6854803.3,664341.6 6854808.8,664336.1 6854812,664325.3 6854816.1,664325.1 6854814.4,664318.2 6854816.3,664318.5 6854818.6,664305.3 6854823.2,664306.6 6854826.4,664307.8 6854828.9,664311.4 6854826.9,664320.8 6854848.6,664310.1 6854854.3,664317.4 6854871.7,664308.3 6854875.5,664300.6 6854858.1,664296.1 6854848.4,664302.9 6854845.5,6642 [...]
+BATIMENT0000000202574990 95.014892578125 MULTIPOLYGON(((417415.2 6866913.9,417408.8 6866909.7,417415.9 6866899.4,417422.2 6866903.6,417415.2 6866913.9)))
+BATIMENT0000000023408130 339.439880371094 MULTIPOLYGON(((130019.1 6848392.4,130018.3 6848384.2,130014.7 6848384.4,130013.7 6848374.4,130016.7 6848374.1,130016.2 6848368.1,130031.1 6848366.6,130031.9 6848373.2,130029.1 6848373.5,130030.6 6848390.2,130019.1 6848392.4)))
+BATIMENT0000000023410595 579.93994140625 MULTIPOLYGON(((128574.6 6847815.6,128547.2 6847817.5,128545.1 6847796.9,128573.1 6847794.6,128574.6 6847815.6)))
+BATIMENT0000000023410549 546.690002441406 MULTIPOLYGON(((129195.1 6847821.9,129172 6847832.3,129163 6847812.4,129186.4 6847802.5,129195.1 6847821.9)))
+BATIMENT0000000023410548 395.440063476562 MULTIPOLYGON(((129163.9 6847790.4,129169 6847805.2,129145.5 6847813.9,129140.2 6847799,129163.9 6847790.4)))
+BATIMENT0000000023413383 370.77001953125 MULTIPOLYGON(((129073.4 6847586.6,129071.4 6847601.6,129047.5 6847599.7,129048.8 6847584.4,129073.4 6847586.6)))
+BATIMENT0000000023413513 182.035095214844 MULTIPOLYGON(((128073.9 6847452.9,128069.6 6847453.4,128067.3 6847444,128085.2 6847439,128087.9 6847447.2,128073.9 6847452.9)))
+BATIMENT0000000023413354 405.349975585938 MULTIPOLYGON(((129000.7 6847551.3,128980.1 6847549,128981.3 6847529.9,129002.3 6847531.7,129000.7 6847551.3)))
+BATIMENT0000000023410553 997.314819335938 MULTIPOLYGON(((129163.5 6847763.7,129167.9 6847776.4,129172.2 6847774.5,129176.1 6847784.2,129178.5 6847783.4,129185.9 6847800.4,129174.6 6847805,129167.6 6847788.2,129169.6 6847787.2,129165.2 6847777.8,129160.3 6847779,129163.4 6847787.5,129139.5 6847796.9,129131.1 6847775.7,129163.5 6847763.7)))
+BATIMENT0000000023410566 276.984924316406 MULTIPOLYGON(((128830 6847991.8,128821.6 6847984.5,128838.7 6847965.5,128846.6 6847972.6,128830 6847991.8)))
+BATIMENT0000000023410570 537.110046386719 MULTIPOLYGON(((128849.5 6848029.7,128838.3 6848025.6,128853 6847982.8,128864.1 6847986.8,128849.5 6848029.7)))
+BATIMENT0000000023408128 453.0849609375 MULTIPOLYGON(((130329.3 6848025.9,130347 6848021.9,130351.4 6848047.1,130334.8 6848051.2,130329.3 6848025.9)))
+BATIMENT0000000023410554 1958.5048828125 MULTIPOLYGON(((128903.7 6847904.5,128899.1 6847911.2,128913.1 6847924,128914.1 6847921.1,128920.8 6847923.9,128911.6 6847946.1,128909.1 6847945.3,128907.5 6847947.8,128896.6 6847971,128881.3 6847964.3,128891.4 6847942.3,128882.3 6847933.8,128881.1 6847934.7,128869 6847923.9,128886.4 6847903.2,128873.5 6847894.1,128880.6 6847884.8,128903.7 6847904.5)))
+BATIMENT0000000023410578 1026.12487792969 MULTIPOLYGON(((128822.8 6847951.1,128850 6847920.5,128864.1 6847933.1,128852.3 6847948.1,128861.2 6847957.3,128850.2 6847970,128838.9 6847961,128837.1 6847963,128822.8 6847951.1)))
+BATIMENT0000000023405871 702.369995117188 MULTIPOLYGON(((130818.6 6848524.4,130801.6 6848527.3,130800.9 6848523.8,130797 6848503.8,130811.4 6848500.4,130810.4 6848491,130818.7 6848490.4,130827.3 6848522.9,130818.6 6848524.4)))
+BATIMENT0000000074773940 52.46044921875 MULTIPOLYGON(((1003487.9 6296351.7,1003479.9 6296350.2,1003480.7 6296344.1,1003488.4 6296344.6,1003487.9 6296351.7)))
+BATIMENT0000000076282154 123.009887695312 MULTIPOLYGON(((244186.6 6866217.7,244176.1 6866219.8,244175.3 6866206.7,244184.7 6866206.4,244186.6 6866217.7)))
+BATIMENT0000000076282153 126.25 MULTIPOLYGON(((244199.9 6866242.9,244194 6866240.6,244192.4 6866243.6,244189.7 6866242.7,244184.9 6866252.5,244192.8 6866256.7,244199.9 6866242.9)))
+BATIMENT0000000076282152 198.285034179688 MULTIPOLYGON(((244508.8 6866249.7,244507.5 6866256.3,244503.9 6866255.5,244503.4 6866258,244491.8 6866256,244492.6 6866252.9,244484.6 6866251,244486 6866243.9,244508.8 6866249.7)))
+BATIMENT0000000023405860 443.744934082031 MULTIPOLYGON(((131469.7 6848645,131472.2 6848625.7,131495.1 6848628.9,131492.3 6848647.9,131469.7 6848645)))
+BATIMENT0000000023405880 403.645080566406 MULTIPOLYGON(((130628.6 6848656.4,130612.3 6848659.7,130608.7 6848639.8,130628.4 6848635.6,130631.5 6848655.8,130628.6 6848656.4)))
+BATIMENT0000000023405882 353.694885253906 MULTIPOLYGON(((130483.4 6848646,130480.1 6848666.3,130462.8 6848662.9,130466.4 6848643.2,130483.4 6848646)))
+BATIMENT0000000023403719 728.854919433594 MULTIPOLYGON(((130275.3 6849014.8,130303.2 6849015.2,130302.8 6849041.6,130274.9 6849040.7,130275.1 6849032.7,130275.3 6849014.8)))
+BATIMENT0000000023403718 785 MULTIPOLYGON(((130351.2 6849050.3,130377.6 6849051.4,130377.6 6849079.9,130349.8 6849079.7,130351.2 6849050.3)))
+BATIMENT0000000023403716 1383.03497314453 MULTIPOLYGON(((130314.4 6849031.4,130347.2 6849033.6,130347.5 6849041.6,130345.2 6849041.8,130344.5 6849077.8,130320.5 6849077,130319.9 6849071.4,130313 6849071.3,130314.4 6849031.4)))
+BATIMENT0000000023403707 428.339904785156 MULTIPOLYGON(((131168.6 6848997,131175.6 6848996.1,131176.6 6849005.1,131184.2 6849004.4,131186.6 6849026,131186.8 6849027.4,131181.7 6849027.9,131181.4 6849025,131174.2 6849025.7,131174.5 6849028.4,131170.2 6849028.9,131167.3 6849006.8,131170.1 6849005.9,131168.6 6848997)))
+BATIMENT0000000023405856 507.029968261719 MULTIPOLYGON(((131588.8 6848694.8,131609 6848698.6,131605.8 6848719.5,131600.1 6848719.8,131599.7 6848722.9,131584.7 6848719.9,131588.8 6848694.8)))
+BATIMENT0000000069853458 49.6500244140625 MULTIPOLYGON(((129325.6 6847609.7,129330.7 6847615.4,129335.6 6847611.1,129330.2 6847605.4,129325.6 6847609.7)))
+BATIMENT0000000069853459 19.5199584960938 MULTIPOLYGON(((129427 6847541.1,129425 6847544,129428.1 6847546.1,129429.2 6847544.4,129431.8 6847546.1,129432.8 6847544.3,129427 6847541.1)))
+BATIMENT0000000069853460 102.81005859375 MULTIPOLYGON(((127736.2 6848323.6,127736.3 6848331.6,127749.1 6848331.4,127749.2 6848324,127745.2 6848324.3,127745.3 6848323,127740.7 6848322.8,127740.5 6848323.7,127736.2 6848323.6)))
+BATIMENT0000000069853461 118.145080566406 MULTIPOLYGON(((131551 6848858,131557.2 6848860.8,131552.6 6848870.8,131555.1 6848871.8,131553 6848876.6,131546.3 6848875,131546.1 6848871.1,131551 6848858)))
+BATIMENT0000000069853462 124.015075683594 MULTIPOLYGON(((127707.9 6848322.5,127708.4 6848331,127722.5 6848330.8,127722.1 6848321.8,127707.9 6848322.5)))
+BATIMENT0000000069853463 136.960021972656 MULTIPOLYGON(((128622.4 6847450.1,128618.3 6847460.2,128619.5 6847460.7,128617.7 6847465.3,128624.5 6847468.3,128626.5 6847463.9,128630.8 6847453.4,128622.4 6847450.1)))
+BATIMENT0000000069853464 20.0750732421875 MULTIPOLYGON(((129404.3 6847543.4,129404.3 6847548.8,129408 6847549,129408.1 6847543.7,129404.3 6847543.4)))
+BATIMENT0000000069853465 158.610046386719 MULTIPOLYGON(((129373.2 6847535.8,129373.6 6847544.2,129384 6847543.9,129383.7 6847549.7,129390.9 6847549.7,129390.9 6847543,129384.8 6847542.6,129384.7 6847536.1,129383.5 6847536,129383.3 6847531.8,129379.3 6847531.8,129379.4 6847535.3,129373.2 6847535.8)))
+BATIMENT0000000069853466 21.1650390625 MULTIPOLYGON(((128555.1 6847584.2,128556 6847588.5,128560.8 6847587.9,128560.2 6847583.8,128555.1 6847584.2)))
+BATIMENT0000000069853467 26.3500366210938 MULTIPOLYGON(((128585.6 6847464.3,128582.5 6847469,128586.4 6847471.6,128589.5 6847467,128585.6 6847464.3)))
+BATIMENT0000000069853468 26.0999755859375 MULTIPOLYGON(((128580.5 6847439.4,128580.6 6847443.2,128587.6 6847442.9,128587.4 6847439.2,128580.5 6847439.4)))
+BATIMENT0000000069853469 15.7200317382812 MULTIPOLYGON(((129314.2 6847541.9,129312.9 6847545.4,129317.2 6847546.7,129318.2 6847543.4,129314.2 6847541.9)))
+BATIMENT0000000069853470 54.489990234375 MULTIPOLYGON(((127407.4 6847723.1,127412.8 6847724.9,127410.4 6847733.7,127404.5 6847731.9,127407.4 6847723.1)))
+BATIMENT0000000069853471 154.234985351562 MULTIPOLYGON(((127449.1 6847652.4,127459.2 6847658.9,127467.4 6847644.9,127460.8 6847640.5,127455.2 6847649.1,127452.6 6847647.6,127449.1 6847652.4)))
+BATIMENT0000000069853472 22.81494140625 MULTIPOLYGON(((128552.5 6847341.2,128552.5 6847345.3,128558.5 6847345.1,128558.2 6847341.4,128552.5 6847341.2)))
+BATIMENT0000000069853473 41.4450073242188 MULTIPOLYGON(((127252.8 6847940.8,127252.6 6847946,127260.3 6847946.5,127260.3 6847940.8,127252.8 6847940.8)))
+BATIMENT0000000069853474 107.905029296875 MULTIPOLYGON(((127490.6 6847618.5,127487 6847625.7,127488 6847626.2,127486.3 6847629.6,127493.8 6847633.6,127498.9 6847623.1,127490.6 6847618.5)))
+BATIMENT0000000069853475 116.830078125 MULTIPOLYGON(((128250.5 6847488.4,128253.9 6847493.6,128256.9 6847491.5,128258.6 6847494.3,128262.3 6847491.9,128260.6 6847488.5,128267.8 6847483.6,128264.7 6847478.8,128250.5 6847488.4)))
+BATIMENT0000000069853476 24.0750122070312 MULTIPOLYGON(((129417.8 6847541.5,129417.5 6847545.6,129423.2 6847546,129423.4 6847541.6,129417.8 6847541.5)))
+BATIMENT0000000069853477 142.919982910156 MULTIPOLYGON(((128248.6 6847408.3,128245.3 6847402.1,128259.7 6847395.3,128259.1 6847394.2,128264.1 6847392.2,128266.3 6847396.6,128262.1 6847398.7,128263.4 6847401.7,128248.6 6847408.3)))
+BATIMENT0000000069853478 20.2451171875 MULTIPOLYGON(((129653.5 6847561.7,129653.2 6847565.4,129659.1 6847565.4,129659.3 6847562.2,129653.5 6847561.7)))
+BATIMENT0000000069853479 148.044921875 MULTIPOLYGON(((127776.5 6848353.6,127776.9 6848357.4,127778.8 6848357.1,127780.3 6848365,127775.5 6848365.9,127776 6848369.8,127768.6 6848370.8,127766.9 6848359.5,127771.6 6848358.7,127771.2 6848354.1,127776.5 6848353.6)))
+BATIMENT0000000069853480 85.1452026367188 MULTIPOLYGON(((128536.8 6847513.2,128536 6847516.3,128533.3 6847523.8,128535.2 6847524.5,128534.1 6847527.1,128537.9 6847528.2,128538.9 6847525.8,128539.9 6847526.1,128542.5 6847517.7,128541.1 6847517.4,128542.2 6847514.3,128536.8 6847513.2)))
+BATIMENT0000000069853481 97.77001953125 MULTIPOLYGON(((129611.3 6847905.9,129609.9 6847911.2,129617.4 6847912.8,129617 6847914.9,129622.3 6847915.9,129624.3 6847906.9,129615.5 6847905.2,129615.1 6847906.5,129611.3 6847905.9)))
+BATIMENT0000000069853482 263.819885253906 MULTIPOLYGON(((129773.1 6847571.9,129779.8 6847571.6,129779.5 6847576,129782.5 6847576.3,129782.3 6847581.5,129802.3 6847584.1,129801.4 6847590.7,129782.1 6847588,129782.4 6847586.5,129778.1 6847586,129770.9 6847585.1,129773.1 6847571.9)))
+BATIMENT0000000014186755 52.499755859375 MULTIPOLYGON(((505874.9 6886677.4,505879.5 6886672.6,505885.3 6886677.5,505879.9 6886682.7,505874.9 6886677.4)))
+BATIMENT0000000202131128 14.695068359375 MULTIPOLYGON(((501242.1 6886837.1,501236.3 6886836.9,501236.5 6886834.4,501242 6886834.4,501242.1 6886837.1)))
+BATIMENT0000000045990077 130.625 MULTIPOLYGON(((674058.8 7048291.8,674055.1 7048272.1,674061.2 7048270.7,674065.4 7048290.4,674058.8 7048291.8)))
+BATIMENT0000000202131129 91.905029296875 MULTIPOLYGON(((501405.8 6886772.8,501400.5 6886775.8,501392.6 6886762.5,501397.2 6886759.3,501405.8 6886772.8)))
+BATIMENT0000000069853483 58.965087890625 MULTIPOLYGON(((128164.4 6847592.4,128167.5 6847589.4,128173.9 6847595.7,128175.2 6847594.9,128178.2 6847598.8,128176.6 6847600.1,128174.7 6847598.2,128171.9 6847600.2,128164.4 6847592.4)))
+BATIMENT0000000069853484 64.6499633789062 MULTIPOLYGON(((128073 6847473.3,128071.9 6847468.9,128086.2 6847466,128086.9 6847470.4,128073 6847473.3)))
+BATIMENT0000000069853485 79.5150756835938 MULTIPOLYGON(((127903.4 6847355.6,127901.6 6847362.1,127913.1 6847365,127914.7 6847358.4,127903.4 6847355.6)))
+BATIMENT0000000069853486 17.7099609375 MULTIPOLYGON(((128423.8 6847559.7,128423.1 6847563.1,128427.9 6847564.5,128428.6 6847560.9,128423.8 6847559.7)))
+BATIMENT0000000069853487 54.050048828125 MULTIPOLYGON(((128203.2 6847301.8,128195.1 6847303.1,128196.4 6847309.6,128204.6 6847308.1,128203.2 6847301.8)))
+BATIMENT0000000069853488 39.5599365234375 MULTIPOLYGON(((127407.7 6847580.4,127412.3 6847579.7,127410.5 6847571.1,127405.9 6847572.7,127407.7 6847580.4)))
+BATIMENT0000000069853489 25.6799926757812 MULTIPOLYGON(((128308.9 6847529.3,128303 6847530.8,128304.7 6847535.1,128309.9 6847533.5,128308.9 6847529.3)))
+BATIMENT0000000069853490 148.425109863281 MULTIPOLYGON(((128364.4 6847448,128368 6847460.7,128375.2 6847458.9,128373.8 6847452.9,128380.4 6847450.9,128378.4 6847444.6,128369.2 6847446.9,128368.9 6847446.1,128364.4 6847448)))
+BATIMENT0000000069853491 243.274963378906 MULTIPOLYGON(((127788.8 6848322.9,127781.1 6848322.5,127781.2 6848323.6,127771.5 6848323.4,127771.4 6848325.9,127767.4 6848326,127767.4 6848332.2,127779.8 6848332.1,127779.5 6848340,127787.7 6848339.9,127788.8 6848322.9)))
+BATIMENT0000000069853492 96.3099975585938 MULTIPOLYGON(((127728.3 6847388.6,127727 6847382.1,127742.3 6847384.3,127742 6847387,127744 6847387.5,127743.3 6847390.7,127728.3 6847388.6)))
+BATIMENT0000000069853493 19.784912109375 MULTIPOLYGON(((128273.1 6847546.7,128274.8 6847550.6,128279 6847548.9,128277.5 6847544.9,128273.1 6847546.7)))
+BATIMENT0000000069853494 19.1099853515625 MULTIPOLYGON(((126978 6848113.3,126982.2 6848114.2,126981.9 6848118.1,126977 6848117.6,126978 6848113.3)))
+BATIMENT0000000069853495 117.375061035156 MULTIPOLYGON(((129528.3 6847858.1,129526.1 6847867.2,129538 6847869.7,129540.4 6847860.1,129528.3 6847858.1)))
+BATIMENT0000000069853496 134.324951171875 MULTIPOLYGON(((129468.7 6847664.5,129470.5 6847672.5,129466 6847673,129466.7 6847677.7,129457.5 6847679,129456.3 6847669.9,129460.8 6847669.3,129460.5 6847665.8,129468.7 6847664.5)))
+BATIMENT0000000069853497 46.25 MULTIPOLYGON(((129618.5 6847918,129623.7 6847919.4,129622 6847927.3,129616.2 6847925.9,129618.5 6847918)))
+BATIMENT0000000069853498 32.6299438476562 MULTIPOLYGON(((129211.9 6847479,129214.2 6847485.4,129218.7 6847483.7,129216.8 6847477.6,129211.9 6847479)))
+BATIMENT0000000069853499 90.1199340820312 MULTIPOLYGON(((127174.1 6847749.8,127181.3 6847750.9,127178.7 6847763.4,127171.7 6847761.7,127174.1 6847749.8)))
+BATIMENT0000000069853500 349.700012207031 MULTIPOLYGON(((128869 6847923.9,128882.7 6847907.5,128870.1 6847897.3,128856.2 6847912.5,128869 6847923.9)))
+BATIMENT0000000069853501 44.5149536132812 MULTIPOLYGON(((127347.4 6847410.1,127346.8 6847412.6,127349.6 6847413.8,127348.7 6847417,127353.4 6847419,127355.9 6847412.4,127347.4 6847410.1)))
+BATIMENT0000000069853502 53.2449951171875 MULTIPOLYGON(((128506.4 6848126,128509 6848132.3,128516.4 6848129.3,128514.3 6848123.4,128506.4 6848126)))
+BATIMENT0000000069853503 24.6799926757812 MULTIPOLYGON(((128030.2 6847454.2,128026.5 6847455.9,128029.4 6847461.4,128032.9 6847460,128030.2 6847454.2)))
+BATIMENT0000000069853504 41.6849365234375 MULTIPOLYGON(((127683.4 6847651.3,127690.6 6847654.5,127688.6 6847659.2,127681.1 6847656.1,127683.4 6847651.3)))
+BATIMENT0000000069853505 31.89501953125 MULTIPOLYGON(((129270.3 6847363.7,129267.1 6847360.9,129272 6847355.3,129275.2 6847358.4,129270.3 6847363.7)))
+BATIMENT0000000069853506 16.2799682617188 MULTIPOLYGON(((129306.5 6847540.8,129306.6 6847544.4,129310.9 6847544.4,129311 6847540.6,129306.5 6847540.8)))
+BATIMENT0000000069853507 66.7999877929688 MULTIPOLYGON(((128063.8 6847455.2,128068.6 6847454,128071.8 6847468,128067.6 6847469.1,128063.8 6847455.2)))
+BATIMENT0000000069853508 33.2549438476562 MULTIPOLYGON(((127285.4 6847620.6,127290.6 6847619.8,127289.7 6847613.6,127284.6 6847614.1,127285.4 6847620.6)))
+BATIMENT0000000069853509 48.074951171875 MULTIPOLYGON(((127595.5 6848140.9,127597 6848148.4,127603 6848147.1,127601.5 6848139.3,127595.5 6848140.9)))
+BATIMENT0000000069853510 35.9249877929688 MULTIPOLYGON(((127209.6 6847721.2,127214.4 6847722.4,127213.1 6847729.7,127208.5 6847728.6,127209.6 6847721.2)))
+BATIMENT0000000069853511 64.1600341796875 MULTIPOLYGON(((129832.1 6847461.2,129831.8 6847463.7,129829.4 6847463.4,129829 6847465.9,129837.5 6847466.9,129837.3 6847469,129841.5 6847469.3,129842.2 6847462.8,129832.1 6847461.2)))
+BATIMENT0000000069853512 75.4751586914062 MULTIPOLYGON(((127757.9 6847351.3,127758.1 6847356.2,127771 6847355.9,127771.2 6847348,127766.3 6847348.2,127766.3 6847351.8,127757.9 6847351.3)))
+BATIMENT0000000069853513 145.759948730469 MULTIPOLYGON(((127758.8 6847464.8,127758.1 6847472.6,127763.3 6847472.8,127762.8 6847478,127770.7 6847478.5,127770.6 6847470.1,127772.2 6847470.1,127772.3 6847465,127758.8 6847464.8)))
+BATIMENT0000000069853514 39.2249755859375 MULTIPOLYGON(((128213.6 6847421.4,128214.9 6847424.1,128227.3 6847418.1,128226 6847415.7,128213.6 6847421.4)))
+BATIMENT0000000069853515 48.6300048828125 MULTIPOLYGON(((127257.5 6847612.3,127257 6847606.9,127266.1 6847606.2,127266.6 6847611.4,127257.5 6847612.3)))
+BATIMENT0000000069853516 353.729858398438 MULTIPOLYGON(((127704.5 6847329.2,127706.2 6847331.4,127703.2 6847334.6,127716.5 6847346.1,127715.7 6847347.1,127723.4 6847353.4,127719.9 6847357.9,127715.1 6847362.3,127710.9 6847365.3,127706.2 6847362.1,127714.5 6847356.6,127715.3 6847355.3,127694.5 6847338.8,127690.1 6847334.8,127695.7 6847330.6,127698.3 6847333.6,127704.5 6847329.2)))
+BATIMENT0000000069853517 253.240051269531 MULTIPOLYGON(((129510.8 6847625.6,129512.8 6847636.5,129510.6 6847637.2,129507.1 6847641.2,129507.5 6847644.4,129496.4 6847647,129494.5 6847635.8,129496.3 6847635.4,129495.5 6847632.5,129500.3 6847631,129499.9 6847628.4,129510.8 6847625.6)))
+BATIMENT0000000069853518 38.8799438476562 MULTIPOLYGON(((127611.5 6847598.7,127610.3 6847601.8,127618.1 6847604.1,127619 6847600.7,127616.7 6847599.9,127617.5 6847597.2,127613.8 6847596.3,127613 6847598.8,127611.5 6847598.7)))
+BATIMENT0000000069853519 91.4550170898438 MULTIPOLYGON(((128268.4 6847472.6,128269.5 6847479.4,128276.1 6847478.4,128276.3 6847480.6,128281.1 6847479.9,128279.3 6847470.3,128268.4 6847472.6)))
+BATIMENT0000000069853520 314.630004882812 MULTIPOLYGON(((127633.8 6847521.3,127632.5 6847526,127633.5 6847526.1,127631.7 6847532.9,127638.7 6847534.5,127638.4 6847535.4,127645.2 6847537.2,127645.7 6847535.8,127663.4 6847540.1,127665.3 6847531.8,127646.8 6847527.5,127641.8 6847526.8,127642.3 6847522.5,127633.8 6847521.3)))
+BATIMENT0000000069853521 134.315002441406 MULTIPOLYGON(((127772.9 6847346.9,127771.6 6847359.4,127778.2 6847360.3,127777.6 6847362.7,127782.4 6847363.4,127783.5 6847356.9,127780.7 6847356.4,127781.8 6847348,127772.9 6847346.9)))
+BATIMENT0000000069853522 536.384887695312 MULTIPOLYGON(((127917.7 6847358.5,127915.5 6847365.4,127918.4 6847366.4,127916 6847375,127916.8 6847375.4,127912.9 6847386.6,127911.8 6847391,127913.7 6847391.7,127910.6 6847399,127913.1 6847400.1,127916.1 6847393.1,127919.6 6847394.4,127917.1 6847401.9,127921.1 6847403.3,127923.5 6847395.8,127926.1 6847396.8,127928.3 6847390.5,127918.6 6847386.8,127921.9 6847377,127924.5 6847368.7,127927.9 6847369.5,127926.1 6847376.5,127924.8 6847375.9,127921.9 [...]
+BATIMENT0000000069853523 34.2350463867188 MULTIPOLYGON(((129769.1 6847590,129768.4 6847594.1,129776.4 6847595.5,129777 6847591.2,129769.1 6847590)))
+BATIMENT0000000069853524 54.1749267578125 MULTIPOLYGON(((128247.3 6847573.7,128247.8 6847576.7,128250.4 6847576.6,128250.7 6847579.8,128258.4 6847579.5,128258.1 6847574.3,128254.8 6847574.6,128254.3 6847573.1,128247.3 6847573.7)))
+BATIMENT0000000069853525 265.52001953125 MULTIPOLYGON(((127945.5 6847511,127942.8 6847543.7,127948.5 6847544,127949.4 6847532.4,127953.3 6847532.8,127954.7 6847511.4,127945.5 6847511)))
+BATIMENT0000000069853526 100.534912109375 MULTIPOLYGON(((127407.7 6847580.4,127403.1 6847581.9,127403.6 6847583.9,127399.2 6847585,127398.6 6847582.9,127395.2 6847579.6,127394.4 6847575.8,127405.9 6847572.7,127407.7 6847580.4)))
+BATIMENT0000000069853527 117.655029296875 MULTIPOLYGON(((128003 6847457.5,128002.5 6847449.4,128016.4 6847447.6,128017.2 6847456.1,128003 6847457.5)))
+BATIMENT0000000069853528 122.375061035156 MULTIPOLYGON(((127207.6 6848080.7,127209 6848091.1,127218.3 6848090,127217.6 6848082.7,127219.1 6848082.4,127218 6848076.2,127213.4 6848077,127213.6 6848079.1,127207.6 6848080.7)))
+BATIMENT0000000069853529 95.9949340820312 MULTIPOLYGON(((126972.5 6848125,126971.7 6848130.8,126985.4 6848132.4,126985.8 6848130.3,126991.5 6848130,126991.3 6848127,126986.8 6848127,126972.5 6848125)))
+BATIMENT0000000069853530 25.679931640625 MULTIPOLYGON(((128545.9 6847401.7,128545.2 6847406.7,128550.1 6847407.1,128550.9 6847401.8,128545.9 6847401.7)))
+BATIMENT0000000069853531 24.6651000976562 MULTIPOLYGON(((128569.5 6847568.4,128570 6847564.3,128575.6 6847564.2,128575.5 6847568.6,128569.5 6847568.4)))
+BATIMENT0000000069853532 21.5449829101562 MULTIPOLYGON(((127716.1 6847423.1,127715.3 6847419.5,127720.9 6847417.8,127721.8 6847421.3,127716.1 6847423.1)))
+BATIMENT0000000069853533 122.865051269531 MULTIPOLYGON(((127895.3 6847537.3,127894.8 6847539.6,127891.5 6847538.8,127890.5 6847542,127893.2 6847542.8,127891.6 6847548.9,127902.3 6847551.6,127904 6847545.1,127900.7 6847544.2,127902 6847539.1,127895.3 6847537.3)))
+BATIMENT0000000069853534 70.715087890625 MULTIPOLYGON(((127691 6848518.5,127696.9 6848517.1,127695.9 6848511.7,127699.4 6848511.5,127700.9 6848522.3,127692 6848524,127691 6848518.5)))
+BATIMENT0000000069853535 48.385009765625 MULTIPOLYGON(((128609.8 6847523.1,128615 6847528.8,128619.5 6847525.1,128614.4 6847518.7,128609.8 6847523.1)))
+BATIMENT0000000069853536 30.6749877929688 MULTIPOLYGON(((127439.8 6847829.6,127437.9 6847833.6,127444.3 6847836.2,127445.9 6847831.7,127439.8 6847829.6)))
+BATIMENT0000000069853537 387.499877929688 MULTIPOLYGON(((130288.8 6849049.9,130287.8 6849071.1,130268.7 6849069.5,130270 6849049.9,130288.8 6849049.9)))
+BATIMENT0000000069853538 19.60498046875 MULTIPOLYGON(((128878.2 6847777,128875.6 6847777.5,128874.2 6847771.1,128877.5 6847770.5,128878.2 6847777)))
+BATIMENT0000000069853539 183.364929199219 MULTIPOLYGON(((129988.7 6848304.1,129990.4 6848334,129994.7 6848333.8,129995.3 6848341,129987.1 6848341.6,129984.3 6848304.9,129988.7 6848304.1)))
+BATIMENT0000000069853540 30.1600341796875 MULTIPOLYGON(((128527.8 6847281.2,128531 6847285,128535.6 6847281.4,128532.3 6847277.3,128527.8 6847281.2)))
+BATIMENT0000000069853541 20.864990234375 MULTIPOLYGON(((128453.1 6847561.2,128456.1 6847562.1,128455.1 6847568.3,128451.8 6847567.7,128453.1 6847561.2)))
+BATIMENT0000000069853542 22.0400390625 MULTIPOLYGON(((129246.3 6847391.2,129247.5 6847386.6,129251.9 6847388,129250.6 6847392.7,129246.3 6847391.2)))
+BATIMENT0000000069853543 25.2599487304688 MULTIPOLYGON(((127480.3 6847632.3,127485.8 6847635.4,127487.5 6847631.7,127482 6847628.7,127480.3 6847632.3)))
+BATIMENT0000000069853544 86.9549560546875 MULTIPOLYGON(((129805.8 6847571.6,129814.4 6847570.7,129815.1 6847580.9,129806.4 6847581.4,129805.8 6847571.6)))
+BATIMENT0000000069853545 29.5599975585938 MULTIPOLYGON(((129306 6847566,129306.1 6847572.1,129310.5 6847572.2,129310.7 6847565.3,129306 6847566)))
+BATIMENT0000000069853546 77.1449584960938 MULTIPOLYGON(((128531.7 6847521.2,128529.9 6847527.3,128518.3 6847523.9,128520.4 6847517.7,128531.7 6847521.2)))
+BATIMENT0000000069853547 37.9949951171875 MULTIPOLYGON(((127181.9 6847580.9,127185.4 6847587.7,127189.9 6847585.2,127186.7 6847578.9,127181.9 6847580.9)))
+BATIMENT0000000069853548 29.4149169921875 MULTIPOLYGON(((128458.1 6847552.7,128458.9 6847549,128466.8 6847551.3,128465.5 6847554.7,128458.1 6847552.7)))
+BATIMENT0000000069853549 31.3200073242188 MULTIPOLYGON(((128561.7 6847338.1,128561.7 6847344.4,128566.7 6847344,128566.3 6847337.3,128561.7 6847338.1)))
+BATIMENT0000000069853550 113.424987792969 MULTIPOLYGON(((128866.7 6847803.3,128885.4 6847803.8,128885 6847810.9,128881.1 6847810.5,128881.1 6847808.8,128873.1 6847808.3,128873.1 6847810.3,128866.1 6847809.9,128866.7 6847803.3)))
+BATIMENT0000000025218245 51.9449462890625 MULTIPOLYGON(((349412.2 6266327.2,349405.2 6266325.1,349407.7 6266318,349413.9 6266319.8,349412.2 6266327.2)))
+BATIMENT0000000012669526 342.45458984375 MULTIPOLYGON(((925123.3 6515132.5,925125.3 6515124.7,925108.9 6515121.6,925111 6515097.6,925103 6515097.1,925100.9 6515123.7,925108.2 6515124.4,925107.4 6515129.3,925123.3 6515132.5)))
+BATIMENT0000000023590199 660.360229492188 MULTIPOLYGON(((187961.1 6797686.7,187953.1 6797677.8,187945.1 6797681.5,187939.1 6797670.3,187938.5 6797667.9,187962.1 6797654.3,187963.4 6797656.1,187969.8 6797667.2,187975.7 6797678.6,187961.1 6797686.7)))
+BATIMENT0000000076283444 30.989990234375 MULTIPOLYGON(((253582.8 6865546,253584.6 6865543.5,253575.4 6865539.4,253574.2 6865542.6,253582.8 6865546)))
+BATIMENT0000000074773939 133.919921875 MULTIPOLYGON(((1003432.4 6296478.4,1003439.2 6296477.4,1003446.1 6296495.9,1003440.1 6296498.1,1003432.4 6296478.4)))
+BATIMENT0000000069853551 43.1650390625 MULTIPOLYGON(((128569.4 6847678.3,128574.4 6847677,128578.6 6847676.4,128577.3 6847671.8,128568.1 6847673.8,128569.4 6847678.3)))
+BATIMENT0000000069853552 137.27001953125 MULTIPOLYGON(((128460.1 6847539,128458.7 6847545.2,128473.9 6847549.6,128473.4 6847551.2,128478.5 6847552.4,128480.2 6847545.2,128460.1 6847539)))
+BATIMENT0000000069853553 124.775024414062 MULTIPOLYGON(((127480.5 6847555,127477.8 6847554,127475.5 6847558.8,127469.2 6847556,127470.2 6847553.9,127468.2 6847552.7,127471.4 6847546.3,127474.2 6847547.4,127477.4 6847545.1,127483.9 6847548.2,127480.5 6847555)))
+BATIMENT0000000069853554 71.8500366210938 MULTIPOLYGON(((127996.6 6847463.7,128001.6 6847463.1,128000 6847449.5,127995.2 6847450.1,127996.1 6847457.6,127994.4 6847457.7,127994.4 6847460.9,127996.7 6847460.6,127996.6 6847463.7)))
+BATIMENT0000000069853555 84.260009765625 MULTIPOLYGON(((127826.5 6847760.1,127834.5 6847760.2,127834 6847754,127839.9 6847753.5,127840.9 6847762.6,127827.2 6847764.2,127826.5 6847760.1)))
+BATIMENT0000000069853556 73.9500732421875 MULTIPOLYGON(((128231.9 6847383.2,128239.7 6847391.5,128245.3 6847386.2,128241.3 6847381.7,128238.9 6847383.1,128235.5 6847380.1,128231.9 6847383.2)))
+BATIMENT0000000069853557 96.9249267578125 MULTIPOLYGON(((129428.2 6847618.3,129427.1 6847625.7,129424.3 6847625.2,129423.7 6847632.2,129433.1 6847632.7,129434.1 6847626.6,129431.4 6847626,129432.9 6847619.1,129428.2 6847618.3)))
+BATIMENT0000000069853558 109.039855957031 MULTIPOLYGON(((127720.8 6848359.7,127721.3 6848368.7,127719.2 6848368.7,127719.4 6848372.3,127711.6 6848373.1,127711.3 6848368.8,127712.6 6848368.6,127711.9 6848360.1,127720.8 6848359.7)))
+BATIMENT0000000069853559 73.4500732421875 MULTIPOLYGON(((127901 6847708.3,127902 6847714.4,127897.8 6847715,127898.3 6847722.3,127904.3 6847720.9,127903.3 6847714.4,127907.2 6847713.5,127906.1 6847707.5,127901 6847708.3)))
+BATIMENT0000000069853560 135.275085449219 MULTIPOLYGON(((128728.5 6847521.1,128725.6 6847526.4,128723 6847525.5,128720.1 6847531.5,128722.8 6847532.8,128720.3 6847538.5,128725.3 6847540.4,128728.3 6847532.8,128730.2 6847533.3,128734.2 6847523.2,128728.5 6847521.1)))
+BATIMENT0000000069853561 197.039978027344 MULTIPOLYGON(((127764.8 6847869.2,127760 6847887.9,127767.1 6847889.8,127770.3 6847877.6,127777.5 6847879.3,127779.3 6847872.3,127764.8 6847869.2)))
+BATIMENT0000000069853562 19.8800048828125 MULTIPOLYGON(((128202.7 6847546.3,128205.1 6847549,128209.5 6847544.9,128207.3 6847542.7,128202.7 6847546.3)))
+BATIMENT0000000069853563 40.6000366210938 MULTIPOLYGON(((128896.8 6847773.9,128898.2 6847779.4,128905.5 6847776.2,128904 6847771.6,128896.8 6847773.9)))
+BATIMENT0000000069853564 67.0750122070312 MULTIPOLYGON(((127266.6 6847730.5,127274 6847736.8,127268.5 6847743.1,127263.7 6847739.1,127266.6 6847730.5)))
+BATIMENT0000000069853565 63.8050537109375 MULTIPOLYGON(((127531.4 6848004.6,127536.9 6848010.6,127531 6848016.1,127525.8 6848010.7,127531.4 6848004.6)))
+BATIMENT0000000069853566 14.6400146484375 MULTIPOLYGON(((128147.7 6847332.2,128150.2 6847335.2,128153.3 6847333.1,128151 6847330.1,128147.7 6847332.2)))
+BATIMENT0000000069853567 29.169921875 MULTIPOLYGON(((127200.5 6847519.5,127201 6847522.5,127210.3 6847520.7,127209.6 6847517.6,127200.5 6847519.5)))
+BATIMENT0000000069853568 31.2550659179688 MULTIPOLYGON(((128197.2 6847315,128195.8 6847308.7,128191 6847309.5,128192.1 6847315.5,128197.2 6847315)))
+BATIMENT0000000069853569 31.1099243164062 MULTIPOLYGON(((128523.8 6847292,128521.6 6847286.8,128525.5 6847283.2,128528.4 6847288.2,128523.8 6847292)))
+BATIMENT0000000069853570 138.64501953125 MULTIPOLYGON(((128542.9 6847331.2,128543.3 6847337.2,128544.7 6847337.2,128544.9 6847345.6,128549.9 6847345.4,128549.8 6847337.5,128558.2 6847337.1,128557.4 6847330.2,128542.9 6847331.2)))
+BATIMENT0000000069853571 169.544982910156 MULTIPOLYGON(((127210.4 6847947.9,127211.6 6847961.1,127210.5 6847961.3,127212 6847968.8,127207.7 6847969.8,127205.3 6847961.8,127200.8 6847962.1,127200.6 6847952.6,127201.9 6847952.5,127201.7 6847949.3,127210.4 6847947.9)))
+BATIMENT0000000069853572 25.7249755859375 MULTIPOLYGON(((128330.2 6847518,128331.6 6847524.5,128335.3 6847523.5,128334 6847517,128330.2 6847518)))
+BATIMENT0000000069853574 114.47998046875 MULTIPOLYGON(((127730.3 6847380.2,127731.4 6847364.7,127738.7 6847364.9,127737.8 6847380.3,127730.3 6847380.2)))
+BATIMENT0000000069853575 204.469909667969 MULTIPOLYGON(((127331.5 6847460.4,127333.5 6847463.5,127332.6 6847464.4,127340.2 6847476,127341.2 6847475.3,127343.8 6847478.7,127350.7 6847474.4,127338.3 6847455.5,127331.5 6847460.4)))
+BATIMENT0000000069853576 113.150024414062 MULTIPOLYGON(((128618.8 6848047.9,128613.2 6848050,128618.5 6848064.4,128620 6848064,128621.8 6848068.4,128625.8 6848067,128618.8 6848047.9)))
+BATIMENT0000000069853577 78.780029296875 MULTIPOLYGON(((127676.2 6848451.4,127677.8 6848460.5,127686.5 6848458.9,127684.8 6848450.3,127676.2 6848451.4)))
+BATIMENT0000000069853578 54.47998046875 MULTIPOLYGON(((127671.9 6848429.2,127673.5 6848437.4,127667.1 6848438.8,127665.5 6848430.7,127671.9 6848429.2)))
+BATIMENT0000000069853579 38.880126953125 MULTIPOLYGON(((129645.5 6847898.4,129647 6847904.2,129653.5 6847903.2,129651.7 6847897.3,129645.5 6847898.4)))
+BATIMENT0000000069853580 19.929931640625 MULTIPOLYGON(((128248.2 6847498.9,128250.5 6847504.2,128254 6847502.8,128251.5 6847498,128248.2 6847498.9)))
+BATIMENT0000000069853581 43.7999267578125 MULTIPOLYGON(((128815.4 6847499.8,128815.3 6847507.2,128821.4 6847507.6,128821.3 6847500.4,128815.4 6847499.8)))
+BATIMENT0000000069853582 49.60498046875 MULTIPOLYGON(((128629.2 6847620.1,128629.6 6847626.6,128637.7 6847626.5,128637 6847620.5,128629.2 6847620.1)))
+BATIMENT0000000069853583 63.5899658203125 MULTIPOLYGON(((128688.8 6848028.4,128691.4 6848037.5,128697.7 6848035.5,128695.9 6848026.8,128688.8 6848028.4)))
+BATIMENT0000000069853584 30.4450073242188 MULTIPOLYGON(((127712.8 6847579.9,127717.5 6847579.4,127717.5 6847572.9,127713.3 6847572.7,127712.8 6847579.9)))
diff --git a/test/data/CoversTest.txt b/test/data/CoversTest.txt
new file mode 100644
index 0000000..90c4fb1
--- /dev/null
+++ b/test/data/CoversTest.txt
@@ -0,0 +1,168 @@
+#2d or 3d|gA|gB|expected
+
+# Point/Point
+2|POINT(0.0 0.0)|POINT(0.0 0.0)|true
+3|POINT(0.0 0.0)|POINT(0.0 0.0)|true
+2|POINT(0.0 0.0)|POINT(3.0 4.0)|false
+3|POINT(0.0 0.0)|POINT(3.0 4.0)|false
+2|POINT(0.0 0.0)|POINT EMPTY|false
+3|POINT(0.0 0.0)|POINT EMPTY|false
+2|POINT EMPTY|POINT(0.0 0.0)|false
+3|POINT EMPTY|POINT(0.0 0.0)|false
+
+# LineString/Point
+2|LINESTRING(0 0,1 1)|POINT(0.5 0.5)|true
+3|LINESTRING(0 0,1 1)|POINT(0.5 0.5)|true
+2|LINESTRING(0 0,1 1)|POINT(0 0)|true
+3|LINESTRING(0 0,1 1)|POINT(0 0)|true
+2|LINESTRING(0 0,1 1)|POINT(2 2)|false
+3|LINESTRING(0 0,1 1)|POINT(2 2)|false
+2|POINT(0 0)|LINESTRING(0 0,1 1)|false
+3|POINT(0 0)|LINESTRING(0 0,1 1)|false
+
+# LineString/LineString
+2|LINESTRING(0 0,1 1)|LINESTRING(0.2 0.2,0.8 0.8)|true
+3|LINESTRING(0 0,1 1)|LINESTRING(0.2 0.2,0.8 0.8)|true
+2|LINESTRING(0 0,1 1)|LINESTRING(0 0,2 2)|false
+3|LINESTRING(0 0,1 1)|LINESTRING(0 0,2 2)|false
+2|LINESTRING(0 0,1 1)|LINESTRING(0 0,-1 0)|false
+3|LINESTRING(0 0,1 1)|LINESTRING(0 0,-1 0)|false
+2|LINESTRING(0 0,1 1)|LINESTRING(0 1,1 0)|false
+3|LINESTRING(0 0,1 1)|LINESTRING(0 1,1 0)|false
+2|LINESTRING(0 0,1 1)|LINESTRING(0 1,1 0)|false
+3|LINESTRING(0 0,1 1)|LINESTRING(0 1,1 0)|false
+2|LINESTRING(0 0,0.5 0.5,1 1)|LINESTRING(0 0,1 1)|true
+3|LINESTRING(0 0,0.5 0.5,1 1)|LINESTRING(0 0,1 1)|true
+2|LINESTRING(0 0,1 1)|MULTILINESTRING((0 0,0.5 0.5),(0.5 0.5,1 1))|true
+3|LINESTRING(0 0,1 1)|MULTILINESTRING((0 0,0.5 0.5),(0.5 0.5,1 1))|true
+
+# Triangle|Point
+2|TRIANGLE((0 0,1 0,1 1,0 0))|POINT(0 0)|true
+3|TRIANGLE((0 0,1 0,1 1,0 0))|POINT(0 0)|true
+2|TRIANGLE((0 0,1 0,1 1,0 0))|POINT(0.5 0.5)|true
+3|TRIANGLE((0 0,1 0,1 1,0 0))|POINT(0.5 0.5)|true
+2|TRIANGLE((0 0,1 0,1 1,0 0))|POINT(0.2 0.2)|true
+3|TRIANGLE((0 0,1 0,1 1,0 0))|POINT(0.2 0.2)|true
+2|TRIANGLE((0 0,1 0,1 1,0 0))|POINT(2 1)|false
+3|TRIANGLE((0 0,1 0,1 1,0 0))|POINT(2 1)|false
+2|POINT(0 0)|TRIANGLE((0 0,1 0,1 1,0 0))|false
+3|POINT(0 0)|TRIANGLE((0 0,1 0,1 1,0 0))|false
+
+# Triangle|LineString
+2|TRIANGLE((0 0,1 0,1 1,0 0))|LINESTRING(0 0,1 1)|true
+3|TRIANGLE((0 0,1 0,1 1,0 0))|LINESTRING(0 0,1 1)|true
+2|TRIANGLE((0 0,1 0,1 1,0 0))|LINESTRING(0 0,0.5 0.5)|true
+3|TRIANGLE((0 0,1 0,1 1,0 0))|LINESTRING(0 0,0.5 0.5)|true
+2|TRIANGLE((0 0,1 0,1 1,0 0))|LINESTRING(0.2 0.2,0.5 0.5)|true
+3|TRIANGLE((0 0,1 0,1 1,0 0))|LINESTRING(0.2 0.2,0.5 0.5)|true
+2|TRIANGLE((0 0,1 0,1 1,0 0))|LINESTRING(0.2 0.2,2 0.5)|false
+3|TRIANGLE((0 0,1 0,1 1,0 0))|LINESTRING(0.2 0.2,2 0.5)|false
+2|TRIANGLE((0 0,1 0,1 1,0 0))|LINESTRING(-1 0.5,2 0.5)|false
+3|TRIANGLE((0 0,1 0,1 1,0 0))|LINESTRING(-1 0.5,2 0.5)|false
+2|POINT(0.2 0.2)|TRIANGLE((0 0,1 0,1 1,0 0))|false
+3|POINT(0.2 0.2)|TRIANGLE((0 0,1 0,1 1,0 0))|false
+2|LINESTRING(0 0,1 0,1 1)|TRIANGLE((0 0,1 0,1 1,0 0))|false
+3|LINESTRING(0 0,1 0,1 1)|TRIANGLE((0 0,1 0,1 1,0 0))|false
+
+# Triangle|Triangle
+2|TRIANGLE((0 0,1 0,1 1,0 0))|TRIANGLE((0 0,1 0,1 1,0 0))|true
+3|TRIANGLE((0 0,1 0,1 1,0 0))|TRIANGLE((0 0,1 0,1 1,0 0))|true
+2|TRIANGLE((0 0,1 0,1 1,0 0))|TRIANGLE((0 0,0.5 0,0.5 0.5,0 0))|true
+3|TRIANGLE((0 0,1 0,1 1,0 0))|TRIANGLE((0 0,0.5 0,0.5 0.5,0 0))|true
+2|TRIANGLE((0 0,0.5 0,0.5 0.5,0 0))|TRIANGLE((0 0,1 0,1 1,0 0))|false
+3|TRIANGLE((0 0,0.5 0,0.5 0.5,0 0))|TRIANGLE((0 0,1 0,1 1,0 0))|false
+2|TRIANGLE((0 0,1 0,1 1,0 0))|TRIANGLE((-1 0,0 0,0 1,-1 0))|false
+3|TRIANGLE((0 0,1 0,1 1,0 0))|TRIANGLE((-1 0,0 0,0 1,-1 0))|false
+
+# Polygon|Point
+2|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|POINT(0 0)|true
+2|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|POINT(0.5 0.5)|false
+2|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|POINT(0.2 0.2)|true
+3|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|POINT(0 0)|true
+3|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|POINT(0.5 0.5)|false
+3|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|POINT(0.2 0.2)|true
+
+# Polygon|LineString
+2|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|LINESTRING(0 0,0.2 0.2)|true
+2|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|LINESTRING(0 0,1 1)|false
+2|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|MULTILINESTRING((0 0,0.4 0.4),(0.6 0.6,0.8 0.8))|true
+2|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|LINESTRING(0.5 0.5,1 1)|false
+3|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|LINESTRING(0 0,0.2 0.2)|true
+3|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|LINESTRING(0 0,1 1)|false
+3|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|MULTILINESTRING((0 0,0.4 0.4),(0.6 0.6,0.8 0.8))|true
+3|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|LINESTRING(0.5 0.5,1 1)|false
+
+# Polygon|Triangle
+2|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|TRIANGLE((0 0,0.3 0,0.3 0.3,0 0))|true
+2|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|TRIANGLE((0 0,0.4 0,0.4 0.4,0 0))|true
+2|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|TRIANGLE((0 0,0.4 0,0.5 0.5,0 0))|false
+3|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|TRIANGLE((0 0,0.3 0,0.3 0.3,0 0))|true
+3|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|TRIANGLE((0 0,0.4 0,0.4 0.4,0 0))|true
+3|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|TRIANGLE((0 0,0.4 0,0.5 0.5,0 0))|false
+
+# Polygon|Polygon
+2|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|POLYGON((0 0,0.4 0,0.4 0.4,0 0.4,0 0))|true
+2|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|POLYGON((-1 0,0.4 0,0.4 0.4,0 0.4,-1 0))|false
+2|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|POLYGON((0 0,0.5 0,0.5 0.5,0 0.5,0 0))|false
+2|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|true
+2|POLYGON((0 0,1 0,1 1,0 1,0 0))|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|true
+3|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|POLYGON((0 0,0.4 0,0.4 0.4,0 0.4,0 0))|true
+3|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|POLYGON((-1 0,0.4 0,0.4 0.4,0 0.4,-1 0))|false
+3|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|POLYGON((0 0,0.5 0,0.5 0.5,0 0.5,0 0))|false
+3|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|true
+3|POLYGON((0 0,1 0,1 1,0 1,0 0))|POLYGON((0 0,1 0,1 1,0 1,0 0),(0.4 0.4,0.4 0.6,0.6 0.6,0.6 0.4,0.4 0.4))|true
+
+3|POLYGON((1/1 1/4 1/2,1/1 0/1 1/2,1/2 0/1 1/2,1/2 1/2 1/2,1/1 1/4 1/2))|POLYGON((1/1 1/2 1/2,1/1 1/4 1/2,1/2 1/2 1/2,1/1 1/2 1/2)))|false
+3|POLYGON((1/1 1/2 1/2,1/1 1/4 1/2,1/2 1/2 1/2,1/1 1/2 1/2)))|POLYGON((1/1 1/4 1/2,1/1 0/1 1/2,1/2 0/1 1/2,1/2 1/2 1/2,1/1 1/4 1/2))|false
+
+# TIN|Point
+2|TIN(((0.6 0.4,0.4 0.4,0 0,0.6 0.4)),((0.6 0.4,0 0,1 0,0.6 0.4)),((0 1,0 0,0.4 0.4,0 1)),((0 1,0.4 0.6,0.6 0.6,0 1)),((0 1,0.4 0.4,0.4 0.6,0 1)),((1 1,0.6 0.6,1 0,1 1)),((1 1,0 1,0.6 0.6,1 1)),((0.6 0.6,0.6 0.4,1 0,0.6 0.6)))|POINT(0 0)|true
+2|TIN(((0.6 0.4,0.4 0.4,0 0,0.6 0.4)),((0.6 0.4,0 0,1 0,0.6 0.4)),((0 1,0 0,0.4 0.4,0 1)),((0 1,0.4 0.6,0.6 0.6,0 1)),((0 1,0.4 0.4,0.4 0.6,0 1)),((1 1,0.6 0.6,1 0,1 1)),((1 1,0 1,0.6 0.6,1 1)),((0.6 0.6,0.6 0.4,1 0,0.6 0.6)))|POINT(0.5 0.5)|false
+3|TIN(((0.6 0.4,0.4 0.4,0 0,0.6 0.4)),((0.6 0.4,0 0,1 0,0.6 0.4)),((0 1,0 0,0.4 0.4,0 1)),((0 1,0.4 0.6,0.6 0.6,0 1)),((0 1,0.4 0.4,0.4 0.6,0 1)),((1 1,0.6 0.6,1 0,1 1)),((1 1,0 1,0.6 0.6,1 1)),((0.6 0.6,0.6 0.4,1 0,0.6 0.6)))|POINT(0 0)|true
+3|TIN(((0.6 0.4,0.4 0.4,0 0,0.6 0.4)),((0.6 0.4,0 0,1 0,0.6 0.4)),((0 1,0 0,0.4 0.4,0 1)),((0 1,0.4 0.6,0.6 0.6,0 1)),((0 1,0.4 0.4,0.4 0.6,0 1)),((1 1,0.6 0.6,1 0,1 1)),((1 1,0 1,0.6 0.6,1 1)),((0.6 0.6,0.6 0.4,1 0,0.6 0.6)))|POINT(0.5 0.5)|false
+
+# TIN|LineString
+2|TIN(((0.6 0.4,0.4 0.4,0 0,0.6 0.4)),((0.6 0.4,0 0,1 0,0.6 0.4)),((0 1,0 0,0.4 0.4,0 1)),((0 1,0.4 0.6,0.6 0.6,0 1)),((0 1,0.4 0.4,0.4 0.6,0 1)),((1 1,0.6 0.6,1 0,1 1)),((1 1,0 1,0.6 0.6,1 1)),((0.6 0.6,0.6 0.4,1 0,0.6 0.6)))|LINESTRING(0 0,0.1 0.1)|true
+2|TIN(((0.6 0.4,0.4 0.4,0 0,0.6 0.4)),((0.6 0.4,0 0,1 0,0.6 0.4)),((0 1,0 0,0.4 0.4,0 1)),((0 1,0.4 0.6,0.6 0.6,0 1)),((0 1,0.4 0.4,0.4 0.6,0 1)),((1 1,0.6 0.6,1 0,1 1)),((1 1,0 1,0.6 0.6,1 1)),((0.6 0.6,0.6 0.4,1 0,0.6 0.6)))|LINESTRING(0 0,0.5 0.5)|false
+2|TIN(((0.6 0.4,0.4 0.4,0 0,0.6 0.4)),((0.6 0.4,0 0,1 0,0.6 0.4)),((0 1,0 0,0.4 0.4,0 1)),((0 1,0.4 0.6,0.6 0.6,0 1)),((0 1,0.4 0.4,0.4 0.6,0 1)),((1 1,0.6 0.6,1 0,1 1)),((1 1,0 1,0.6 0.6,1 1)),((0.6 0.6,0.6 0.4,1 0,0.6 0.6)))|LINESTRING(-1 -1,0.5 0.5)|false
+3|TIN(((0.6 0.4,0.4 0.4,0 0,0.6 0.4)),((0.6 0.4,0 0,1 0,0.6 0.4)),((0 1,0 0,0.4 0.4,0 1)),((0 1,0.4 0.6,0.6 0.6,0 1)),((0 1,0.4 0.4,0.4 0.6,0 1)),((1 1,0.6 0.6,1 0,1 1)),((1 1,0 1,0.6 0.6,1 1)),((0.6 0.6,0.6 0.4,1 0,0.6 0.6)))|LINESTRING(0 0,0.1 0.1)|true
+3|TIN(((0.6 0.4,0.4 0.4,0 0,0.6 0.4)),((0.6 0.4,0 0,1 0,0.6 0.4)),((0 1,0 0,0.4 0.4,0 1)),((0 1,0.4 0.6,0.6 0.6,0 1)),((0 1,0.4 0.4,0.4 0.6,0 1)),((1 1,0.6 0.6,1 0,1 1)),((1 1,0 1,0.6 0.6,1 1)),((0.6 0.6,0.6 0.4,1 0,0.6 0.6)))|LINESTRING(0 0,0.5 0.5)|false
+3|TIN(((0.6 0.4,0.4 0.4,0 0,0.6 0.4)),((0.6 0.4,0 0,1 0,0.6 0.4)),((0 1,0 0,0.4 0.4,0 1)),((0 1,0.4 0.6,0.6 0.6,0 1)),((0 1,0.4 0.4,0.4 0.6,0 1)),((1 1,0.6 0.6,1 0,1 1)),((1 1,0 1,0.6 0.6,1 1)),((0.6 0.6,0.6 0.4,1 0,0.6 0.6)))|LINESTRING(-1 -1,0.5 0.5)|false
+
+# TIN|Triangle
+2|TIN(((0.6 0.4,0.4 0.4,0 0,0.6 0.4)),((0.6 0.4,0 0,1 0,0.6 0.4)),((0 1,0 0,0.4 0.4,0 1)),((0 1,0.4 0.6,0.6 0.6,0 1)),((0 1,0.4 0.4,0.4 0.6,0 1)),((1 1,0.6 0.6,1 0,1 1)),((1 1,0 1,0.6 0.6,1 1)),((0.6 0.6,0.6 0.4,1 0,0.6 0.6)))|TRIANGLE((0 0,0.1 0,0.1 0.1,0 0))|true
+2|TIN(((0.6 0.4,0.4 0.4,0 0,0.6 0.4)),((0.6 0.4,0 0,1 0,0.6 0.4)),((0 1,0 0,0.4 0.4,0 1)),((0 1,0.4 0.6,0.6 0.6,0 1)),((0 1,0.4 0.4,0.4 0.6,0 1)),((1 1,0.6 0.6,1 0,1 1)),((1 1,0 1,0.6 0.6,1 1)),((0.6 0.6,0.6 0.4,1 0,0.6 0.6)))|TRIANGLE((0 0,0.4 0,0.4 0.4,0 0))|true
+2|TIN(((0.6 0.4,0.4 0.4,0 0,0.6 0.4)),((0.6 0.4,0 0,1 0,0.6 0.4)),((0 1,0 0,0.4 0.4,0 1)),((0 1,0.4 0.6,0.6 0.6,0 1)),((0 1,0.4 0.4,0.4 0.6,0 1)),((1 1,0.6 0.6,1 0,1 1)),((1 1,0 1,0.6 0.6,1 1)),((0.6 0.6,0.6 0.4,1 0,0.6 0.6)))|TRIANGLE((0 0,0.5 0,0.5 0.5,0 0))|false
+3|TIN(((0.6 0.4,0.4 0.4,0 0,0.6 0.4)),((0.6 0.4,0 0,1 0,0.6 0.4)),((0 1,0 0,0.4 0.4,0 1)),((0 1,0.4 0.6,0.6 0.6,0 1)),((0 1,0.4 0.4,0.4 0.6,0 1)),((1 1,0.6 0.6,1 0,1 1)),((1 1,0 1,0.6 0.6,1 1)),((0.6 0.6,0.6 0.4,1 0,0.6 0.6)))|TRIANGLE((0 0,0.1 0,0.1 0.1,0 0))|true
+3|TIN(((0.6 0.4,0.4 0.4,0 0,0.6 0.4)),((0.6 0.4,0 0,1 0,0.6 0.4)),((0 1,0 0,0.4 0.4,0 1)),((0 1,0.4 0.6,0.6 0.6,0 1)),((0 1,0.4 0.4,0.4 0.6,0 1)),((1 1,0.6 0.6,1 0,1 1)),((1 1,0 1,0.6 0.6,1 1)),((0.6 0.6,0.6 0.4,1 0,0.6 0.6)))|TRIANGLE((0 0,0.4 0,0.4 0.4,0 0))|true
+3|TIN(((0.6 0.4,0.4 0.4,0 0,0.6 0.4)),((0.6 0.4,0 0,1 0,0.6 0.4)),((0 1,0 0,0.4 0.4,0 1)),((0 1,0.4 0.6,0.6 0.6,0 1)),((0 1,0.4 0.4,0.4 0.6,0 1)),((1 1,0.6 0.6,1 0,1 1)),((1 1,0 1,0.6 0.6,1 1)),((0.6 0.6,0.6 0.4,1 0,0.6 0.6)))|TRIANGLE((0 0,0.5 0,0.5 0.5,0 0))|false
+
+# TIN <-> Polygon
+2|TIN(((0.6 0.4,0.4 0.4,0 0,0.6 0.4)),((0.6 0.4,0 0,1 0,0.6 0.4)),((0 1,0 0,0.4 0.4,0 1)),((0 1,0.4 0.6,0.6 0.6,0 1)),((0 1,0.4 0.4,0.4 0.6,0 1)),((1 1,0.6 0.6,1 0,1 1)),((1 1,0 1,0.6 0.6,1 1)),((0.6 0.6,0.6 0.4,1 0,0.6 0.6)))|POLYGON((0 0,1 0,1 1,0 1,0 0))|false
+2|POLYGON((0 0,1 0,1 1,0 1,0 0))|TIN(((0.6 0.4,0.4 0.4,0 0,0.6 0.4)),((0.6 0.4,0 0,1 0,0.6 0.4)),((0 1,0 0,0.4 0.4,0 1)),((0 1,0.4 0.6,0.6 0.6,0 1)),((0 1,0.4 0.4,0.4 0.6,0 1)),((1 1,0.6 0.6,1 0,1 1)),((1 1,0 1,0.6 0.6,1 1)),((0.6 0.6,0.6 0.4,1 0,0.6 0.6)))|true
+3|TIN(((0.6 0.4,0.4 0.4,0 0,0.6 0.4)),((0.6 0.4,0 0,1 0,0.6 0.4)),((0 1,0 0,0.4 0.4,0 1)),((0 1,0.4 0.6,0.6 0.6,0 1)),((0 1,0.4 0.4,0.4 0.6,0 1)),((1 1,0.6 0.6,1 0,1 1)),((1 1,0 1,0.6 0.6,1 1)),((0.6 0.6,0.6 0.4,1 0,0.6 0.6)))|POLYGON((0 0,1 0,1 1,0 1,0 0))|false
+3|POLYGON((0 0,1 0,1 1,0 1,0 0))|TIN(((0.6 0.4,0.4 0.4,0 0,0.6 0.4)),((0.6 0.4,0 0,1 0,0.6 0.4)),((0 1,0 0,0.4 0.4,0 1)),((0 1,0.4 0.6,0.6 0.6,0 1)),((0 1,0.4 0.4,0.4 0.6,0 1)),((1 1,0.6 0.6,1 0,1 1)),((1 1,0 1,0.6 0.6,1 1)),((0.6 0.6,0.6 0.4,1 0,0.6 0.6)))|true
+
+3|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|POINT(0.5 0.5 0.5)|true
+3|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|POINT(1.5 0.5 0.5)|false
+
+3|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|LINESTRING(0 0,0.5 0.5)|true
+3|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|LINESTRING(0 0,1 1)|true
+3|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|LINESTRING(-1 0,0 0,1 1)|false
+
+3|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|TRIANGLE((0 0,1 0,1 1,0 0))|true
+3|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|TRIANGLE((0 0,2 0,2 2,0 0))|false
+3|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|TRIANGLE((0.1 0.1 0.1,0.5 0.1 0.1,0.5 0.5 0.5,0.1 0.1 0.1))|true
+
+3|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|POLYGON((0 0,1 0,1 1,0 1,0 0))|true
+3|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|POLYGON((0 0,2 0,2 2,0 2,0 0))|false
+
+3|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|SOLID(( ((0 0 0,0 0.1 0,0.1 0.1 0,0.1 0 0,0 0 0)), ((0.1 0 0,0.1 0.1 0,0.1 0.1 0.1,0.1 0 0.1,0.1 0 0)), ((0 0.1 0,0 0.1 0.1,0.1 0.1 0.1,0.1 0.1 0,0 0.1 0)), ((0 0 0.1,0 0.1 0.1,0 0.1 0,0 0 0,0 0 0.1)), ((0.1 0 0.1,0.1 0.1 0.1,0 0.1 0.1,0 0 0.1,0.1 0 0.1)), ((0.1 0 0,0.1 [...]
+3|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|SOLID(( ((0.1 0.1 0.1,0.1 1.1 0.1,1.1 1.1 0.1,1.1 0.1 0.1,0.1 0.1 0.1)), ((1.1 0.1 0.1,1.1 1.1 0.1,1.1 1.1 1.1,1.1 0.1 1.1,1.1 0.1 0.1)), ((0.1 1.1 0.1,0.1 1.1 1.1,1.1 1.1 1.1,1.1 1.1 0.1,0.1 1.1 0.1)), ((0.1 0.1 1.1,0.1 1.1 1.1,0.1 1.1 0.1,0.1 0.1 0.1,0.1 0.1 1.1)), (( [...]
+
+
+
+
+3|POLYGON((1/2 0/1 1/2,1/2 1/2 1/2,1/1 1/4 1/2,1/1 0/1 1/2,1/2 0/1 1/2))|TRIANGLE((1 0.25 0.5,1 0.5 0.5,0.5 0.5 0.5,1 0.25 0.5))|false
+
+
diff --git a/test/data/DistanceTest.txt b/test/data/DistanceTest.txt
new file mode 100644
index 0000000..cfdfee0
--- /dev/null
+++ b/test/data/DistanceTest.txt
@@ -0,0 +1,44 @@
+#2d or 3d|gA|gB|expected
+
+# Point/Point
+2|POINT(0.0 0.0)|POINT(3.0 4.0)|5.000
+3|POINT(0.0 0.0)|POINT(3.0 4.0)|5.000
+3|POINT(1.0 2.0 3.0)|POINT(1.0 5.0 7.0)|5.000
+
+# Point/LineString
+3|POINT(1.0 2.0 3.0)|LINESTRING(1.0 5.0 7.0,9.0 9.0 9.0,15.0 6.0 7.0)|5.000
+
+# LineString/LineString
+2|LINESTRING(0.0 0.0,1.0 1.0)|LINESTRING(2.0 1.0,3.0 3.0)|1.0
+
+
+# LineString/LineString
+2|LINESTRING(0.0 0.0,1.0 1.0)|LINESTRING(2.0 1.0,3.0 3.0)|1.0
+
+# Point/Polygon
+2|POINT(-11.1111111 40)|POLYGON((-8.1111111 60,-8.16875525879031 59.4147290339516,-8.33947250246614 58.8519497029047,-8.61670226309236 58.3332893009412,-8.98979075644036 57.8786796564404,-9.44440040094119 57.5055911630924,-9.96306080290473 57.2283614024661,-10.5258401339516 57.0576441587903,-11.1111111 57,-11.6963820660484 57.0576441587903,-12.2591613970953 57.2283614024661,-12.7778217990588 57.5055911630924,-13.2324314435596 57.8786796564404,-13.6055199369076 58.3332893009412,-13.882749 [...]
+2|POINT(-11.1111111 40)|POLYGON((-9.1111111 40,-9.14954053919354 39.6098193559677,-9.26335203497743 39.2346331352698,-9.44817187539491 38.8888595339608,-9.6968975376269 38.5857864376269,-9.99997063396079 38.3370607753949,-10.3457442352698 38.1522409349774,-10.7209304559677 38.0384294391935,-11.1111111 38,-11.5012917440323 38.0384294391935,-11.8764779647302 38.1522409349774,-12.2222515660392 38.3370607753949,-12.5253246623731 38.5857864376269,-12.7740503246051 38.8888595339608,-12.9588701 [...]
+3|POINT(-11.1111111 40)|POLYGON((-8.1111111 60,-8.16875525879031 59.4147290339516,-8.33947250246614 58.8519497029047,-8.61670226309236 58.3332893009412,-8.98979075644036 57.8786796564404,-9.44440040094119 57.5055911630924,-9.96306080290473 57.2283614024661,-10.5258401339516 57.0576441587903,-11.1111111 57,-11.6963820660484 57.0576441587903,-12.2591613970953 57.2283614024661,-12.7778217990588 57.5055911630924,-13.2324314435596 57.8786796564404,-13.6055199369076 58.3332893009412,-13.882749 [...]
+3|POINT(-11.1111111 40)|POLYGON((-9.1111111 40,-9.14954053919354 39.6098193559677,-9.26335203497743 39.2346331352698,-9.44817187539491 38.8888595339608,-9.6968975376269 38.5857864376269,-9.99997063396079 38.3370607753949,-10.3457442352698 38.1522409349774,-10.7209304559677 38.0384294391935,-11.1111111 38,-11.5012917440323 38.0384294391935,-11.8764779647302 38.1522409349774,-12.2222515660392 38.3370607753949,-12.5253246623731 38.5857864376269,-12.7740503246051 38.8888595339608,-12.9588701 [...]
+
+3|POINT(-11.1111111 40)|POLYGON ZM ((-71.0771 42.3866 1 2,-71.0767 42.3872 1 2.3,-71.0767 42.3863 1 2.3,-71.0771 42.3866 1 2))|60.0213818552506
+3|POINT(-11.1111111 40)|POLYGON ZM ((-71.0775 42.386 2 1.5,-71.0773 42.3863 1.75 1.5,-71.0773 42.3859 1.75 1.5,-71.0775 42.386 2 1.5))|60.0391441478015
+3|POINT(-11.1111111 40)|POLYGON ZM ((-71.0771 42.3866 1 2,-71.0767 42.3872 1 2.3,-71.0767 42.3863 1 2.3,-71.0771 42.3866 1 2))|60.0213818552506
+3|POINT(-11.1111111 40)|POLYGON ZM ((-71.0775 42.386 2 1.5,-71.0773 42.3863 1.75 1.5,-71.0773 42.3859 1.75 1.5,-71.0775 42.386 2 1.5))|60.0391441478015
+3|POINT(-11.1111111 40)|POLYHEDRALSURFACE Z (((-72.2 41.755 0,-72.2 41.755 1,-72.2 42.755 1,-72.2 42.755 0,-72.2 41.755 0)),((-72.2 41.755 0,-72.2 42.755 0,-71.2 42.755 0,-71.2 41.755 0,-72.2 41.755 0)),((-72.2 41.755 0,-71.2 41.755 0,-71.2 41.755 1,-72.2 41.755 1,-72.2 41.755 0)),((-71.2 42.755 0,-71.2 42.755 1,-71.2 41.755 1,-71.2 41.755 0,-71.2 42.755 0)),((-72.2 42.755 0,-72.2 42.755 1,-71.2 42.755 1,-71.2 42.755 0,-72.2 42.755 0)),((-72.2 41.755 1,-71.2 41.755 1,-71.2 42.755 1,-72.2 [...]
+3|POINT(-11.1111111 40)|POLYHEDRALSURFACE Z (((-72.2 41.755 0,-72.2 41.755 1,-72.2 42.755 1,-72.2 42.755 0,-72.2 41.755 0)),((-72.2 41.755 0,-72.2 42.755 0,-71.2 42.755 0,-71.2 41.755 0,-72.2 41.755 0)))|60.1145123429987
+3|POINT(-11.1111111 40)|GEOMETRYCOLLECTION Z (MULTIPOLYGON Z (((-71.0821 42.3036 2,-71.0822 42.3036 2,-71.082 42.3038 2,-71.0819 42.3037 2,-71.0821 42.3036 2))),POLYGON Z ((-71.1261 42.2703 1,-71.1257 42.2703 1,-71.1257 42.2701 1,-71.126 42.2701 1,-71.1261 42.2702 1,-71.1261 42.2703 1)))|60.048335155759
+3|POINT(-11.1111111 40)|GEOMETRYCOLLECTION Z (MULTIPOLYGON Z (((-71.0821 42.3036 2,-71.0822 42.3036 2,-71.082 42.3038 2,-71.0819 42.3037 2,-71.0821 42.3036 2))),POLYGON Z ((-71.1261 42.2703 1,-71.1257 42.2703 1,-71.1257 42.2701 1,-71.126 42.2701 1,-71.1261 42.2702 1,-71.1261 42.2703 1)))|60.048335155759
+3|POINT(-11.1111111 40)|GEOMETRYCOLLECTION M (MULTIPOLYGON M (((-71.0821 42.3036 2,-71.0822 42.3036 3,-71.082 42.3038 2,-71.0819 42.3037 2,-71.0821 42.3036 2))),POLYGON M ((-71.1261 42.2703 1,-71.1257 42.2703 1,-71.1257 42.2701 2,-71.126 42.2701 1,-71.1261 42.2702 1,-71.1261 42.2703 1)))|60.0150194116303
+3|POINT(-11.1111111 40)|GEOMETRYCOLLECTION M (MULTIPOLYGON M (((-71.0821 42.3036 2,-71.0822 42.3036 3,-71.082 42.3038 2,-71.0819 42.3037 2,-71.0821 42.3036 2))),POLYGON M ((-71.1261 42.2703 1,-71.1257 42.2703 1,-71.1257 42.2701 2,-71.126 42.2701 1,-71.1261 42.2702 1,-71.1261 42.2703 1)))|60.0150194116303
+
+# Polygon/Polygon
+2|POLYGON((0.0 0.0,5.0 0.0,5.0 5.0,0.0 5.0,0.0 0.0),(1.0 1.0,1.0 4.0,4.0 4.0,4.0 1.0,1.0 1.0))|POLYGON((2.0 2.0,3.0 2.0,3.0 3.0,2.0 3.0,2.0 2.0))|1.0
+3|POLYGON((0.0 0.0,5.0 0.0,5.0 5.0,0.0 5.0,0.0 0.0),(1.0 1.0,1.0 4.0,4.0 4.0,4.0 1.0,1.0 1.0))|POLYGON((2.0 2.0,3.0 2.0,3.0 3.0,2.0 3.0,2.0 2.0))|1.0
+
+# Polygon/MultiPolygon
+2|POLYGON((-8.1111111 60,-8.16875525879031 59.4147290339516,-8.33947250246614 58.8519497029047,-8.61670226309236 58.3332893009412,-8.98979075644036 57.8786796564404,-9.44440040094119 57.5055911630924,-9.96306080290473 57.2283614024661,-10.5258401339516 57.0576441587903,-11.1111111 57,-11.6963820660484 57.0576441587903,-12.2591613970953 57.2283614024661,-12.7778217990588 57.5055911630924,-13.2324314435596 57.8786796564404,-13.6055199369076 58.3332893009412,-13.8827496975339 58.85194970290 [...]
+2|POLYGON((-9.1111111 40,-9.14954053919354 39.6098193559677,-9.26335203497743 39.2346331352698,-9.44817187539491 38.8888595339608,-9.6968975376269 38.5857864376269,-9.99997063396079 38.3370607753949,-10.3457442352698 38.1522409349774,-10.7209304559677 38.0384294391935,-11.1111111 38,-11.5012917440323 38.0384294391935,-11.8764779647302 38.1522409349774,-12.2222515660392 38.3370607753949,-12.5253246623731 38.5857864376269,-12.7740503246051 38.8888595339608,-12.9588701650226 39.234633135269 [...]
+3|POLYGON((-8.1111111 60,-8.16875525879031 59.4147290339516,-8.33947250246614 58.8519497029047,-8.61670226309236 58.3332893009412,-8.98979075644036 57.8786796564404,-9.44440040094119 57.5055911630924,-9.96306080290473 57.2283614024661,-10.5258401339516 57.0576441587903,-11.1111111 57,-11.6963820660484 57.0576441587903,-12.2591613970953 57.2283614024661,-12.7778217990588 57.5055911630924,-13.2324314435596 57.8786796564404,-13.6055199369076 58.3332893009412,-13.8827496975339 58.85194970290 [...]
+3|POLYGON((-9.1111111 40,-9.14954053919354 39.6098193559677,-9.26335203497743 39.2346331352698,-9.44817187539491 38.8888595339608,-9.6968975376269 38.5857864376269,-9.99997063396079 38.3370607753949,-10.3457442352698 38.1522409349774,-10.7209304559677 38.0384294391935,-11.1111111 38,-11.5012917440323 38.0384294391935,-11.8764779647302 38.1522409349774,-12.2222515660392 38.3370607753949,-12.5253246623731 38.5857864376269,-12.7740503246051 38.8888595339608,-12.9588701650226 39.234633135269 [...]
+
diff --git a/test/data/IntersectionTest.txt b/test/data/IntersectionTest.txt
new file mode 100644
index 0000000..fe93a68
--- /dev/null
+++ b/test/data/IntersectionTest.txt
@@ -0,0 +1,688 @@
+####################################################################################################
+# syntax :
+#
+# - lines starting with '#' and empty lines are ignored
+#
+# - 2D intersection test :
+# 2|geometry A wkt|geometry B wkt|expected wkt result
+#
+# - 3D intersection test :
+# 3|geometry A wkt|geometry B wkt|expected wkt result
+#
+# - geometry storage
+# S|name|WKT
+#
+# - reference to a stored geometry : @name
+# @A always refers to the first geometry
+# @B always regers to the second geometry
+#
+# e.g.
+# S|square|POLYGON((0 0,1 0,1 1,0 1,0 0))
+# 2|@square|POINT(0.5 0)|@B
+# ... will check that intersection(POLYGON((0 0,1 0,1 1,0 1,0 0)), POINT(0.5 0)) == POINT(0.5 0)
+####################################################################################################
+
+####################################################################################################
+# detected bugs :
+#
+# - the output is not always clean :
+# - TIN should sometimes be COLLECTION(TIN) if more than one connected component
+# - MULTIPOLYGON should be POLYHEDRAL (if connected polygons)
+# - GEOMETRYCOLLECTION(TRIANGLE...) could be a TIN
+####################################################################################################
+
+#
+# point x point
+#
+
+2|POINT(0 0)|POINT(0 0)|POINT(0 0)
+3|POINT(0 0 0)|POINT(0 0 0)|POINT(0 0 0)
+2|POINT(1 0)|POINT(0 0)|GEOMETRYCOLLECTION EMPTY
+3|POINT(1 0 0)|POINT(0 0 0)|GEOMETRYCOLLECTION EMPTY
+
+#
+# point x linestring
+#
+
+# point on the linestring
+2|POINT(0.5 0)|LINESTRING(0 0,1 0)|POINT(0.5 0)
+3|POINT(0.5 0 0)|LINESTRING(0 0 0,1 0 0)|POINT(0.5 0 0)
+# point outside
+2|POINT(0 1)|LINESTRING(0 0,1 0)|GEOMETRYCOLLECTION EMPTY
+3|POINT(0 1 0)|LINESTRING(0 0 0,1 0 0)|GEOMETRYCOLLECTION EMPTY
+
+#
+# linestring x linestring
+#
+
+# linestring crossing
+2|LINESTRING(0.5 0,0.5 1)|LINESTRING(0 0,1 0)|POINT(0.5 0)
+3|LINESTRING(0.5 0 0,0.5 1 0)|LINESTRING(0 0 0,1 0 0)|POINT(0.5 0 0)
+# linestring outside
+2|LINESTRING(0 1,1 1)|LINESTRING(0 0,1 0)|GEOMETRYCOLLECTION EMPTY
+3|LINESTRING(0 1 0,1 1 0)|LINESTRING(0 0 0,1 0 0)|GEOMETRYCOLLECTION EMPTY
+# a "sub" linestring
+2|LINESTRING(0.5 0,0.7 0)|LINESTRING(0 0,1 0)|LINESTRING(0.5 0,0.7 0)
+3|LINESTRING(0.5 0 0,0.7 0 0)|LINESTRING(0 0 0,1 0 0)|LINESTRING(0.5 0 0,0.7 0 0)
+
+#
+# point x triangle
+#
+
+# point on an edge
+2|POINT(0.5 0)|TRIANGLE((0 0,1 0,1 1,0 0))|POINT(0.5 0)
+3|POINT(0.5 0 0)|TRIANGLE((0 0 0,1 0 0,1 1 0,0 0 0))|POINT(0.5 0 0)
+# point inside
+2|POINT(0.5 0.5)|TRIANGLE((0 0,1 0,1 1,0 0))|POINT(0.5 0.5)
+3|POINT(0.5 0.5 0)|TRIANGLE((0 0 0,1 0 0,1 1 0,0 0 0))|POINT(0.5 0.5 0)
+# point outside
+2|POINT(-1 0)|TRIANGLE((0 0,1 0,1 1,0 0))|GEOMETRYCOLLECTION EMPTY
+3|POINT(-1 0 0)|TRIANGLE((0 0 0,1 0 0,1 1 0,0 0 0))|GEOMETRYCOLLECTION EMPTY
+
+#
+# linestring x triangle
+#
+
+# linestring crossing
+2|LINESTRING(0 0,2 1)|TRIANGLE((0 0,1 0,1 1,0 0))|LINESTRING(0 0,1 0.5)
+3|LINESTRING(0 0 0,2 1 0)|TRIANGLE((0 0 0,1 0 0,1 1 0,0 0 0))|LINESTRING(0 0 0,1 0.5 0)
+# linestring crossing on a vertex
+2|LINESTRING(0 0,0 1)|TRIANGLE((0 0,1 0,1 1,0 0))|POINT(0 0)
+3|LINESTRING(0 0 0,0 1 0)|TRIANGLE((0 0 0,1 0 0,1 1 0,0 0 0))|POINT(0 0 0)
+# linestring outside
+2|LINESTRING(-1 0,-1 1)|TRIANGLE((0 0,1 0,1 1,0 0))|GEOMETRYCOLLECTION EMPTY
+3|LINESTRING(-1 0 0,-1 1 0)|TRIANGLE((0 0 0,1 0 0,1 1 0,0 0 0))|GEOMETRYCOLLECTION EMPTY
+
+#
+# triangle x triangle
+#
+
+# a triangle crossing, resulting in a triangle
+2|TRIANGLE((0.5 0,1.5 0,1.5 1,0.5 0))|TRIANGLE((0 0,1 0,1 1,0 0))|TRIANGLE((1 0.5,0.5 0,1 0,1 0.5))
+3|TRIANGLE((0.5 0 0,1.5 0 0,1.5 1 0,0.5 0 0))|TRIANGLE((0 0 0,1 0 0,1 1 0,0 0 0))|TRIANGLE((1 0.5 0,0.5 0 0,1 0 0,1 0.5 0))
+# a triangle crossing, resulting in a polygon
+2|TRIANGLE((0 0.5,0 -0.5,1 0.5,0 0.5))|TRIANGLE((0 0,1 0,1 1,0 0))|POLYGON((1/1 1/2,1/2 0/1,0/1 0/1,1/2 1/2,1/1 1/2))
+3|TRIANGLE((0 0.5 0,0 -0.5 0,1 0.5 0,0 0.5 0))|TRIANGLE((0 0 0,1 0 0,1 1 0,0 0 0))|TIN(((0.5 0.5 0,0 0 0,0.5 0 0,0.5 0.5 0)),((1 0.5 0,0.5 0.5 0,0.5 0 0,1 0.5 0)))
+# triangle crossing, resulting in a segment (3D only)
+3|TRIANGLE((0 0.5 1,1 0.5 -1,1 0.5 1,0 0.5 1))|TRIANGLE((0 0 0,1 0 0,1 1 0,0 0 0))|LINESTRING(1/1 1/2 0/1,1/2 1/2 0/1)
+# triangle crossing on an edge
+2|TRIANGLE((0 0,1 -1,1 0,0 0))|TRIANGLE((0 0,1 0,1 1,0 0))|LINESTRING(1 0,0 0)
+3|TRIANGLE((0 0 0,1 -1 0,1 0 0,0 0 0))|TRIANGLE((0 0 0,1 0 0,1 1 0,0 0 0))|LINESTRING(0 0 0,1 0 0)
+# triangle crossing on a vertex
+2|TRIANGLE((1 0,2 0,2 1,1 0))|TRIANGLE((0 0,1 0,1 1,0 0))|POINT(1 0)
+3|TRIANGLE((1 0 0,2 0 0,2 1 0,1 0 0))|TRIANGLE((0 0 0,1 0 0,1 1 0,0 0 0))|POINT(1 0 0)
+# triangle outside
+2|TRIANGLE((-3 0,-2 0,-2 1,-3 0))|TRIANGLE((0 0,1 0,1 1,0 0))|GEOMETRYCOLLECTION EMPTY
+3|TRIANGLE((-3 0 0,-2 0 0,-2 1 0,-3 0 0))|TRIANGLE((0 0 0,1 0 0,1 1 0,0 0 0))|GEOMETRYCOLLECTION EMPTY
+
+#
+# point x polygon
+#
+
+# point inside
+2|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|POINT(0.1 0.1)|POINT(0.1 0.1)
+3|POLYGON((0 0 0,2 0 0,2 2 0,0 2 0,0 0 0),(1.3 1.3 0,1.3 1.7 0,1.7 1.7 0,1.7 1.3 0,1.3 1.3 0))|POINT(0.1 0.1 0)|POINT(0.1 0.1 0)
+# point on an edge
+2|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|POINT(0.1 0)|POINT(0.1 0)
+3|POLYGON((0 0 0,2 0 0,2 2 0,0 2 0,0 0 0),(1.3 1.3 0,1.3 1.7 0,1.7 1.7 0,1.7 1.3 0,1.3 1.3 0))|POINT(0.1 00 0)|POINT(0.1 0 0)
+# point on a vertex
+2|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|POINT(0 0)|POINT(0 0)
+3|POLYGON((0 0 0,2 0 0,2 2 0,0 2 0,0 0 0),(1.3 1.3 0,1.3 1.7 0,1.7 1.7 0,1.7 1.3 0,1.3 1.3 0))|POINT(0 0 0)|POINT(0 0 0)
+# point on an interior edge
+2|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|POINT(1.5 1.3)|POINT(1.5 1.3)
+3|POLYGON((0 0 0,2 0 0,2 2 0,0 2 0,0 0 0),(1.3 1.3 0,1.3 1.7 0,1.7 1.7 0,1.7 1.3 0,1.3 1.3 0))|POINT(1.5 1.3 0)|POINT(1.5 1.3 0)
+# point in a hole
+2|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|POINT(1.5 1.5)|GEOMETRYCOLLECTION EMPTY
+3|POLYGON((0 0 0,2 0 0,2 2 0,0 2 0,0 0 0),(1.3 1.3 0,1.3 1.7 0,1.7 1.7 0,1.7 1.3 0,1.3 1.3 0))|POINT(1.5 1.5 0)|GEOMETRYCOLLECTION EMPTY
+# point outside
+2|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|POINT(2.5 2.5)|GEOMETRYCOLLECTION EMPTY
+3|POLYGON((0 0 0,2 0 0,2 2 0,0 2 0,0 0 0),(1.3 1.3 0,1.3 1.7 0,1.7 1.7 0,1.7 1.3 0,1.3 1.3 0))|POINT(2.5 2.5 0)|GEOMETRYCOLLECTION EMPTY
+
+#
+# linestring x polygon
+#
+
+# a linestring inside
+2|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|LINESTRING(-0.5 0.5,2.5 0.5)|LINESTRING(0/1 1/2,1/2 1/2,45/26 1/2,49/26 1/2,2/1 1/2)
+3|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|LINESTRING(-0.5 0.5,2.5 0.5)|LINESTRING(0/1 1/2 0,1/2 1/2 0,45/26 1/2 0,49/26 1/2 0,2/1 1/2 0)
+# a linestring on an edge
+2|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|LINESTRING(0 0,1 0)|LINESTRING(0 0,1 0)
+3|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|LINESTRING(0 0,1 0)|LINESTRING(0 0 0,1 0 0)
+# a linestring inside a hole
+2|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|LINESTRING(1.4 1.4,1.6 1.6)|GEOMETRYCOLLECTION EMPTY
+3|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|LINESTRING(1.4 1.4,1.6 1.6)|GEOMETRYCOLLECTION EMPTY
+# a linestring outside
+2|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|LINESTRING(-0.5 0,1 -2)|GEOMETRYCOLLECTION EMPTY
+3|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|LINESTRING(-0.5 0,1 -2)|GEOMETRYCOLLECTION EMPTY
+
+#
+# triangle x polygon
+#
+
+# touching a vertex
+2|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|TRIANGLE((-1 -1,0 -1,0 0,-1 -1))|POINT(0 0)
+3|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|TRIANGLE((-1 -1,0 -1,0 0,-1 -1))|POINT(0 0 0)
+# touching an edge
+2|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|TRIANGLE((-1 0,0 0,0 1,-1 0))|LINESTRING(0 0,0 1)
+3|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|TRIANGLE((-1 0,0 0,0 1,-1 0))|LINESTRING(0 0 0,0 1 0)
+# overlapping
+2|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|TRIANGLE((-1 0,1 0,1 1,-1 0))|POLYGON((1 1,0 0.5,0 0,1 0,1 1))
+3|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|TRIANGLE((-1 0,1 0,1 1,-1 0))|TIN(((0/1 0/1 0/1,1/1 0/1 0/1,1/1 1/1 0/1,0/1 0/1 0/1)),((0/1 1/2 0/1,0/1 0/1 0/1,1/1 1/1 0/1,0/1 1/2 0/1)))
+# inside
+2|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|TRIANGLE((0.1 0.1,1 0.1,1 1,0.1 0.1))|TRIANGLE((0.1 0.1,1 0.1,1 1,0.1 0.1))
+3|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|TRIANGLE((0.1 0.1,1 0.1,1 1,0.1 0.1))|TRIANGLE((0.1 0.1 0,1 0.1 0,1 1 0,0.1 0.1 0))
+# triangle inside a hole
+2|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|TRIANGLE((1.4 1.4,1.6 1.4,1.6 1.6,1.4 1.4))|GEOMETRYCOLLECTION EMPTY
+3|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|TRIANGLE((1.4 1.4,1.6 1.4,1.6 1.6,1.4 1.4))|GEOMETRYCOLLECTION EMPTY
+
+#
+# polygon x polygon
+#
+
+# on a vertex
+2|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|POLYGON((-1 -1,0 -1,0 0,-1 0,-1 -1))|POINT(0 0)
+3|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|POLYGON((-1 -1,0 -1,0 0,-1 0,-1 -1))|POINT(0 0 0)
+# on an edge
+2|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|POLYGON((-1 0,0 0,0 1,-1 1,-1 0))|LINESTRING(0 0,0 1)
+3|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|POLYGON((-1 0,0 0,0 1,-1 1,-1 0))|LINESTRING(0 0 0,0 1 0)
+# overlapping
+2|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|POLYGON((0 0,1 0,1 1,0 1,0 0))|POLYGON((1 1,0 1,0 0,1 0,1 1))
+3|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|POLYGON((0 0,1 0,1 1,0 1,0 0))|TIN(((1/2 1/2 0/1,0/1 1/1 0/1,0/1 0/1 0/1,1/2 1/2 0/1)),((1/2 1/2 0/1,0/1 0/1 0/1,1/1 0/1 0/1,1/2 1/2 0/1)),((1/2 1/2 0/1,1/1 0/1 0/1,1/1 1/1 0/1,1/2 1/2 0/1)),((0/1 1/1 0/1,1/2 1/2 0/1,1/1 1/1 0/1,0/1 1/1 0/1)))
+# inside a hole
+2|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|POLYGON((1.4 1.4,1.6 1.4,1.6 1.6,1.4 1.6,1.4 1.4))|GEOMETRYCOLLECTION EMPTY
+3|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|POLYGON((1.4 1.4,1.6 1.4,1.6 1.6,1.4 1.6,1.4 1.4))|GEOMETRYCOLLECTION EMPTY
+# overlapping a hole => multipolygon
+2|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|POLYGON((1.4 0,1.6 0,1.6 2,1.4 2,1.4 0))|MULTIPOLYGON(((1.6 1.3,1.4 1.3,1.4 0,1.6 0,1.6 1.3)),((1.4 2,1.4 1.7,1.6 1.7,1.6 2,1.4 2)))
+# FIXME => multi TIN ? DONE IN SFCGAL 1.1
+3|POLYGON((0 0,2 0,2 2,0 2,0 0),(1.3 1.3,1.3 1.7,1.7 1.7,1.7 1.3,1.3 1.3))|POLYGON((1.4 0,1.6 0,1.6 2,1.4 2,1.4 0))|GEOMETRYCOLLECTION(TIN(((104/73 128/73 0/1,7/5 2/1 0/1,7/5 61/35 0/1,104/73 128/73 0/1)),((7/5 2/1 0/1,104/73 128/73 0/1,8/5 64/35 0/1,7/5 2/1 0/1)),((8/5 2/1 0/1,7/5 2/1 0/1,8/5 64/35 0/1,8/5 2/1 0/1)),((143/100 17/10 0/1,104/73 128/73 0/1,7/5 61/35 0/1,143/100 17/10 0/1)),((7/5 17/10 0/1,143/100 17/10 0/1,7/5 61/35 0/1,7/5 17/10 0/1)),((104/73 128/73 0/1,143/100 17/10 0/1 [...]
+
+#
+# point x polyhedral
+#
+
+# store a polyhedral : tesselation of a polygon with hole
+S|polyhedral|POLYHEDRALSURFACE(((1.7 1.7,1.7 1.3,2 2,1.7 1.7)),((1.3 1.3,0 0,2 0,1.3 1.3)),((1.7 1.3,1.3 1.3,2 0,1.7 1.3)),((0 2,0 0,1.3 1.3,0 2)),((0 2,1.3 1.7,2 2,0 2)),((0 2,1.3 1.3,1.3 1.7,0 2)),((1.3 1.7,1.7 1.7,2 2,1.3 1.7)),((2 2,1.7 1.3,2 0,2 2)))
+
+# point inside
+2|@polyhedral|POINT(0.1 0.1)|POINT(0.1 0.1)
+3|@polyhedral|POINT(0.1 0.1 0)|POINT(0.1 0.1 0)
+# point on an edge
+2|@polyhedral|POINT(0.1 0)|POINT(0.1 0)
+3|@polyhedral|POINT(0.1 00 0)|POINT(0.1 0 0)
+# point on a vertex
+2|@polyhedral|POINT(0 0)|POINT(0 0)
+3|@polyhedral|POINT(0 0 0)|POINT(0 0 0)
+# point on an interior edge
+2|@polyhedral|POINT(1.5 1.3)|POINT(1.5 1.3)
+3|@polyhedral|POINT(1.5 1.3 0)|POINT(1.5 1.3 0)
+# point in a hole
+2|@polyhedral|POINT(1.5 1.5)|GEOMETRYCOLLECTION EMPTY
+3|@polyhedral|POINT(1.5 1.5 0)|GEOMETRYCOLLECTION EMPTY
+# point outside
+2|@polyhedral|POINT(2.5 2.5)|GEOMETRYCOLLECTION EMPTY
+3|@polyhedral|POINT(2.5 2.5 0)|GEOMETRYCOLLECTION EMPTY
+
+#
+# linestring x polyhedral
+#
+
+# a linestring inside
+2|@polyhedral|LINESTRING(-0.5 0.5,2.5 0.5)|LINESTRING(0/1 1/2,1/2 1/2,45/26 1/2,49/26 1/2,2/1 1/2)
+3|@polyhedral|LINESTRING(-0.5 0.5,2.5 0.5)|LINESTRING(0/1 1/2 0,1/2 1/2 0,45/26 1/2 0,49/26 1/2 0,2/1 1/2 0)
+# a linestring on an edge
+2|@polyhedral|LINESTRING(0 0,1 0)|LINESTRING(0 0,1 0)
+3|@polyhedral|LINESTRING(0 0,1 0)|LINESTRING(0 0 0,1 0 0)
+# a linestring inside a hole
+2|@polyhedral|LINESTRING(1.4 1.4,1.6 1.6)|GEOMETRYCOLLECTION EMPTY
+3|@polyhedral|LINESTRING(1.4 1.4,1.6 1.6)|GEOMETRYCOLLECTION EMPTY
+# a linestring outside
+2|@polyhedral|LINESTRING(-0.5 0,1 -2)|GEOMETRYCOLLECTION EMPTY
+3|@polyhedral|LINESTRING(-0.5 0,1 -2)|GEOMETRYCOLLECTION EMPTY
+
+#
+# triangle x polyhedral
+#
+
+# touching a vertex
+2|@polyhedral|TRIANGLE((-1 -1,0 -1,0 0,-1 -1))|POINT(0 0)
+3|@polyhedral|TRIANGLE((-1 -1,0 -1,0 0,-1 -1))|POINT(0 0 0)
+# touching an edge
+2|@polyhedral|TRIANGLE((-1 0,0 0,0 1,-1 0))|LINESTRING(0 0,0 1)
+3|@polyhedral|TRIANGLE((-1 0,0 0,0 1,-1 0))|LINESTRING(0 0 0,0 1 0)
+# overlapping
+# FIXME should be TIN
+2|@polyhedral|TRIANGLE((-1 0,1 0,1 1,-1 0))|GEOMETRYCOLLECTION(TRIANGLE((1 1,0 0,0 0.5,1 1)),TRIANGLE((1 0,0 0,1 1,1 0)))
+3|@polyhedral|TRIANGLE((-1 0,1 0,1 1,-1 0))|TIN(((0/1 0/1 0/1,1/1 0/1 0/1,1/1 1/1 0/1,0/1 0/1 0/1)),((0/1 1/2 0/1,0/1 0/1 0/1,1/1 1/1 0/1,0/1 1/2 0/1)))
+## inside
+2|@polyhedral|TRIANGLE((0.1 0.1,1 0.1,1 1,0.1 0.1))|TRIANGLE((0.1 0.1,1 0.1,1 1,0.1 0.1))
+3|@polyhedral|TRIANGLE((0.1 0.1,1 0.1,1 1,0.1 0.1))|TRIANGLE((0.1 0.1 0,1 0.1 0,1 1 0,0.1 0.1 0))
+# triangle inside a hole
+2|@polyhedral|TRIANGLE((1.4 1.4,1.6 1.4,1.6 1.6,1.4 1.4))|GEOMETRYCOLLECTION EMPTY
+3|@polyhedral|TRIANGLE((1.4 1.4,1.6 1.4,1.6 1.6,1.4 1.4))|GEOMETRYCOLLECTION EMPTY
+
+#
+# polygon x polyhedral
+#
+
+# on a vertex
+2|@polyhedral|POLYGON((-1 -1,0 -1,0 0,-1 0,-1 -1))|POINT(0 0)
+3|@polyhedral|POLYGON((-1 -1,0 -1,0 0,-1 0,-1 -1))|POINT(0 0 0)
+# on an edge
+2|@polyhedral|POLYGON((-1 0,0 0,0 1,-1 1,-1 0))|LINESTRING(0 0,0 1)
+3|@polyhedral|POLYGON((-1 0,0 0,0 1,-1 1,-1 0))|LINESTRING(0 0 0,0 1 0)
+# overlapping
+2|@polyhedral|POLYGON((0 0,1 0,1 1,0 1,0 0))|GEOMETRYCOLLECTION(TRIANGLE((0 1,0 0,1 1,0 1)),TRIANGLE((1 1,0 0,1 0,1 1)))
+3|@polyhedral|POLYGON((0 0,1 0,1 1,0 1,0 0))|TIN(((1/2 1/2 0/1,0/1 1/1 0/1,0/1 0/1 0/1,1/2 1/2 0/1)),((1/2 1/2 0/1,0/1 0/1 0/1,1/1 0/1 0/1,1/2 1/2 0/1)),((1/2 1/2 0/1,1/1 0/1 0/1,1/1 1/1 0/1,1/2 1/2 0/1)),((0/1 1/1 0/1,1/2 1/2 0/1,1/1 1/1 0/1,0/1 1/1 0/1)))
+# inside a hole
+2|@polyhedral|POLYGON((1.4 1.4,1.6 1.4,1.6 1.6,1.4 1.6,1.4 1.4))|GEOMETRYCOLLECTION EMPTY
+3|@polyhedral|POLYGON((1.4 1.4,1.6 1.4,1.6 1.6,1.4 1.6,1.4 1.4))|GEOMETRYCOLLECTION EMPTY
+# overlapping a hole => multipolygon
+2|@polyhedral|POLYGON((1.4 0,1.6 0,1.6 2,1.4 2,1.4 0))|MULTIPOLYGON(((7/5 2/1,7/5 61/35,8/5 64/35,8/5 2/1,7/5 2/1)),((8/5 13/10,7/5 13/10,7/5 39/35,8/5 26/35,8/5 13/10)),((7/5 61/35,7/5 17/10,8/5 17/10,8/5 64/35,7/5 61/35)),((7/5 39/35,7/5 0/1,8/5 0/1,8/5 26/35,7/5 39/35)))
+# FIXME => multi TIN ? DONE IN SFCGAL 1.1
+3|@polyhedral|POLYGON((1.4 0,1.6 0,1.6 2,1.4 2,1.4 0))|GEOMETRYCOLLECTION(TIN(((86/57 52/57 0/1,8/5 0/1 0/1,8/5 26/35 0/1,86/57 52/57 0/1)),((86/57 52/57 0/1,7/5 39/35 0/1,7/5 0/1 0/1,86/57 52/57 0/1)),((8/5 0/1 0/1,86/57 52/57 0/1,7/5 0/1 0/1,8/5 0/1 0/1)),((8/5 13/10 0/1,86/57 52/57 0/1,8/5 26/35 0/1,8/5 13/10 0/1)),((8/5 13/10 0/1,147/100 13/10 0/1,86/57 52/57 0/1,8/5 13/10 0/1)),((7/5 39/35 0/1,147/100 13/10 0/1,7/5 13/10 0/1,7/5 39/35 0/1)),((7/5 39/35 0/1,86/57 52/57 0/1,147/100 13 [...]
+
+#
+# polyhedral x polyhedral
+#
+
+# on a vertex
+2|@polyhedral|POLYHEDRALSURFACE(((-1 0,0 -1,0 0,-1 0)),((-1 0,-1 -1,0 -1,-1 0)))|POINT(0 0)
+3|@polyhedral|POLYHEDRALSURFACE(((-1 0,0 -1,0 0,-1 0)),((-1 0,-1 -1,0 -1,-1 0)))|POINT(0 0 0)
+# on an edge
+2|@polyhedral|POLYHEDRALSURFACE(((-1 1,0 0,0 1,-1 1)),((-1 1,-1 0,0 0,-1 1)))|LINESTRING(0 0,0 1)
+3|@polyhedral|POLYHEDRALSURFACE(((-1 1,0 0,0 1,-1 1)),((-1 1,-1 0,0 0,-1 1)))|LINESTRING(0 0 0,0 1 0)
+# overlapping
+# FIXME : fix the output
+2|@polyhedral|POLYHEDRALSURFACE(((0 1,1 0,1 1,0 1)),((0 1,0 0,1 0,0 1)))|GEOMETRYCOLLECTION(TRIANGLE((1 -0,0 0,0.5 0.5,1 -0)),TRIANGLE((0.5 0.5,0 0,-0 1,0.5 0.5)),TRIANGLE((1 1,0.5 0.5,0 1,1 1)),TRIANGLE((1 0,0.5 0.5,1 1,1 0)))
+3|@polyhedral|POLYHEDRALSURFACE(((0 1,1 0,1 1,0 1)),((0 1,0 0,1 0,0 1)))|TIN(((0 1 0,0.5 0.5 0,1 1 0,0 1 0)),((0.5 0.5 0,1 0 0,1 1 0,0.5 0.5 0)),((0.5 0.5 0,0 1 0,0 0 0,0.5 0.5 0)),((0.5 0.5 0,0 0 0,1 0 0,0.5 0.5 0)))
+# inside a hole
+2|@polyhedral|POLYHEDRALSURFACE(((1.4 1.6,1.6 1.4,1.6 1.6,1.4 1.6)),((1.4 1.6,1.4 1.4,1.6 1.4,1.4 1.6)))|GEOMETRYCOLLECTION EMPTY
+3|@polyhedral|POLYHEDRALSURFACE(((1.4 1.6,1.6 1.4,1.6 1.6,1.4 1.6)),((1.4 1.6,1.4 1.4,1.6 1.4,1.4 1.6)))|GEOMETRYCOLLECTION EMPTY
+# overlapping a hole => multipolygon
+# FIXME fix output
+2|@polyhedral|POLYHEDRALSURFACE(((1.4 2,1.6 0,1.6 2,1.4 2)),((1.4 2,1.4 0,1.6 0,1.4 2)))|GEOMETRYCOLLECTION(POLYGON((8/5 64/35,104/73 128/73,7/5 2/1,8/5 2/1,8/5 64/35)),TRIANGLE((104/73 128/73,7/5 61/35,7/5 2/1,104/73 128/73)),TRIANGLE((8/5 0/1,86/57 52/57,8/5 26/35,8/5 0/1)),POLYGON((8/5 17/10,143/100 17/10,104/73 128/73,8/5 64/35,8/5 17/10)),POLYGON((143/100 17/10,7/5 17/10,7/5 61/35,104/73 128/73,143/100 17/10)),POLYGON((8/5 26/35,86/57 52/57,147/100 13/10,8/5 13/10,8/5 26/35)),POLYGO [...]
+# FIXME => multi TIN ? DONE IN SFCGAL 1.1
+3|@polyhedral|POLYHEDRALSURFACE(((1.4 2,1.6 0,1.6 2,1.4 2)),((1.4 2,1.4 0,1.6 0,1.4 2)))|GEOMETRYCOLLECTION(TIN(((86/57 52/57 0/1,8/5 0/1 0/1,8/5 26/35 0/1,86/57 52/57 0/1)),((86/57 52/57 0/1,7/5 39/35 0/1,7/5 0/1 0/1,86/57 52/57 0/1)),((8/5 0/1 0/1,86/57 52/57 0/1,7/5 0/1 0/1,8/5 0/1 0/1)),((8/5 13/10 0/1,86/57 52/57 0/1,8/5 26/35 0/1,8/5 13/10 0/1)),((8/5 13/10 0/1,147/100 13/10 0/1,86/57 52/57 0/1,8/5 13/10 0/1)),((7/5 39/35 0/1,147/100 13/10 0/1,7/5 13/10 0/1,7/5 39/35 0/1)),((7/5 39 [...]
+
+#
+# point x tin
+#
+
+# store a TIN : tesselation of a polygon with hole
+S|poly_tin|TIN(((1.7 1.7,1.7 1.3,2 2,1.7 1.7)),((1.3 1.3,0 0,2 0,1.3 1.3)),((1.7 1.3,1.3 1.3,2 0,1.7 1.3)),((0 2,0 0,1.3 1.3,0 2)),((0 2,1.3 1.7,2 2,0 2)),((0 2,1.3 1.3,1.3 1.7,0 2)),((1.3 1.7,1.7 1.7,2 2,1.3 1.7)),((2 2,1.7 1.3,2 0,2 2)))
+
+# point inside
+2|@poly_tin|POINT(0.1 0.1)|POINT(0.1 0.1)
+3|@poly_tin|POINT(0.1 0.1 0)|POINT(0.1 0.1 0)
+# point on an edge
+2|@poly_tin|POINT(0.1 0)|POINT(0.1 0)
+3|@poly_tin|POINT(0.1 00 0)|POINT(0.1 0 0)
+# point on a vertex
+2|@poly_tin|POINT(0 0)|POINT(0 0)
+3|@poly_tin|POINT(0 0 0)|POINT(0 0 0)
+# point on an interior edge
+2|@poly_tin|POINT(1.5 1.3)|POINT(1.5 1.3)
+3|@poly_tin|POINT(1.5 1.3 0)|POINT(1.5 1.3 0)
+# point in a hole
+2|@poly_tin|POINT(1.5 1.5)|GEOMETRYCOLLECTION EMPTY
+3|@poly_tin|POINT(1.5 1.5 0)|GEOMETRYCOLLECTION EMPTY
+# point outside
+2|@poly_tin|POINT(2.5 2.5)|GEOMETRYCOLLECTION EMPTY
+3|@poly_tin|POINT(2.5 2.5 0)|GEOMETRYCOLLECTION EMPTY
+
+
+#
+# linestring x tin
+#
+
+# a linestring inside
+2|@poly_tin|LINESTRING(-0.5 0.5,2.5 0.5)|LINESTRING(0/1 1/2,1/2 1/2,45/26 1/2,49/26 1/2,2/1 1/2)
+3|@poly_tin|LINESTRING(-0.5 0.5,2.5 0.5)|LINESTRING(0/1 1/2 0,1/2 1/2 0,45/26 1/2 0,49/26 1/2 0,2/1 1/2 0)
+# a linestring on an edge
+2|@poly_tin|LINESTRING(0 0,1 0)|LINESTRING(0 0,1 0)
+3|@poly_tin|LINESTRING(0 0,1 0)|LINESTRING(0 0 0,1 0 0)
+# a linestring inside a hole
+2|@poly_tin|LINESTRING(1.4 1.4,1.6 1.6)|GEOMETRYCOLLECTION EMPTY
+3|@poly_tin|LINESTRING(1.4 1.4,1.6 1.6)|GEOMETRYCOLLECTION EMPTY
+# a linestring outside
+2|@poly_tin|LINESTRING(-0.5 0,1 -2)|GEOMETRYCOLLECTION EMPTY
+3|@poly_tin|LINESTRING(-0.5 0,1 -2)|GEOMETRYCOLLECTION EMPTY
+
+#
+# triangle x tin
+#
+
+# touching a vertex
+2|@poly_tin|TRIANGLE((-1 -1,0 -1,0 0,-1 -1))|POINT(0 0)
+3|@poly_tin|TRIANGLE((-1 -1,0 -1,0 0,-1 -1))|POINT(0 0 0)
+# touching an edge
+2|@poly_tin|TRIANGLE((-1 0,0 0,0 1,-1 0))|LINESTRING(0 0,0 1)
+3|@poly_tin|TRIANGLE((-1 0,0 0,0 1,-1 0))|LINESTRING(0 0 0,0 1 0)
+# overlapping
+# FIXME should be TIN
+2|@poly_tin|TRIANGLE((-1 0,1 0,1 1,-1 0))|GEOMETRYCOLLECTION(TRIANGLE((1 1,0 0,0 0.5,1 1)),TRIANGLE((1 0,0 0,1 1,1 0)))
+3|@poly_tin|TRIANGLE((-1 0,1 0,1 1,-1 0))|TIN(((0/1 0/1 0/1,1/1 0/1 0/1,1/1 1/1 0/1,0/1 0/1 0/1)),((0/1 1/2 0/1,0/1 0/1 0/1,1/1 1/1 0/1,0/1 1/2 0/1)))
+## inside
+2|@poly_tin|TRIANGLE((0.1 0.1,1 0.1,1 1,0.1 0.1))|TRIANGLE((0.1 0.1,1 0.1,1 1,0.1 0.1))
+3|@poly_tin|TRIANGLE((0.1 0.1,1 0.1,1 1,0.1 0.1))|TRIANGLE((0.1 0.1 0,1 0.1 0,1 1 0,0.1 0.1 0))
+# triangle inside a hole
+2|@poly_tin|TRIANGLE((1.4 1.4,1.6 1.4,1.6 1.6,1.4 1.4))|GEOMETRYCOLLECTION EMPTY
+3|@poly_tin|TRIANGLE((1.4 1.4,1.6 1.4,1.6 1.6,1.4 1.4))|GEOMETRYCOLLECTION EMPTY
+
+#
+# polygon x tin
+#
+
+# on a vertex
+2|@poly_tin|POLYGON((-1 -1,0 -1,0 0,-1 0,-1 -1))|POINT(0 0)
+3|@poly_tin|POLYGON((-1 -1,0 -1,0 0,-1 0,-1 -1))|POINT(0 0 0)
+# on an edge
+2|@poly_tin|POLYGON((-1 0,0 0,0 1,-1 1,-1 0))|LINESTRING(0 0,0 1)
+3|@poly_tin|POLYGON((-1 0,0 0,0 1,-1 1,-1 0))|LINESTRING(0 0 0,0 1 0)
+# overlapping
+2|@poly_tin|POLYGON((0 0,1 0,1 1,0 1,0 0))|GEOMETRYCOLLECTION(TRIANGLE((0 1,0 0,1 1,0 1)),TRIANGLE((1 1,0 0,1 0,1 1)))
+3|@poly_tin|POLYGON((0 0,1 0,1 1,0 1,0 0))|TIN(((1/2 1/2 0/1,0/1 1/1 0/1,0/1 0/1 0/1,1/2 1/2 0/1)),((1/2 1/2 0/1,0/1 0/1 0/1,1/1 0/1 0/1,1/2 1/2 0/1)),((1/2 1/2 0/1,1/1 0/1 0/1,1/1 1/1 0/1,1/2 1/2 0/1)),((0/1 1/1 0/1,1/2 1/2 0/1,1/1 1/1 0/1,0/1 1/1 0/1)))
+# inside a hole
+2|@poly_tin|POLYGON((1.4 1.4,1.6 1.4,1.6 1.6,1.4 1.6,1.4 1.4))|GEOMETRYCOLLECTION EMPTY
+3|@poly_tin|POLYGON((1.4 1.4,1.6 1.4,1.6 1.6,1.4 1.6,1.4 1.4))|GEOMETRYCOLLECTION EMPTY
+# overlapping a hole => multipolygon
+2|@poly_tin|POLYGON((1.4 0,1.6 0,1.6 2,1.4 2,1.4 0))|MULTIPOLYGON(((7/5 2/1,7/5 61/35,8/5 64/35,8/5 2/1,7/5 2/1)),((8/5 13/10,7/5 13/10,7/5 39/35,8/5 26/35,8/5 13/10)),((7/5 61/35,7/5 17/10,8/5 17/10,8/5 64/35,7/5 61/35)),((7/5 39/35,7/5 0/1,8/5 0/1,8/5 26/35,7/5 39/35)))
+# FIXME => multi TIN ? DONE IN SFCGAL 1.1
+3|@poly_tin|POLYGON((1.4 0,1.6 0,1.6 2,1.4 2,1.4 0))|GEOMETRYCOLLECTION(TIN(((7/5 2/1 0/1,104/73 128/73 0/1,8/5 64/35 0/1,7/5 2/1 0/1)),((8/5 2/1 0/1,7/5 2/1 0/1,8/5 64/35 0/1,8/5 2/1 0/1)),((104/73 128/73 0/1,143/100 17/10 0/1,8/5 17/10 0/1,104/73 128/73 0/1)),((8/5 64/35 0/1,104/73 128/73 0/1,8/5 17/10 0/1,8/5 64/35 0/1)),((104/73 128/73 0/1,7/5 2/1 0/1,7/5 61/35 0/1,104/73 128/73 0/1)),((143/100 17/10 0/1,104/73 128/73 0/1,7/5 61/35 0/1,143/100 17/10 0/1)),((7/5 17/10 0/1,143/100 17/1 [...]
+#
+# tin x tin
+#
+
+# on a vertex
+2|@poly_tin|TIN(((-1 0,0 -1,0 0,-1 0)),((-1 0,-1 -1,0 -1,-1 0)))|POINT(0 0)
+3|@poly_tin|TIN(((-1 0,0 -1,0 0,-1 0)),((-1 0,-1 -1,0 -1,-1 0)))|POINT(0 0 0)
+# on an edge
+2|@poly_tin|TIN(((-1 1,0 0,0 1,-1 1)),((-1 1,-1 0,0 0,-1 1)))|LINESTRING(0 0,0 1)
+3|@poly_tin|TIN(((-1 1,0 0,0 1,-1 1)),((-1 1,-1 0,0 0,-1 1)))|LINESTRING(0 0 0,0 1 0)
+# overlapping
+# FIXME : fix the output
+2|@poly_tin|TIN(((0 1,1 0,1 1,0 1)),((0 1,0 0,1 0,0 1)))|GEOMETRYCOLLECTION(TRIANGLE((1 -0,0 0,0.5 0.5,1 -0)),TRIANGLE((0.5 0.5,0 0,-0 1,0.5 0.5)),TRIANGLE((1 1,0.5 0.5,0 1,1 1)),TRIANGLE((1 0,0.5 0.5,1 1,1 0)))
+3|@poly_tin|TIN(((0 1,1 0,1 1,0 1)),((0 1,0 0,1 0,0 1)))|TIN(((1/2 1/2 0/1,0/1 1/1 0/1,0/1 0/1 0/1,1/2 1/2 0/1)),((1/2 1/2 0/1,0/1 0/1 0/1,1/1 0/1 0/1,1/2 1/2 0/1)),((1/2 1/2 0/1,1/1 0/1 0/1,1/1 1/1 0/1,1/2 1/2 0/1)),((0/1 1/1 0/1,1/2 1/2 0/1,1/1 1/1 0/1,0/1 1/1 0/1)))
+# inside a hole
+2|@poly_tin|TIN(((1.4 1.6,1.6 1.4,1.6 1.6,1.4 1.6)),((1.4 1.6,1.4 1.4,1.6 1.4,1.4 1.6)))|GEOMETRYCOLLECTION EMPTY
+3|@poly_tin|TIN(((1.4 1.6,1.6 1.4,1.6 1.6,1.4 1.6)),((1.4 1.6,1.4 1.4,1.6 1.4,1.4 1.6)))|GEOMETRYCOLLECTION EMPTY
+# overlapping a hole => multipolygon
+# FIXME fix output
+2|@poly_tin|TIN(((1.4 2,1.6 0,1.6 2,1.4 2)),((1.4 2,1.4 0,1.6 0,1.4 2)))|GEOMETRYCOLLECTION(POLYGON((8/5 64/35,104/73 128/73,7/5 2/1,8/5 2/1,8/5 64/35)),TRIANGLE((104/73 128/73,7/5 61/35,7/5 2/1,104/73 128/73)),TRIANGLE((8/5 0/1,86/57 52/57,8/5 26/35,8/5 0/1)),POLYGON((8/5 17/10,143/100 17/10,104/73 128/73,8/5 64/35,8/5 17/10)),POLYGON((143/100 17/10,7/5 17/10,7/5 61/35,104/73 128/73,143/100 17/10)),POLYGON((8/5 26/35,86/57 52/57,147/100 13/10,8/5 13/10,8/5 26/35)),POLYGON((8/5 0/1,7/5 0 [...]
+# FIXME => multi TIN ? DONE IN SFCGAL 1.1
+3|@poly_tin|TIN(((1.4 2,1.6 0,1.6 2,1.4 2)),((1.4 2,1.4 0,1.6 0,1.4 2)))|GEOMETRYCOLLECTION(TIN(((143/100 17/10 0/1,104/73 128/73 0/1,7/5 61/35 0/1,143/100 17/10 0/1)),((7/5 17/10 0/1,143/100 17/10 0/1,7/5 61/35 0/1,7/5 17/10 0/1)),((104/73 128/73 0/1,7/5 2/1 0/1,7/5 61/35 0/1,104/73 128/73 0/1)),((7/5 2/1 0/1,104/73 128/73 0/1,8/5 64/35 0/1,7/5 2/1 0/1)),((8/5 2/1 0/1,7/5 2/1 0/1,8/5 64/35 0/1,8/5 2/1 0/1)),((104/73 128/73 0/1,143/100 17/10 0/1,8/5 17/10 0/1,104/73 128/73 0/1)),((8/5 64 [...]
+
+
+#
+# point x solid
+#
+
+# store the cube
+S|cube|SOLID((((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)),((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)),((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)),((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)),((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0))))
+
+# point on a vertex
+3|@cube|POINT(0 0 0)|@B
+# point on an edge
+3|@cube|POINT(0.5 0 0)|@B
+# point on a face
+3|@cube|POINT(0.5 0.5 0)|@B
+# point inside
+3|@cube|POINT(0.5 0.5 0.5)|@B
+# point outside
+3|@cube|POINT(2 2 2)|GEOMETRYCOLLECTION EMPTY
+
+#
+# linestring x solid
+#
+
+
+# on a vertex
+3|@cube|LINESTRING(-1 0 0,0 0 0)|POINT(0 0 0)
+# on an edge
+3|@cube|LINESTRING(-1 0,2 0)|LINESTRING(0 0 0,1 0 0)
+# inside a face
+3|@cube|LINESTRING(-1 0.5 0.5,0.5 0.5 0.5)|LINESTRING(0 0.5 0.5,0.5 0.5 0.5)
+# completely inside
+3|@cube|LINESTRING(0.2 0.2 0.2,0.7 0.7 0.7)|@B
+
+#
+# triangle x solid
+#
+
+# on a vertex
+3|@cube|TRIANGLE((-1 -1,0 -1,0 0,-1 -1))|POINT(0 0 0)
+# overlapping giving a polygon
+3|@cube|TRIANGLE((-1 0,1 0,1 1,-1 0))|TIN(((0/1 0/1 0/1,1/1 0/1 0/1,1/1 1/1 0/1,0/1 0/1 0/1)),((1/1 1/1 0/1,0/1 1/2 0/1,0/1 0/1 0/1,1/1 1/1 0/1)))
+# overlapping giving a triangle
+# FIXME : should be a triangle
+3|@cube|TRIANGLE((0.5 0,1.5 0,1.5 1,0.5 0))|TRIANGLE((1/1 0/1 0/1,1/1 1/2 0/1,1/2 0/1 0/1,1/1 0/1 0/1))
+# partly inside
+3|@cube|TRIANGLE((0.5 0 0.5,1.5 0 0.5,1.5 1 0.5,0.5 0 0.5))|TRIANGLE((1/1 0/1 1/2,1/1 1/2 1/2,1/2 0/1 1/2,1/1 0/1 1/2))
+# inside
+3|@cube|TRIANGLE((0.2 0.2 0.2,0.7 0.2 0.2,0.7 0.7 0.2,0.2 0.2 0.2))|@B
+
+#
+# polygon x solid
+#
+
+# on a vertex
+3|@cube|POLYGON((-1 -1,0 -1,0 0,-1 0,-1 -1))|POINT(0 0 0)
+# on an edge
+3|@cube|POLYGON((-1 0,0 0,0 0.5,-1 0.5,-1 0))|LINESTRING(0 0 0,0 0.5 0)
+# overlapping giving a polygon
+3|@cube|POLYGON((0.5 0 0,1.5 0 0,1.5 0.5 0,0.5 0.5 0,0.5 0 0))|TIN(((1/1 1/4 0/1,1/2 1/2 0/1,1/2 0/1 0/1,1/1 1/4 0/1)),((1/1 0/1 0/1,1/1 1/4 0/1,1/2 0/1 0/1,1/1 0/1 0/1)),((1/1 1/4 0/1,1/1 1/2 0/1,1/2 1/2 0/1,1/1 1/4 0/1)))
+# partly inside
+3|@cube|POLYGON((0.5 0 0.5,1.5 0 0.5,1.5 0.5 0.5,0.5 0.5 0.5,0.5 0 0.5))|TIN(((1/1 1/4 1/2,1/2 0/1 1/2,1/1 0/1 1/2,1/1 1/4 1/2)),((1/2 1/2 1/2,1/2 0/1 1/2,1/1 1/4 1/2,1/2 1/2 1/2)),((1/1 1/4 1/2,1/1 1/2 1/2,1/2 1/2 1/2,1/1 1/4 1/2)))
+# inside
+3|@cube|POLYGON((0.2 0.2 0.2,0.7 0.2 0.2,0.7 0.7 0.2,0.2 0.7 0.2,0.2 0.2 0.2))|TIN(((1/5 7/10 1/5,1/5 1/5 1/5,7/10 1/5 1/5,1/5 7/10 1/5)),((1/5 7/10 1/5,7/10 1/5 1/5,7/10 7/10 1/5,1/5 7/10 1/5)))
+# concave polygone that touches on two points
+3|@cube|POLYGON((0.2 0.5 0, 0.2 0.5 -1, 0.8 0.5 -1, 0.8 0.5 0, 0.5 0.5 -0.5, 0.2 0.5 0))|MULTIPOINT(0.8 0.5 0,0.2 0.5 0)
+# cube inside a hole
+3|@cube|POLYGON((-1 -1,2 -1,2 2,-1 2,-1 -1),(-0.5 -0.5,-0.5 1.5,1.5 1.5,1.5 -0.5,-0.5 -0.5))|GEOMETRYCOLLECTION EMPTY
+
+#
+# polyhedral x solid
+#
+
+# on a vertex
+3|@cube|POLYHEDRALSURFACE(((-1 0,0 -1,0 0,-1 0)),((-1 0,-1 -1,0 -1,-1 0)))|POINT(0 0 0)
+# on an edge
+3|@cube|POLYHEDRALSURFACE(((-1 0.5,0 0,0 0.5,-1 0.5)),((-1 0.5,-1 0,0 0,-1 0.5)))|LINESTRING(0 0 0,0 0.5 0)
+# overlapping giving a polygon
+3|@cube|POLYHEDRALSURFACE(((0.5 0.5 0,1.5 0 0,1.5 0.5 0,0.5 0.5 0)),((0.5 0.5 0,0.5 0 0,1.5 0 0,0.5 0.5 0)))|TIN(((1/2 1/2 0/1,1/1 1/4 0/1,1/1 1/2 0/1,1/2 1/2 0/1)),((1/1 0/1 0/1,1/1 1/4 0/1,1/2 1/2 0/1,1/1 0/1 0/1)),((1/2 1/2 0/1,1/2 0/1 0/1,1/1 0/1 0/1,1/2 1/2 0/1)))
+# partly inside
+3|@cube|POLYHEDRALSURFACE(((0.5 0.5 0.5,1.5 0 0.5,1.5 0.5 0.5,0.5 0.5 0.5)),((0.5 0.5 0.5,0.5 0 0.5,1.5 0 0.5,0.5 0.5 0.5)))|TIN(((1/1 1/4 1/2,1/1 1/2 1/2,1/2 1/2 1/2,1/1 1/4 1/2)),((1/1 1/4 1/2,1/2 0/1 1/2,1/1 0/1 1/2,1/1 1/4 1/2)),((1/2 1/2 1/2,1/2 0/1 1/2,1/1 1/4 1/2,1/2 1/2 1/2)))
+# inside
+3|@cube|POLYHEDRALSURFACE(((0.2 0.7 0.2,0.7 0.2 0.2,0.7 0.7 0.2,0.2 0.7 0.2)),((0.2 0.7 0.2,0.2 0.2 0.2,0.7 0.2 0.2,0.2 0.7 0.2)))|TIN(((1/5 7/10 1/5,1/5 1/5 1/5,7/10 1/5 1/5,1/5 7/10 1/5)),((1/5 7/10 1/5,7/10 1/5 1/5,7/10 7/10 1/5,1/5 7/10 1/5)))
+# concave polygone that touches on two points
+3|@cube|POLYHEDRALSURFACE(((0.5 0.5 -0.5,0.2 0.5 -1,0.8 0.5 -1,0.5 0.5 -0.5)),((0.8 0.5 0,0.5 0.5 -0.5,0.8 0.5 -1,0.8 0.5 0)),((0.2 0.5 0,0.2 0.5 -1,0.5 0.5 -0.5,0.2 0.5 0)))|MULTIPOINT(0.8 0.5 0,0.2 0.5 0)
+# cube inside a hole
+3|@cube|POLYHEDRALSURFACE(((1.5 -0.5,-0.5 -0.5,-1 -1,1.5 -0.5)),((1.5 -0.5,-1 -1,2 -1,1.5 -0.5)),((-1 2,-1 -1,-0.5 -0.5,-1 2)),((-1 2,-0.5 1.5,1.5 1.5,-1 2)),((-1 2,-0.5 -0.5,-0.5 1.5,-1 2)),((2 2,1.5 1.5,2 -1,2 2)),((2 2,-1 2,1.5 1.5,2 2)),((1.5 1.5,1.5 -0.5,2 -1,1.5 1.5)))|GEOMETRYCOLLECTION EMPTY
+
+#
+# tin x solid
+#
+
+# on a vertex
+3|@cube|TIN(((-1 0,0 -1,0 0,-1 0)),((-1 0,-1 -1,0 -1,-1 0)))|POINT(0 0 0)
+# on an edge
+3|@cube|TIN(((-1 0.5,0 0,0 0.5,-1 0.5)),((-1 0.5,-1 0,0 0,-1 0.5)))|LINESTRING(0 0 0,0 0.5 0)
+# overlapping giving a polygon
+3|@cube|TIN(((0.5 0.5 0,1.5 0 0,1.5 0.5 0,0.5 0.5 0)),((0.5 0.5 0,0.5 0 0,1.5 0 0,0.5 0.5 0)))|TIN(((1/1 1/4 0/1,1/2 1/2 0/1,1/2 0/1 0/1,1/1 1/4 0/1)),((1/1 0/1 0/1,1/1 1/4 0/1,1/2 0/1 0/1,1/1 0/1 0/1)),((1/1 1/4 0/1,1/1 1/2 0/1,1/2 1/2 0/1,1/1 1/4 0/1)))
+# partly inside
+3|@cube|TIN(((0.5 0.5 0.5,1.5 0 0.5,1.5 0.5 0.5,0.5 0.5 0.5)),((0.5 0.5 0.5,0.5 0 0.5,1.5 0 0.5,0.5 0.5 0.5)))|TIN(((1/1 1/4 1/2,1/1 1/2 1/2,1/2 1/2 1/2,1/1 1/4 1/2)),((1/1 1/4 1/2,1/2 1/2 1/2,1/2 0/1 1/2,1/1 1/4 1/2)),((1/1 0/1 1/2,1/1 1/4 1/2,1/2 0/1 1/2,1/1 0/1 1/2)))
+# inside
+3|@cube|TIN(((0.2 0.7 0.2,0.7 0.2 0.2,0.7 0.7 0.2,0.2 0.7 0.2)),((0.2 0.7 0.2,0.2 0.2 0.2,0.7 0.2 0.2,0.2 0.7 0.2)))|TIN(((1/5 7/10 1/5,1/5 1/5 1/5,7/10 1/5 1/5,1/5 7/10 1/5)),((1/5 7/10 1/5,7/10 1/5 1/5,7/10 7/10 1/5,1/5 7/10 1/5)))
+# concave polygone that touches on two points
+3|@cube|TIN(((0.5 0.5 -0.5,0.2 0.5 -1,0.8 0.5 -1,0.5 0.5 -0.5)),((0.8 0.5 0,0.5 0.5 -0.5,0.8 0.5 -1,0.8 0.5 0)),((0.2 0.5 0,0.2 0.5 -1,0.5 0.5 -0.5,0.2 0.5 0)))|MULTIPOINT(0.8 0.5 0,0.2 0.5 0)
+# cube inside a hole
+3|@cube|TIN(((1.5 -0.5,-0.5 -0.5,-1 -1,1.5 -0.5)),((1.5 -0.5,-1 -1,2 -1,1.5 -0.5)),((-1 2,-1 -1,-0.5 -0.5,-1 2)),((-1 2,-0.5 1.5,1.5 1.5,-1 2)),((-1 2,-0.5 -0.5,-0.5 1.5,-1 2)),((2 2,1.5 1.5,2 -1,2 2)),((2 2,-1 2,1.5 1.5,2 2)),((1.5 1.5,1.5 -0.5,2 -1,1.5 1.5)))|GEOMETRYCOLLECTION EMPTY
+
+#
+# solid x solid
+#
+
+# cube x cube => cube (its TIN version)
+3|@cube|@cube|SOLID((((1 1 0,0 1 0,1 1 1,1 1 0)),((1 1 1,1 0 1,1 1 0,1 1 1)),((0 1 0,0 1 1,1 1 1,0 1 0)),((1 1 0,0 0 0,0 1 0,1 1 0)),((1 0 1,1 0 0,1 1 0,1 0 1)),((1 1 1,0 1 1,1 0 1,1 1 1)),((0 1 0,0 0 0,0 1 1,0 1 0)),((1 1 0,1 0 0,0 0 0,1 1 0)),((1 0 1,0 0 1,1 0 0,1 0 1)),((0 1 1,0 0 1,1 0 1,0 1 1)),((0 0 0,0 0 1,0 1 1,0 0 0)),((1 0 0,0 0 1,0 0 0,1 0 0))))
+# cube x displaced cube (-1 -1 -1) => point
+3|SOLID((((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)),((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)),((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)),((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)),((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0))))|SOLID((((-1 -1 -1,-1 0 -1,0 0 -1,0 -1 -1,-1 -1 -1)),((0 -1 -1,0 0 -1,0 0 0,0 -1 0,0 -1 -1)),((-1 0 -1,-1 0 0,0 0 0,0 0 -1,-1 0 -1)),((-1 -1 0,-1 0 0,-1 0 -1,-1 -1 -1,-1 -1 0)),((0 -1 0,0 0 0,-1 0 0,-1 -1 0,0 -1 0)),((0 -1 -1,0 -1 0,-1 -1 0,-1 -1 -1,0 -1 -1))))|POINT(0 0 0)
+3|@cube|SOLID((((-1 -1 -1,-1 0 -1,0 0 -1,0 -1 -1,-1 -1 -1)),((0 -1 -1,0 0 -1,0 0 0,0 -1 0,0 -1 -1)),((-1 0 -1,-1 0 0,0 0 0,0 0 -1,-1 0 -1)),((-1 -1 0,-1 0 0,-1 0 -1,-1 -1 -1,-1 -1 0)),((0 -1 0,0 0 0,-1 0 0,-1 -1 0,0 -1 0)),((0 -1 -1,0 -1 0,-1 -1 0,-1 -1 -1,0 -1 -1))))|POINT(0 0 0)
+# cube x displaced cube (-1 -1 0) => line
+3|@cube|SOLID((((-1 -1 0,-1 0 0,0 0 0,0 -1 0,-1 -1 0)),((0 -1 0,0 0 0,0 0 1,0 -1 1,0 -1 0)),((-1 0 0,-1 0 1,0 0 1,0 0 0,-1 0 0)),((-1 -1 1,-1 0 1,-1 0 0,-1 -1 0,-1 -1 1)),((0 -1 1,0 0 1,-1 0 1,-1 -1 1,0 -1 1)),((0 -1 0,0 -1 1,-1 -1 1,-1 -1 0,0 -1 0))))|LINESTRING(0 0 0,0 0 1)
+# cube x displaced cube (-1 0 0) => face
+3|@cube|SOLID((((-1 -0 -0,-1 1 -0,-0 1 -0,-0 -0 -0,-1 -0 -0)),((-0 -0 -0,-0 1 -0,-0 1 1,-0 -0 1,-0 -0 -0)),((-1 1 -0,-1 1 1,-0 1 1,-0 1 -0,-1 1 -0)),((-1 -0 1,-1 1 1,-1 1 -0,-1 -0 -0,-1 -0 1)),((-0 -0 1,-0 1 1,-1 1 1,-1 -0 1,-0 -0 1)),((-0 -0 -0,-0 -0 1,-1 -0 1,-1 -0 -0,-0 -0 -0))))|TIN(((0 0.5 0.5,0 0 1,0 0 0,0 0.5 0.5)),((0 0 1,0 0.5 0.5,0 1 1,0 0 1)),((0 0.5 0.5,0 0 0,0 1 0,0 0.5 0.5)),((0 0.5 0.5,0 1 0,0 1 1,0 0.5 0.5)))
+# cube x displaced cube (+0.5 0 0) => small cube
+3|@cube|SOLID((((0.5 0 0,0.5 1 0,1.5 1 0,1.5 0 0,0.5 0 0)),((1.5 0 0,1.5 1 0,1.5 1 1,1.5 0 1,1.5 0 0)),((0.5 1 0,0.5 1 1,1.5 1 1,1.5 1 0,0.5 1 0)),((0.5 0 1,0.5 1 1,0.5 1 0,0.5 0 0,0.5 0 1)),((1.5 0 1,1.5 1 1,0.5 1 1,0.5 0 1,1.5 0 1)),((1.5 0 0,1.5 0 1,0.5 0 1,0.5 0 0,1.5 0 0))))|SOLID((((1 0.5 0,1 0 0,0.5 0 0,1 0.5 0)),((0.5 0 0,0.5 0.5 0,1 0.5 0,0.5 0 0)),((1 0 0,0.5 0 0.5,0.5 0 0,1 0 0)),((1 0.5 0,1 0 0.5,1 0 0,1 0.5 0)),((0.5 0.5 0,1 1 0,1 0.5 0,0.5 0.5 0)),((0.5 0 0,0.5 1 1,0.5 0.5 [...]
+
+# store an 'inverted' cube
+S|inverted_cube|SOLID((((0 0 0,0 1 0,0 1 1,0 0 1,0 0 0)),((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0)),((0 0 0,0 0 1,1 0 1,1 0 0,0 0 0)),((1 0 0,1 0 1,1 1 1,1 1 0,1 0 0)),((0 0 1,0 1 1,1 1 1,1 0 1,0 0 1)),((0 1 0,1 1 0,1 1 1,0 1 1,0 1 0))))
+
+# point on a vertex
+3|@inverted_cube|POINT(0 0 0)|@B
+# point on an edge
+3|@inverted_cube|POINT(0.5 0 0)|@B
+# point on a face
+3|@inverted_cube|POINT(0.5 0.5 0)|@B
+# point inside
+3|@inverted_cube|POINT(0.5 0.5 0.5)|@B
+# point outside
+3|@inverted_cube|POINT(2 2 2)|GEOMETRYCOLLECTION EMPTY
+
+#
+# linestring x solid
+#
+
+
+# on a vertex
+3|@inverted_cube|LINESTRING(-1 0 0,0 0 0)|POINT(0 0 0)
+# on an edge
+3|@inverted_cube|LINESTRING(-1 0,2 0)|LINESTRING(0 0 0,1 0 0)
+# inside a face
+3|@inverted_cube|LINESTRING(-1 0.5 0.5,0.5 0.5 0.5)|LINESTRING(0 0.5 0.5,0.5 0.5 0.5)
+# completely inside
+3|@inverted_cube|LINESTRING(0.2 0.2 0.2,0.7 0.7 0.7)|@B
+
+#
+# triangle x solid
+#
+
+# on a vertex
+3|@inverted_cube|TRIANGLE((-1 -1,0 -1,0 0,-1 -1))|POINT(0 0 0)
+# overlapping giving a polygon
+3|@inverted_cube|TRIANGLE((-1 0,1 0,1 1,-1 0))|TIN(((0 0 0,1/3 2/3 0,0 1/2 0,0 0 0)),((0 0 0,1 0 0,1/3 2/3 0,0 0 0)),((1 0 0,1 1 0,1/3 2/3 0,1 0 0)))
+# overlapping giving a triangle
+3|@inverted_cube|TRIANGLE((0.5 0,1.5 0,1.5 1,0.5 0))|TIN(((3/4 1/4 0/1,1/1 0/1 0/1,1/1 1/2 0/1,3/4 1/4 0/1)),((1/2 0/1 0/1,1/1 0/1 0/1,3/4 1/4 0/1,1/2 0/1 0/1)))
+# partly inside
+3|@inverted_cube|TRIANGLE((0.5 0 0.5,1.5 0 0.5,1.5 1 0.5,0.5 0 0.5))|TRIANGLE((1/1 0/1 1/2,1/1 1/2 1/2,1/2 0/1 1/2,1/1 0/1 1/2))
+# inside
+3|@inverted_cube|TRIANGLE((0.2 0.2 0.2,0.7 0.2 0.2,0.7 0.7 0.2,0.2 0.2 0.2))|@B
+
+#
+# polygon x solid
+#
+
+# on a vertex
+3|@inverted_cube|POLYGON((-1 -1,0 -1,0 0,-1 0,-1 -1))|POINT(0 0 0)
+# on an edge
+3|@inverted_cube|POLYGON((-1 0,0 0,0 0.5,-1 0.5,-1 0))|LINESTRING(0 0 0,0 0.5 0)
+# overlapping giving a polygon
+3|@inverted_cube|POLYGON((0.5 0 0,1.5 0 0,1.5 0.5 0,0.5 0.5 0,0.5 0 0))|TIN(((1/1 1/4 0/1,1/2 1/2 0/1,1/2 0/1 0/1,1/1 1/4 0/1)),((1/1 0/1 0/1,1/1 1/4 0/1,1/2 0/1 0/1,1/1 0/1 0/1)),((1/1 1/4 0/1,1/1 1/2 0/1,1/2 1/2 0/1,1/1 1/4 0/1)))
+# partly inside
+3|@inverted_cube|POLYGON((0.5 0 0.5,1.5 0 0.5,1.5 0.5 0.5,0.5 0.5 0.5,0.5 0 0.5))|TIN(((1/1 1/4 1/2,1/2 0/1 1/2,1/1 0/1 1/2,1/1 1/4 1/2)),((1/2 1/2 1/2,1/2 0/1 1/2,1/1 1/4 1/2,1/2 1/2 1/2)),((1/1 1/4 1/2,1/1 1/2 1/2,1/2 1/2 1/2,1/1 1/4 1/2)))
+# inside
+3|@inverted_cube|POLYGON((0.2 0.2 0.2,0.7 0.2 0.2,0.7 0.7 0.2,0.2 0.7 0.2,0.2 0.2 0.2))|TIN(((1/5 7/10 1/5,1/5 1/5 1/5,7/10 1/5 1/5,1/5 7/10 1/5)),((1/5 7/10 1/5,7/10 1/5 1/5,7/10 7/10 1/5,1/5 7/10 1/5)))
+# concave polygone that touches on two points
+3|@inverted_cube|POLYGON((0.2 0.5 0, 0.2 0.5 -1, 0.8 0.5 -1, 0.8 0.5 0, 0.5 0.5 -0.5, 0.2 0.5 0))|MULTIPOINT(0.8 0.5 0,0.2 0.5 0)
+# cube inside a hole
+3|@inverted_cube|POLYGON((-1 -1,2 -1,2 2,-1 2,-1 -1),(-0.5 -0.5,-0.5 1.5,1.5 1.5,1.5 -0.5,-0.5 -0.5))|GEOMETRYCOLLECTION EMPTY
+
+#
+# polyhedral x solid
+#
+
+# on a vertex
+3|@inverted_cube|POLYHEDRALSURFACE(((-1 0,0 -1,0 0,-1 0)),((-1 0,-1 -1,0 -1,-1 0)))|POINT(0 0 0)
+# on an edge
+3|@inverted_cube|POLYHEDRALSURFACE(((-1 0.5,0 0,0 0.5,-1 0.5)),((-1 0.5,-1 0,0 0,-1 0.5)))|LINESTRING(0 0 0,0 0.5 0)
+# overlapping giving a polygon
+3|@inverted_cube|POLYHEDRALSURFACE(((0.5 0.5 0,1.5 0 0,1.5 0.5 0,0.5 0.5 0)),((0.5 0.5 0,0.5 0 0,1.5 0 0,0.5 0.5 0)))|TIN(((1/2 1/2 0/1,1/1 1/4 0/1,1/1 1/2 0/1,1/2 1/2 0/1)),((1/1 0/1 0/1,1/1 1/4 0/1,1/2 1/2 0/1,1/1 0/1 0/1)),((1/2 1/2 0/1,1/2 0/1 0/1,1/1 0/1 0/1,1/2 1/2 0/1)))
+# partly inside
+3|@inverted_cube|POLYHEDRALSURFACE(((0.5 0.5 0.5,1.5 0 0.5,1.5 0.5 0.5,0.5 0.5 0.5)),((0.5 0.5 0.5,0.5 0 0.5,1.5 0 0.5,0.5 0.5 0.5)))|TIN(((1/1 1/4 1/2,1/1 1/2 1/2,1/2 1/2 1/2,1/1 1/4 1/2)),((1/1 1/4 1/2,1/2 0/1 1/2,1/1 0/1 1/2,1/1 1/4 1/2)),((1/2 1/2 1/2,1/2 0/1 1/2,1/1 1/4 1/2,1/2 1/2 1/2)))
+# inside
+3|@inverted_cube|POLYHEDRALSURFACE(((0.2 0.7 0.2,0.7 0.2 0.2,0.7 0.7 0.2,0.2 0.7 0.2)),((0.2 0.7 0.2,0.2 0.2 0.2,0.7 0.2 0.2,0.2 0.7 0.2)))|TIN(((1/5 7/10 1/5,1/5 1/5 1/5,7/10 1/5 1/5,1/5 7/10 1/5)),((1/5 7/10 1/5,7/10 1/5 1/5,7/10 7/10 1/5,1/5 7/10 1/5)))
+# concave polygone that touches on two points
+3|@inverted_cube|POLYHEDRALSURFACE(((0.5 0.5 -0.5,0.2 0.5 -1,0.8 0.5 -1,0.5 0.5 -0.5)),((0.8 0.5 0,0.5 0.5 -0.5,0.8 0.5 -1,0.8 0.5 0)),((0.2 0.5 0,0.2 0.5 -1,0.5 0.5 -0.5,0.2 0.5 0)))|MULTIPOINT(0.8 0.5 0,0.2 0.5 0)
+# cube inside a hole
+3|@inverted_cube|POLYHEDRALSURFACE(((1.5 -0.5,-0.5 -0.5,-1 -1,1.5 -0.5)),((1.5 -0.5,-1 -1,2 -1,1.5 -0.5)),((-1 2,-1 -1,-0.5 -0.5,-1 2)),((-1 2,-0.5 1.5,1.5 1.5,-1 2)),((-1 2,-0.5 -0.5,-0.5 1.5,-1 2)),((2 2,1.5 1.5,2 -1,2 2)),((2 2,-1 2,1.5 1.5,2 2)),((1.5 1.5,1.5 -0.5,2 -1,1.5 1.5)))|GEOMETRYCOLLECTION EMPTY
+
+#
+# tin x solid
+#
+
+# on a vertex
+3|@inverted_cube|TIN(((-1 0,0 -1,0 0,-1 0)),((-1 0,-1 -1,0 -1,-1 0)))|POINT(0 0 0)
+# on an edge
+3|@inverted_cube|TIN(((-1 0.5,0 0,0 0.5,-1 0.5)),((-1 0.5,-1 0,0 0,-1 0.5)))|LINESTRING(0 0 0,0 0.5 0)
+# overlapping giving a polygon
+3|@inverted_cube|TIN(((0.5 0.5 0,1.5 0 0,1.5 0.5 0,0.5 0.5 0)),((0.5 0.5 0,0.5 0 0,1.5 0 0,0.5 0.5 0)))|TIN(((1/1 1/4 0/1,1/2 1/2 0/1,1/2 0/1 0/1,1/1 1/4 0/1)),((1/1 0/1 0/1,1/1 1/4 0/1,1/2 0/1 0/1,1/1 0/1 0/1)),((1/1 1/4 0/1,1/1 1/2 0/1,1/2 1/2 0/1,1/1 1/4 0/1)))
+# partly inside
+3|@inverted_cube|TIN(((0.5 0.5 0.5,1.5 0 0.5,1.5 0.5 0.5,0.5 0.5 0.5)),((0.5 0.5 0.5,0.5 0 0.5,1.5 0 0.5,0.5 0.5 0.5)))|TIN(((1/1 1/4 1/2,1/1 1/2 1/2,1/2 1/2 1/2,1/1 1/4 1/2)),((1/1 1/4 1/2,1/2 1/2 1/2,1/2 0/1 1/2,1/1 1/4 1/2)),((1/1 0/1 1/2,1/1 1/4 1/2,1/2 0/1 1/2,1/1 0/1 1/2)))
+# inside
+3|@inverted_cube|TIN(((0.2 0.7 0.2,0.7 0.2 0.2,0.7 0.7 0.2,0.2 0.7 0.2)),((0.2 0.7 0.2,0.2 0.2 0.2,0.7 0.2 0.2,0.2 0.7 0.2)))|TIN(((1/5 7/10 1/5,1/5 1/5 1/5,7/10 1/5 1/5,1/5 7/10 1/5)),((1/5 7/10 1/5,7/10 1/5 1/5,7/10 7/10 1/5,1/5 7/10 1/5)))
+# concave polygone that touches on two points
+3|@inverted_cube|TIN(((0.5 0.5 -0.5,0.2 0.5 -1,0.8 0.5 -1,0.5 0.5 -0.5)),((0.8 0.5 0,0.5 0.5 -0.5,0.8 0.5 -1,0.8 0.5 0)),((0.2 0.5 0,0.2 0.5 -1,0.5 0.5 -0.5,0.2 0.5 0)))|MULTIPOINT(0.8 0.5 0,0.2 0.5 0)
+# cube inside a hole
+3|@inverted_cube|TIN(((1.5 -0.5,-0.5 -0.5,-1 -1,1.5 -0.5)),((1.5 -0.5,-1 -1,2 -1,1.5 -0.5)),((-1 2,-1 -1,-0.5 -0.5,-1 2)),((-1 2,-0.5 1.5,1.5 1.5,-1 2)),((-1 2,-0.5 -0.5,-0.5 1.5,-1 2)),((2 2,1.5 1.5,2 -1,2 2)),((2 2,-1 2,1.5 1.5,2 2)),((1.5 1.5,1.5 -0.5,2 -1,1.5 1.5)))|GEOMETRYCOLLECTION EMPTY
+
+#
+# solid x solid
+#
+
+# cube x cube => cube (its TIN version)
+3|@inverted_cube|@inverted_cube|SOLID((((1 1 0,0 1 0,1 1 1,1 1 0)),((1 1 1,1 0 1,1 1 0,1 1 1)),((0 1 0,0 1 1,1 1 1,0 1 0)),((1 1 0,0 0 0,0 1 0,1 1 0)),((1 0 1,1 0 0,1 1 0,1 0 1)),((1 1 1,0 1 1,1 0 1,1 1 1)),((0 1 0,0 0 0,0 1 1,0 1 0)),((1 1 0,1 0 0,0 0 0,1 1 0)),((1 0 1,0 0 1,1 0 0,1 0 1)),((0 1 1,0 0 1,1 0 1,0 1 1)),((0 0 0,0 0 1,0 1 1,0 0 0)),((1 0 0,0 0 1,0 0 0,1 0 0))))
+# cube x displaced cube (-1 -1 -1) => point
+3|SOLID((((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)),((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)),((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)),((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)),((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0))))|SOLID((((-1 -1 -1,-1 0 -1,0 0 -1,0 -1 -1,-1 -1 -1)),((0 -1 -1,0 0 -1,0 0 0,0 -1 0,0 -1 -1)),((-1 0 -1,-1 0 0,0 0 0,0 0 -1,-1 0 -1)),((-1 -1 0,-1 0 0,-1 0 -1,-1 -1 -1,-1 -1 0)),((0 -1 0,0 0 0,-1 0 0,-1 -1 0,0 -1 0)),((0 -1 -1,0 -1 0,-1 -1 0,-1 -1 -1,0 -1 -1))))|POINT(0 0 0)
+3|@inverted_cube|SOLID((((-1 -1 -1,-1 0 -1,0 0 -1,0 -1 -1,-1 -1 -1)),((0 -1 -1,0 0 -1,0 0 0,0 -1 0,0 -1 -1)),((-1 0 -1,-1 0 0,0 0 0,0 0 -1,-1 0 -1)),((-1 -1 0,-1 0 0,-1 0 -1,-1 -1 -1,-1 -1 0)),((0 -1 0,0 0 0,-1 0 0,-1 -1 0,0 -1 0)),((0 -1 -1,0 -1 0,-1 -1 0,-1 -1 -1,0 -1 -1))))|POINT(0 0 0)
+# cube x displaced cube (-1 -1 0) => line
+# FIXME : wrong result !
+3|@inverted_cube|SOLID((((-1 -1 0,-1 0 0,0 0 0,0 -1 0,-1 -1 0)),((0 -1 0,0 0 0,0 0 1,0 -1 1,0 -1 0)),((-1 0 0,-1 0 1,0 0 1,0 0 0,-1 0 0)),((-1 -1 1,-1 0 1,-1 0 0,-1 -1 0,-1 -1 1)),((0 -1 1,0 0 1,-1 0 1,-1 -1 1,0 -1 1)),((0 -1 0,0 -1 1,-1 -1 1,-1 -1 0,0 -1 0))))|LINESTRING(0 0 0,0 0 1)
+# cube x displaced cube (-1 0 0) => face
+# FIXME : wrong result !
+3|@inverted_cube|SOLID((((-1 -0 -0,-1 1 -0,-0 1 -0,-0 -0 -0,-1 -0 -0)),((-0 -0 -0,-0 1 -0,-0 1 1,-0 -0 1,-0 -0 -0)),((-1 1 -0,-1 1 1,-0 1 1,-0 1 -0,-1 1 -0)),((-1 -0 1,-1 1 1,-1 1 -0,-1 -0 -0,-1 -0 1)),((-0 -0 1,-0 1 1,-1 1 1,-1 -0 1,-0 -0 1)),((-0 -0 -0,-0 -0 1,-1 -0 1,-1 -0 -0,-0 -0 -0))))|TIN(((0/1 0/1 1/1,0/1 0/1 0/1,0/1 1/1 0/1,0/1 0/1 1/1)),((0/1 0/1 1/1,0/1 1/1 0/1,0/1 1/1 1/1,0/1 0/1 1/1)))
+# cube x displaced cube (+0.5 0 0) => small cube
+# FIXME : wrong result !
+3|@inverted_cube|SOLID((((0.5 0 0,0.5 1 0,1.5 1 0,1.5 0 0,0.5 0 0)),((1.5 0 0,1.5 1 0,1.5 1 1,1.5 0 1,1.5 0 0)),((0.5 1 0,0.5 1 1,1.5 1 1,1.5 1 0,0.5 1 0)),((0.5 0 1,0.5 1 1,0.5 1 0,0.5 0 0,0.5 0 1)),((1.5 0 1,1.5 1 1,0.5 1 1,0.5 0 1,1.5 0 1)),((1.5 0 0,1.5 0 1,0.5 0 1,0.5 0 0,1.5 0 0))))|SOLID((((1/1 1/1 0/1,1/1 1/1 1/2,1/1 1/2 0/1,1/1 1/1 0/1)),((1/1 1/2 0/1,1/2 1/2 0/1,1/1 1/1 0/1,1/1 1/2 0/1)),((1/1 1/1 1/2,1/1 0/1 0/1,1/1 1/2 0/1,1/1 1/1 1/2)),((1/1 1/1 0/1,3/4 1/1 1/4,1/1 1/1 1/2,1 [...]
+
+
+#
+# some limit cases
+#
+
+# double points
+2|POLYGON((0 0,10 0,10 0,10 10,0 10,0 0))|POLYGON((0 0,5 0,5 5,0 5,0 0))|POLYGON((5 5,0 5,0 0,5 0,5 5))
+3|POLYGON((0 0,10 0,10 0,10 10,0 10,0 0))|POLYGON((0 0,5 0,5 5,0 5,0 0))|TIN(((0 5 0,0 0 0,5 0 0,0 5 0)),((0 5 0,5 0 0,5 5 0,0 5 0)))
+# double points
+# FIXME clean output
+2|LINESTRING(0 0,0 10,10 10,10 0)|LINESTRING(10 10 4,10 0 5,0 0 5)|GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(10 0,10 10))
+3|LINESTRING(0 0,0 10,10 10,10 0)|LINESTRING(10 10 4,10 0 5,0 0 5)|GEOMETRYCOLLECTION EMPTY
+
+# intersection with empty
+2|POINT EMPTY|POINT EMPTY|GEOMETRYCOLLECTION EMPTY
+3|POINT EMPTY|POINT EMPTY|GEOMETRYCOLLECTION EMPTY
+2|LINESTRING EMPTY|LINESTRING(10 10 4,10 0 5,0 0 5)|GEOMETRYCOLLECTION EMPTY
+3|LINESTRING EMPTY|LINESTRING(10 10 4,10 0 5,0 0 5)|GEOMETRYCOLLECTION EMPTY
+2|POLYGON EMPTY|TRIANGLE((0 0,1 0,1 1,0 0))|GEOMETRYCOLLECTION EMPTY
+3|POLYGON EMPTY|TRIANGLE((0 0,1 0,1 1,0 0))|GEOMETRYCOLLECTION EMPTY
+2|POLYGON EMPTY|POLYGON((0 0,1 0,1 1,0 1,0 0))|GEOMETRYCOLLECTION EMPTY
+3|POLYGON EMPTY|POLYGON((0 0,1 0,1 1,0 1,0 0))|GEOMETRYCOLLECTION EMPTY
+
+# intersection of polygon with a hole that intersects the boundary
+2|POLYGON((-1/1 -1/1,1/1 -1/1,1/1 1/1,-1/1 1/1,-1/1 -1/1))|POLYGON((-1/1 -1/1,1/1 -1/1,1/1 1/1,-1/1 1/1,-1/1 -1/1),(-1/2 -1/2,-1/2 1/2,1/2 1/2,1/1 -1/2,-1/2 -1/2))|!NotImplemented
+
+# reversed polygons
+2|POLYGON((0 0,0 1,1 1,1 0,0 0))|POINT(0.5 0.5)|POINT(0.5 0.5)
+3|POLYGON((0 0,0 1,1 1,1 0,0 0))|POINT(0.5 0.5)|POINT(0.5 0.5 0)
+2|POLYGON((0 0,0 1,1 1,1 0,0 0))|LINESTRING(0 0,1 1)|LINESTRING(0 0,0.5 0.5,1 1)
+3|POLYGON((0 0,0 1,1 1,1 0,0 0))|LINESTRING(0 0,1 1)|LINESTRING(0 0 0,1 1 0)
+2|POLYGON((0 0,0 1,1 1,1 0,0 0))|POLYGON((0 0,1 0,1 1,0 1,0 0))|@B
+2|POLYGON((0 0,0 1,1 1,1 0,0 0),(0.4 0.4,0.6 0.4,0.6 0.6,0.4 0.6,0.4 0.4))|POLYGON((0 0,1 0,1 1,0 1,0 0))|@A
diff --git a/test/data/IntersectsTest.txt b/test/data/IntersectsTest.txt
new file mode 100644
index 0000000..8e42256
--- /dev/null
+++ b/test/data/IntersectsTest.txt
@@ -0,0 +1,493 @@
+#2d or 3d|gA|gB|expected
+
+# Point/Point
+2|POINT(0.0 0.0)|POINT(0.0 0.0)|true
+3|POINT(0.0 0.0 0.0)|POINT(0.0 0.0 0.0)|true
+2|POINT(0.0 0.0)|POINT(3.0 4.0)|false
+3|POINT(0.0 0.0 0.0)|POINT(0.0 0.0 1.0)|false
+# intersects2d on 2d and 3d geometries
+2|POINT(0.0 0.0)|POINT(0.0 0.0 1.0)|true
+# intersects3d on 2d points
+3|POINT(0.0 0.0)|POINT(0.0 0.0)|true
+# intersects3d on 2d and 3d points
+3|POINT(0.0 0.0)|POINT(0.0 0.0 0.0)|true
+
+# Point/LineString
+3|POINT(0.0 0.0 0.0)|LINESTRING(0 0 0, 1 0 0, 1 1 0)|true
+3|POINT(0.5 0.0 0.0)|LINESTRING(0 0 0, 1 0 0, 1 1 0)|true
+3|POINT(0.0 0.0 1.0)|LINESTRING(0 0 0, 1 0 0, 1 1 0)|false
+2|POINT(0.0 0.0 0.0)|LINESTRING(0 0 0, 1 0 0, 1 1 0)|true
+2|POINT(0.5 0.0 0.0)|LINESTRING(0 0 0, 1 0 0, 1 1 0)|true
+2|POINT(0.0 0.0 1.0)|LINESTRING(0 0 0, 1 0 0, 1 1 0)|true
+3|POINT(0.0 0.0)|LINESTRING(0 0 0, 1 0 0, 1 1 0)|true
+
+# Point/Triangle
+# point on a vertex
+2|POINT(0.0 0.0 0.0)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|true
+3|POINT(0.0 0.0 0.0)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|true
+# point on a boundary
+2|POINT(0.5 0.0 0.0)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|true
+3|POINT(0.5 0.0 0.0)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|true
+# point not inside
+2|POINT(2.0 0.0 1.0)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|false
+3|POINT(2.0 0.0 1.0)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|false
+# point inside the triangle
+2|POINT(0.8 0.2 0.0)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|true
+3|POINT(0.8 0.2 0.0)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|true
+# point outside the triangle
+2|POINT(2.8 2.2 0.0)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|false
+3|POINT(2.8 2.2 0.0)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|false
+# 2d x 3d
+3|POINT(0.8 0.2)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|true
+
+## Point / Polygon
+2|POINT(0.0 0.0)|POLYGON((0.0 0.0,1.0 0.0,1.0 1.0,0.0 1.0,0.0 0.0))|true
+2|POINT(0.5 0.0)|POLYGON((0.0 0.0,1.0 0.0,1.0 1.0,0.0 1.0,0.0 0.0))|true
+2|POINT(0.0 1.5)|POLYGON((0.0 0.0,1.0 0.0,1.0 1.0,0.0 1.0,0.0 0.0))|false
+2|POINT(0.5 0.5)|POLYGON((0.0 0.0,1.0 0.0,1.0 1.0,0.0 1.0,0.0 0.0))|true
+2|POINT(0.6 0.6)|POLYGON((0.0 0.0,1.0 0.0,1.0 1.0,0.0 1.0,0.0 0.0))|true
+# polygon with a hole
+2|POINT(0.0 0.0)|POLYGON((0.0 0.0,4.0 0.0,4.0 4.0,0.0 4.0,0.0 0.0),(2 2,2 3,3 3,3 2,2 2))|true
+2|POINT(0.5 0.0)|POLYGON((0.0 0.0,4.0 0.0,4.0 4.0,0.0 4.0,0.0 0.0),(2 2,2 3,3 3,3 2,2 2))|true
+2|POINT(0.0 5.5)|POLYGON((0.0 0.0,4.0 0.0,4.0 4.0,0.0 4.0,0.0 0.0),(2 2,2 3,3 3,3 2,2 2))|false
+2|POINT(0.5 0.5)|POLYGON((0.0 0.0,4.0 0.0,4.0 4.0,0.0 4.0,0.0 0.0),(2 2,2 3,3 3,3 2,2 2))|true
+2|POINT(2.5 2.5)|POLYGON((0.0 0.0,4.0 0.0,4.0 4.0,0.0 4.0,0.0 0.0),(2 2,2 3,3 3,3 2,2 2))|false
+# 3D
+3|POINT(0.0 0.0 0.0)|POLYGON((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0))|true
+3|POINT(0.5 0.0 0.0)|POLYGON((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0))|true
+3|POINT(0.0 1.5 0.0)|POLYGON((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0))|false
+3|POINT(0.6 0.6 0.0)|POLYGON((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0))|true
+3|POINT(0.5 0.5 0.0)|POLYGON((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0))|true
+3|POINT(0.5 0.5 0.5)|POLYGON((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0))|false
+# 3d with hole
+3|POINT(0.0 0.0 0)|POLYGON((0.0 0.0 0,4.0 0.0 0,4.0 4.0 0,0.0 4.0 0,0.0 0.0 0),(2 2 0,2 3 0,3 3 0,3 2 0,2 2 0))|true
+3|POINT(0.5 0.0 0)|POLYGON((0.0 0.0 0,4.0 0.0 0,4.0 4.0 0,0.0 4.0 0,0.0 0.0 0),(2 2 0,2 3 0,3 3 0,3 2 0,2 2 0))|true
+3|POINT(0.0 5.5 0)|POLYGON((0.0 0.0 0,4.0 0.0 0,4.0 4.0 0,0.0 4.0 0,0.0 0.0 0),(2 2 0,2 3 0,3 3 0,3 2 0,2 2 0))|false
+3|POINT(0.5 0.5 0)|POLYGON((0.0 0.0 0,4.0 0.0 0,4.0 4.0 0,0.0 4.0 0,0.0 0.0 0),(2 2 0,2 3 0,3 3 0,3 2 0,2 2 0))|true
+3|POINT(2.5 2.5 0)|POLYGON((0.0 0.0 0,4.0 0.0 0,4.0 4.0 0,0.0 4.0 0,0.0 0.0 0),(2 2 0,2 3 0,3 3 0,3 2 0,2 2 0))|false
+# 2d x 3d
+3|POINT(0.5 0.5)|POLYGON((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0))|true
+
+## Point / TIN
+2|POINT(0.0 0.0)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|true
+3|POINT(0.0 0.0 0.0)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|true
+# on an edge
+2|POINT(0.5 0.5)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|true
+3|POINT(0.5 0.5 0.0)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|true
+# inside the first triangle
+2|POINT(0.2 0.2)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|true
+3|POINT(0.2 0.2 0.0)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|true
+# inside another triangle
+2|POINT(1.2 0.2)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|true
+3|POINT(1.2 0.2 0.0)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|true
+3|POINT(1.2 0.2 1.0)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|false
+# outside
+2|POINT(2.1 0.0)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|false
+3|POINT(2.1 0.0 0.0)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|false
+# 2d x 3d
+3|POINT(1.2 0.2)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|true
+
+## Point / Polyhedral
+## Polyhedral : a square with a concave part glued to a square with a hole
+# on a vertex
+2|POINT(0 0)|POLYHEDRALSURFACE(((0 0,0.5 0.5,1 0,1 1,0 1,0 0)),((1 0,2 0,2 1,1 1,1 0),(1.2 0.2,1.2 0.8,1.8 0.8,1.8 0.2,1.2 0.2)))|true
+# in the concave part
+2|POINT(0.5 0)|POLYHEDRALSURFACE(((0 0,0.5 0.5,1 0,1 1,0 1,0 0)),((1 0,2 0,2 1,1 1,1 0),(1.2 0.2,1.2 0.8,1.8 0.8,1.8 0.2,1.2 0.2)))|false
+# on an edge
+2|POINT(0 0.5)|POLYHEDRALSURFACE(((0 0,0.5 0.5,1 0,1 1,0 1,0 0)),((1 0,2 0,2 1,1 1,1 0),(1.2 0.2,1.2 0.8,1.8 0.8,1.8 0.2,1.2 0.2)))|true
+# inside the first polygon
+2|POINT(0.7 0.7)|POLYHEDRALSURFACE(((0 0,0.5 0.5,1 0,1 1,0 1,0 0)),((1 0,2 0,2 1,1 1,1 0),(1.2 0.2,1.2 0.8,1.8 0.8,1.8 0.2,1.2 0.2)))|true
+# inside the second polygon
+2|POINT(1.2 0.1)|POLYHEDRALSURFACE(((0 0,0.5 0.5,1 0,1 1,0 1,0 0)),((1 0,2 0,2 1,1 1,1 0),(1.2 0.2,1.2 0.8,1.8 0.8,1.8 0.2,1.2 0.2)))|true
+# inside the hole
+2|POINT(1.5 0.5)|POLYHEDRALSURFACE(((0 0,0.5 0.5,1 0,1 1,0 1,0 0)),((1 0,2 0,2 1,1 1,1 0),(1.2 0.2,1.2 0.8,1.8 0.8,1.8 0.2,1.2 0.2)))|false
+# on the edge of the hole
+2|POINT(1.2 0.5)|POLYHEDRALSURFACE(((0 0,0.5 0.5,1 0,1 1,0 1,0 0)),((1 0,2 0,2 1,1 1,1 0),(1.2 0.2,1.2 0.8,1.8 0.8,1.8 0.2,1.2 0.2)))|true
+
+# 3d
+3|POINT(0 0 0)|POLYHEDRALSURFACE(((0 0 0,0.5 0.5 0,1 0 0,1 1 0,0 1 0,0 0 0)),((1 0 0,2 0 0,2 1 0,1 1 0,1 0 0),(1.2 0.2 0,1.2 0.8 0,1.8 0.8 0,1.8 0.2 0,1.2 0.2 0)))|true
+3|POINT(0.5 0 0)|POLYHEDRALSURFACE(((0 0 0,0.5 0.5 0,1 0 0,1 1 0,0 1 0,0 0 0)),((1 0 0,2 0 0,2 1 0,1 1 0,1 0 0),(1.2 0.2 0,1.2 0.8 0,1.8 0.8 0,1.8 0.2 0,1.2 0.2 0)))|false
+3|POINT(0 0.5 0)|POLYHEDRALSURFACE(((0 0 0,0.5 0.5 0,1 0 0,1 1 0,0 1 0,0 0 0)),((1 0 0,2 0 0,2 1 0,1 1 0,1 0 0),(1.2 0.2 0,1.2 0.8 0,1.8 0.8 0,1.8 0.2 0,1.2 0.2 0)))|true
+3|POINT(0.7 0.7 0)|POLYHEDRALSURFACE(((0 0 0,0.5 0.5 0,1 0 0,1 1 0,0 1 0,0 0 0)),((1 0 0,2 0 0,2 1 0,1 1 0,1 0 0),(1.2 0.2 0,1.2 0.8 0,1.8 0.8 0,1.8 0.2 0,1.2 0.2 0)))|true
+3|POINT(1.2 0.1 0)|POLYHEDRALSURFACE(((0 0 0,0.5 0.5 0,1 0 0,1 1 0,0 1 0,0 0 0)),((1 0 0,2 0 0,2 1 0,1 1 0,1 0 0),(1.2 0.2 0,1.2 0.8 0,1.8 0.8 0,1.8 0.2 0,1.2 0.2 0)))|true
+3|POINT(1.5 0.5 0)|POLYHEDRALSURFACE(((0 0 0,0.5 0.5 0,1 0 0,1 1 0,0 1 0,0 0 0)),((1 0 0,2 0 0,2 1 0,1 1 0,1 0 0),(1.2 0.2 0,1.2 0.8 0,1.8 0.8 0,1.8 0.2 0,1.2 0.2 0)))|false
+3|POINT(1.2 0.5 0)|POLYHEDRALSURFACE(((0 0 0,0.5 0.5 0,1 0 0,1 1 0,0 1 0,0 0 0)),((1 0 0,2 0 0,2 1 0,1 1 0,1 0 0),(1.2 0.2 0,1.2 0.8 0,1.8 0.8 0,1.8 0.2 0,1.2 0.2 0)))|true
+# 2d x 3d
+3|POINT(0 0)|POLYHEDRALSURFACE(((0 0 0,0.5 0.5 0,1 0 0,1 1 0,0 1 0,0 0 0)),((1 0 0,2 0 0,2 1 0,1 1 0,1 0 0),(1.2 0.2 0,1.2 0.8 0,1.8 0.8 0,1.8 0.2 0,1.2 0.2 0)))|true
+
+## Point / Solid
+3|POINT(0.0 0.0 0.0)|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+3|POINT(0.0 0.5 0.0)|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+3|POINT(0.5 0.5 0.0)|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+3|POINT(1.5 0.5 0.5)|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|false
+
+# 2d x 3d
+3|POINT(0.5 0.5)|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+
+
+3|POINT(0.5 0.5 0.5)|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+## with a concave part
+3|POINT(0.1 0.2 0.2)|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0.5 0.5 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,0.5 0.5 1,1 0 1)), ((1 0 0,1 0 1,0.5 0.5 1,0.5 0.5 0,1 0 0)), ((0 0 0,0.5 0.5 0,0.5 0.5 1,0 0 1,0 0 0)) ))|true
+3|POINT(0.5 0.5 0.0)|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0.5 0.5 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,0.5 0.5 1,1 0 1)), ((1 0 0,1 0 1,0.5 0.5 1,0.5 0.5 0,1 0 0)), ((0 0 0,0.5 0.5 0,0.5 0.5 1,0 0 1,0 0 0)) ))|true
+# point outside a concave volume (but inside the convex hull)
+3|POINT(0.5 0 0.0)|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0.5 0.5 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,0.5 0.5 1,1 0 1)), ((1 0 0,1 0 1,0.5 0.5 1,0.5 0.5 0,1 0 0)), ((0 0 0,0.5 0.5 0,0.5 0.5 1,0 0 1,0 0 0)) ))|false
+
+## LineString / LineString
+2|LINESTRING(0 0, 1 0, 1 1)|LINESTRING(0 -1, 1 0.5, 1 4)|true
+2|LINESTRING(10 0, 11 0, 11 1)|LINESTRING(0 0, 1 0, 1 1)|false
+3|LINESTRING(0 0 0, 1 0 0, 1 1 0)|LINESTRING(0 0 0, 1 0 1, 1 4 0)|true
+3|LINESTRING(10 0 0, 11 0 0, 11 1 0)|LINESTRING(0 0 0, 1 0 0, 1 1 0)|false
+# 2d x 3d
+3|LINESTRING(0 0, 1 0, 1 1)|LINESTRING(0 0 0, 1 0 1, 1 4 0)|true
+
+## LineString / Triangle
+2|LINESTRING(0 0,0 1)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|true
+# line that shares a vertex
+2|LINESTRING(0 1, 1 0.4)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|true
+# line inside
+2|LINESTRING(0.4 0.2,0.5 0.3)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|true
+# line traversing the triangle
+2|LINESTRING(-1 0.5,2 0.5)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|true
+# line outside
+2|LINESTRING(-1 1.5,2 1.5)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|false
+
+# 3D
+3|LINESTRING(0 0 0,0 1 0)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|true
+3|LINESTRING(0 1 0,1 0.4 0)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|true
+3|LINESTRING(0.4 0.2 0,0.5 0.3 0)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|true
+3|LINESTRING(-1 0.5 0,2 0.5 0)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|true
+3|LINESTRING(-1 1.5 0,2 1.5 0)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|false
+# 2d x 3d
+3|LINESTRING(0 0,0 1)|TRIANGLE((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0))|true
+
+## LineString / Polygon
+# polygon with a hole and a concave part
+# POLYGON((0.0 0.0 0.0,0.5 0.1 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0),(0.2 0.2 0.0,0.2 0.8 0.0,0.8 0.8 0.0,0.8 0.2 0.0,0.2 0.2 0.0))
+# on the edge
+2|LINESTRING(0 0 0,1 0 0)|POLYGON((0.0 0.0 0.0,0.5 0.1 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0),(0.2 0.2 0.0,0.2 0.8 0.0,0.8 0.8 0.0,0.8 0.2 0.0,0.2 0.2 0.0))|true
+3|LINESTRING(0 0 0,1 0 0)|POLYGON((0.0 0.0 0.0,0.5 0.1 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0),(0.2 0.2 0.0,0.2 0.8 0.0,0.8 0.8 0.0,0.8 0.2 0.0,0.2 0.2 0.0))|true
+# crossing
+2|LINESTRING(0 0 0,1 1 0)|POLYGON((0.0 0.0 0.0,0.5 0.1 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0),(0.2 0.2 0.0,0.2 0.8 0.0,0.8 0.8 0.0,0.8 0.2 0.0,0.2 0.2 0.0))|true
+3|LINESTRING(0 0 0,1 1 0)|POLYGON((0.0 0.0 0.0,0.5 0.1 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0),(0.2 0.2 0.0,0.2 0.8 0.0,0.8 0.8 0.0,0.8 0.2 0.0,0.2 0.2 0.0))|true
+# crossing (bis)
+2|LINESTRING(-1 -1 0,2 2 0)|POLYGON((0.0 0.0 0.0,0.5 0.1 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0),(0.2 0.2 0.0,0.2 0.8 0.0,0.8 0.8 0.0,0.8 0.2 0.0,0.2 0.2 0.0))|true
+3|LINESTRING(-1 -1 0,2 2 0)|POLYGON((0.0 0.0 0.0,0.5 0.1 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0),(0.2 0.2 0.0,0.2 0.8 0.0,0.8 0.8 0.0,0.8 0.2 0.0,0.2 0.2 0.0))|true
+# in the hole
+2|LINESTRING(0.3 0.3 0,0.7 0.7 0)|POLYGON((0.0 0.0 0.0,0.5 0.1 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0),(0.2 0.2 0.0,0.2 0.8 0.0,0.8 0.8 0.0,0.8 0.2 0.0,0.2 0.2 0.0))|false
+3|LINESTRING(0.3 0.3 0,0.7 0.7 0)|POLYGON((0.0 0.0 0.0,0.5 0.1 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0),(0.2 0.2 0.0,0.2 0.8 0.0,0.8 0.8 0.0,0.8 0.2 0.0,0.2 0.2 0.0))|false
+# outside
+2|LINESTRING(-1 -1 0,-0.5 0.5 0)|POLYGON((0.0 0.0 0.0,0.5 0.1 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0),(0.2 0.2 0.0,0.2 0.8 0.0,0.8 0.8 0.0,0.8 0.2 0.0,0.2 0.2 0.0))|false
+3|LINESTRING(-1 -1 0,-0.5 0.5 0)|POLYGON((0.0 0.0 0.0,0.5 0.1 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0),(0.2 0.2 0.0,0.2 0.8 0.0,0.8 0.8 0.0,0.8 0.2 0.0,0.2 0.2 0.0))|false
+# 2d x 3d
+3|LINESTRING(0 0,1 1)|POLYGON((0.0 0.0 0.0,0.5 0.1 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0),(0.2 0.2 0.0,0.2 0.8 0.0,0.8 0.8 0.0,0.8 0.2 0.0,0.2 0.2 0.0))|true
+
+## LineString / TIN
+# line that shares a vertex
+2|LINESTRING(0 0, 0 1)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|true
+# line crossing an edge
+2|LINESTRING(0 1, 1 0.4)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|true
+# line inside the triangle
+2|LINESTRING(0.4 0.2,0.5 0.3)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|true
+# line traversing the triangle
+2|LINESTRING(-1 0.5,2 0.5)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|true
+# line outside
+2|LINESTRING(-1 1.5,2 1.5)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|false
+## 3D
+3|LINESTRING(0 0 0,0 1 0)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|true
+3|LINESTRING(0 1 0,1 0.4 0)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|true
+3|LINESTRING(0.4 0.2 0,0.5 0.3 0)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|true
+3|LINESTRING(-1 0.5 0,2 0.5 0)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|true
+3|LINESTRING(-1 1.5 0,2 1.5 0)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|false
+# 2d x 3d
+3|LINESTRING(0.4 0.2,0.5 0.3)|TIN(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 0.0 0.0)),((1.0 0.0 0.0,2.0 0.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0)),((2.0 0.0 0.0,2.0 1.0 0.0,1.0 1.0 0.0,2.0 0.0 0.0)))|true
+
+## LineString / Polyhedral
+## TODO
+2|LINESTRING(0.0 0.0,0.5 0.5)|POLYHEDRALSURFACE(((0 0 0,0.5 0.5 0,1 0 0,1 1 0,0 1 0,0 0 0)),((1 0 0,2 0 0,2 1 0,1 1 0,1 0 0),(1.2 0.2 0,1.2 0.8 0,1.8 0.8 0,1.8 0.2 0,1.2 0.2 0)))|true
+3|LINESTRING(0.0 0.0 0.0,0.5 0.5 0.0)|POLYHEDRALSURFACE(((0 0 0,0.5 0.5 0,1 0 0,1 1 0,0 1 0,0 0 0)),((1 0 0,2 0 0,2 1 0,1 1 0,1 0 0),(1.2 0.2 0,1.2 0.8 0,1.8 0.8 0,1.8 0.2 0,1.2 0.2 0)))|true
+# crossing an edge
+2|LINESTRING(-1 0.5,1 0.5)|POLYHEDRALSURFACE(((0 0 0,0.5 0.5 0,1 0 0,1 1 0,0 1 0,0 0 0)),((1 0 0,2 0 0,2 1 0,1 1 0,1 0 0),(1.2 0.2 0,1.2 0.8 0,1.8 0.8 0,1.8 0.2 0,1.2 0.2 0)))|true
+3|LINESTRING(-1 0.5 0,1 0.5 0)|POLYHEDRALSURFACE(((0 0 0,0.5 0.5 0,1 0 0,1 1 0,0 1 0,0 0 0)),((1 0 0,2 0 0,2 1 0,1 1 0,1 0 0),(1.2 0.2 0,1.2 0.8 0,1.8 0.8 0,1.8 0.2 0,1.2 0.2 0)))|true
+# inside the hole
+2|LINESTRING(1.3 0.3,1.7 0.7)|POLYHEDRALSURFACE(((0 0 0,0.5 0.5 0,1 0 0,1 1 0,0 1 0,0 0 0)),((1 0 0,2 0 0,2 1 0,1 1 0,1 0 0),(1.2 0.2 0,1.2 0.8 0,1.8 0.8 0,1.8 0.2 0,1.2 0.2 0)))|false
+3|LINESTRING(1.3 0.3,1.7 0.7)|POLYHEDRALSURFACE(((0 0 0,0.5 0.5 0,1 0 0,1 1 0,0 1 0,0 0 0)),((1 0 0,2 0 0,2 1 0,1 1 0,1 0 0),(1.2 0.2 0,1.2 0.8 0,1.8 0.8 0,1.8 0.2 0,1.2 0.2 0)))|false
+# outside
+2|LINESTRING(-1 -1,-0.7 0.5)|POLYHEDRALSURFACE(((0 0 0,0.5 0.5 0,1 0 0,1 1 0,0 1 0,0 0 0)),((1 0 0,2 0 0,2 1 0,1 1 0,1 0 0),(1.2 0.2 0,1.2 0.8 0,1.8 0.8 0,1.8 0.2 0,1.2 0.2 0)))|false
+3|LINESTRING(-1 -1,-0.7 0.5)|POLYHEDRALSURFACE(((0 0 0,0.5 0.5 0,1 0 0,1 1 0,0 1 0,0 0 0)),((1 0 0,2 0 0,2 1 0,1 1 0,1 0 0),(1.2 0.2 0,1.2 0.8 0,1.8 0.8 0,1.8 0.2 0,1.2 0.2 0)))|false
+# 2d x 3d
+3|LINESTRING(-1 0.5,1 0.5)|POLYHEDRALSURFACE(((0 0 0,0.5 0.5 0,1 0 0,1 1 0,0 1 0,0 0 0)),((1 0 0,2 0 0,2 1 0,1 1 0,1 0 0),(1.2 0.2 0,1.2 0.8 0,1.8 0.8 0,1.8 0.2 0,1.2 0.2 0)))|true
+
+## LineString / Solid
+3|LINESTRING(0.5 0.5 0.5,0.7 0.7 0.7)|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+3|LINESTRING(0.5 0.5 0.5,1.5 1.5 1.5)|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+3|LINESTRING(2.5 2.5 2.5,1.5 1.5 1.5)|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|false
+3|LINESTRING(-1 0.5 0.5,1.5 0.5 0.5)|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+3|LINESTRING(-1 0.0 0.0,1.5 0.0 0.0)|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+
+## Triangle / Triangle
+## TODO
+# triangle touching
+2|TRIANGLE((1 0 0,2 0 0,1.5 1 0,1 0 0))|TRIANGLE((0 0 0,1 0 0,0.5 1 0,0 0 0))|true
+3|TRIANGLE((1 0 0,2 0 0,1.5 1 0,1 0 0))|TRIANGLE((0 0 0,1 0 0,0.5 1 0,0 0 0))|true
+# triangles sharing an edge
+2|TRIANGLE((0 0 0,1 0 0,0.5 -1 0,0 0 0))|TRIANGLE((0 0 0,1 0 0,0.5 1 0,0 0 0))|true
+3|TRIANGLE((0 0 0,1 0 0,0.5 -1 0,0 0 0))|TRIANGLE((0 0 0,1 0 0,0.5 1 0,0 0 0))|true
+# triangles overlapping
+2|TRIANGLE((0.5 0.5 0,1.5 0.5 0,1 1.5 0,0.5 0.5 0))|TRIANGLE((0 0 0,1 0 0,0.5 1 0,0 0 0))|true
+3|TRIANGLE((0.5 0.5 0,1.5 0.5 0,1 1.5 0,0.5 0.5 0))|TRIANGLE((0 0 0,1 0 0,0.5 1 0,0 0 0))|true
+# triangles overlapping in 3d
+3|TRIANGLE((0.5 0.5 -0.5,0.5 0.5 0.5,0.5 0.8 0.0,0.5 0.5 -0.5))|TRIANGLE((0 0 0,1 0 0,0.5 1 0,0 0 0))|true
+# outside
+2|TRIANGLE((2 0 0,3 0 0,1.5 1 0,2 0 0))|TRIANGLE((0 0 0,1 0 0,0.5 1 0,0 0 0))|false
+3|TRIANGLE((1 0 1,2 0 1,1.5 1 1,1 0 1))|TRIANGLE((0 0 0,1 0 0,0.5 1 0,0 0 0))|false
+# 2d x 3d
+3|TRIANGLE((1 0,2 0,1.5 1,1 0))|TRIANGLE((0 0 0,1 0 0,0.5 1 0,0 0 0))|true
+
+## Triangle / Polygon
+# intersection on a vertex
+2|TRIANGLE((-1 -1 0,0 -1 0,0 0 0,-1 -1 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0))|true
+3|TRIANGLE((-1 -1 0,0 -1 0,0 0 0,-1 -1 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0))|true
+# intersection on an edge
+2|TRIANGLE((-1 0 0,0.5 -1 0,0.5 0 0,-1 0 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0))|true
+3|TRIANGLE((-1 0 0,0.5 -1 0,0.5 0 0,-1 0 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0))|true
+# triangle overlapping
+2|TRIANGLE((-1 -1 0,0.5 -1 0,0.5 0.5 0,-1 -1 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0))|true
+3|TRIANGLE((-1 -1 0,0.5 -1 0,0.5 0.5 0,-1 -1 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0))|true
+# triangle inside polygon
+2|TRIANGLE((0.3 0.3 0,0.7 0.3 0,0.7 0.7 0,0.3 0.3 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0))|true
+3|TRIANGLE((0.3 0.3 0,0.7 0.3 0,0.7 0.7 0,0.3 0.3 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0))|true
+# triangle containing polygon
+2|TRIANGLE((-4 -0.1 0,4 -0.1 0,4 4 0,-4 -0.1 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0))|true
+3|TRIANGLE((-4 -0.1 0,4 -0.1 0,4 4 0,-4 -0.1 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0))|true
+# triangle inside a polygon hole
+2|TRIANGLE((0.3 0.3 0,0.7 0.3 0,0.7 0.7 0,0.3 0.3 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0),(0.2 0.2 0,0.2 0.8 0,0.8 0.8 0,0.8 0.2 0,0.2 0.2 0))|false
+3|TRIANGLE((0.3 0.3 0,0.7 0.3 0,0.7 0.7 0,0.3 0.3 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0),(0.2 0.2 0,0.2 0.8 0,0.8 0.8 0,0.8 0.2 0,0.2 0.2 0))|false
+# triangle touching a polygon hole
+2|TRIANGLE((0.2 0.2 0,0.7 0.3 0,0.7 0.7 0,0.2 0.2 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0),(0.2 0.2 0,0.2 0.8 0,0.8 0.8 0,0.8 0.2 0,0.2 0.2 0))|true
+3|TRIANGLE((0.2 0.2 0,0.7 0.3 0,0.7 0.7 0,0.2 0.2 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0),(0.2 0.2 0,0.2 0.8 0,0.8 0.8 0,0.8 0.2 0,0.2 0.2 0))|true
+# triangle outside
+2|TRIANGLE((-1 0 0,-0.5 0 0,-0.5 1 0,-1 0 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0))|false
+3|TRIANGLE((-1 0 0,-0.5 0 0,-0.5 1 0,-1 0 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0))|false
+
+## Triangle / TIN
+# intersection on a vertex
+2|TRIANGLE((-1 -1 0,0 -1 0,0 0 0,-1 -1 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|TRIANGLE((-1 -1 0,0 -1 0,0 0 0,-1 -1 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# intersection on an edge
+2|TRIANGLE((-1 0 0,0.5 -1 0,0.5 0 0,-1 0 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|TRIANGLE((-1 0 0,0.5 -1 0,0.5 0 0,-1 0 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# triangle overlapping
+2|TRIANGLE((-1 -1 0,0.5 -1 0,0.5 0.5 0,-1 -1 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|TRIANGLE((-1 -1 0,0.5 -1 0,0.5 0.5 0,-1 -1 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# triangle inside polygon
+2|TRIANGLE((0.3 0.3 0,0.7 0.3 0,0.7 0.7 0,0.3 0.3 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|TRIANGLE((0.3 0.3 0,0.7 0.3 0,0.7 0.7 0,0.3 0.3 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# triangle containing polygon
+2|TRIANGLE((-4 -0.1 0,4 -0.1 0,4 4 0,-4 -0.1 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|TRIANGLE((-4 -0.1 0,4 -0.1 0,4 4 0,-4 -0.1 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# triangle outside
+2|TRIANGLE((-1 0 0,-0.5 0 0,-0.5 1 0,-1 0 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|false
+3|TRIANGLE((-1 0 0,-0.5 0 0,-0.5 1 0,-1 0 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|false
+
+## Triangle / Polyhedral
+# intersection on a vertex
+2|TRIANGLE((-1 -1 0,0 -1 0,0 0 0,-1 -1 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|TRIANGLE((-1 -1 0,0 -1 0,0 0 0,-1 -1 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# intersection on an edge
+2|TRIANGLE((-1 0 0,0.5 -1 0,0.5 0 0,-1 0 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|TRIANGLE((-1 0 0,0.5 -1 0,0.5 0 0,-1 0 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# triangle overlapping
+2|TRIANGLE((-1 -1 0,0.5 -1 0,0.5 0.5 0,-1 -1 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|TRIANGLE((-1 -1 0,0.5 -1 0,0.5 0.5 0,-1 -1 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# triangle inside polygon
+2|TRIANGLE((0.3 0.3 0,0.7 0.3 0,0.7 0.7 0,0.3 0.3 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|TRIANGLE((0.3 0.3 0,0.7 0.3 0,0.7 0.7 0,0.3 0.3 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# triangle containing polygon
+2|TRIANGLE((-4 -0.1 0,4 -0.1 0,4 4 0,-4 -0.1 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|TRIANGLE((-4 -0.1 0,4 -0.1 0,4 4 0,-4 -0.1 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# triangle outside
+2|TRIANGLE((-1 0 0,-0.5 0 0,-0.5 1 0,-1 0 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|false
+3|TRIANGLE((-1 0 0,-0.5 0 0,-0.5 1 0,-1 0 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|false
+
+## Triangle / Solid
+3|TRIANGLE((0.5 0.5 0.5,0.7 0.7 0.2,0.2 0.2 0.2,0.5 0.5 0.5))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+3|TRIANGLE((-0.5 -0.5 -0.5,0.7 0.7 0.2,0.2 0.2 0.2,-0.5 -0.5 -0.5))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+3|TRIANGLE((-0.5 -0.5 -0.5,-0.7 -0.7 -0.2,-0.2 -0.2 -0.2,-0.5 -0.5 -0.5))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|false
+3|TRIANGLE((-1 0.5 0.5,1.5 0.5 0.5,0.0 0.0 1.5,-1 0.5 0.5))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+3|TRIANGLE((-1 0.0 0.0,1.5 0.0 0.0,0.0 0.0 -1,-1 0.0 0.0))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+
+# Polygon / Polygon
+# intersection on a vertex
+2|POLYGON((-1 -1 0,0 -1 0,0 0 0,-1 0 0,-1 -1 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0))|true
+3|POLYGON((-1 -1 0,0 -1 0,0 0 0,-1 0 0,-1 -1 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0))|true
+# intersection on an edge
+2|POLYGON((-1 0 0,0 0 0,0 1 0,-1 1 0,-1 0 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0))|true
+3|POLYGON((-1 0 0,0 0 0,0 1 0,-1 1 0,-1 0 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0))|true
+# overlapping
+2|POLYGON((-0.5 0 0,0.5 0 0,0.5 0.5 0,-0.5 0.5 0,-0.5 0 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0))|true
+3|POLYGON((-0.5 0 0,0.5 0 0,0.5 0.5 0,-0.5 0.5 0,-0.5 0 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0))|true
+# inside
+2|POLYGON((0.2 0.2 0,0.8 0.2 0,0.8 0.8 0,0.2 0.8 0,0.2 0.2 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0))|true
+3|POLYGON((0.2 0.2 0,0.8 0.2 0,0.8 0.8 0,0.2 0.8 0,0.2 0.2 0))|POLYGON((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0))|true
+
+# Polygon with a hole / Polygon inside the hole of A
+2|POLYGON((0.0 0.0,5.0 0.0,5.0 5.0,0.0 5.0,0.0 0.0),(1.0 1.0,1.0 4.0,4.0 4.0,4.0 1.0,1.0 1.0))|POLYGON((2.0 2.0,3.0 2.0,3.0 3.0,2.0 3.0,2.0 2.0))|false
+3|POLYGON((0.0 0.0 0.0,5.0 0.0 0.0,5.0 5.0 0.0,0.0 5.0 0.0,0.0 0.0 0.0),(1.0 1.0 0.0,1.0 4.0 0.0,4.0 4.0 0.0,4.0 1.0 0.0,1.0 1.0 0.0))|POLYGON((2.0 2.0 0.0,3.0 2.0 0.0,3.0 3.0 0.0,2.0 3.0 0.0,2.0 2.0 0.0))|false
+# Polygon with a hole / Polygon crossing the hole of A
+2|POLYGON((0.0 0.0,5.0 0.0,5.0 5.0,0.0 5.0,0.0 0.0),(1.0 1.0,1.0 4.0,4.0 4.0,4.0 1.0,1.0 1.0))|POLYGON((0.5 0.5,2.0 0.5,2.0 2.0,0.5 2.0,0.5 0.5))|true
+3|POLYGON((0.0 0.0 0.0,5.0 0.0 0.0,5.0 5.0 0.0,0.0 5.0 0.0,0.0 0.0 0.0),(1.0 1.0 0.0,1.0 4.0 0.0,4.0 4.0 0.0,4.0 1.0 0.0,1.0 1.0 0.0))|POLYGON((0.5 0.5 0.0,2.0 0.5 0.0,2.0 2.0 0.0,0.5 2.0 0.0,0.5 0.5 0.0))|true
+# Polygon with a hole / Polygon outside the hole of A
+2|POLYGON((0.0 0.0,5.0 0.0,5.0 5.0,0.0 5.0,0.0 0.0),(1.0 1.0,1.0 4.0,4.0 4.0,4.0 1.0,1.0 1.0))|POLYGON((0.5 0.5,4.5 0.5,4.5 4.5,0.5 4.5,0.5 0.5))|true
+3|POLYGON((0.0 0.0 0.0,5.0 0.0 0.0,5.0 5.0 0.0,0.0 5.0 0.0,0.0 0.0 0.0),(1.0 1.0 0.0,1.0 4.0 0.0,4.0 4.0 0.0,4.0 1.0 0.0,1.0 1.0 0.0))|POLYGON((0.5 0.5 0.0,4.5 0.5 0.0,4.5 4.5 0.0,0.5 4.5 0.0,0.5 0.5 0.0))|true
+
+## Polygon / TIN
+# intersection on a vertex
+2|POLYGON((-1 -1 0,0 -1 0,0 0 0,-1 -1 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|POLYGON((-1 -1 0,0 -1 0,0 0 0,-1 -1 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# intersection on an edge
+2|POLYGON((-1 0 0,0.5 -1 0,0.5 0 0,-1 0 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|POLYGON((-1 0 0,0.5 -1 0,0.5 0 0,-1 0 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# polygon overlapping
+2|POLYGON((-1 -1 0,0.5 -1 0,0.5 0.5 0,-1 -1 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|POLYGON((-1 -1 0,0.5 -1 0,0.5 0.5 0,-1 -1 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# polygon inside tin
+2|POLYGON((0.3 0.3 0,0.7 0.3 0,0.7 0.7 0,0.3 0.3 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|POLYGON((0.3 0.3 0,0.7 0.3 0,0.7 0.7 0,0.3 0.3 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# polygon containing tin
+2|POLYGON((-4 -0.1 0,4 -0.1 0,4 4 0,-4 -0.1 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|POLYGON((-4 -0.1 0,4 -0.1 0,4 4 0,-4 -0.1 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# polygon outside
+2|POLYGON((-1 0 0,-0.5 0 0,-0.5 1 0,-1 0 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|false
+3|POLYGON((-1 0 0,-0.5 0 0,-0.5 1 0,-1 0 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|false
+# tin inside a polygon hole
+2|POLYGON((-5 -5,5 -5,5 5,-5 5,-5 -5),(-4 -0.1 0,4 4 0,4 -0.1 0,-4 -0.1 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|false
+3|POLYGON((-5 -5,5 -5,5 5,-5 5,-5 -5),(-4 -0.1 0,4 4 0,4 -0.1 0,-4 -0.1 0))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|false
+
+## Polygon / Polyhedral
+# intersection on a vertex
+2|POLYGON((-1 -1 0,0 -1 0,0 0 0,-1 -1 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|POLYGON((-1 -1 0,0 -1 0,0 0 0,-1 -1 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# intersection on an edge
+2|POLYGON((-1 0 0,0.5 -1 0,0.5 0 0,-1 0 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|POLYGON((-1 0 0,0.5 -1 0,0.5 0 0,-1 0 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# polygon overlapping
+2|POLYGON((-1 -1 0,0.5 -1 0,0.5 0.5 0,-1 -1 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|POLYGON((-1 -1 0,0.5 -1 0,0.5 0.5 0,-1 -1 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# polygon inside polyhedral
+2|POLYGON((0.3 0.3 0,0.7 0.3 0,0.7 0.7 0,0.3 0.3 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|POLYGON((0.3 0.3 0,0.7 0.3 0,0.7 0.7 0,0.3 0.3 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# polygon containing polyhedral
+2|POLYGON((-4 -0.1 0,4 -0.1 0,4 4 0,-4 -0.1 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|POLYGON((-4 -0.1 0,4 -0.1 0,4 4 0,-4 -0.1 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# polygon outside
+2|POLYGON((-1 0 0,-0.5 0 0,-0.5 1 0,-1 0 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|false
+3|POLYGON((-1 0 0,-0.5 0 0,-0.5 1 0,-1 0 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|false
+# polyhedral inside a polygon hole
+2|POLYGON((-5 -5,5 -5,5 5,-5 5,-5 -5),(-4 -0.1 0,4 4 0,4 -0.1 0,-4 -0.1 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|false
+3|POLYGON((-5 -5,5 -5,5 5,-5 5,-5 -5),(-4 -0.1 0,4 4 0,4 -0.1 0,-4 -0.1 0))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|false
+
+## Polygon / Solid
+# polygon intersects on a vertex
+3|POLYGON((-1 -1 0,0 -1 0,0 0 0,-1 0 0,-1 -1 0))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+# polygon intersects on an edge
+3|POLYGON((-1 0 0,0 0 0,0 1 0,-1 1 0,-1 0 0))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+# polygon overlapping a face
+3|POLYGON((-0.5 0 0,0.5 0 0,0.5 0.5 0,-0.5 0.5 0,-0.5 0 0))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+# polygon overlapping the volume
+3|POLYGON((-0.5 0 0.5,0.5 0 0.5,0.5 0.5 0.5,-0.5 0.5 0.5,-0.5 0 0.5))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+# polygon inside the solid
+3|POLYGON((0.2 0.2 0.5,0.8 0.2 0.5,0.8 0.8 0.5,0.2 0.8 0.5,0.2 0.2 0.5))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+# solid inside the hole of a polygon
+3|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|POLYGON((-1 -1 0,2 -1 0,2 2 0,-1 2 0,-1 -1 0),(-0.5 -0.5 0,-0.5 1.5 0,1.5 1.5 0,1.5 -0.5 0,-0.5 -0.5 0))|false
+
+## TIN / TIN
+# intersection on a vertex
+2|TIN(((-1 0 0,0 -1 0,0 0 0,-1 0 0)),((-1 0 0,-1 -1 0,0 -1 0,-1 0 0)))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|TIN(((-1 0 0,0 -1 0,0 0 0,-1 0 0)),((-1 0 0,-1 -1 0,0 -1 0,-1 0 0)))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# intersection on an edge
+2|TIN(((-1 1 0,0 0 0,0 1 0,-1 1 0)),((-1 1 0,-1 0 0,0 0 0,-1 1 0)))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|TIN(((-1 1 0,0 0 0,0 1 0,-1 1 0)),((-1 1 0,-1 0 0,0 0 0,-1 1 0)))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# overlapping
+2|TIN(((-0.5 0.5 0,0.5 0 0,0.5 0.5 0,-0.5 0.5 0)),((-0.5 0.5 0,-0.5 0 0,0.5 0 0,-0.5 0.5 0)))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|TIN(((-0.5 0.5 0,0.5 0 0,0.5 0.5 0,-0.5 0.5 0)),((-0.5 0.5 0,-0.5 0 0,0.5 0 0,-0.5 0.5 0)))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# inside
+2|TIN(((0.2 0.8 0,0.8 0.2 0,0.8 0.8 0,0.2 0.8 0)),((0.2 0.8 0,0.2 0.2 0,0.8 0.2 0,0.2 0.8 0)))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|TIN(((0.2 0.8 0,0.8 0.2 0,0.8 0.8 0,0.2 0.8 0)),((0.2 0.8 0,0.2 0.2 0,0.8 0.2 0,0.2 0.8 0)))|TIN(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+
+## TIN / Polyhedral
+# intersection on a vertex
+2|TIN(((-1 0 0,0 -1 0,0 0 0,-1 0 0)),((-1 0 0,-1 -1 0,0 -1 0,-1 0 0)))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|TIN(((-1 0 0,0 -1 0,0 0 0,-1 0 0)),((-1 0 0,-1 -1 0,0 -1 0,-1 0 0)))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# intersection on an edge
+2|TIN(((-1 1 0,0 0 0,0 1 0,-1 1 0)),((-1 1 0,-1 0 0,0 0 0,-1 1 0)))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|TIN(((-1 1 0,0 0 0,0 1 0,-1 1 0)),((-1 1 0,-1 0 0,0 0 0,-1 1 0)))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# overlapping
+2|TIN(((-0.5 0.5 0,0.5 0 0,0.5 0.5 0,-0.5 0.5 0)),((-0.5 0.5 0,-0.5 0 0,0.5 0 0,-0.5 0.5 0)))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|TIN(((-0.5 0.5 0,0.5 0 0,0.5 0.5 0,-0.5 0.5 0)),((-0.5 0.5 0,-0.5 0 0,0.5 0 0,-0.5 0.5 0)))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# inside
+2|TIN(((0.2 0.8 0,0.8 0.2 0,0.8 0.8 0,0.2 0.8 0)),((0.2 0.8 0,0.2 0.2 0,0.8 0.2 0,0.2 0.8 0)))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|TIN(((0.2 0.8 0,0.8 0.2 0,0.8 0.8 0,0.2 0.8 0)),((0.2 0.8 0,0.2 0.2 0,0.8 0.2 0,0.2 0.8 0)))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+
+## TIN / Solid
+# polygon intersects on a vertex
+3|TIN(((-1 0 0,0 -1 0,0 0 0,-1 0 0)),((-1 0 0,-1 -1 0,0 -1 0,-1 0 0)))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+# polygon intersects on an edge
+3|TIN(((-1 1 0,0 0 0,0 1 0,-1 1 0)),((-1 1 0,-1 0 0,0 0 0,-1 1 0)))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+# polygon overlapping a face
+3|TIN(((-0.5 0.5 0,0.5 0 0,0.5 0.5 0,-0.5 0.5 0)),((-0.5 0.5 0,-0.5 0 0,0.5 0 0,-0.5 0.5 0)))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+# polygon overlapping the volume
+3|TIN(((-0.5 0.5 0.5,0.5 0 0.5,0.5 0.5 0.5,-0.5 0.5 0.5)),((-0.5 0.5 0.5,-0.5 0 0.5,0.5 0 0.5,-0.5 0.5 0.5)))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+# polygon inside the solid
+3|TIN(((0.2 0.8 0.5,0.8 0.2 0.5,0.8 0.8 0.5,0.2 0.8 0.5)),((0.2 0.8 0.5,0.2 0.2 0.5,0.8 0.2 0.5,0.2 0.8 0.5)))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+
+## Polyhedral / Polyhedral
+# intersection on a vertex
+2|POLYHEDRALSURFACE(((-1 0 0,0 -1 0,0 0 0,-1 0 0)),((-1 0 0,-1 -1 0,0 -1 0,-1 0 0)))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|POLYHEDRALSURFACE(((-1 0 0,0 -1 0,0 0 0,-1 0 0)),((-1 0 0,-1 -1 0,0 -1 0,-1 0 0)))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# intersection on an edge
+2|POLYHEDRALSURFACE(((-1 1 0,0 0 0,0 1 0,-1 1 0)),((-1 1 0,-1 0 0,0 0 0,-1 1 0)))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|POLYHEDRALSURFACE(((-1 1 0,0 0 0,0 1 0,-1 1 0)),((-1 1 0,-1 0 0,0 0 0,-1 1 0)))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# overlapping
+2|POLYHEDRALSURFACE(((-0.5 0.5 0,0.5 0 0,0.5 0.5 0,-0.5 0.5 0)),((-0.5 0.5 0,-0.5 0 0,0.5 0 0,-0.5 0.5 0)))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|POLYHEDRALSURFACE(((-0.5 0.5 0,0.5 0 0,0.5 0.5 0,-0.5 0.5 0)),((-0.5 0.5 0,-0.5 0 0,0.5 0 0,-0.5 0.5 0)))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+# inside
+2|POLYHEDRALSURFACE(((0.2 0.8 0,0.8 0.2 0,0.8 0.8 0,0.2 0.8 0)),((0.2 0.8 0,0.2 0.2 0,0.8 0.2 0,0.2 0.8 0)))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+3|POLYHEDRALSURFACE(((0.2 0.8 0,0.8 0.2 0,0.8 0.8 0,0.2 0.8 0)),((0.2 0.8 0,0.2 0.2 0,0.8 0.2 0,0.2 0.8 0)))|POLYHEDRALSURFACE(((0 1 0,1 0 0,1 1 0,0 1 0)),((0 1 0,0 0 0,1 0 0,0 1 0)))|true
+
+## Polyhedral / Solid
+# polygon intersects on a vertex
+3|POLYHEDRALSURFACE(((-1 0 0,0 -1 0,0 0 0,-1 0 0)),((-1 0 0,-1 -1 0,0 -1 0,-1 0 0)))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+# polygon intersects on an edge
+3|POLYHEDRALSURFACE(((-1 1 0,0 0 0,0 1 0,-1 1 0)),((-1 1 0,-1 0 0,0 0 0,-1 1 0)))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+# polygon overlapping a face
+3|POLYHEDRALSURFACE(((-0.5 0.5 0,0.5 0 0,0.5 0.5 0,-0.5 0.5 0)),((-0.5 0.5 0,-0.5 0 0,0.5 0 0,-0.5 0.5 0)))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+# polygon overlapping the volume
+3|POLYHEDRALSURFACE(((-0.5 0.5 0.5,0.5 0 0.5,0.5 0.5 0.5,-0.5 0.5 0.5)),((-0.5 0.5 0.5,-0.5 0 0.5,0.5 0 0.5,-0.5 0.5 0.5)))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+# polygon inside the solid
+3|POLYHEDRALSURFACE(((0.2 0.8 0.5,0.8 0.2 0.5,0.8 0.8 0.5,0.2 0.8 0.5)),((0.2 0.8 0.5,0.2 0.2 0.5,0.8 0.2 0.5,0.2 0.8 0.5)))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+
+## Solid / Solid
+# solid translated by 2 0 0 x solid
+3|SOLID(( ((2 0 0,2 1 0,3 1 0,3 0 0,2 0 0)), ((3 0 0,3 1 0,3 1 1,3 0 1,3 0 0)), ((2 1 0,2 1 1,3 1 1,3 1 0,2 1 0)), ((2 0 1,2 1 1,2 1 0,2 0 0,2 0 1)), ((3 0 1,3 1 1,2 1 1,2 0 1,3 0 1)), ((3 0 0,3 0 1,2 0 1,2 0 0,3 0 0)) ))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|false
+# a touching solid (on the edge)
+3|SOLID((((1 -0 -0,1 1 -0,2 1 -0,2 -0 -0,1 -0 -0)),((2 -0 -0,2 1 -0,2 1 1,2 -0 1,2 -0 -0)),((1 1 -0,1 1 1,2 1 1,2 1 -0,1 1 -0)),((1 -0 1,1 1 1,1 1 -0,1 -0 -0,1 -0 1)),((2 -0 1,2 1 1,1 1 1,1 -0 1,2 -0 1)),((2 -0 -0,2 -0 1,1 -0 1,1 -0 -0,2 -0 -0))))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+# an overlapping solid
+3|SOLID((((1 -0 -0,1 1 -0,2 1 -0,2 -0 -0,1 -0 -0)),((2 -0 -0,2 1 -0,2 1 1,2 -0 1,2 -0 -0)),((1 1 -0,1 1 1,2 1 1,2 1 -0,1 1 -0)),((1 -0 1,1 1 1,1 1 -0,1 -0 -0,1 -0 1)),((2 -0 1,2 1 1,1 1 1,1 -0 1,2 -0 1)),((2 -0 -0,2 -0 1,1 -0 1,1 -0 -0,2 -0 -0))))|SOLID(( ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)), ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)), ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)), ((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1)), ((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1)), ((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0)) ))|true
+## TODO : solids with holes
+
+# reversed polygon
+2|POLYGON((0 0,0 1,1 1,1 0,0 0))|POINT(0.5 0.5)|true
+3|POLYGON((0 0,0 1,1 1,1 0,0 0))|POINT(0.5 0.5 0)|true
+2|POLYGON((0 0,0 1,1 1,1 0,0 0))|LINESTRING(0 0,1 1)|true
+3|POLYGON((0 0,0 1,1 1,1 0,0 0))|LINESTRING(0 0,1 1)|true
+2|POLYGON((0 0,0 1,1 1,1 0,0 0))|POLYGON((0 0,1 0,1 1,0 1,0 0))|true
+2|POLYGON((0 0,0 1,1 1,1 0,0 0),(0.4 0.4,0.6 0.4,0.6 0.6,0.4 0.6,0.4 0.4))|POLYGON((0 0,1 0,1 1,0 1,0 0))|true
+
+# reversed solids
+3|SOLID((((0 0 0,0 1 0,0 1 1,0 0 1,0 0 0)),((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0)),((0 0 0,0 0 1,1 0 1,1 0 0,0 0 0)),((1 0 0,1 0 1,1 1 1,1 1 0,1 0 0)),((0 0 1,0 1 1,1 1 1,1 0 1,0 0 1)),((0 1 0,1 1 0,1 1 1,0 1 1,0 1 0))))|POINT(0.5 0.5 0.5)|true
+3|SOLID((((0 0 0,0 1 0,0 1 1,0 0 1,0 0 0)),((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0)),((0 0 0,0 0 1,1 0 1,1 0 0,0 0 0)),((1 0 0,1 0 1,1 1 1,1 1 0,1 0 0)),((0 0 1,0 1 1,1 1 1,1 0 1,0 0 1)),((0 1 0,1 1 0,1 1 1,0 1 1,0 1 0))))|POINT(1.5 0.5 0.5)|false
+3|SOLID((((0 0 0,0 1 0,0 1 1,0 0 1,0 0 0)),((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0)),((0 0 0,0 0 1,1 0 1,1 0 0,0 0 0)),((1 0 0,1 0 1,1 1 1,1 1 0,1 0 0)),((0 0 1,0 1 1,1 1 1,1 0 1,0 0 1)),((0 1 0,1 1 0,1 1 1,0 1 1,0 1 0))))|LINESTRING(0 0 0,0.5 0.5 0.5)|true
+3|SOLID((((0 0 0,0 1 0,0 1 1,0 0 1,0 0 0)),((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0)),((0 0 0,0 0 1,1 0 1,1 0 0,0 0 0)),((1 0 0,1 0 1,1 1 1,1 1 0,1 0 0)),((0 0 1,0 1 1,1 1 1,1 0 1,0 0 1)),((0 1 0,1 1 0,1 1 1,0 1 1,0 1 0))))|POLYGON((0.2 0.2 0.5,0.8 0.2 0.5,0.8 0.8 0.5,0.2 0.8 0.5,0.2 0.2 0.5))|true
+3|SOLID((((0 0 0,0 1 0,0 1 1,0 0 1,0 0 0)),((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0)),((0 0 0,0 0 1,1 0 1,1 0 0,0 0 0)),((1 0 0,1 0 1,1 1 1,1 1 0,1 0 0)),((0 0 1,0 1 1,1 1 1,1 0 1,0 0 1)),((0 1 0,1 1 0,1 1 1,0 1 1,0 1 0))))|SOLID((((0 0 0,0 1 0,0 1 1,0 0 1,0 0 0)),((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0)),((0 0 0,0 0 1,1 0 1,1 0 0,0 0 0)),((1 0 0,1 0 1,1 1 1,1 1 0,1 0 0)),((0 0 1,0 1 1,1 1 1,1 0 1,0 0 1)),((0 1 0,1 1 0,1 1 1,0 1 1,0 1 0))))|true
+3|SOLID((((0 0 0,0 1 0,0 1 1,0 0 1,0 0 0)),((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0)),((0 0 0,0 0 1,1 0 1,1 0 0,0 0 0)),((1 0 0,1 0 1,1 1 1,1 1 0,1 0 0)),((0 0 1,0 1 1,1 1 1,1 0 1,0 0 1)),((0 1 0,1 1 0,1 1 1,0 1 1,0 1 0))))|SOLID((((0.2 0.2 0.2,0.2 0.8 0.2,0.2 0.8 0.8,0.2 0.2 0.8,0.2 0.2 0.2)),((0.2 0.2 0.2,0.8 0.2 0.2,0.8 0.8 0.2,0.2 0.8 0.2,0.2 0.2 0.2)),((0.2 0.2 0.2,0.2 0.2 0.8,0.8 0.2 0.8,0.8 0.2 0.2,0.2 0.2 0.2)),((0.8 0.2 0.2,0.8 0.2 0.8,0.8 0.8 0.8,0.8 0.8 0.2,0.8 0.2 0.2)),((0.2 0.2 0.8, [...]
+
diff --git a/test/data/StraightSkeletonTest.txt b/test/data/StraightSkeletonTest.txt
new file mode 100644
index 0000000..8afe705
--- /dev/null
+++ b/test/data/StraightSkeletonTest.txt
@@ -0,0 +1,3 @@
+#input|output
+POLYGON((24.881887 5.207295,24.918189 15.553369,41.363002 15.698577,41.181492 -1.036652,33.521766 -1.072954,33.412860 5.243597,24.881887 5.207295))|MULTILINESTRING((24.881887 5.207295,30.084842 10.414135),(33.412860 5.243597,37.318651 9.234258),(33.521766 -1.072954,37.339128 2.829246),(41.181492 -1.036652,37.339128 2.829246),(41.363002 15.698577,36.107380 10.453539),(24.918189 15.553369,30.084842 10.414135),(37.339128 2.829246,37.318651 9.234258),(37.318651 9.234258,36.107380 10.453539), [...]
+
diff --git a/test/data/TriangulatePolygonTest.txt b/test/data/TriangulatePolygonTest.txt
new file mode 100644
index 0000000..0327c53
--- /dev/null
+++ b/test/data/TriangulatePolygonTest.txt
@@ -0,0 +1,46 @@
+#should throw? wkt
+0 POLYGON((0.0 0.0,1.0 0.0,1.0 1.0,0.0 1.0,0.0 0.0))
+0 POLYGON((0.0 0.0,1.0 0.0,1.0 1.0,0.0 1.0,0.0 0.0),(0.2 0.2,0.2 0.8,0.8 0.8,0.8 0.2,0.2 0.2))
+0 POLYGON((0.0 0.0,1.0 0.0,0.0 0.5,0.0 0.0))
+
+
+0 POLYGON((-4.50429870120885e-16 0.662500147457656,0.0022364652369431 0.666684279623519,0.151471862576139 0.848528137423853,0.333315720376473 0.997763534763051,0.540779881161888 1.10865543901354,0.765891613580642 1.17694233648388,0.999999999999996 1.2,1.23410838641935 1.17694233648388,1.4592201188381 1.10865543901355,1.66668427962352 0.997763534763056,1.84852813742385 0.848528137423859,1.99776353476305 0.666684279623525,2.10865543901354 0.45922011883811,2.17694233648388 0.234108386419357 [...]
+
+0 POLYGON((1.3 0.0,4.0 0.5,6.7 1.0,5.2 10.0,4.0 10.1,0.0 9.1,1.3 0.0))
+
+# aligned points
+0 MULTIPOLYGON(((2.4 1,4.7 1.5,7 2,7.5 0,12.2 1.1,9.3 13.8,0 11.7,2.4 1)))
+
+
+#
+0 MULTIPOLYGON(((0.8 1.7,0.5 1.5,0.2 1.3,0 0.9,0 0.5,0.3 0.2,0.6 0,0.9 0,1.3 0,1.6 0.3,1.8 0.5,1.8 0.9,1.7 1.2,1.6 1.5,1.3 1.8,0.8 1.7)))
+
+
+#--
+# a polygon with collinear points
+0 MULTIPOLYGON(((4.8 2.2,4.6 2.4,4.4 2.6,4.8 3.1,3.4 4.6,0 1.5,1.5 0.1,2 0.5,2.3 0.2,2.4 0,4.8 2.2)))
+# the same polygon without collinear points (ST_Simplify(g,0.001))
+0 MULTIPOLYGON(((4.8 2.2,4.4 2.6,4.8 3.1,3.4 4.6,0 1.5,1.5 0.1,2 0.5,2.3 0.2,2.4 0,4.8 2.2)))
+
+
+#-- collinear points again?
+0 MULTIPOLYGON(((5.8 20,4.3 18.5,1.8 16,4.3 13.4,0 8.9,5.5 3.2,4.7 2.4,7.1 0,13.7 6.6,8.6 11.9,11.1 14.7,5.8 20)))
+0 MULTIPOLYGON(((5.8 20,1.8 16,4.3 13.4,0 8.9,5.5 3.2,4.7 2.4,7.1 0,13.7 6.6,8.6 11.9,11.1 14.7,5.8 20)))
+
+#-- collinar points ?
+0 MULTIPOLYGON(((12.2 0,24.5 11,36.8 22,48.2 32.1,34 44,8.5 21.3,8.3 21.5,8.1 21.6,7.6 21.7,7.2 21.7,6.8 21.5,6.4 21.2,6.1 20.8,6.1 20.4,6.1 20,6.3 19.6,6.4 19.4,0 13.7,12.2 0)))
+0 MULTIPOLYGON(((12.2 0,36.8 22,48.2 32.1,34 44,8.5 21.3,8.3 21.5,8.1 21.6,7.6 21.7,7.2 21.7,6.8 21.5,6.4 21.2,6.1 20.8,6.1 20,6.4 19.4,0 13.7,12.2 0)))
+
+
+#--
+0 MULTIPOLYGON(((1.1 0,4.1 0.5,7.1 1,5.9 7.5,0 6.5,1.1 0)))
+
+
+#-- test with constraint intersection
+1 MULTIPOLYGON(((8.30000000004657 15.9000000003725,13.5999999999767 13.0999999996275,15.5999999999767 8.70000000018626,13.5999999999767 2.90000000037253,8.5 0.099999999627471,2.19999999995343 1.79999999981374,0 5.20000000018626,2.69999999995343 15,8.30000000004657 15.9000000003725,2.69999999995343 15,0 5.09999999962747,2.19999999995343 1.70000000018626,8.5 0,13.5999999999767 2.79999999981374,15.5999999999767 8.70000000018626,13.5999999999767 13.0999999996275,8.30000000004657 15.9000000003725)))
+
+#BATIMENT0000000240188968|MULTIPOLYGON(((562966.5 6928402.1,562966.5 6928401.9,562966.5 6928402,562966.5 6928402.1)))
+#Exception en point flottant (core dumped)
+1 MULTIPOLYGON(((562966.5 6928402.1,562966.5 6928401.9,562966.5 6928402,562966.5 6928402.1)))
+
+
diff --git a/test/data/WktTest.txt b/test/data/WktTest.txt
new file mode 100644
index 0000000..a5ed46f
--- /dev/null
+++ b/test/data/WktTest.txt
@@ -0,0 +1,29 @@
+#-- contains trimed WKT geometries with 1 decimals
+POINT(2.0 3.0)
+POINT(2.0 3.0 4.0)
+POINT(123.4 543.2)
+
+LINESTRING(5.0 6.0,8.0 9.0)
+LINESTRING(5.0 6.0 7.0,8.0 9.0 10.0)
+
+#polygon 2d
+POLYGON((0.0 0.0,1.0 0.0,1.0 1.0,0.0 1.0,0.0 0.0))
+POLYGON((0.0 0.0,1.0 0.0,1.0 1.0,0.0 1.0,0.0 0.0),(0.2 0.2,0.8 0.2,0.8 0.8,0.2 0.8,0.2 0.2))
+
+#polygon 3d
+POLYGON((0.0 0.0 0.0,0.0 0.0 1.0,0.0 1.0 1.0,0.0 1.0 0.0,0.0 0.0 0.0))
+
+MULTIPOINT((1234.8 6543.9),(1.4 2.3),(3.6 4.7),(65.2 124.8))
+
+GEOMETRYCOLLECTION(POINT(1.0 1.0),LINESTRING(4.0 5.0,6.0 7.0,8.0 9.0),POINT(30.0 30.0))
+
+
+SOLID((((0.0 0.0 0.0,0.0 1.0 0.0,1.0 1.0 0.0,1.0 0.0 0.0,0.0 0.0 0.0),(0.2 0.2 0.0,0.8 0.2 0.0,0.8 0.8 0.0,0.2 0.8 0.0,0.2 0.2 0.0)),((0.0 0.0 1.0,1.0 0.0 1.0,1.0 1.0 1.0,0.0 1.0 1.0,0.0 0.0 1.0),(0.2 0.2 1.0,0.2 0.8 1.0,0.8 0.8 1.0,0.8 0.2 1.0,0.2 0.2 1.0)),((0.0 0.0 0.0,0.0 0.0 1.0,0.0 1.0 1.0,0.0 1.0 0.0,0.0 0.0 0.0)),((0.0 1.0 0.0,0.0 1.0 1.0,1.0 1.0 1.0,1.0 1.0 0.0,0.0 1.0 0.0)),((1.0 1.0 0.0,1.0 1.0 1.0,1.0 0.0 1.0,1.0 0.0 0.0,1.0 1.0 0.0)),((1.0 0.0 0.0,1.0 0.0 1.0,0.0 0.0 1.0,0.0 [...]
+
+
+POINT M(13.2 47.3 1000.0)
+POINT ZM(13.2 47.2 0.2 1000.8)
+LINESTRING ZM(15.2 57.6 0.3 1000.0,15.8 57.1 0.3 1100.0)
+POLYGON M((0.0 0.0 0.0,1.0 0.0 1.0,1.0 1.0 2.0,0.0 1.0 3.0,0.0 0.0 4.0))
+MULTIPOINT M((0.0 0.0 0.0),(1.0 1.0 1.0))
+
diff --git a/test/data/countries.wkt b/test/data/countries.wkt
new file mode 100644
index 0000000..92cb0b0
--- /dev/null
+++ b/test/data/countries.wkt
@@ -0,0 +1,2 @@
+MULTIPOLYGON(((0.569679740254401 0.174192330925372,0.583063936578014 0.149749378245225,0.591409680239167 0.119880400174374,0.595905529643062 0.111198759728985,0.600685599887129 0.10515261671393,0.60569821412787 0.102310412809324,0.622673922290289 0.0950757122883275,0.629779431602117 0.0906315397278163,0.66238725989075 0.0584371225891474,0.699335908851708 0.00970624685985655,0.704916963873416 -0.000835745559207624,0.705614595863494 -0.00739865251178884,0.705459566232605 -0.010447561991348 [...]
+MULTIPOLYGON(((0.205237545011542 -0.402891556731243,0.222368281905531 -0.403744218352267,0.230093908841653 -0.403279130358863,0.238568843711974 -0.403718379930547,0.241721105979096 -0.407723303818694,0.233220332687054 -0.418032751341707,0.247999792091562 -0.439452632963901,0.244976721033666 -0.453224402015815,0.229112056011402 -0.463068762444687,0.205289220955606 -0.472654740455164,0.209242468000312 -0.462707027238787,0.212110510326639 -0.458986324190812,0.191181555119513 -0.466143510346 [...]
diff --git a/test/data/cow-nonormals.obj b/test/data/cow-nonormals.obj
new file mode 100644
index 0000000..99e9282
--- /dev/null
+++ b/test/data/cow-nonormals.obj
@@ -0,0 +1,10388 @@
+# The units used in this file are centimeters.
+v 2.229345 -0.992723 -0.862826
+v 2.292449 -0.871852 -0.882400
+v 2.410367 -0.777999 -0.841105
+v 2.407309 -0.974980 -0.805091
+v 2.539200 -0.727778 -0.750475
+v 2.520417 -0.954785 -0.739445
+v 2.637655 -0.768176 -0.637039
+v 2.669281 -0.930664 -0.557166
+v 2.514167 -1.077721 -0.706614
+v 2.386465 -1.116066 -0.761367
+v 2.180012 -1.130557 -0.821812
+v 2.354287 -1.193746 -0.735189
+v 2.158051 -1.209613 -0.783941
+v 2.318787 -1.294090 -0.673863
+v 2.126237 -1.330172 -0.721011
+v 2.274533 -1.433487 -0.567366
+v 2.486533 -1.274971 -0.627822
+v 2.457060 -1.400958 -0.539866
+v 2.549322 -1.335209 -0.535156
+v 2.617970 -1.235597 -0.520238
+v 2.510841 -1.158786 -0.678057
+v 2.670253 -1.108365 -0.544018
+v 2.710721 -0.830091 -0.532493
+v 2.857666 -0.930625 -0.391195
+v 2.757946 -1.099958 -0.471684
+v 2.847364 -1.103812 -0.402301
+v 2.803736 -1.255869 -0.438328
+v 2.740886 -1.339225 -0.463604
+v 2.663024 -1.440487 -0.478149
+v 2.515314 -1.507063 -0.483275
+v 2.422296 -1.510915 -0.494169
+v 2.249663 -1.492705 -0.531270
+v 2.079600 -1.473377 -0.654997
+v 2.960118 -0.941827 -0.284743
+v 2.928787 -1.107467 -0.312054
+v 2.893096 -1.302168 -0.332049
+v 2.824356 -1.407256 -0.355013
+v 2.721135 -1.520418 -0.362378
+v 2.545261 -1.593300 -0.386310
+v 2.396607 -1.593239 -0.389972
+v 2.243492 -1.584783 -0.431143
+v 2.048200 -1.581983 -0.555832
+v 2.970902 -0.959664 0.000000
+v 2.931756 -1.129655 0.000000
+v 2.896234 -1.319560 0.000000
+v 2.821376 -1.431534 0.000000
+v 2.706963 -1.528854 0.000000
+v 2.534227 -1.617078 0.000000
+v 2.348182 -1.624595 0.000000
+v 2.167167 -1.596326 0.000000
+v 1.920432 -1.567396 0.000000
+v 2.881063 -0.493146 -0.521968
+v 2.736198 -0.346225 -0.659345
+v 2.835437 -0.231101 -0.577890
+v 2.986408 -0.413503 -0.428964
+v 2.910769 -0.638444 -0.431191
+v 2.825540 -0.567578 -0.552597
+v 2.688131 -0.517509 -0.672975
+v 2.647368 -0.611550 -0.669485
+v 2.618307 -0.549092 -0.805491
+v 2.993075 -0.708434 -0.342596
+v 3.045715 -0.767786 -0.261741
+v 3.065544 -0.788768 0.000000
+v 3.107533 -0.691019 -0.264602
+v 3.118124 -0.703925 0.000000
+v 3.053144 -0.609681 -0.326931
+f 3 4 2
+f 1 2 4
+f 5 6 3
+f 4 3 6
+f 6 5 7
+f 7 8 6
+f 8 9 6
+f 10 4 9
+f 6 9 4
+f 11 1 10
+f 4 10 1
+f 10 12 11
+f 11 12 13
+f 13 12 15
+f 12 14 15
+f 15 14 16
+f 16 14 18
+f 14 17 18
+f 18 17 19
+f 19 17 20
+f 22 20 21
+f 20 17 21
+f 21 17 12
+f 17 14 12
+f 12 10 21
+f 10 9 21
+f 8 22 9
+f 21 9 22
+f 8 7 23
+f 22 24 25
+f 25 20 22
+f 20 25 27
+f 25 26 27
+f 26 25 24
+f 20 27 28
+f 20 28 19
+f 28 29 19
+f 30 18 29
+f 19 29 18
+f 18 30 31
+f 18 31 16
+f 31 32 16
+f 33 15 32
+f 16 32 15
+f 34 35 24
+f 24 35 26
+f 35 36 26
+f 26 36 27
+f 36 37 27
+f 27 37 28
+f 37 38 29
+f 39 30 38
+f 29 38 30
+f 40 31 39
+f 30 39 31
+f 32 31 41
+f 31 40 41
+f 41 42 32
+f 32 42 33
+f 44 35 43
+f 34 43 35
+f 45 36 44
+f 35 44 36
+f 37 36 46
+f 36 45 46
+f 47 38 46
+f 37 46 38
+f 48 39 47
+f 38 47 39
+f 49 40 48
+f 39 48 40
+f 50 41 49
+f 40 49 41
+f 42 41 51
+f 41 50 51
+f 52 53 54
+f 54 55 52
+f 52 55 56
+f 56 57 52
+f 52 57 58
+f 7 5 59
+f 59 5 60
+f 60 58 59
+f 56 23 57
+f 7 57 23
+f 23 56 24
+f 24 56 61
+f 24 61 34
+f 61 62 34
+f 34 62 43
+f 62 63 43
+f 64 65 62
+f 63 62 65
+f 24 22 8
+f 23 24 8
+f 59 58 57
+f 7 59 57
+f 55 66 56
+f 66 61 56
+f 66 64 61
+f 61 64 62
+v -2.033406 -0.910030 -0.964220
+v -2.119856 -1.128800 -0.970960
+v -2.306662 -1.116976 -0.961238
+v -2.031698 -1.097344 -0.966701
+v -1.782298 -1.020581 -0.943381
+v -2.462835 -1.305500 -0.966395
+v -2.337617 -1.334842 -0.966761
+v -2.161843 -1.325837 -0.957465
+v -2.042059 -1.312976 -0.940911
+v -1.776785 -1.275107 -0.914703
+v -1.709172 -1.283232 -0.897427
+v -1.456655 -1.295527 -0.894240
+v -2.591357 -1.510845 -0.885470
+v -2.417777 -1.553136 -0.887222
+v -2.223917 -1.541268 -0.879260
+v -2.049879 -1.562369 -0.829319
+v -1.777628 -1.473076 -0.845827
+v -1.778934 -1.550199 -0.776454
+v -1.686329 -1.414405 -0.869373
+v -1.592146 -1.408592 -0.838483
+v -1.552229 -1.555077 -0.735708
+v -1.659758 -1.544361 -0.788181
+v -1.366873 -1.340211 -0.907567
+v -1.376186 -1.661988 -0.718954
+v -1.198513 -1.456102 -0.885435
+v -1.200688 -1.577575 -0.799188
+v -0.953236 -1.545941 -0.899180
+f 67 68 69
+f 68 67 70
+f 70 67 71
+f 72 69 73
+f 73 69 74
+f 69 68 74
+f 75 74 70
+f 74 68 70
+f 71 76 70
+f 75 70 76
+f 76 71 77
+f 77 71 78
+f 79 72 80
+f 72 73 80
+f 81 80 74
+f 80 73 74
+f 82 81 75
+f 81 74 75
+f 75 83 82
+f 82 83 84
+f 83 75 76
+f 83 76 85
+f 76 77 85
+f 78 86 77
+f 85 77 86
+f 86 78 87
+f 87 88 86
+f 86 88 85
+f 88 84 85
+f 85 84 83
+f 90 87 89
+f 87 78 89
+f 90 89 92
+f 89 91 92
+f 92 91 93
+v -0.953236 -1.545941 -0.899180
+v -1.091175 -1.707120 -0.727242
+v -1.226563 -1.655159 -0.687343
+v -1.200688 -1.577575 -0.799188
+v -1.376186 -1.661988 -0.718954
+v -1.089642 -1.757196 -0.685154
+v -1.266738 -1.691944 -0.557922
+v -0.972089 -1.774507 -0.768570
+v -0.812845 -1.785424 -0.768511
+v -0.535144 -1.615983 -0.920556
+v -0.680046 -1.768325 -0.819080
+v -0.564074 -1.789401 -0.803191
+v -0.422877 -1.751200 -0.823423
+v -0.063012 -1.583021 -0.865082
+v -0.078470 -1.688266 -0.800230
+v -0.094135 -1.769086 -0.556924
+v -0.543078 -1.810473 -0.563825
+v -0.977375 -1.793126 -0.498747
+v -1.108758 -1.770749 -0.473033
+v -1.305099 -1.708460 -0.484230
+v -1.397474 -1.693815 -0.570541
+f 94 95 97
+f 95 96 97
+f 97 96 98
+f 100 96 99
+f 96 95 99
+f 95 94 101
+f 101 94 102
+f 103 104 94
+f 102 94 104
+f 104 103 105
+f 105 103 106
+f 103 107 106
+f 106 107 108
+f 110 106 109
+f 106 108 109
+f 110 105 106
+f 105 110 104
+f 111 102 110
+f 104 110 102
+f 99 95 101
+f 100 99 112
+f 99 111 112
+f 112 113 100
+f 100 98 96
+f 98 100 114
+v -1.397474 -1.693815 -0.570541
+v -1.480217 -1.656600 -0.606638
+v -1.376186 -1.661988 -0.718954
+v -1.552229 -1.555077 -0.735708
+v -1.601625 -1.593321 -0.605607
+v -1.519339 -1.653776 -0.501741
+v -1.406693 -1.697325 -0.450399
+v -1.576196 -1.696317 -0.358146
+v -1.386502 -1.718441 -0.350823
+f 115 116 117
+f 117 116 118
+f 118 116 119
+f 119 116 120
+f 121 120 115
+f 120 116 115
+f 119 120 122
+f 122 120 123
+f 120 121 123
+v -1.386502 -1.718441 -0.350823
+v -1.406693 -1.697325 -0.450399
+v -1.305099 -1.708460 -0.484230
+v -0.972514 -1.822778 -0.372649
+v -0.977375 -1.793126 -0.498747
+v -0.543078 -1.810473 -0.563825
+v -0.523838 -1.850065 -0.388007
+v -0.094135 -1.769086 -0.556924
+v -0.112666 -1.806584 -0.383324
+v 0.489819 -1.524947 -0.672392
+v 0.480235 -1.631521 -0.401961
+v 0.446550 -1.672950 0.000000
+v -0.155114 -1.828285 0.000000
+v -0.530369 -1.860806 0.000000
+v -0.956007 -1.825728 0.000000
+v -1.395728 -1.723811 0.000000
+f 124 125 126
+f 124 126 127
+f 129 130 128
+f 127 128 130
+f 131 132 129
+f 130 129 132
+f 133 134 131
+f 132 131 134
+f 134 135 132
+f 135 136 132
+f 132 136 130
+f 136 137 130
+f 130 137 127
+f 137 138 127
+f 138 139 127
+f 127 139 124
+v -1.386502 -1.718441 -0.350823
+v -1.395728 -1.723811 0.000000
+v -1.610025 -1.711571 0.000000
+v -1.576196 -1.696317 -0.358146
+v -1.799827 -1.753136 0.000000
+v -1.764045 -1.764987 -0.406586
+v -1.747790 -1.667608 -0.606340
+v -1.601625 -1.593321 -0.605607
+v -1.778934 -1.550199 -0.776454
+v -1.659758 -1.544361 -0.788181
+v -1.552229 -1.555077 -0.735708
+v -2.734184 -1.717948 -0.749581
+v -2.591357 -1.510845 -0.885470
+v -2.417777 -1.553136 -0.887222
+v -2.508885 -1.719933 -0.721675
+v -2.223917 -1.541268 -0.879260
+v -2.267049 -1.753901 -0.662106
+v -2.049879 -1.562369 -0.829319
+v -2.037371 -1.736360 -0.656787
+v -1.883160 -1.829718 -0.401567
+v -1.936032 -1.829617 -0.488916
+v -2.027242 -1.813012 -0.555232
+v -2.126375 -1.866497 -0.502895
+v -2.176551 -1.873816 -0.445782
+v -2.317557 -1.874200 -0.470587
+v -2.446375 -1.893261 -0.494110
+v -2.466779 -1.857679 -0.570461
+v -2.547737 -1.833025 -0.609321
+v -2.647220 -1.844010 -0.594347
+v -2.699966 -1.850397 -0.570070
+v -2.811581 -1.798210 -0.712737
+v -2.941731 -1.787431 -0.442574
+v -2.709403 -1.879947 -0.508775
+v -2.684452 -1.891207 -0.447388
+v -2.892162 -1.781087 0.000000
+v -2.614084 -1.905005 -0.404925
+v -2.656867 -1.853045 0.000000
+v -2.503818 -1.909806 -0.431456
+v -2.348005 -1.869142 0.000000
+v -2.147113 -1.903198 -0.362462
+v -2.062725 -1.884246 -0.307336
+v -2.092921 -1.839622 0.000000
+v -1.946306 -1.872735 -0.344251
+f 142 143 141
+f 140 141 143
+f 145 143 144
+f 143 142 144
+f 147 143 146
+f 145 146 143
+f 147 146 148
+f 148 149 147
+f 147 149 150
+f 151 152 154
+f 152 153 154
+f 156 154 155
+f 154 153 155
+f 156 155 158
+f 155 157 158
+f 157 148 158
+f 158 148 146
+f 159 160 145
+f 146 145 160
+f 158 146 161
+f 160 161 146
+f 162 156 161
+f 158 161 156
+f 164 156 163
+f 156 162 163
+f 164 165 156
+f 165 166 156
+f 154 156 167
+f 156 166 167
+f 151 154 168
+f 154 167 168
+f 168 169 151
+f 151 169 170
+f 172 173 171
+f 171 173 174
+f 173 175 174
+f 174 175 176
+f 176 175 178
+f 175 177 178
+f 164 178 165
+f 178 177 165
+f 164 163 178
+f 163 179 178
+f 180 181 179
+f 178 179 181
+f 181 180 144
+f 180 182 144
+f 145 144 159
+f 144 182 159
+v -1.089642 -1.757196 -0.685154
+v -0.972089 -1.774507 -0.768570
+v -0.977375 -1.793126 -0.498747
+v -0.812845 -1.785424 -0.768511
+f 183 184 185
+f 186 185 184
+v -3.139394 -1.687482 -0.638546
+v -3.120907 -1.707924 -0.431829
+v -3.314868 -1.599081 -0.439626
+v -3.304804 -1.582192 -0.643445
+v -3.442085 -1.484120 -0.406377
+v -3.387254 -1.486027 -0.672861
+v -3.557869 -1.325941 -0.378030
+v -3.533910 -1.330455 -0.568246
+v -3.639586 -1.140102 -0.333800
+v -3.631179 -1.157838 -0.505610
+v -3.686518 -0.955181 -0.320349
+v -3.667859 -0.964867 -0.464702
+v -3.676599 -0.729578 -0.330724
+v -3.665774 -0.734080 -0.446286
+v -3.616627 -0.350374 -0.338492
+v -3.595973 -0.346391 -0.426453
+v -3.570243 -0.060093 -0.344854
+v -3.529709 -0.065998 -0.437217
+v -3.535416 0.191408 -0.338478
+v -3.516840 0.149002 -0.430359
+v -3.536654 0.442277 -0.322000
+v -3.552320 0.219613 0.000000
+v -3.544507 0.467147 0.000000
+v -3.583763 -0.052271 0.000000
+v -3.637643 -0.356271 0.000000
+v -3.673607 -0.720796 0.000000
+v -3.678793 -0.926816 0.000000
+v -3.650579 -1.142448 0.000000
+v -3.522115 -1.366623 0.000000
+v -3.417689 -1.494416 0.000000
+v -3.271035 -1.609292 0.000000
+v -3.110300 -1.691720 0.000000
+v -2.941731 -1.787431 -0.442574
+v -2.892162 -1.781087 0.000000
+v -3.470778 -0.078218 -0.546398
+v -3.526766 -0.317542 -0.560837
+v -3.569993 -0.731989 -0.649435
+v -3.550120 -0.984868 -0.675228
+v -3.492599 -1.180646 -0.692282
+v -3.335942 -1.365685 -0.724590
+v -3.415655 -0.308965 -0.671045
+v -3.283698 -0.730967 -0.793898
+v -3.438226 -0.721479 -0.728141
+v -3.355398 -0.969157 -0.766213
+v -3.279790 -1.162072 -0.784602
+v -3.251210 -0.948205 -0.819868
+v -3.566995 0.656967 0.000000
+v -3.556552 0.704883 -0.280630
+v -3.599077 0.796217 0.000000
+v -3.578170 0.837714 -0.288502
+f 188 189 187
+f 187 189 190
+f 192 190 191
+f 190 189 191
+f 191 193 192
+f 192 193 194
+f 194 193 196
+f 193 195 196
+f 196 195 198
+f 195 197 198
+f 197 199 198
+f 198 199 200
+f 202 200 201
+f 200 199 201
+f 201 203 202
+f 202 203 204
+f 205 206 203
+f 204 203 206
+f 206 205 207
+f 205 208 207
+f 207 208 209
+f 208 205 210
+f 205 203 210
+f 201 199 211
+f 211 199 212
+f 199 197 212
+f 212 197 213
+f 213 197 214
+f 197 195 214
+f 215 214 193
+f 214 195 193
+f 191 216 193
+f 215 193 216
+f 189 217 191
+f 216 191 217
+f 189 188 217
+f 217 188 218
+f 220 218 219
+f 218 188 219
+f 203 201 210
+f 210 201 211
+f 206 221 204
+f 202 204 222
+f 204 221 222
+f 223 200 222
+f 202 222 200
+f 224 198 223
+f 200 223 198
+f 198 224 196
+f 224 225 196
+f 226 194 225
+f 196 225 194
+f 194 226 192
+f 227 228 229
+f 221 227 222
+f 222 227 223
+f 227 229 223
+f 230 224 229
+f 223 229 224
+f 225 224 231
+f 224 230 231
+f 225 231 226
+f 231 230 232
+f 234 207 233
+f 207 209 233
+f 235 236 233
+f 234 233 236
+f 230 229 232
+f 232 229 228
+v 1.734568 -2.965876 -0.986396
+v 1.718315 -2.775468 -0.921796
+v 1.771416 -2.769024 -0.946100
+v 1.806371 -2.949735 -0.984058
+v 1.911792 -2.895773 -0.950117
+v 1.880971 -2.733242 -0.890200
+v 1.960643 -2.712860 -0.900890
+v 2.021366 -2.881725 -0.945561
+v 1.994078 -2.713047 -0.824553
+v 2.057496 -2.887282 -0.844225
+v 1.735077 -3.022732 -0.972751
+v 1.802387 -3.089615 -0.961851
+v 1.721745 -3.116887 -0.979111
+v 1.811797 -3.135641 -0.933096
+f 237 238 240
+f 238 239 240
+f 244 241 243
+f 241 242 243
+f 246 244 245
+f 244 243 245
+f 237 240 247
+f 247 248 249
+f 249 248 250
+v 1.970051 -3.141862 -1.065178
+v 2.110033 -3.148257 -1.068816
+v 2.148880 -3.221616 -1.076203
+v 2.031262 -3.256709 -1.111122
+v 2.247981 -3.342804 -1.127459
+v 2.138771 -3.397683 -1.214726
+v 2.343303 -3.507846 -1.195262
+v 2.254361 -3.550931 -1.235118
+v 2.025468 -3.556842 -1.204841
+v 1.981186 -3.441282 -1.180532
+v 1.926176 -3.288880 -1.093746
+v 1.886443 -3.191742 -1.047318
+v 2.281229 -3.338250 -1.043475
+v 2.201939 -3.226457 -0.996503
+v 2.170039 -3.134504 -0.978866
+v 2.091539 -3.032437 -0.947029
+v 2.113587 -3.011851 -0.851648
+v 2.217369 -3.156093 -0.888927
+v 1.841888 -3.246003 -1.014774
+v 1.865135 -3.353827 -1.054981
+v 1.919391 -3.487078 -1.110869
+v 1.980621 -3.043895 -0.964237
+f 251 252 254
+f 252 253 254
+f 254 253 256
+f 253 255 256
+f 255 257 256
+f 256 257 258
+f 259 260 258
+f 258 260 256
+f 256 260 254
+f 260 261 254
+f 254 261 251
+f 261 262 251
+f 255 253 263
+f 263 253 264
+f 264 253 265
+f 253 252 265
+f 268 265 267
+f 265 266 267
+f 261 270 262
+f 269 262 270
+f 261 260 270
+f 271 270 260
+f 260 259 271
+f 272 265 252
+v 2.021366 -2.881725 -0.945561
+v 2.057496 -2.887282 -0.844225
+v 2.113587 -3.011851 -0.851648
+v 2.091539 -3.032437 -0.947029
+v 1.911792 -2.895773 -0.950117
+v 1.848272 -2.927260 -0.996966
+v 1.830669 -2.736121 -0.903313
+v 1.880971 -2.733242 -0.890200
+v 1.806371 -2.949735 -0.984058
+v 1.771416 -2.769024 -0.946100
+v 1.705953 -3.006628 -0.832630
+v 1.735077 -3.022732 -0.972751
+v 1.721745 -3.116887 -0.979111
+v 1.709173 -3.133145 -0.807940
+v 1.811797 -3.135641 -0.933096
+v 1.806407 -3.173343 -0.834455
+f 273 274 276
+f 274 275 276
+f 278 279 277
+f 277 279 280
+f 279 278 282
+f 281 282 278
+f 285 286 284
+f 283 284 286
+f 285 287 286
+f 286 287 288
+v 1.806407 -3.173343 -0.834455
+v 1.811797 -3.135641 -0.933096
+v 1.841888 -3.246003 -1.014774
+v 1.832790 -3.296508 -0.865078
+v 1.933899 -3.546253 -0.912438
+v 1.919391 -3.487078 -1.110869
+v 2.025468 -3.556842 -1.204841
+v 2.078928 -3.584991 -0.917088
+v 1.865135 -3.353827 -1.054981
+v 1.839523 -3.405292 -0.883488
+f 291 292 290
+f 289 290 292
+f 296 293 295
+f 293 294 295
+f 297 298 291
+f 292 291 298
+f 293 298 294
+f 298 297 294
+v 1.741854 -3.114181 -0.700705
+v 1.709173 -3.133145 -0.807940
+v 1.806407 -3.173343 -0.834455
+v 1.900481 -3.131932 -0.728621
+f 302 299 301
+f 299 300 301
+v 1.832790 -3.296508 -0.865078
+v 1.929730 -3.298418 -0.689538
+v 1.900481 -3.131932 -0.728621
+v 1.806407 -3.173343 -0.834455
+v 1.839523 -3.405292 -0.883488
+v 1.941325 -3.434803 -0.701314
+v 1.933899 -3.546253 -0.912438
+v 2.002745 -3.523420 -0.688103
+v 2.078928 -3.584991 -0.917088
+v 2.126553 -3.549679 -0.701005
+v 2.197935 -3.583948 -0.936437
+v 2.244147 -3.545557 -0.732888
+f 304 305 303
+f 303 305 306
+f 304 303 308
+f 303 307 308
+f 309 310 307
+f 308 307 310
+f 309 311 310
+f 310 311 312
+f 311 313 312
+f 312 313 314
+v 1.705953 -3.006628 -0.832630
+v 1.709173 -3.133145 -0.807940
+v 1.741854 -3.114181 -0.700705
+v 1.776024 -2.980086 -0.707575
+v 1.736425 -2.743683 -0.736866
+v 1.700797 -2.794792 -0.824250
+v 2.021366 -2.881725 -0.945561
+v 2.091539 -3.032437 -0.947029
+v 1.980621 -3.043895 -0.964237
+v 1.911792 -2.895773 -0.950117
+f 318 315 317
+f 315 316 317
+f 319 320 318
+f 318 320 315
+f 322 323 321
+f 321 323 324
+v 1.898573 -3.068274 -0.994338
+v 1.980621 -3.043895 -0.964237
+v 2.110033 -3.148257 -1.068816
+v 1.970051 -3.141862 -1.065178
+f 327 328 326
+f 325 326 328
+v 1.980621 -3.043895 -0.964237
+v 1.898573 -3.068274 -0.994338
+v 1.848272 -2.927260 -0.996966
+v 1.911792 -2.895773 -0.950117
+v 1.855134 -3.083228 -0.986129
+v 1.806371 -2.949735 -0.984058
+f 329 330 332
+f 330 331 332
+f 331 330 334
+f 330 333 334
+v 1.855134 -3.083228 -0.986129
+v 1.898573 -3.068274 -0.994338
+v 1.970051 -3.141862 -1.065178
+v 1.886443 -3.191742 -1.047318
+v 1.811797 -3.135641 -0.933096
+v 1.841888 -3.246003 -1.014774
+f 337 338 336
+f 335 336 338
+f 340 339 338
+f 339 335 338
+v 1.802387 -3.089615 -0.961851
+v 1.855134 -3.083228 -0.986129
+v 1.811797 -3.135641 -0.933096
+v 1.735077 -3.022732 -0.972751
+v 1.806371 -2.949735 -0.984058
+v 1.705953 -3.006628 -0.832630
+v 1.734568 -2.965876 -0.986396
+f 341 342 343
+f 345 342 344
+f 344 342 341
+f 344 346 347
+v 2.217369 -3.156093 -0.888927
+v 2.113587 -3.011851 -0.851648
+v 2.073690 -3.020848 -0.782654
+v 2.187495 -3.161535 -0.800285
+f 348 349 351
+f 349 350 351
+v 2.113587 -3.011851 -0.851648
+v 2.057496 -2.887282 -0.844225
+v 2.001343 -2.847715 -0.762517
+v 2.073690 -3.020848 -0.782654
+f 354 355 353
+f 352 353 355
+v 2.170039 -3.134504 -0.978866
+v 2.217369 -3.156093 -0.888927
+v 2.236407 -3.220054 -0.892030
+v 2.201939 -3.226457 -0.996503
+v 2.247981 -3.342804 -1.127459
+v 2.281229 -3.338250 -1.043475
+v 2.386827 -3.462222 -1.136480
+v 2.343303 -3.507846 -1.195262
+v 2.327021 -3.352317 -0.958234
+v 2.440236 -3.509564 -1.019417
+v 2.309358 -3.345468 -0.801508
+v 2.377814 -3.484109 -0.800332
+v 2.235942 -3.243103 -0.823955
+v 2.187495 -3.161535 -0.800285
+f 356 357 359
+f 357 358 359
+f 363 360 362
+f 360 361 362
+f 365 362 364
+f 362 361 364
+f 358 364 359
+f 364 361 359
+f 365 364 367
+f 364 366 367
+f 366 364 368
+f 364 358 368
+f 369 368 357
+f 368 358 357
+v 1.741854 -3.114181 -0.700705
+v 1.900481 -3.131932 -0.728621
+v 1.857471 -2.950722 -0.669988
+v 1.776024 -2.980086 -0.707575
+v 1.998099 -3.039955 -0.718855
+v 1.945632 -2.876710 -0.703118
+v 2.073690 -3.020848 -0.782654
+v 2.001343 -2.847715 -0.762517
+v 1.884318 -2.724404 -0.701999
+v 1.841282 -2.716008 -0.708009
+v 1.972647 -2.728848 -0.772496
+f 370 371 372
+f 370 372 373
+f 371 374 372
+f 374 375 372
+f 377 375 376
+f 374 376 375
+f 379 372 378
+f 372 375 378
+f 378 375 380
+f 375 377 380
+v 1.900481 -3.131932 -0.728621
+v 1.929730 -3.298418 -0.689538
+v 2.059222 -3.230076 -0.674936
+v 1.998099 -3.039955 -0.718855
+v 2.187495 -3.161535 -0.800285
+v 2.073690 -3.020848 -0.782654
+v 1.941325 -3.434803 -0.701314
+v 2.107985 -3.363571 -0.677007
+v 2.235942 -3.243103 -0.823955
+f 384 381 383
+f 381 382 383
+f 383 385 384
+f 384 385 386
+f 387 388 382
+f 382 388 383
+f 389 385 388
+f 383 388 385
+v 1.776024 -2.980086 -0.707575
+v 1.857471 -2.950722 -0.669988
+v 1.841282 -2.716008 -0.708009
+v 1.736425 -2.743683 -0.736866
+f 392 393 391
+f 390 391 393
+v 2.107985 -3.363571 -0.677007
+v 1.941325 -3.434803 -0.701314
+v 2.002745 -3.523420 -0.688103
+v 2.126553 -3.549679 -0.701005
+v 2.235942 -3.243103 -0.823955
+v 2.309358 -3.345468 -0.801508
+v 2.244147 -3.545557 -0.732888
+v 2.377814 -3.484109 -0.800332
+v 2.440236 -3.509564 -1.019417
+v 2.197935 -3.583948 -0.936437
+v 2.078928 -3.584991 -0.917088
+v 2.025468 -3.556842 -1.204841
+v 2.254361 -3.550931 -1.235118
+f 394 395 396
+f 397 394 396
+f 398 394 399
+f 397 400 394
+f 399 394 401
+f 401 394 400
+f 403 402 400
+f 402 401 400
+f 406 403 405
+f 404 405 403
+v -2.591357 -1.510845 -0.885470
+v -2.734184 -1.717948 -0.749581
+v -2.837147 -1.791733 -0.921563
+v -2.687162 -1.539807 -0.988048
+v -2.918293 -1.904184 -1.004659
+v -2.765069 -1.561164 -1.084313
+v -3.010917 -1.884498 -1.083510
+v -2.862576 -1.546894 -1.117139
+v -3.117476 -1.866892 -1.108034
+v -2.955052 -1.496840 -1.128812
+v -3.232610 -1.834299 -1.087832
+v -3.063133 -1.440555 -1.090926
+v -3.365990 -1.485170 -0.888076
+v -3.490520 -1.760417 -0.903104
+v -3.498521 -1.762078 -0.762472
+v -3.387254 -1.486027 -0.672861
+v -3.335942 -1.365685 -0.724590
+v -3.319817 -1.365015 -0.886015
+v -3.078699 -2.553982 -1.046834
+v -3.162498 -2.556375 -1.058409
+v -3.177824 -2.279173 -1.047580
+v -3.068444 -2.260195 -1.035070
+v -3.169489 -2.110039 -1.076796
+v -3.047974 -2.109628 -1.063497
+v -3.207447 -2.103206 -1.071366
+v -3.251541 -2.564050 -1.023627
+v -3.281816 -2.305055 -1.001878
+v -3.327526 -2.075729 -1.005328
+v -3.357996 -1.811803 -0.975625
+v -3.347304 -2.573628 -0.955211
+v -3.389388 -2.305625 -0.950348
+v -3.451965 -2.077314 -0.931974
+v -3.022819 -2.522240 -0.979148
+v -3.007483 -2.270712 -0.984279
+v -2.969687 -2.097941 -0.982836
+v -2.892438 -1.950810 -0.878120
+v -2.981187 -2.142718 -0.858353
+v -3.030605 -2.311222 -0.884330
+v -3.046610 -2.510881 -0.900772
+v -2.964215 -1.978727 -0.776572
+v -3.040398 -2.156239 -0.808208
+v -3.120761 -2.157770 -0.766432
+v -3.144012 -2.333635 -0.829994
+v -3.066022 -1.953125 -0.719516
+v -3.211005 -1.850398 -0.700723
+v -3.253309 -2.137354 -0.760713
+v -3.235873 -2.335338 -0.820588
+v -3.240554 -2.555467 -0.856262
+v -3.132772 -2.528669 -0.848639
+v -3.304804 -1.582192 -0.643445
+v -3.381262 -1.828189 -0.697034
+v -3.139394 -1.687482 -0.638546
+v -3.422698 -2.070796 -0.773898
+v -3.339489 -2.328145 -0.827572
+v -3.297886 -2.549020 -0.861657
+v -3.463753 -2.079892 -0.844667
+v -3.412068 -2.356105 -0.865813
+v -3.372066 -2.569159 -0.904785
+v -3.342096 -1.533989 -0.921628
+v 1.953911 -2.462233 -0.830594
+v 1.930747 -2.463535 -0.894743
+v 1.985330 -2.221319 -0.893145
+v 2.024530 -2.195334 -0.811284
+v 2.013095 -2.051912 -0.911043
+v 2.047696 -2.050138 -0.814712
+v 2.021591 -1.755289 -0.912093
+v 2.053108 -1.738285 -0.824853
+v 2.036036 -1.579080 -0.967151
+v 2.059844 -1.561331 -0.858957
+v 1.678986 -2.513137 -0.891745
+v 1.737623 -2.485017 -0.918334
+v 1.771416 -2.769024 -0.946100
+v 1.718315 -2.775468 -0.921796
+v 1.648793 -2.280014 -0.929365
+v 1.710406 -2.272223 -0.954296
+v 1.624900 -2.087301 -0.963391
+v 1.720031 -2.105568 -0.971354
+v 1.572979 -1.827591 -0.985823
+v 1.717145 -1.809530 -1.004092
+v 1.541750 -1.643613 -1.014190
+v 1.650318 -1.645881 -1.053347
+v 1.586321 -2.273752 -0.880969
+v 1.655948 -2.520927 -0.844269
+v 1.529305 -2.092083 -0.887353
+v 1.508714 -1.808578 -0.934359
+v 1.480629 -1.640132 -0.953447
+v 1.601290 -2.267132 -0.787696
+v 1.663494 -2.485963 -0.790773
+v 1.544087 -2.080722 -0.786432
+v 1.473886 -1.818947 -0.799576
+v 1.451825 -1.576856 -0.702758
+v 1.677597 -2.237953 -0.696318
+v 1.756349 -2.446399 -0.705428
+v 1.643403 -2.076583 -0.689565
+v 1.596751 -1.722028 -0.684655
+v 1.599889 -1.595526 -0.623185
+v 1.994078 -2.713047 -0.824553
+v 1.960643 -2.712860 -0.900890
+v 1.864064 -2.469953 -0.935601
+v 1.880971 -2.733242 -0.890200
+v 1.941767 -1.759457 -0.997454
+v 1.937009 -1.625419 -1.026843
+v 1.918641 -2.083654 -1.001275
+v 1.906370 -2.282284 -0.964887
+v 1.801127 -2.484690 -0.938593
+v 1.830669 -2.736121 -0.903313
+v 1.804927 -1.581954 -1.089198
+v 1.818846 -1.756976 -1.023593
+v 1.839224 -2.109267 -0.998351
+v 1.818266 -2.313852 -0.968652
+f 409 410 408
+f 407 408 410
+f 412 410 411
+f 410 409 411
+f 411 413 412
+f 412 413 414
+f 416 414 415
+f 414 413 415
+f 418 416 417
+f 416 415 417
+f 419 420 422
+f 420 421 422
+f 422 423 419
+f 423 424 419
+f 425 426 428
+f 426 427 428
+f 427 429 428
+f 428 429 430
+f 415 413 429
+f 430 429 413
+f 427 431 429
+f 429 431 415
+f 431 417 415
+f 426 432 427
+f 432 433 427
+f 434 431 433
+f 427 433 431
+f 435 417 434
+f 431 434 417
+f 437 433 436
+f 432 436 433
+f 438 434 437
+f 433 437 434
+f 420 435 438
+f 434 438 435
+f 428 440 425
+f 439 425 440
+f 440 428 441
+f 428 430 441
+f 413 411 430
+f 441 430 411
+f 442 411 409
+f 443 441 442
+f 411 442 441
+f 441 443 440
+f 443 444 440
+f 440 444 439
+f 444 445 439
+f 442 446 443
+f 446 447 443
+f 443 447 444
+f 444 447 449
+f 447 448 449
+f 450 448 446
+f 446 448 447
+f 451 452 450
+f 450 452 448
+f 452 453 448
+f 448 453 449
+f 454 455 453
+f 449 453 455
+f 422 421 456
+f 456 421 457
+f 456 457 458
+f 457 451 458
+f 452 451 459
+f 451 457 459
+f 459 460 452
+f 452 460 453
+f 453 460 454
+f 460 461 454
+f 462 459 421
+f 457 421 459
+f 462 463 459
+f 459 463 460
+f 460 463 461
+f 463 464 461
+f 462 438 463
+f 438 437 463
+f 436 464 437
+f 463 437 464
+f 421 420 462
+f 420 438 462
+f 419 465 420
+f 435 420 465
+f 469 466 468
+f 466 467 468
+f 468 470 469
+f 469 470 471
+f 471 470 473
+f 470 472 473
+f 474 475 472
+f 473 472 475
+f 478 479 477
+f 476 477 479
+f 476 480 477
+f 480 481 477
+f 480 482 481
+f 482 483 481
+f 483 482 485
+f 484 485 482
+f 485 484 487
+f 486 487 484
+f 489 488 476
+f 488 480 476
+f 482 480 490
+f 490 480 488
+f 490 491 482
+f 491 484 482
+f 484 491 486
+f 492 486 491
+f 488 489 493
+f 493 489 494
+f 490 488 495
+f 495 488 493
+f 491 490 496
+f 496 490 495
+f 492 491 497
+f 497 491 496
+f 499 498 494
+f 498 493 494
+f 495 493 500
+f 500 493 498
+f 501 496 500
+f 496 495 500
+f 497 496 502
+f 502 496 501
+f 504 467 503
+f 467 466 503
+f 506 505 504
+f 505 467 504
+f 474 472 508
+f 507 508 472
+f 509 507 470
+f 507 472 470
+f 468 467 510
+f 510 467 505
+f 510 509 468
+f 509 470 468
+f 477 511 478
+f 478 511 512
+f 505 506 511
+f 511 506 512
+f 513 514 487
+f 485 487 514
+f 514 515 485
+f 483 485 515
+f 515 516 483
+f 481 483 516
+f 481 516 477
+f 477 516 511
+f 514 513 507
+f 513 508 507
+f 515 514 509
+f 514 507 509
+f 516 515 510
+f 515 509 510
+f 510 505 516
+f 511 516 505
+v 1.980621 -3.043895 -0.964237
+v 2.091539 -3.032437 -0.947029
+v 2.170039 -3.134504 -0.978866
+v 2.197935 -3.583948 -0.936437
+v 2.254361 -3.550931 -1.235118
+v 2.343303 -3.507846 -1.195262
+v 2.386827 -3.462222 -1.136480
+v 2.440236 -3.509564 -1.019417
+f 517 518 519
+f 521 522 520
+f 522 523 520
+f 520 523 524
+v 1.841282 -2.716008 -0.708009
+v 1.756349 -2.446399 -0.705428
+v 1.663494 -2.485963 -0.790773
+v 1.736425 -2.743683 -0.736866
+v 1.740323 -1.679830 -0.664098
+v 1.721211 -1.590185 -0.601932
+v 1.599889 -1.595526 -0.623185
+v 1.596751 -1.722028 -0.684655
+v 1.747671 -2.067518 -0.638841
+v 1.643403 -2.076583 -0.689565
+v 1.772999 -2.230292 -0.644940
+v 1.677597 -2.237953 -0.696318
+v 1.655948 -2.520927 -0.844269
+v 1.700797 -2.794792 -0.824250
+v 2.057496 -2.887282 -0.844225
+v 1.994078 -2.713047 -0.824553
+v 1.972647 -2.728848 -0.772496
+v 2.001343 -2.847715 -0.762517
+v 1.828658 -2.477348 -0.673470
+v 1.884318 -2.724404 -0.701999
+v 1.947264 -2.443232 -0.732587
+v 1.921881 -2.157616 -0.692678
+v 1.953911 -2.462233 -0.830594
+v 1.991892 -1.748400 -0.652770
+v 1.963153 -1.588839 -0.612861
+v 1.945206 -2.015769 -0.672724
+v 2.053108 -1.738285 -0.824853
+v 2.059844 -1.561331 -0.858957
+v 2.047696 -2.050138 -0.814712
+v 2.024530 -2.195334 -0.811284
+v 2.111557 -1.376942 -0.896570
+v 2.141273 -1.234642 -0.941254
+v 2.158051 -1.209613 -0.783941
+v 2.126237 -1.330172 -0.721011
+v 2.071448 -1.410118 -1.006192
+v 2.099566 -1.259996 -1.055763
+v 1.974215 -1.469208 -1.068951
+v 1.966698 -1.228160 -1.153716
+v 1.801794 -1.465464 -1.129277
+v 1.805207 -1.268427 -1.165317
+v 1.612396 -1.485728 -1.099731
+v 1.601721 -1.262359 -1.141420
+v 1.516700 -1.453050 -1.068516
+v 1.497480 -1.283201 -1.088258
+v 1.454817 -1.430228 -0.976569
+v 1.430817 -1.301205 -1.024924
+v 1.328862 -1.352627 -0.758733
+v 1.348219 -1.282064 -0.845204
+v 2.177450 -1.127765 -0.974416
+v 2.180012 -1.130557 -0.821812
+v 2.148553 -1.103067 -1.065410
+v 2.024692 -1.074646 -1.172465
+v 1.838895 -1.087204 -1.201408
+v 1.645819 -1.087442 -1.173773
+v 1.524407 -1.125312 -1.142248
+v 1.438439 -1.148029 -1.098069
+v 1.310865 -1.136322 -0.914838
+v 2.079600 -1.473377 -0.654997
+v 2.048200 -1.581983 -0.555832
+v 1.804927 -1.581954 -1.089198
+v 1.650318 -1.645881 -1.053347
+v 1.937009 -1.625419 -1.026843
+v 2.036036 -1.579080 -0.967151
+v 2.222082 -0.957342 -1.014137
+v 2.229345 -0.992723 -0.862826
+v 1.635139 -0.965221 -1.184968
+v 1.867657 -0.920633 -1.206933
+v 2.058189 -0.931238 -1.163518
+v 2.158585 -0.955809 -1.113647
+v 1.480629 -1.640132 -0.953447
+v 1.451825 -1.576856 -0.702758
+v 1.337875 -0.945716 -1.021299
+v 1.428883 -0.986690 -1.133905
+v 1.541750 -1.643613 -1.014190
+v 1.536037 -0.985876 -1.185597
+v 3.233975 2.059193 -0.072431
+v 3.009101 1.971604 -0.034220
+v 2.985371 1.982663 0.000000
+v 3.247406 2.073333 0.000000
+v 3.252224 2.026347 -0.148215
+v 3.036361 1.913989 -0.169838
+v 3.276333 1.863773 -0.294266
+v 3.058366 1.773346 -0.297337
+v 3.337545 1.748927 -0.340210
+v 3.086666 1.632991 -0.338863
+v 3.377233 1.587800 -0.400781
+v 3.115383 1.492390 -0.380228
+v 3.473410 1.366149 -0.454658
+v 3.163181 1.209972 -0.462438
+v 3.528445 1.060127 -0.489443
+v 3.189664 0.907503 -0.500122
+v 3.559394 0.706516 -0.452535
+v 3.280681 0.510802 -0.499434
+v 3.619650 0.472046 -0.391742
+v 3.321825 0.266690 -0.465750
+v 3.641195 0.407454 -0.362198
+v 3.360040 0.165487 -0.412685
+v 3.674710 0.338839 -0.307840
+v 3.378799 0.073736 -0.355362
+v 3.700363 0.265794 -0.240762
+v 3.438950 -0.082580 -0.257015
+v 3.737014 0.181837 -0.176819
+v 3.514981 -0.121886 -0.187589
+v 3.731689 0.186391 0.000000
+v 3.486028 -0.141683 0.000000
+v 3.716360 2.343387 0.000000
+v 3.727093 2.308406 -0.150049
+v 3.458300 2.151656 -0.102662
+v 3.454971 2.169877 0.000000
+v 4.120842 0.627141 -0.185461
+v 4.126565 0.642027 0.000000
+v 3.929251 0.411689 0.000000
+v 3.955635 0.432417 -0.197586
+v 3.889626 0.475277 -0.247365
+v 4.105198 0.672581 -0.300001
+v 3.861841 0.560638 -0.311961
+v 4.068249 0.798926 -0.400813
+v 3.849352 0.664451 -0.387198
+v 4.041657 1.039756 -0.496922
+v 3.823137 0.853054 -0.461519
+v 3.988510 1.297806 -0.539537
+v 3.747724 1.184933 -0.518662
+v 3.886058 1.550141 -0.504830
+v 3.650974 1.463740 -0.478617
+v 3.881998 1.764428 -0.476337
+v 3.590526 1.701090 -0.411994
+v 3.814876 1.968416 -0.443000
+v 3.541188 1.849183 -0.386366
+v 3.758215 2.206683 -0.323051
+v 3.479418 1.978250 -0.317478
+v 3.745669 2.266001 -0.241930
+v 3.460196 2.103494 -0.180368
+v 3.118124 -0.703925 0.000000
+v 3.107533 -0.691019 -0.264602
+v 3.342159 -0.384674 -0.201349
+v 3.335210 -0.375755 0.000000
+v 2.361089 1.766660 -0.202595
+v 2.339597 1.807702 0.000000
+v 2.723503 1.898839 0.000000
+v 2.715712 1.828219 -0.167709
+v 2.406969 1.645328 -0.341479
+v 2.738132 1.687333 -0.295046
+v 2.519027 1.485931 -0.422962
+v 2.775680 1.538710 -0.352829
+v 2.553871 1.284278 -0.512335
+v 2.815366 1.377583 -0.413399
+v 2.637461 1.017260 -0.581611
+v 2.854291 1.093951 -0.494650
+v 2.747937 0.712253 -0.615674
+v 2.948387 0.783357 -0.515058
+v 2.811504 0.469098 -0.657443
+v 3.061090 0.397226 -0.574193
+v 2.898733 0.271916 -0.651298
+v 2.919870 0.084875 -0.642460
+v 3.136321 0.171237 -0.539896
+v 2.953029 -0.127690 -0.520499
+v 3.166160 0.021310 -0.457261
+v 2.986408 -0.413503 -0.428964
+v 3.199571 -0.153739 -0.380150
+v 3.053144 -0.609681 -0.326931
+v 3.286426 -0.300744 -0.276331
+v 2.835437 -0.231101 -0.577890
+v 2.753156 0.400829 -0.713141
+v 2.679445 0.687427 -0.720573
+v 2.790681 0.219187 -0.718263
+v 2.790657 0.044324 -0.717488
+v 2.736198 -0.346225 -0.659345
+v 2.743995 -0.129852 -0.718277
+v 2.514162 0.988713 -0.674527
+v 2.482917 0.997637 -0.702425
+v 2.396355 1.242239 -0.597722
+v 2.618307 -0.549092 -0.805491
+v 2.539200 -0.727778 -0.750475
+v 2.410367 -0.777999 -0.841105
+v 2.543372 -0.548031 -0.937182
+v 2.690576 -0.368057 -0.819343
+v 2.594499 -0.422948 -0.981263
+v 2.702577 -0.197406 -0.795611
+v 2.607430 -0.208248 -0.974218
+v 2.734183 0.038769 -0.865810
+v 2.649413 0.031535 -1.024796
+v 2.731512 0.219003 -0.891585
+v 2.668936 0.206182 -1.014371
+v 2.706960 0.393597 -0.849582
+v 2.616001 0.447717 -0.960748
+v 2.604217 0.728827 -0.769671
+v 2.570400 0.738683 -0.830405
+v 2.688131 -0.517509 -0.672975
+v 2.542439 0.999928 -0.648592
+v 2.132390 1.755821 -0.180271
+v 2.128139 1.788397 0.000000
+v 2.183003 1.654070 -0.341767
+v 2.301359 1.397721 -0.546015
+v 2.292449 -0.871852 -0.882400
+v 2.245624 -0.864372 -0.995778
+v 2.346081 -0.745350 -1.013296
+v 2.096552 1.678482 -0.326810
+v 2.069379 1.727818 -0.212746
+v 2.189848 1.468992 -0.517501
+v 2.266003 1.273253 -0.663332
+v 2.347317 1.066114 -0.758763
+v 2.399389 0.782091 -0.915279
+v 2.448969 0.529858 -1.037335
+v 2.495354 0.250522 -1.132081
+v 2.500490 -0.035029 -1.170179
+v 2.452588 -0.244072 -1.138797
+v 2.439827 -0.395385 -1.131324
+v 2.384638 -0.591919 -1.043058
+v 2.013534 -0.662303 -1.191491
+v 2.108912 -0.357128 -1.259691
+v 2.042206 1.777154 0.000000
+v 1.807583 1.756546 -0.177627
+v 1.794465 1.787719 0.000000
+v 2.136269 -0.187666 -1.278057
+v 2.141790 -0.055306 -1.295565
+v 2.081700 0.283249 -1.259461
+v 2.023441 0.529338 -1.144399
+v 1.975941 0.827957 -1.018423
+v 1.958254 1.130271 -0.861813
+v 1.859443 1.450393 -0.632222
+v 1.821946 1.618209 -0.403751
+v 1.798719 1.714447 -0.259352
+v 0.737904 1.604213 -0.281713
+v 0.223642 1.684075 -0.160743
+v 0.234527 1.730117 0.000000
+v 0.733818 1.740873 0.000000
+v 0.725959 1.478055 -0.461804
+v 0.237330 1.595746 -0.288672
+v 0.760722 1.205036 -0.700545
+v 0.289039 1.496446 -0.430055
+v 0.857323 0.985001 -0.874029
+v 0.305671 1.298417 -0.629719
+v 0.921312 0.755659 -0.999330
+v 0.243473 1.134082 -0.819993
+v 0.939271 0.379986 -1.185872
+v 0.316341 0.785311 -1.086260
+v 0.927775 0.195225 -1.233043
+v 0.539252 0.353984 -1.254493
+v 0.950215 0.042751 -1.256188
+v 0.539150 0.148262 -1.321014
+v 0.943855 -0.101127 -1.274771
+v 0.516872 -0.020713 -1.356627
+v 0.960321 -0.308052 -1.243133
+v 0.542386 -0.188227 -1.370375
+v 0.974530 -0.525273 -1.140353
+v 0.546875 -0.390940 -1.363244
+v 0.948819 -0.638568 -1.102958
+v 0.550658 -0.633015 -1.331311
+v 0.939974 -0.894739 -1.019809
+v 0.527724 -0.862854 -1.253811
+v 0.956456 -1.070504 -0.921063
+v 0.544825 -1.133123 -1.096902
+v 0.930660 -1.216516 -0.831196
+v 0.530629 -1.316423 -0.929842
+v 0.922703 -1.296032 -0.728307
+v 0.538756 -1.408602 -0.764911
+v 0.912699 -1.455066 -0.576185
+v 0.489819 -1.524947 -0.672392
+v 0.912989 -1.499314 -0.419547
+v 0.480235 -1.631521 -0.401961
+v 0.927497 -1.558489 0.000000
+v 0.446550 -1.672950 0.000000
+v -0.221516 1.686349 -0.151403
+v -0.559706 1.694180 -0.186107
+v -0.547248 1.742126 0.000000
+v -0.228904 1.734267 0.000000
+v -0.267035 1.627058 -0.266577
+v -0.557624 1.641278 -0.271462
+v -0.247999 1.565146 -0.389142
+v -0.626493 1.585426 -0.443136
+v -0.179548 1.471301 -0.544513
+v -0.597781 1.489620 -0.641047
+v -0.192546 1.305535 -0.700080
+v -0.674657 1.333008 -0.761059
+v -0.406155 1.005088 -0.971088
+v -0.910602 1.204118 -0.837740
+v -0.115190 0.458427 -1.346197
+v -0.969076 0.901205 -1.146223
+v 0.005537 0.163519 -1.472265
+v -0.752416 0.438132 -1.467349
+v 0.018086 0.002865 -1.523199
+v -0.645496 0.179261 -1.584316
+v 0.034087 -0.225059 -1.542949
+v -0.536767 -0.144454 -1.682232
+v 0.010486 -0.502317 -1.576297
+v -0.533528 -0.582280 -1.701405
+v 0.021051 -0.831931 -1.511548
+v -0.505045 -0.913827 -1.645612
+v -0.041570 -1.143825 -1.395176
+v -0.487217 -1.193519 -1.504026
+v -0.071941 -1.346991 -1.237379
+v -0.524231 -1.399266 -1.313019
+v -0.072300 -1.450245 -1.087397
+v -0.526127 -1.495000 -1.167736
+v -0.063012 -1.583021 -0.865082
+v -0.535144 -1.615983 -0.920556
+v -0.894132 1.712652 -0.151911
+v -1.215563 1.757097 -0.133494
+v -1.179474 1.786649 0.000000
+v -0.866132 1.754670 0.000000
+v -0.954897 1.677544 -0.293034
+v -1.227613 1.709095 -0.276029
+v -1.017767 1.607824 -0.541965
+v -1.292756 1.656509 -0.514030
+v -1.046070 1.509097 -0.761060
+v -1.338488 1.613735 -0.725441
+v -1.115594 1.392380 -0.819623
+v -1.403848 1.533059 -0.902827
+v -1.278903 1.192051 -0.946843
+v -1.551526 1.400025 -1.050193
+v -1.200768 0.978822 -1.103391
+v -1.552899 1.128654 -1.151040
+v -1.147922 0.807955 -1.254191
+v -1.454529 0.875045 -1.238858
+v -1.120716 0.424016 -1.456990
+v -1.405685 0.573835 -1.352181
+v -1.077307 0.165008 -1.553393
+v -1.479588 0.295746 -1.440042
+v -1.053434 -0.342553 -1.690245
+v -1.489699 -0.024215 -1.510987
+v -1.077209 -0.869649 -1.633144
+v -1.395501 -0.698702 -1.553257
+v -1.061272 -1.141877 -1.496230
+v -1.376176 -0.948757 -1.451608
+v -1.001366 -1.335897 -1.353338
+v -1.402349 -1.127845 -1.309055
+v -0.952525 -1.440582 -1.168650
+v -1.407658 -1.236026 -1.112930
+v 1.644178 -0.857872 -1.208494
+v 1.640095 -0.674556 -1.246804
+v 1.462507 1.745481 -0.222394
+v 1.456656 1.785879 0.000000
+v 1.483832 1.697594 -0.288781
+v 1.497138 1.618935 -0.401108
+v 1.504951 1.483493 -0.585976
+v 1.517126 1.334367 -0.741076
+v 1.570685 0.938327 -0.989108
+v 1.582203 0.771083 -1.068180
+v 1.630080 0.420236 -1.172369
+v 1.649027 0.224458 -1.211969
+v 1.660355 0.019397 -1.246002
+v 1.664159 -0.189659 -1.266729
+v 1.678622 -0.410061 -1.291177
+v 1.604939 -1.556997 0.000000
+v 1.920432 -1.567396 0.000000
+v 1.210555 -1.460061 -0.576841
+v 1.192040 -1.330605 -0.678707
+v 1.223415 -1.532658 -0.434522
+v 1.289448 -1.546597 0.000000
+v 1.219163 -1.218342 -0.823029
+v 1.252961 -0.928825 -1.001643
+v 1.373216 -0.564620 -1.106245
+v 1.230116 -1.085439 -0.894543
+v -0.078470 -1.688266 -0.800230
+v -0.094135 -1.769086 -0.556924
+v -0.953236 -1.545941 -0.899180
+v 2.881063 -0.493146 -0.521968
+v 2.663024 -1.440487 -0.478149
+v 2.740886 -1.339225 -0.463604
+v 2.824356 -1.407256 -0.355013
+v -1.365948 1.769608 -0.133901
+v -1.350950 1.807009 0.000000
+v -1.396332 1.723782 -0.267642
+v -1.417595 1.676180 -0.529265
+v -1.465432 1.655336 -0.722125
+v -1.582187 1.567542 -0.982349
+v -1.721806 1.391264 -1.113307
+v -1.733703 1.083864 -1.181489
+v -1.807421 0.657142 -1.209422
+v -1.796156 0.452382 -1.243643
+v -1.810920 0.287592 -1.292257
+v -1.795130 0.033439 -1.371160
+v -1.802864 -0.282523 -1.401315
+v -1.837859 -0.540871 -1.295851
+v -1.782928 -0.770786 -1.173619
+v -1.757573 -0.945337 -1.075832
+v -1.683863 1.789041 -0.121501
+v -1.676510 1.826886 0.000000
+v -1.714432 1.747956 -0.247594
+v -1.744732 1.734849 -0.433807
+v -1.929731 1.617188 -0.806390
+v -1.996117 1.387891 -1.064104
+v -1.980388 1.134038 -1.143196
+v -2.013663 0.810726 -1.158827
+v -2.030191 0.547622 -1.189762
+v -2.021159 0.411979 -1.234679
+v -1.932916 0.232972 -1.304589
+v -1.897394 0.037852 -1.365798
+v -1.950547 -0.275573 -1.377028
+v -2.033655 -0.526012 -1.277639
+v -2.050292 -0.755566 -1.114167
+v -2.043593 -0.875823 -1.028879
+v -1.782298 -1.020581 -0.943381
+v -2.033406 -0.910030 -0.964220
+v -1.198513 -1.456102 -0.885435
+v -1.456655 -1.295527 -0.894240
+v -1.366873 -1.340211 -0.907567
+v -2.079597 1.817785 -0.138375
+v -2.057387 1.841308 0.000000
+v -2.100170 1.789980 -0.229245
+v -2.137524 1.753182 -0.433142
+v -2.172139 1.623010 -0.805318
+v -2.205791 1.356023 -1.081662
+v -2.296056 1.062810 -1.171139
+v -2.298249 0.768333 -1.203884
+v -2.256285 0.547326 -1.238301
+v -2.158400 0.381542 -1.272962
+v -2.070413 0.207766 -1.335106
+v -2.064786 0.018789 -1.411866
+v -2.187634 -0.375454 -1.406902
+v -2.276341 -0.689823 -1.268026
+v -2.292049 -0.933921 -1.128136
+v -2.299356 -1.025449 -1.044687
+v -2.306662 -1.116976 -0.961238
+v -2.672899 1.905110 -0.067168
+v -2.629466 1.918204 0.000000
+v -2.697367 1.871291 -0.218796
+v -2.703112 1.825435 -0.395127
+v -2.715246 1.746763 -0.604653
+v -2.717480 1.576797 -0.875971
+v -2.684930 1.262021 -1.110490
+v -2.572286 0.835495 -1.252192
+v -2.536112 0.656633 -1.269661
+v -2.520947 0.559036 -1.273617
+v -2.473750 0.300945 -1.316695
+v -2.433366 0.078222 -1.371269
+v -2.414730 -0.108377 -1.395384
+v -2.382920 -0.417450 -1.375045
+v -2.430508 -0.822313 -1.254486
+v -2.566746 -1.211312 -1.167101
+v -3.053102 1.968810 -0.051104
+v -3.037562 2.001526 0.000000
+v -3.077669 1.871112 -0.217368
+v -3.075310 1.846000 -0.363149
+v -3.109047 1.789477 -0.565323
+v -3.085650 1.657340 -0.784479
+v -3.028932 1.461517 -0.941324
+v -2.930312 1.103580 -1.125876
+v -2.825835 0.755899 -1.209042
+v -2.790630 0.468810 -1.224273
+v -2.787011 0.264495 -1.237352
+v -2.687022 0.076781 -1.290565
+v -2.649338 -0.241719 -1.339644
+v -2.616467 -0.511373 -1.344133
+v -2.624856 -0.888200 -1.261176
+v -2.725776 -1.214862 -1.190384
+v -2.765069 -1.561164 -1.084313
+v -2.862576 -1.546894 -1.117139
+v -3.358510 1.810253 -0.380095
+v -3.519716 1.685231 -0.317130
+v -3.507689 1.700214 0.000000
+v -3.392806 1.769365 0.000000
+v -3.395381 1.726325 -0.554770
+v -3.527168 1.583508 -0.512679
+v -3.338742 1.598933 -0.689636
+v -3.512997 1.448050 -0.611386
+v -3.278080 1.432418 -0.853958
+v -3.476235 1.287798 -0.704766
+v -3.244771 1.195540 -0.910945
+v -3.442151 1.105486 -0.762934
+v -3.196410 0.797564 -0.985913
+v -3.379131 0.767915 -0.885996
+v -3.112555 0.457376 -1.084816
+v -3.306875 0.379713 -0.987620
+v -3.044646 0.224321 -1.164934
+v -3.251181 0.175063 -1.053445
+v -2.971546 0.032038 -1.215971
+v -3.160225 -0.018852 -1.113626
+v -2.907080 -0.345582 -1.281557
+v -3.101125 -0.354760 -1.162409
+v -2.901159 -0.619504 -1.284058
+v -3.096267 -0.668100 -1.140081
+v -2.937658 -1.002749 -1.219413
+v -3.122061 -0.998702 -1.065015
+v -2.982676 -1.264649 -1.133596
+v -3.150210 -1.259588 -1.001021
+v -3.063133 -1.440555 -1.090926
+v -3.188954 -1.408279 -0.963611
+v -3.734989 1.589433 -0.295202
+v -3.690685 1.602080 0.000000
+v -3.697974 1.466697 -0.433432
+v -3.684619 1.350690 -0.501428
+v -3.655148 1.190938 -0.573692
+v -3.639878 1.015186 -0.615203
+v -3.582867 0.734419 -0.697787
+v -3.504525 0.405574 -0.847066
+v -3.424258 0.158638 -0.918279
+v -3.365413 -0.113447 -0.952400
+v -3.290393 -0.424259 -0.984153
+v -3.233333 -0.683782 -1.015512
+v -3.238094 -0.979377 -0.961631
+v -3.277510 -1.177346 -0.915300
+v -3.319817 -1.365015 -0.886015
+v -3.709741 1.351194 -0.211745
+v -3.709827 1.417763 0.000000
+v -3.701634 1.272650 -0.270469
+v -3.695872 1.156978 -0.316829
+v -3.672431 1.044224 -0.364991
+v -3.664355 0.932851 -0.370749
+v -3.631292 0.701013 -0.420276
+v -3.570384 0.385564 -0.524480
+v -3.520188 0.140164 -0.618561
+v -3.458251 -0.125950 -0.731712
+v -3.406618 -0.343461 -0.746456
+v -3.283698 -0.730967 -0.793898
+v -2.687162 -1.539807 -0.988048
+v -2.462835 -1.305500 -0.966395
+v -2.591357 -1.510845 -0.885470
+v -2.955052 -1.496840 -1.128812
+v -3.232610 -1.834299 -1.087832
+v -3.357996 -1.811803 -0.975625
+v -3.342096 -1.533989 -0.921628
+v -3.365990 -1.485170 -0.888076
+v -2.892438 -1.950810 -0.878120
+v -2.734184 -1.717948 -0.749581
+v -2.811581 -1.798210 -0.712737
+v -2.964215 -1.978727 -0.776572
+v -2.837147 -1.791733 -0.921563
+v -3.030605 -2.311222 -0.884330
+v -3.144012 -2.333635 -0.829994
+v -3.132772 -2.528669 -0.848639
+v -3.046610 -2.510881 -0.900772
+v -3.302419 -3.017921 -1.128514
+v -3.320330 -2.827513 -1.063914
+v -3.261810 -2.821069 -1.088218
+v -3.223286 -3.001780 -1.126176
+v -3.107105 -2.947818 -1.092235
+v -3.141072 -2.785287 -1.032318
+v -3.053267 -2.764905 -1.043008
+v -2.986345 -2.933770 -1.087679
+v -3.016419 -2.765091 -0.966671
+v -2.946527 -2.939327 -0.986343
+v -3.301857 -3.074776 -1.114869
+v -3.227676 -3.141660 -1.103969
+v -3.316551 -3.168932 -1.121229
+v -3.217306 -3.187686 -1.075214
+f 526 527 525
+f 525 527 528
+f 529 530 532
+f 530 531 532
+f 529 532 533
+f 533 532 534
+f 533 534 535
+f 535 534 536
+f 528 527 538
+f 527 537 538
+f 540 541 539
+f 539 541 542
+f 541 545 544
+f 543 544 545
+f 545 546 543
+f 535 543 546
+f 526 525 543
+f 543 525 544
+f 543 535 526
+f 535 536 526
+f 545 541 547
+f 547 541 540
+f 549 530 548
+f 548 530 529
+f 533 550 529
+f 550 548 529
+f 549 548 552
+f 551 552 548
+f 551 548 553
+f 553 548 550
+f 550 546 553
+f 554 553 546
+f 546 545 554
+f 547 554 545
+f 558 555 557
+f 555 556 557
+f 560 556 559
+f 559 556 555
+f 562 560 561
+f 561 560 559
+f 561 563 562
+f 563 564 562
+f 566 564 565
+f 565 564 563
+f 566 565 568
+f 567 568 565
+f 568 567 570
+f 569 570 567
+f 569 571 570
+f 571 572 570
+f 556 573 557
+f 573 574 557
+f 575 573 560
+f 560 573 556
+f 576 575 562
+f 562 575 560
+f 577 576 564
+f 564 576 562
+f 566 578 564
+f 578 577 564
+f 578 566 579
+f 568 579 566
+f 570 580 568
+f 580 579 568
+f 580 570 581
+f 572 581 570
+f 552 582 549
+f 582 583 549
+f 565 563 585
+f 584 585 563
+f 586 584 561
+f 584 563 561
+f 587 586 559
+f 586 561 559
+f 552 587 555
+f 587 559 555
+f 552 555 582
+f 555 558 582
+f 573 588 574
+f 574 588 589
+f 591 577 590
+f 577 578 590
+f 577 591 576
+f 576 591 592
+f 575 576 593
+f 576 592 593
+f 573 575 588
+f 575 593 588
+f 595 571 594
+f 571 569 594
+f 581 596 580
+f 596 597 580
+f 567 565 598
+f 565 585 598
+f 569 567 594
+f 567 598 594
+f 579 599 578
+f 599 590 578
+f 580 597 579
+f 597 599 579
+f 603 600 602
+f 600 601 602
+f 601 600 605
+f 604 605 600
+f 604 606 605
+f 606 607 605
+f 609 607 608
+f 608 607 606
+f 608 610 609
+f 610 611 609
+f 613 611 612
+f 612 611 610
+f 615 613 614
+f 614 613 612
+f 617 615 616
+f 616 615 614
+f 619 617 618
+f 618 617 616
+f 619 618 621
+f 620 621 618
+f 623 621 622
+f 622 621 620
+f 625 623 624
+f 624 623 622
+f 624 626 625
+f 626 627 625
+f 629 627 628
+f 628 627 626
+f 631 632 630
+f 630 632 633
+f 635 636 634
+f 634 636 637
+f 634 637 638
+f 634 638 639
+f 639 638 640
+f 639 640 641
+f 641 640 642
+f 643 641 644
+f 641 642 644
+f 646 645 644
+f 645 643 644
+f 648 647 646
+f 647 645 646
+f 649 647 650
+f 647 648 650
+f 651 649 652
+f 649 650 652
+f 653 651 654
+f 651 652 654
+f 654 656 653
+f 655 653 656
+f 655 656 631
+f 631 656 632
+f 658 659 657
+f 657 659 660
+f 662 663 661
+f 661 663 664
+f 661 664 665
+f 665 664 666
+f 665 666 667
+f 667 666 668
+f 669 667 670
+f 667 668 670
+f 670 672 669
+f 671 669 672
+f 672 674 671
+f 673 671 674
+f 676 675 674
+f 675 673 674
+f 677 675 676
+f 676 679 677
+f 678 677 679
+f 680 678 681
+f 678 679 681
+f 682 680 683
+f 680 681 683
+f 684 682 685
+f 682 683 685
+f 658 684 659
+f 684 685 659
+f 600 603 632
+f 633 632 603
+f 627 629 659
+f 660 659 629
+f 663 602 601
+f 605 664 601
+f 664 663 601
+f 664 605 666
+f 666 605 607
+f 666 607 668
+f 668 607 609
+f 670 668 611
+f 668 609 611
+f 672 670 613
+f 670 611 613
+f 613 615 672
+f 674 672 615
+f 615 617 674
+f 676 674 617
+f 617 619 676
+f 679 676 619
+f 681 679 621
+f 679 619 621
+f 683 681 623
+f 681 621 623
+f 623 625 683
+f 685 683 625
+f 627 659 625
+f 659 685 625
+f 637 636 626
+f 636 628 626
+f 626 624 637
+f 638 637 624
+f 640 638 622
+f 638 624 622
+f 640 622 620
+f 640 620 642
+f 642 620 618
+f 618 616 642
+f 644 642 616
+f 616 614 644
+f 646 644 614
+f 614 612 646
+f 648 646 612
+f 650 648 610
+f 648 612 610
+f 610 608 650
+f 652 650 608
+f 654 652 606
+f 652 608 606
+f 606 604 654
+f 656 654 604
+f 632 656 600
+f 656 604 600
+f 682 686 680
+f 687 688 675
+f 688 673 675
+f 677 689 675
+f 689 687 675
+f 690 689 678
+f 689 677 678
+f 686 691 692
+f 692 678 686
+f 678 680 686
+f 692 690 678
+f 693 694 695
+f 698 699 697
+f 696 697 699
+f 700 696 701
+f 696 699 701
+f 701 703 700
+f 702 700 703
+f 702 703 704
+f 704 703 705
+f 704 705 706
+f 706 705 707
+f 709 708 707
+f 708 706 707
+f 708 709 710
+f 710 709 711
+f 694 693 711
+f 693 710 711
+f 696 700 712
+f 700 691 712
+f 693 695 713
+f 713 688 693
+f 710 693 688
+f 708 710 687
+f 710 688 687
+f 706 708 689
+f 708 687 689
+f 689 690 706
+f 704 706 690
+f 702 704 692
+f 704 690 692
+f 692 691 702
+f 700 702 691
+f 688 713 673
+f 713 671 673
+f 661 714 662
+f 714 715 662
+f 714 661 716
+f 716 661 665
+f 716 665 717
+f 717 665 667
+f 667 669 717
+f 695 717 669
+f 669 671 695
+f 713 695 671
+f 720 698 719
+f 718 719 698
+f 716 721 714
+f 721 722 714
+f 717 723 716
+f 723 721 716
+f 723 717 724
+f 724 717 695
+f 694 725 695
+f 725 724 695
+f 725 694 726
+f 726 694 711
+f 709 727 711
+f 727 726 711
+f 727 709 728
+f 728 709 707
+f 728 707 729
+f 729 707 705
+f 703 730 705
+f 730 729 705
+f 703 701 730
+f 731 730 701
+f 731 701 732
+f 732 701 699
+f 699 698 732
+f 720 732 698
+f 718 589 719
+f 589 588 719
+f 720 719 733
+f 734 732 733
+f 732 720 733
+f 722 736 735
+f 735 736 737
+f 732 734 731
+f 731 734 738
+f 730 731 738
+f 730 738 729
+f 729 738 739
+f 740 728 739
+f 728 729 739
+f 728 740 727
+f 727 740 741
+f 741 742 727
+f 726 727 742
+f 726 742 725
+f 725 742 743
+f 744 724 743
+f 724 725 743
+f 724 744 723
+f 723 744 745
+f 723 745 721
+f 721 745 746
+f 721 746 722
+f 722 746 736
+f 747 748 750
+f 748 749 750
+f 748 747 752
+f 751 752 747
+f 753 754 751
+f 754 752 751
+f 755 756 753
+f 756 754 753
+f 757 758 755
+f 758 756 755
+f 758 757 760
+f 759 760 757
+f 760 759 762
+f 761 762 759
+f 763 764 761
+f 764 762 761
+f 765 766 763
+f 766 764 763
+f 767 768 765
+f 768 766 765
+f 769 770 767
+f 770 768 767
+f 772 770 771
+f 771 770 769
+f 773 774 771
+f 774 772 771
+f 776 774 775
+f 775 774 773
+f 778 776 777
+f 777 776 775
+f 778 777 780
+f 779 780 777
+f 782 780 781
+f 781 780 779
+f 784 782 783
+f 783 782 781
+f 786 784 785
+f 785 784 783
+f 787 788 790
+f 788 789 790
+f 787 791 788
+f 791 792 788
+f 794 792 793
+f 793 792 791
+f 795 796 793
+f 796 794 793
+f 798 796 797
+f 797 796 795
+f 800 798 799
+f 799 798 797
+f 801 802 799
+f 802 800 799
+f 802 801 804
+f 803 804 801
+f 804 803 806
+f 805 806 803
+f 806 805 808
+f 807 808 805
+f 808 807 810
+f 809 810 807
+f 810 809 812
+f 811 812 809
+f 811 813 812
+f 813 814 812
+f 816 814 815
+f 815 814 813
+f 818 816 817
+f 817 816 815
+f 819 820 817
+f 820 818 817
+f 821 822 824
+f 822 823 824
+f 821 825 822
+f 825 826 822
+f 825 827 826
+f 827 828 826
+f 829 830 827
+f 830 828 827
+f 830 829 832
+f 831 832 829
+f 834 832 833
+f 833 832 831
+f 835 836 833
+f 836 834 833
+f 835 837 836
+f 837 838 836
+f 837 839 838
+f 839 840 838
+f 842 840 841
+f 841 840 839
+f 843 844 841
+f 844 842 841
+f 844 843 846
+f 845 846 843
+f 847 848 845
+f 848 846 845
+f 849 850 847
+f 850 848 847
+f 851 852 849
+f 852 850 849
+f 853 854 733
+f 855 856 736
+f 856 737 736
+f 736 746 855
+f 857 855 746
+f 745 858 746
+f 858 857 746
+f 744 859 745
+f 859 858 745
+f 743 860 744
+f 860 859 744
+f 860 743 861
+f 861 743 742
+f 862 861 742
+f 863 862 741
+f 862 742 741
+f 741 740 863
+f 864 863 740
+f 739 865 740
+f 865 864 740
+f 865 739 866
+f 866 739 738
+f 738 734 866
+f 867 866 734
+f 734 733 867
+f 854 867 733
+f 588 593 733
+f 593 592 733
+f 719 588 733
+f 590 853 733
+f 591 590 733
+f 592 591 733
+f 868 530 869
+f 530 549 869
+f 595 870 571
+f 870 871 571
+f 531 872 595
+f 872 870 595
+f 549 583 869
+f 531 868 872
+f 868 873 872
+f 868 531 530
+f 874 572 871
+f 871 572 571
+f 875 876 596
+f 581 877 596
+f 877 875 596
+f 572 874 581
+f 874 877 581
+f 853 590 599
+f 597 854 599
+f 854 853 599
+f 876 867 854
+f 876 854 597
+f 856 855 750
+f 873 785 872
+f 872 785 783
+f 872 783 870
+f 870 783 781
+f 779 871 781
+f 871 870 781
+f 871 779 874
+f 874 779 777
+f 777 775 874
+f 877 874 775
+f 773 875 775
+f 875 877 775
+f 876 875 771
+f 875 773 771
+f 876 771 769
+f 767 867 769
+f 867 876 769
+f 867 767 866
+f 866 767 765
+f 866 765 865
+f 865 765 763
+f 761 864 763
+f 864 865 763
+f 864 761 863
+f 863 761 759
+f 863 759 862
+f 862 759 757
+f 755 861 757
+f 861 862 757
+f 861 755 753
+f 861 753 860
+f 860 753 751
+f 860 751 859
+f 859 751 747
+f 858 859 747
+f 750 857 747
+f 857 858 747
+f 855 857 750
+f 790 749 787
+f 748 787 749
+f 752 791 748
+f 791 787 748
+f 754 793 752
+f 793 791 752
+f 793 754 795
+f 756 795 754
+f 795 756 797
+f 758 797 756
+f 760 799 758
+f 799 797 758
+f 799 760 801
+f 762 801 760
+f 801 762 803
+f 764 803 762
+f 803 764 805
+f 766 805 764
+f 805 766 807
+f 768 807 766
+f 770 809 768
+f 809 807 768
+f 809 770 811
+f 772 811 770
+f 813 811 774
+f 774 811 772
+f 815 813 776
+f 776 813 774
+f 776 778 815
+f 778 817 815
+f 817 778 819
+f 780 819 778
+f 819 780 878
+f 782 878 780
+f 782 879 878
+f 788 821 789
+f 821 824 789
+f 825 821 792
+f 792 821 788
+f 827 825 794
+f 794 825 792
+f 796 829 794
+f 829 827 794
+f 796 798 829
+f 798 831 829
+f 798 800 831
+f 800 833 831
+f 802 835 800
+f 835 833 800
+f 804 837 802
+f 837 835 802
+f 806 839 804
+f 839 837 804
+f 808 841 806
+f 841 839 806
+f 841 808 843
+f 810 843 808
+f 843 810 845
+f 812 845 810
+f 814 847 812
+f 847 845 812
+f 814 816 847
+f 816 849 847
+f 816 818 849
+f 818 851 849
+f 851 818 880
+f 820 880 818
+f 712 691 881
+f 882 883 884
+f 876 597 596
+f 823 822 886
+f 822 885 886
+f 887 885 826
+f 826 885 822
+f 826 828 887
+f 828 888 887
+f 830 889 828
+f 889 888 828
+f 889 830 890
+f 832 890 830
+f 891 890 834
+f 834 890 832
+f 892 891 836
+f 836 891 834
+f 893 892 838
+f 838 892 836
+f 838 840 893
+f 840 894 893
+f 840 842 894
+f 842 895 894
+f 844 896 842
+f 896 895 842
+f 846 897 844
+f 897 896 844
+f 848 898 846
+f 898 897 846
+f 898 848 899
+f 850 899 848
+f 899 850 900
+f 852 900 850
+f 886 885 902
+f 885 901 902
+f 903 901 887
+f 887 901 885
+f 888 904 887
+f 904 903 887
+f 905 904 889
+f 889 904 888
+f 906 905 890
+f 890 905 889
+f 890 891 906
+f 891 907 906
+f 908 907 892
+f 892 907 891
+f 892 893 908
+f 893 909 908
+f 894 910 893
+f 910 909 893
+f 910 894 911
+f 895 911 894
+f 895 896 911
+f 896 912 911
+f 897 913 896
+f 913 912 896
+f 914 913 898
+f 898 913 897
+f 899 915 898
+f 915 914 898
+f 900 916 899
+f 916 915 899
+f 900 917 916
+f 917 918 916
+f 852 851 919
+f 919 851 880
+f 852 920 900
+f 920 917 900
+f 921 920 852
+f 919 921 852
+f 922 923 901
+f 901 923 902
+f 901 903 922
+f 903 924 922
+f 925 924 904
+f 904 924 903
+f 904 905 925
+f 905 926 925
+f 927 926 906
+f 906 926 905
+f 928 927 907
+f 907 927 906
+f 907 908 928
+f 908 929 928
+f 908 909 929
+f 909 930 929
+f 930 909 931
+f 910 931 909
+f 911 932 910
+f 932 931 910
+f 933 932 912
+f 912 932 911
+f 933 912 934
+f 913 934 912
+f 935 934 914
+f 914 934 913
+f 936 935 915
+f 915 935 914
+f 915 916 936
+f 916 937 936
+f 918 938 916
+f 938 937 916
+f 939 940 922
+f 922 940 923
+f 941 939 924
+f 924 939 922
+f 924 925 941
+f 925 942 941
+f 926 943 925
+f 943 942 925
+f 927 944 926
+f 944 943 926
+f 944 927 945
+f 928 945 927
+f 945 928 946
+f 929 946 928
+f 930 947 929
+f 947 946 929
+f 931 948 930
+f 948 947 930
+f 949 948 932
+f 932 948 931
+f 932 933 949
+f 933 950 949
+f 934 951 933
+f 951 950 933
+f 935 952 934
+f 952 951 934
+f 952 935 953
+f 936 953 935
+f 953 936 954
+f 937 954 936
+f 940 939 956
+f 939 955 956
+f 955 939 957
+f 941 957 939
+f 942 958 941
+f 958 957 941
+f 943 959 942
+f 959 958 942
+f 943 944 959
+f 944 960 959
+f 945 961 944
+f 961 960 944
+f 946 962 945
+f 962 961 945
+f 962 946 963
+f 947 963 946
+f 963 947 964
+f 948 964 947
+f 949 965 948
+f 965 964 948
+f 949 950 965
+f 950 966 965
+f 966 950 967
+f 951 967 950
+f 952 968 951
+f 968 967 951
+f 953 969 952
+f 969 968 952
+f 954 970 953
+f 970 969 953
+f 971 972 954
+f 972 970 954
+f 973 974 976
+f 974 975 976
+f 978 974 977
+f 977 974 973
+f 980 978 979
+f 979 978 977
+f 982 980 981
+f 981 980 979
+f 981 983 982
+f 983 984 982
+f 983 985 984
+f 985 986 984
+f 986 985 988
+f 987 988 985
+f 989 990 987
+f 990 988 987
+f 990 989 992
+f 991 992 989
+f 991 993 992
+f 993 994 992
+f 996 994 995
+f 995 994 993
+f 995 997 996
+f 997 998 996
+f 997 999 998
+f 999 1000 998
+f 999 1001 1000
+f 1001 1002 1000
+f 1003 1004 974
+f 974 1004 975
+f 974 978 1003
+f 978 1005 1003
+f 978 980 1005
+f 980 1006 1005
+f 1007 1006 982
+f 982 1006 980
+f 1008 1007 984
+f 984 1007 982
+f 986 1009 984
+f 1009 1008 984
+f 988 1010 986
+f 1010 1009 986
+f 1010 988 1011
+f 990 1011 988
+f 992 1012 990
+f 1012 1011 990
+f 992 994 1012
+f 994 1013 1012
+f 994 996 1013
+f 996 1014 1013
+f 996 998 1014
+f 998 1015 1014
+f 1000 1016 998
+f 1016 1015 998
+f 1016 1000 1017
+f 1002 1017 1000
+f 1004 1003 1019
+f 1003 1018 1019
+f 1005 1020 1003
+f 1020 1018 1003
+f 1006 1021 1005
+f 1021 1020 1005
+f 1007 1022 1006
+f 1022 1021 1006
+f 1007 1008 1022
+f 1008 1023 1022
+f 1008 1009 1023
+f 1009 1024 1023
+f 1010 1025 1009
+f 1025 1024 1009
+f 1025 1010 1026
+f 1011 1026 1010
+f 1026 1011 1027
+f 1012 1027 1011
+f 1012 1013 1027
+f 1013 1028 1027
+f 1028 1013 1029
+f 1014 1029 1013
+f 969 970 997
+f 970 999 997
+f 969 997 968
+f 968 997 995
+f 968 995 967
+f 967 995 993
+f 993 991 967
+f 966 967 991
+f 966 991 965
+f 965 991 989
+f 987 964 989
+f 964 965 989
+f 985 963 987
+f 963 964 987
+f 963 985 962
+f 962 985 983
+f 961 962 981
+f 962 983 981
+f 960 961 979
+f 961 981 979
+f 959 960 977
+f 960 979 977
+f 958 959 973
+f 959 977 973
+f 971 954 1030
+f 937 938 954
+f 954 938 1031
+f 1030 954 1032
+f 954 1031 1032
+f 533 535 550
+f 546 550 535
+f 722 735 714
+f 735 715 714
+f 1033 970 972
+f 1035 1002 1034
+f 1034 1002 1001
+f 970 1033 999
+f 1033 1001 999
+f 1036 1037 1002
+f 1037 1017 1002
+f 1035 1036 1002
+f 1039 1040 1038
+f 1038 1040 1041
+f 1038 1042 1039
+f 1043 1044 1046
+f 1044 1045 1046
+f 1048 1049 1047
+f 1047 1049 1050
+f 1054 1051 1053
+f 1051 1052 1053
+f 1056 1054 1055
+f 1054 1053 1055
+f 1047 1050 1057
+f 1057 1058 1059
+f 1059 1058 1060
+v -3.042899 -3.193907 -1.207296
+v -2.888628 -3.200302 -1.210934
+v -2.845816 -3.273661 -1.218321
+v -2.975439 -3.308754 -1.253240
+v -2.736599 -3.394849 -1.269577
+v -2.856957 -3.449728 -1.356844
+v -2.631547 -3.559891 -1.337380
+v -2.729567 -3.602976 -1.377236
+v -2.981824 -3.608887 -1.346959
+v -3.030627 -3.493327 -1.322650
+v -3.091252 -3.340925 -1.235864
+v -3.135041 -3.243787 -1.189436
+v -2.699957 -3.390295 -1.185593
+v -2.787341 -3.278502 -1.138621
+v -2.822497 -3.186549 -1.120984
+v -2.909010 -3.084482 -1.089147
+v -2.884711 -3.063896 -0.993766
+v -2.770335 -3.208138 -1.031045
+v -3.184143 -3.298048 -1.156892
+v -3.158524 -3.405872 -1.197099
+v -3.098730 -3.539123 -1.252987
+v -3.031250 -3.095940 -1.106355
+f 1061 1062 1064
+f 1062 1063 1064
+f 1064 1063 1066
+f 1063 1065 1066
+f 1065 1067 1066
+f 1066 1067 1068
+f 1069 1070 1068
+f 1068 1070 1066
+f 1066 1070 1064
+f 1070 1071 1064
+f 1064 1071 1061
+f 1071 1072 1061
+f 1063 1074 1065
+f 1073 1065 1074
+f 1074 1063 1075
+f 1063 1062 1075
+f 1078 1075 1077
+f 1075 1076 1077
+f 1071 1080 1072
+f 1079 1072 1080
+f 1071 1070 1080
+f 1081 1080 1070
+f 1070 1069 1081
+f 1082 1075 1062
+v -2.986345 -2.933770 -1.087679
+v -2.946527 -2.939327 -0.986343
+v -2.884711 -3.063896 -0.993766
+v -2.909010 -3.084482 -1.089147
+v -3.107105 -2.947818 -1.092235
+v -3.177108 -2.979305 -1.139084
+v -3.196508 -2.788166 -1.045431
+v -3.141072 -2.785287 -1.032318
+v -3.223286 -3.001780 -1.126176
+v -3.261810 -2.821069 -1.088218
+v -3.333954 -3.058673 -0.974748
+v -3.301857 -3.074776 -1.114869
+v -3.316551 -3.168932 -1.121229
+v -3.330406 -3.185190 -0.950058
+v -3.217306 -3.187686 -1.075214
+v -3.223246 -3.225388 -0.976573
+f 1083 1084 1086
+f 1084 1085 1086
+f 1088 1089 1087
+f 1087 1089 1090
+f 1089 1088 1092
+f 1091 1092 1088
+f 1095 1096 1094
+f 1093 1094 1096
+f 1095 1097 1096
+f 1096 1097 1098
+v -3.223246 -3.225388 -0.976573
+v -3.217306 -3.187686 -1.075214
+v -3.184143 -3.298048 -1.156892
+v -3.194170 -3.348553 -1.007196
+v -3.082741 -3.598298 -1.054556
+v -3.098730 -3.539123 -1.252987
+v -2.981824 -3.608887 -1.346959
+v -2.922908 -3.637036 -1.059206
+v -3.158524 -3.405872 -1.197099
+v -3.186750 -3.457336 -1.025606
+f 1101 1102 1100
+f 1099 1100 1102
+f 1106 1103 1105
+f 1103 1104 1105
+f 1107 1108 1101
+f 1102 1101 1108
+f 1103 1108 1104
+f 1108 1107 1104
+v -3.294389 -3.166225 -0.842823
+v -3.330406 -3.185190 -0.950058
+v -3.223246 -3.225388 -0.976573
+v -3.119570 -3.183977 -0.870739
+f 1112 1109 1111
+f 1109 1110 1111
+v -3.194170 -3.348553 -1.007196
+v -3.087335 -3.350463 -0.831656
+v -3.119570 -3.183977 -0.870739
+v -3.223246 -3.225388 -0.976573
+v -3.186750 -3.457336 -1.025606
+v -3.074557 -3.486847 -0.843432
+v -3.082741 -3.598298 -1.054556
+v -3.006867 -3.575464 -0.830221
+v -2.922908 -3.637036 -1.059206
+v -2.870422 -3.601724 -0.843123
+v -2.791754 -3.635993 -1.078555
+v -2.740824 -3.597601 -0.875006
+f 1114 1115 1113
+f 1113 1115 1116
+f 1114 1113 1118
+f 1113 1117 1118
+f 1117 1119 1118
+f 1118 1119 1120
+f 1119 1121 1120
+f 1120 1121 1122
+f 1121 1123 1122
+f 1122 1123 1124
+v -3.333954 -3.058673 -0.974748
+v -3.330406 -3.185190 -0.950058
+v -3.294389 -3.166225 -0.842823
+v -3.256731 -3.032131 -0.849693
+v -3.300372 -2.795728 -0.878984
+v -3.339637 -2.846837 -0.966368
+v -2.986345 -2.933770 -1.087679
+v -2.909010 -3.084482 -1.089147
+v -3.031250 -3.095940 -1.106355
+v -3.107105 -2.947818 -1.092235
+f 1128 1125 1127
+f 1125 1126 1127
+f 1129 1130 1128
+f 1128 1130 1125
+f 1132 1133 1131
+f 1131 1133 1134
+v -3.121673 -3.120319 -1.136456
+v -3.031250 -3.095940 -1.106355
+v -2.888628 -3.200302 -1.210934
+v -3.042899 -3.193907 -1.207296
+f 1137 1138 1136
+f 1135 1136 1138
+v -3.031250 -3.095940 -1.106355
+v -3.121673 -3.120319 -1.136456
+v -3.177108 -2.979305 -1.139084
+v -3.107105 -2.947818 -1.092235
+v -3.169546 -3.135273 -1.128247
+v -3.223286 -3.001780 -1.126176
+f 1139 1140 1142
+f 1140 1141 1142
+f 1141 1140 1144
+f 1140 1143 1144
+v -3.169546 -3.135273 -1.128247
+v -3.121673 -3.120319 -1.136456
+v -3.042899 -3.193907 -1.207296
+v -3.135041 -3.243787 -1.189436
+v -3.217306 -3.187686 -1.075214
+v -3.184143 -3.298048 -1.156892
+f 1147 1148 1146
+f 1145 1146 1148
+f 1150 1149 1148
+f 1149 1145 1148
+v -3.227676 -3.141660 -1.103969
+v -3.169546 -3.135273 -1.128247
+v -3.217306 -3.187686 -1.075214
+v -3.301857 -3.074776 -1.114869
+v -3.223286 -3.001780 -1.126176
+v -3.333954 -3.058673 -0.974748
+v -3.302419 -3.017921 -1.128514
+v -3.339637 -2.846837 -0.966368
+v -3.320330 -2.827513 -1.063914
+f 1151 1152 1153
+f 1155 1152 1154
+f 1154 1152 1151
+f 1154 1156 1157
+f 1157 1156 1159
+f 1158 1159 1156
+v -2.770335 -3.208138 -1.031045
+v -2.884711 -3.063896 -0.993766
+v -2.928681 -3.072892 -0.924772
+v -2.803260 -3.213580 -0.942403
+f 1160 1161 1163
+f 1161 1162 1163
+v -2.884711 -3.063896 -0.993766
+v -2.946527 -2.939327 -0.986343
+v -3.008412 -2.899760 -0.904635
+v -2.928681 -3.072892 -0.924772
+f 1166 1167 1165
+f 1164 1165 1167
+v -2.822497 -3.186549 -1.120984
+v -2.770335 -3.208138 -1.031045
+v -2.749355 -3.272099 -1.034148
+v -2.787341 -3.278502 -1.138621
+v -2.736599 -3.394849 -1.269577
+v -2.699957 -3.390295 -1.185593
+v -2.583580 -3.514267 -1.278598
+v -2.631547 -3.559891 -1.337380
+v -2.649491 -3.404362 -1.100352
+v -2.524720 -3.561609 -1.161535
+v -2.668957 -3.397513 -0.943626
+v -2.593513 -3.536154 -0.942450
+v -2.749867 -3.295148 -0.966073
+v -2.803260 -3.213580 -0.942403
+f 1168 1169 1171
+f 1169 1170 1171
+f 1175 1172 1174
+f 1172 1173 1174
+f 1177 1174 1176
+f 1174 1173 1176
+f 1170 1176 1171
+f 1176 1173 1171
+f 1179 1177 1178
+f 1177 1176 1178
+f 1178 1176 1180
+f 1176 1170 1180
+f 1181 1180 1169
+f 1180 1170 1169
+v -3.294389 -3.166225 -0.842823
+v -3.119570 -3.183977 -0.870739
+v -3.166971 -3.002766 -0.812106
+v -3.256731 -3.032131 -0.849693
+v -3.011987 -3.092000 -0.860973
+v -3.069810 -2.928755 -0.845236
+v -2.928681 -3.072892 -0.924772
+v -3.008412 -2.899760 -0.904635
+v -3.137383 -2.776449 -0.844117
+v -3.184812 -2.768053 -0.850127
+v -3.040038 -2.780893 -0.914614
+f 1182 1183 1184
+f 1182 1184 1185
+f 1183 1186 1184
+f 1186 1187 1184
+f 1189 1187 1188
+f 1186 1188 1187
+f 1191 1184 1190
+f 1184 1187 1190
+f 1190 1187 1192
+f 1187 1189 1192
+v -3.119570 -3.183977 -0.870739
+v -3.087335 -3.350463 -0.831656
+v -2.944625 -3.282121 -0.817054
+v -3.011987 -3.092000 -0.860973
+v -2.803260 -3.213580 -0.942403
+v -2.928681 -3.072892 -0.924772
+v -3.074557 -3.486847 -0.843432
+v -2.890885 -3.415616 -0.819125
+v -2.749867 -3.295148 -0.966073
+f 1196 1193 1195
+f 1193 1194 1195
+f 1197 1198 1195
+f 1196 1195 1198
+f 1200 1195 1199
+f 1194 1199 1195
+f 1201 1197 1200
+f 1195 1200 1197
+v -3.256731 -3.032131 -0.849693
+v -3.166971 -3.002766 -0.812106
+v -3.184812 -2.768053 -0.850127
+v -3.300372 -2.795728 -0.878984
+f 1204 1205 1203
+f 1202 1203 1205
+v -2.890885 -3.415616 -0.819125
+v -3.074557 -3.486847 -0.843432
+v -3.006867 -3.575464 -0.830221
+v -2.870422 -3.601724 -0.843123
+v -2.749867 -3.295148 -0.966073
+v -2.668957 -3.397513 -0.943626
+v -2.740824 -3.597601 -0.875006
+v -2.593513 -3.536154 -0.942450
+v -2.524720 -3.561609 -1.161535
+v -2.791754 -3.635993 -1.078555
+v -2.922908 -3.637036 -1.059206
+v -2.981824 -3.608887 -1.346959
+v -2.729567 -3.602976 -1.377236
+v -3.031250 -3.095940 -1.106355
+v -2.909010 -3.084482 -1.089147
+v -2.822497 -3.186549 -1.120984
+v -2.631547 -3.559891 -1.337380
+v -2.583580 -3.514267 -1.278598
+f 1206 1207 1208
+f 1209 1206 1208
+f 1210 1206 1211
+f 1209 1212 1206
+f 1211 1206 1213
+f 1213 1206 1212
+f 1214 1213 1215
+f 1213 1212 1215
+f 1217 1218 1216
+f 1216 1218 1215
+f 1219 1220 1221
+f 1218 1222 1215
+f 1222 1223 1215
+f 1215 1223 1214
+v -2.946527 -2.939327 -0.986343
+v -3.016419 -2.765091 -0.966671
+v -3.040038 -2.780893 -0.914614
+v -3.008412 -2.899760 -0.904635
+v -3.053267 -2.764905 -1.043008
+v -3.141072 -2.785287 -1.032318
+v -3.162498 -2.556375 -1.058409
+v -3.078699 -2.553982 -1.046834
+v -3.320330 -2.827513 -1.063914
+v -3.339637 -2.846837 -0.966368
+v -3.372066 -2.569159 -0.904785
+v -3.347304 -2.573628 -0.955211
+v -3.261810 -2.821069 -1.088218
+v -3.251541 -2.564050 -1.023627
+v -3.196508 -2.788166 -1.045431
+v -3.022819 -2.522240 -0.979148
+v -3.297886 -2.549020 -0.861657
+v -3.300372 -2.795728 -0.878984
+v -3.240554 -2.555467 -0.856262
+v -3.184812 -2.768053 -0.850127
+v -3.132772 -2.528669 -0.848639
+v -3.137383 -2.776449 -0.844117
+v -3.046610 -2.510881 -0.900772
+v -3.279790 -1.162072 -0.784602
+v -3.277510 -1.177346 -0.915300
+v -3.319817 -1.365015 -0.886015
+v -3.335942 -1.365685 -0.724590
+v -3.251210 -0.948205 -0.819868
+v -3.283698 -0.730967 -0.793898
+v -3.233333 -0.683782 -1.015512
+v -3.238094 -0.979377 -0.961631
+v -3.415655 -0.308965 -0.671045
+v -3.406618 -0.343461 -0.746456
+v -3.556552 0.704883 -0.280630
+v -3.578170 0.837714 -0.288502
+v -3.664355 0.932851 -0.370749
+v -3.631292 0.701013 -0.420276
+v -3.536654 0.442277 -0.322000
+v -3.570384 0.385564 -0.524480
+v -3.516840 0.149002 -0.430359
+v -3.520188 0.140164 -0.618561
+v -3.470778 -0.078218 -0.546398
+v -3.458251 -0.125950 -0.731712
+v -3.623861 0.911561 0.000000
+v -3.599077 0.796217 0.000000
+v -3.601668 1.293049 0.000000
+v -3.709827 1.417763 0.000000
+v -3.709741 1.351194 -0.211745
+v -3.701634 1.272650 -0.270469
+v -3.608593 1.163581 0.000000
+v -3.695872 1.156978 -0.316829
+v -3.622326 1.005378 0.000000
+v -3.672431 1.044224 -0.364991
+v -3.900566 1.002504 0.000000
+v -3.887340 1.003866 -0.057635
+v -3.844470 0.498176 -0.053132
+v -3.856649 0.496801 0.000000
+v -3.875140 1.480358 0.000000
+v -3.860820 1.479723 -0.062137
+v -3.712832 1.794492 0.000000
+v -3.698925 1.787941 -0.066640
+v -3.478430 1.975409 0.000000
+v -3.469715 1.961504 -0.071141
+v -3.242148 2.021387 0.000000
+v -3.238225 2.005405 -0.075645
+v -3.851206 1.007586 -0.099831
+v -3.811194 0.501935 -0.092033
+v -3.821694 1.477989 -0.107631
+v -3.660928 1.770041 -0.115431
+v -3.445903 1.923509 -0.123229
+v -3.227504 1.961738 -0.131029
+v -3.801840 1.012668 -0.115288
+v -3.765736 0.507070 -0.106281
+v -3.768245 1.475619 -0.124295
+v -3.609021 1.745588 -0.133304
+v -3.413372 1.871604 -0.142309
+v -3.752468 1.017751 -0.099865
+v -3.720269 0.512205 -0.092064
+v -3.714787 1.473248 -0.107668
+v -3.557104 1.721130 -0.115470
+v -3.380836 1.819691 -0.123273
+v -3.716312 1.021474 -0.057693
+v -3.686972 0.515966 -0.053185
+v -3.675638 1.471512 -0.062201
+v -3.519086 1.703220 -0.066709
+v -3.357009 1.781675 -0.071216
+v -3.703058 1.022838 -0.000069
+v -3.674766 0.517345 -0.000063
+v -3.661286 1.470876 -0.000074
+v -3.507689 1.700214 0.000000
+v -3.348274 1.767738 -0.000085
+v -3.077669 1.871112 -0.217368
+v -3.037562 2.001526 0.000000
+v -3.053102 1.968810 -0.051104
+v -3.358510 1.810253 -0.380095
+v -3.075310 1.846000 -0.363149
+f 1224 1225 1227
+f 1225 1226 1227
+f 1230 1231 1229
+f 1228 1229 1231
+f 1234 1235 1233
+f 1232 1233 1235
+f 1235 1237 1232
+f 1236 1232 1237
+f 1237 1230 1236
+f 1238 1236 1230
+f 1229 1238 1230
+f 1225 1228 1239
+f 1231 1239 1228
+f 1233 1241 1234
+f 1240 1234 1241
+f 1241 1243 1240
+f 1242 1240 1243
+f 1245 1244 1243
+f 1244 1242 1243
+f 1226 1246 1245
+f 1246 1244 1245
+f 1226 1225 1246
+f 1239 1246 1225
+f 1247 1248 1250
+f 1248 1249 1250
+f 1253 1254 1252
+f 1251 1252 1254
+f 1247 1251 1248
+f 1251 1254 1248
+f 1255 1256 1252
+f 1259 1260 1258
+f 1257 1258 1260
+f 1262 1261 1260
+f 1261 1257 1260
+f 1263 1261 1264
+f 1261 1262 1264
+f 1264 1266 1263
+f 1265 1263 1266
+f 1265 1266 1255
+f 1255 1266 1256
+f 1259 1258 1267
+f 1267 1258 1268
+f 1269 1270 1271
+f 1269 1271 1272
+f 1274 1273 1272
+f 1273 1269 1272
+f 1276 1275 1274
+f 1275 1273 1274
+f 1276 1259 1275
+f 1267 1275 1259
+f 1278 1279 1277
+f 1277 1279 1280
+f 1277 1281 1278
+f 1281 1282 1278
+f 1283 1284 1281
+f 1284 1282 1281
+f 1283 1285 1284
+f 1285 1286 1284
+f 1285 1287 1286
+f 1287 1288 1286
+f 1289 1290 1278
+f 1278 1290 1279
+f 1278 1282 1289
+f 1282 1291 1289
+f 1282 1284 1291
+f 1284 1292 1291
+f 1284 1286 1292
+f 1286 1293 1292
+f 1288 1294 1286
+f 1294 1293 1286
+f 1295 1296 1289
+f 1289 1296 1290
+f 1289 1291 1295
+f 1291 1297 1295
+f 1292 1298 1291
+f 1298 1297 1291
+f 1293 1299 1292
+f 1299 1298 1292
+f 1294 1299 1293
+f 1300 1301 1295
+f 1295 1301 1296
+f 1295 1297 1300
+f 1297 1302 1300
+f 1297 1298 1302
+f 1298 1303 1302
+f 1299 1304 1298
+f 1304 1303 1298
+f 1305 1306 1300
+f 1300 1306 1301
+f 1300 1302 1305
+f 1302 1307 1305
+f 1302 1303 1307
+f 1303 1308 1307
+f 1303 1304 1308
+f 1304 1309 1308
+f 1310 1311 1305
+f 1305 1311 1306
+f 1305 1307 1310
+f 1307 1312 1310
+f 1307 1308 1312
+f 1308 1313 1312
+f 1309 1314 1308
+f 1314 1313 1308
+f 1294 1315 1299
+f 1287 1316 1288
+f 1288 1316 1317
+f 1294 1288 1317
+f 1294 1317 1315
+f 1315 1318 1299
+f 1315 1319 1318
+v -1.883160 -1.829718 -0.401567
+v -1.933565 -1.993029 -0.438902
+v -1.971059 -1.992958 -0.500845
+v -1.936032 -1.829617 -0.488916
+v -2.035740 -1.981182 -0.547873
+v -2.027242 -1.813012 -0.555232
+v -2.106039 -2.019111 -0.510759
+v -2.126375 -1.866497 -0.502895
+v -2.141621 -2.024301 -0.470257
+v -2.176551 -1.873816 -0.445782
+v -2.120746 -2.045137 -0.411171
+v -2.147113 -1.903198 -0.362462
+v -2.060902 -2.031698 -0.372079
+v -2.062725 -1.884246 -0.307336
+v -1.978344 -2.023535 -0.398257
+v -1.946306 -1.872735 -0.344251
+v -2.446375 -1.893261 -0.494110
+v -2.499138 -2.038090 -0.504529
+v -2.513608 -2.012858 -0.558673
+v -2.466779 -1.857679 -0.570461
+v -2.571019 -1.995375 -0.586230
+v -2.547737 -1.833025 -0.609321
+v -2.641567 -2.003164 -0.575611
+v -2.647220 -1.844010 -0.594347
+v -2.678971 -2.007694 -0.558395
+v -2.699966 -1.850397 -0.570070
+v -2.685663 -2.028649 -0.514928
+v -2.709403 -1.879947 -0.508775
+v -2.667969 -2.036634 -0.471396
+v -2.684452 -1.891207 -0.447388
+v -2.618068 -2.046419 -0.441284
+v -2.614084 -1.905005 -0.404925
+v -2.539874 -2.049824 -0.460098
+v -2.503818 -1.909806 -0.431456
+v -2.065655 -2.124623 -0.368720
+v -1.985123 -2.116661 -0.394256
+v -2.124030 -2.137733 -0.406853
+v -2.144393 -2.117408 -0.464489
+v -2.109684 -2.112345 -0.503997
+v -2.041110 -2.075348 -0.540201
+v -1.978016 -2.086834 -0.494327
+v -1.941442 -2.086904 -0.433904
+v -2.552923 -2.142304 -0.454579
+v -2.513187 -2.130859 -0.497920
+v -2.629199 -2.138983 -0.436227
+v -2.677875 -2.129439 -0.465600
+v -2.695135 -2.121650 -0.508064
+v -2.688607 -2.101208 -0.550465
+v -2.652120 -2.096790 -0.567258
+v -2.583303 -2.089191 -0.577616
+v -2.527301 -2.106246 -0.550735
+v -2.048681 -2.165282 -0.450843
+v -2.603284 -2.176802 -0.510638
+f 1320 1321 1323
+f 1321 1322 1323
+f 1325 1323 1324
+f 1323 1322 1324
+f 1325 1324 1327
+f 1324 1326 1327
+f 1329 1327 1328
+f 1327 1326 1328
+f 1329 1328 1331
+f 1328 1330 1331
+f 1333 1331 1332
+f 1331 1330 1332
+f 1333 1332 1335
+f 1332 1334 1335
+f 1320 1335 1321
+f 1335 1334 1321
+f 1336 1337 1339
+f 1337 1338 1339
+f 1341 1339 1340
+f 1339 1338 1340
+f 1341 1340 1343
+f 1340 1342 1343
+f 1345 1343 1344
+f 1343 1342 1344
+f 1345 1344 1347
+f 1344 1346 1347
+f 1347 1346 1349
+f 1346 1348 1349
+f 1349 1348 1351
+f 1348 1350 1351
+f 1353 1351 1352
+f 1351 1350 1352
+f 1336 1353 1337
+f 1353 1352 1337
+f 1334 1332 1355
+f 1332 1354 1355
+f 1356 1354 1330
+f 1330 1354 1332
+f 1328 1357 1330
+f 1357 1356 1330
+f 1326 1358 1328
+f 1358 1357 1328
+f 1324 1359 1326
+f 1359 1358 1326
+f 1322 1360 1324
+f 1360 1359 1324
+f 1361 1360 1321
+f 1321 1360 1322
+f 1321 1334 1361
+f 1334 1355 1361
+f 1362 1363 1352
+f 1352 1363 1337
+f 1352 1350 1362
+f 1350 1364 1362
+f 1348 1365 1350
+f 1365 1364 1350
+f 1346 1366 1348
+f 1366 1365 1348
+f 1344 1367 1346
+f 1367 1366 1346
+f 1342 1368 1344
+f 1368 1367 1344
+f 1369 1368 1340
+f 1340 1368 1342
+f 1338 1370 1340
+f 1370 1369 1340
+f 1338 1337 1370
+f 1337 1363 1370
+f 1360 1361 1371
+f 1359 1360 1371
+f 1358 1359 1371
+f 1357 1358 1371
+f 1356 1357 1371
+f 1354 1356 1371
+f 1355 1354 1371
+f 1361 1355 1371
+f 1370 1363 1372
+f 1369 1370 1372
+f 1368 1369 1372
+f 1367 1368 1372
+f 1366 1367 1372
+f 1365 1366 1372
+f 1364 1365 1372
+f 1362 1364 1372
+f 1363 1362 1372
+v 4.897808 1.946794 -0.628057
+v 4.925394 1.955229 -0.618837
+v 4.953739 1.952580 -0.592256
+v 4.971872 1.924079 -0.586026
+v 4.953403 1.907939 -0.605609
+v 4.925499 1.917814 -0.613413
+v 4.973133 1.992779 -0.533466
+v 5.001903 1.914398 -0.486724
+v 4.982364 1.873300 -0.536190
+v 4.926194 1.859813 -0.582137
+v 4.852578 1.889721 -0.605031
+v 4.824747 1.946835 -0.626358
+v 4.861611 2.001639 -0.621913
+v 4.935561 2.016016 -0.585700
+f 1373 1374 1378
+f 1374 1375 1378
+f 1378 1375 1377
+f 1375 1376 1377
+f 1375 1379 1376
+f 1379 1380 1376
+f 1380 1381 1376
+f 1376 1381 1377
+f 1377 1381 1382
+f 1383 1378 1382
+f 1378 1377 1382
+f 1384 1373 1383
+f 1373 1378 1383
+f 1373 1384 1385
+f 1379 1375 1386
+f 1386 1375 1374
+v 4.760921 1.881357 -0.613120
+v 4.824747 1.946835 -0.626358
+v 4.852578 1.889721 -0.605031
+v 4.861618 1.854067 -0.618095
+v 4.861611 2.001639 -0.621913
+v 4.842883 2.021333 -0.638025
+v 4.935880 2.051665 -0.572853
+v 4.935561 2.016016 -0.585700
+v 4.991746 2.009819 -0.523206
+v 5.001903 1.914398 -0.486724
+v 4.973133 1.992779 -0.533466
+v 4.926194 1.859813 -0.582137
+v 4.944706 1.840663 -0.575374
+v 4.982364 1.873300 -0.536190
+v 4.991709 1.844295 -0.520761
+v 4.908019 1.796041 -0.587882
+v 4.852582 1.816115 -0.603105
+v 4.963546 1.783161 -0.553515
+v 4.983034 1.806343 -0.505779
+v 5.011430 1.875569 -0.463205
+v 4.918466 2.084725 -0.532713
+v 4.964945 2.053575 -0.499903
+v 5.020077 1.978170 -0.480978
+v 4.825996 2.089176 -0.576083
+v 4.881574 2.094571 -0.539949
+v 4.788476 2.028047 -0.608619
+v 4.751519 2.039658 -0.634134
+v 4.798297 2.118191 -0.591085
+v 4.872539 2.159259 -0.542891
+v 4.927885 2.156560 -0.516579
+v 5.002440 2.105746 -0.468233
+v 5.057495 2.002751 -0.451974
+v 5.075994 1.900999 -0.443793
+v 5.030289 1.827419 -0.440803
+v 4.991904 1.760829 -0.510386
+v 4.936066 1.737668 -0.557276
+v 4.871155 1.741238 -0.592326
+v 4.816181 1.797860 -0.604026
+v 5.095375 1.961238 -0.401516
+v 5.085813 1.888503 -0.408327
+v 5.058179 1.788186 -0.417387
+v 5.019836 1.739907 -0.485562
+v 4.917973 1.681480 -0.544201
+v 4.862636 1.684144 -0.570155
+v 4.752337 1.723388 -0.591296
+v 4.697607 1.768061 -0.576663
+v 5.030641 2.102197 -0.432329
+v 5.067202 2.027704 -0.422291
+v 4.937950 2.181155 -0.486939
+v 4.881855 2.194544 -0.530288
+v 4.807794 2.143653 -0.570393
+v 4.728963 2.036146 -0.614307
+v 4.742358 1.882232 -0.621650
+v 4.744050 2.179337 -0.556057
+v 4.688114 2.046378 -0.604518
+v 4.837331 2.235678 -0.479332
+v 4.893850 2.220523 -0.417713
+v 4.995978 2.148785 -0.344534
+v 5.060840 2.053335 -0.309324
+v 5.097062 1.954206 -0.328795
+v 5.105589 1.864086 -0.347113
+v 4.697024 1.862575 -0.604048
+v 4.739441 2.299169 -0.369987
+v 4.832890 2.262727 -0.283787
+v 4.971394 2.146686 -0.224781
+v 5.072165 2.043630 -0.209228
+v 5.127157 1.942759 -0.211214
+v 5.152698 1.830661 -0.287042
+v 5.133171 1.715563 -0.334258
+v 5.103427 1.624404 -0.434275
+v 4.982822 1.503071 -0.507606
+v 4.927282 1.486953 -0.526327
+v 4.798410 1.473149 -0.570618
+v 4.715646 1.502195 -0.584339
+v 4.615408 1.639641 -0.577768
+v 4.560751 1.785154 -0.562428
+v 4.551484 1.841749 -0.575191
+v 4.533113 1.989009 -0.578975
+v 4.636582 2.263383 -0.471997
+v 4.561299 2.133066 -0.547248
+v 4.912303 2.162645 -0.000090
+v 5.049690 2.032731 0.000071
+v 5.156645 1.942902 -0.119993
+v 5.218821 1.803552 -0.199306
+v 5.216855 1.636645 -0.279797
+v 5.233176 1.442459 -0.362988
+v 4.679116 1.438434 -0.589658
+v 4.596478 1.512987 -0.598982
+v 4.560024 1.604023 -0.589333
+v 4.477781 1.687858 -0.597407
+v 4.459682 1.778884 -0.588185
+v 4.432610 1.878873 -0.577888
+v 4.433020 2.024714 -0.563794
+v 4.634996 2.369115 -0.140117
+v 4.747988 2.300163 -0.000276
+v 4.577573 2.389535 -0.256196
+v 4.472349 2.325133 -0.443764
+v 4.389484 2.190421 -0.473320
+v 5.223191 1.371491 -0.388069
+v 5.158322 1.236770 -0.418043
+v 4.955360 1.236724 -0.505230
+v 4.761601 1.363013 -0.571370
+v 5.177545 1.932323 0.000214
+v 5.321136 1.795562 -0.119606
+v 5.378289 1.768448 0.000441
+v 5.424281 1.721152 0.000496
+v 5.421809 1.685349 -0.123555
+v 5.383208 1.619661 -0.202452
+v 5.373133 1.541142 -0.246712
+v 5.334328 1.402713 -0.332639
+v 5.296963 1.322443 -0.357984
+v 5.260653 1.184173 -0.352062
+v 5.250485 1.123029 -0.385234
+v 4.991713 1.163096 -0.504149
+v 4.733657 1.227371 -0.592883
+v 4.641547 1.285422 -0.622034
+v 4.522247 1.398278 -0.644892
+v 4.430999 1.535753 -0.638888
+v 4.404221 1.662433 -0.616610
+v 4.386380 1.770868 -0.596666
+v 4.377095 1.871713 -0.595743
+v 5.588763 1.573846 0.000686
+v 5.604888 1.546091 -0.113773
+v 5.566339 1.498677 -0.190905
+v 5.528186 1.440180 -0.250666
+v 5.471928 1.345179 -0.313899
+v 5.425783 1.264372 -0.329687
+v 5.397967 1.174238 -0.346802
+v 5.388455 1.119419 -0.351883
+v 5.687035 1.499636 -0.110765
+v 5.741781 1.463956 -0.124891
+v 5.730427 1.435668 -0.209848
+v 5.685194 1.452202 -0.188749
+v 5.710154 1.360653 -0.290072
+v 5.608974 1.317869 -0.319719
+v 5.647186 1.394606 -0.257833
+v 5.681726 1.282503 -0.333871
+v 5.563253 1.235295 -0.317238
+v 5.672187 1.164767 -0.354080
+v 5.580797 1.174135 -0.351054
+v 5.680007 1.510009 0.000786
+v 5.479630 1.111310 -0.364188
+v 5.842092 1.427708 -0.130724
+v 5.915025 1.382159 -0.136820
+v 5.886832 1.385674 -0.172365
+v 5.813217 1.415581 -0.195261
+v 5.908842 1.388968 0.001026
+v 5.963117 1.307775 0.001098
+v 5.979357 1.325532 -0.125337
+v 5.941384 1.330818 -0.178936
+v 5.743997 1.482739 0.000851
+v 5.835498 1.436280 0.000946
+v 5.783731 1.341471 -0.284590
+v 5.847989 1.311569 -0.261476
+v 5.931474 1.233483 -0.215613
+v 5.998088 1.231874 -0.107334
+v 5.963527 1.232407 0.001121
+v 5.927110 1.131195 0.001118
+v 5.961686 1.110978 -0.090324
+v 5.908782 1.066916 0.001121
+v 5.934596 1.054796 -0.077039
+f 1390 1387 1389
+f 1387 1388 1389
+f 1393 1394 1392
+f 1391 1392 1394
+f 1395 1396 1397
+f 1399 1390 1398
+f 1398 1390 1389
+f 1398 1400 1399
+f 1400 1401 1399
+f 1399 1402 1390
+f 1390 1402 1403
+f 1401 1404 1399
+f 1399 1404 1402
+f 1401 1405 1404
+f 1401 1406 1405
+f 1395 1393 1408
+f 1407 1408 1393
+f 1408 1409 1395
+f 1395 1409 1406
+f 1393 1392 1411
+f 1392 1410 1411
+f 1387 1412 1392
+f 1410 1392 1412
+f 1413 1414 1412
+f 1414 1410 1412
+f 1414 1415 1410
+f 1415 1411 1410
+f 1415 1416 1411
+f 1416 1407 1411
+f 1416 1417 1407
+f 1417 1408 1407
+f 1418 1409 1417
+f 1417 1409 1408
+f 1406 1409 1419
+f 1418 1419 1409
+f 1419 1420 1406
+f 1420 1421 1406
+f 1406 1421 1405
+f 1422 1404 1421
+f 1405 1421 1404
+f 1423 1402 1422
+f 1402 1404 1422
+f 1424 1403 1423
+f 1403 1402 1423
+f 1387 1403 1424
+f 1419 1425 1426
+f 1426 1427 1419
+f 1419 1427 1420
+f 1421 1420 1428
+f 1420 1427 1428
+f 1429 1422 1428
+f 1421 1428 1422
+f 1422 1429 1423
+f 1423 1429 1430
+f 1431 1424 1430
+f 1424 1423 1430
+f 1387 1424 1432
+f 1424 1431 1432
+f 1418 1417 1434
+f 1417 1433 1434
+f 1433 1417 1435
+f 1435 1417 1416
+f 1435 1416 1436
+f 1436 1416 1415
+f 1414 1437 1415
+f 1436 1415 1437
+f 1437 1414 1438
+f 1414 1413 1438
+f 1413 1387 1438
+f 1439 1438 1387
+f 1439 1387 1432
+f 1440 1437 1441
+f 1437 1438 1441
+f 1442 1436 1440
+f 1440 1436 1437
+f 1443 1435 1442
+f 1442 1435 1436
+f 1444 1433 1443
+f 1443 1433 1435
+f 1444 1445 1433
+f 1445 1434 1433
+f 1445 1446 1434
+f 1446 1425 1434
+f 1446 1447 1425
+f 1425 1447 1426
+f 1426 1447 1427
+f 1448 1439 1432
+f 1450 1443 1449
+f 1442 1449 1443
+f 1451 1444 1450
+f 1450 1444 1443
+f 1451 1452 1444
+f 1452 1445 1444
+f 1446 1445 1453
+f 1452 1453 1445
+f 1453 1454 1446
+f 1454 1447 1446
+f 1455 1427 1454
+f 1447 1454 1427
+f 1456 1428 1455
+f 1427 1455 1428
+f 1456 1457 1428
+f 1428 1457 1429
+f 1430 1429 1458
+f 1429 1457 1458
+f 1430 1458 1459
+f 1431 1430 1460
+f 1430 1459 1460
+f 1460 1461 1431
+f 1432 1431 1461
+f 1461 1462 1432
+f 1448 1432 1462
+f 1462 1463 1448
+f 1463 1441 1448
+f 1464 1441 1463
+f 1465 1440 1466
+f 1440 1441 1466
+f 1466 1441 1464
+f 1467 1468 1451
+f 1468 1452 1451
+f 1468 1469 1452
+f 1469 1453 1452
+f 1469 1470 1453
+f 1470 1454 1453
+f 1471 1455 1470
+f 1470 1455 1454
+f 1455 1471 1472
+f 1455 1472 1456
+f 1461 1460 1474
+f 1460 1473 1474
+f 1461 1474 1475
+f 1462 1461 1476
+f 1461 1475 1476
+f 1476 1477 1462
+f 1463 1462 1477
+f 1464 1463 1478
+f 1478 1463 1477
+f 1466 1464 1479
+f 1479 1464 1478
+f 1481 1450 1480
+f 1480 1450 1449
+f 1480 1449 1482
+f 1482 1449 1465
+f 1483 1482 1465
+f 1484 1483 1466
+f 1483 1465 1466
+f 1484 1466 1479
+f 1485 1457 1472
+f 1456 1472 1457
+f 1458 1457 1486
+f 1457 1485 1486
+f 1486 1487 1458
+f 1458 1487 1459
+f 1487 1488 1459
+f 1459 1488 1460
+f 1460 1488 1473
+f 1489 1490 1469
+f 1490 1470 1469
+f 1489 1491 1490
+f 1493 1490 1492
+f 1491 1492 1490
+f 1494 1470 1493
+f 1470 1490 1493
+f 1470 1494 1471
+f 1494 1495 1471
+f 1471 1495 1472
+f 1495 1496 1472
+f 1472 1496 1485
+f 1496 1497 1485
+f 1498 1486 1497
+f 1485 1497 1486
+f 1486 1498 1499
+f 1499 1500 1486
+f 1486 1500 1487
+f 1500 1501 1487
+f 1488 1487 1501
+f 1473 1488 1502
+f 1488 1501 1502
+f 1502 1503 1473
+f 1474 1473 1503
+f 1503 1504 1474
+f 1475 1474 1504
+f 1475 1504 1476
+f 1476 1504 1505
+f 1505 1506 1476
+f 1506 1477 1476
+f 1477 1506 1478
+f 1507 1478 1506
+f 1493 1492 1509
+f 1492 1508 1509
+f 1509 1510 1493
+f 1493 1510 1494
+f 1494 1510 1495
+f 1510 1511 1495
+f 1495 1511 1496
+f 1511 1512 1496
+f 1512 1513 1496
+f 1496 1513 1497
+f 1497 1513 1498
+f 1513 1514 1498
+f 1499 1498 1515
+f 1498 1514 1515
+f 1516 1517 1519
+f 1517 1518 1519
+f 1520 1521 1522
+f 1524 1521 1523
+f 1521 1520 1523
+f 1525 1526 1523
+f 1524 1523 1526
+f 1527 1516 1508
+f 1516 1509 1508
+f 1510 1509 1519
+f 1509 1516 1519
+f 1522 1511 1519
+f 1519 1511 1510
+f 1512 1511 1521
+f 1511 1522 1521
+f 1521 1524 1512
+f 1512 1524 1513
+f 1526 1514 1524
+f 1513 1524 1514
+f 1526 1528 1514
+f 1514 1528 1515
+f 1529 1530 1532
+f 1530 1531 1532
+f 1534 1535 1533
+f 1533 1535 1530
+f 1536 1531 1535
+f 1530 1535 1531
+f 1529 1517 1538
+f 1537 1538 1517
+f 1517 1529 1518
+f 1529 1532 1518
+f 1532 1539 1518
+f 1518 1539 1520
+f 1531 1540 1532
+f 1532 1540 1539
+f 1541 1540 1536
+f 1531 1536 1540
+f 1535 1542 1536
+f 1535 1534 1542
+f 1534 1543 1542
+f 1536 1542 1541
+f 1542 1543 1545
+f 1543 1544 1545
+f 1544 1546 1545
+f 1546 1547 1545
+v 5.908782 1.066916 0.001121
+v 5.871947 1.021428 0.001102
+v 5.897758 1.009309 -0.080583
+v 5.934596 1.054796 -0.077039
+v 5.878630 0.986485 -0.128292
+v 5.923808 1.025283 -0.153084
+f 1549 1550 1548
+f 1548 1550 1551
+f 1551 1550 1553
+f 1550 1552 1553
+v 5.961686 1.110978 -0.090324
+v 5.934596 1.054796 -0.077039
+v 5.923808 1.025283 -0.153084
+v 5.950684 1.082725 -0.175648
+v 5.800778 1.078596 -0.319450
+v 5.884856 1.062202 -0.249545
+v 5.857750 0.997026 -0.236768
+v 5.755282 1.004149 -0.307505
+v 5.763952 1.062109 -0.338641
+v 5.912147 1.117911 -0.254197
+v 5.959462 1.157227 -0.187097
+f 1554 1555 1557
+f 1555 1556 1557
+f 1561 1562 1560
+f 1562 1558 1560
+f 1558 1559 1560
+f 1557 1559 1564
+f 1563 1564 1559
+f 1560 1559 1556
+f 1559 1557 1556
+v 5.923808 1.025283 -0.153084
+v 5.878630 0.986485 -0.128292
+v 5.757506 0.957900 -0.210732
+v 5.857750 0.997026 -0.236768
+v 5.755282 1.004149 -0.307505
+v 5.674999 0.950754 -0.227960
+f 1567 1568 1566
+f 1565 1566 1568
+f 1568 1567 1569
+f 1569 1567 1570
+v 5.800778 1.078596 -0.319450
+v 5.837875 1.141493 -0.305184
+v 5.912147 1.117911 -0.254197
+v 5.884856 1.062202 -0.249545
+v 5.672187 1.164767 -0.354080
+v 5.773410 1.225861 -0.323025
+v 5.681726 1.282503 -0.333871
+v 5.764774 1.279824 -0.308562
+v 5.710154 1.360653 -0.290072
+v 5.783731 1.341471 -0.284590
+f 1571 1572 1574
+f 1572 1573 1574
+f 1575 1576 1571
+f 1576 1572 1571
+f 1577 1578 1575
+f 1578 1576 1575
+f 1577 1579 1578
+f 1579 1580 1578
+v 5.895899 1.182730 -0.164705
+v 5.959462 1.157227 -0.187097
+v 5.912147 1.117911 -0.254197
+v 5.849792 1.193480 -0.181047
+v 5.837875 1.141493 -0.305184
+v 5.803425 1.260787 -0.210002
+v 5.840665 1.221942 -0.187128
+v 5.773410 1.225861 -0.323025
+v 5.764774 1.279824 -0.308562
+v 5.783731 1.341471 -0.284590
+v 5.847989 1.311569 -0.261476
+v 5.931474 1.233483 -0.215613
+v 5.998088 1.231874 -0.107334
+v 5.672385 1.007694 -0.341778
+v 5.755282 1.004149 -0.307505
+v 5.674999 0.950754 -0.227960
+v 5.573803 0.952578 -0.243886
+v 5.580727 0.999330 -0.349867
+v 5.535184 0.980180 -0.341257
+f 1581 1582 1583
+f 1585 1584 1583
+f 1584 1581 1583
+f 1587 1588 1586
+f 1586 1588 1589
+f 1586 1589 1590
+f 1586 1590 1591
+f 1592 1587 1591
+f 1586 1591 1587
+f 1587 1592 1584
+f 1593 1581 1592
+f 1592 1581 1584
+f 1594 1595 1597
+f 1595 1596 1597
+f 1598 1594 1597
+f 1598 1597 1599
+v 5.690122 1.092917 -0.370850
+v 5.763952 1.062109 -0.338641
+v 5.681086 1.054964 -0.355860
+v 5.672187 1.164767 -0.354080
+v 5.800778 1.078596 -0.319450
+v 5.580797 1.174135 -0.351054
+v 5.598282 1.094735 -0.386994
+v 5.479630 1.111310 -0.364188
+v 5.470775 1.009574 -0.355371
+v 5.580223 1.047470 -0.372696
+v 5.672385 1.007694 -0.341778
+v 5.580727 0.999330 -0.349867
+v 5.535184 0.980180 -0.341257
+v 5.388455 1.119419 -0.351883
+v 5.425352 1.035967 -0.342720
+v 5.434594 0.970412 -0.330823
+v 5.480649 0.941387 -0.316248
+v 5.379461 1.045817 -0.349748
+v 5.370709 0.980272 -0.337432
+v 5.373646 0.885375 -0.208840
+f 1600 1601 1602
+f 1604 1601 1603
+f 1603 1601 1600
+f 1605 1603 1606
+f 1603 1600 1606
+f 1605 1606 1607
+f 1607 1606 1608
+f 1602 1609 1600
+f 1606 1600 1609
+f 1602 1610 1609
+f 1609 1610 1611
+f 1609 1608 1606
+f 1608 1609 1612
+f 1609 1611 1612
+f 1613 1607 1614
+f 1607 1608 1614
+f 1614 1608 1615
+f 1608 1612 1615
+f 1612 1616 1615
+f 1613 1614 1617
+f 1618 1617 1615
+f 1617 1614 1615
+f 1615 1616 1619
+f 1618 1615 1619
+v 5.573803 0.952578 -0.243886
+v 5.674999 0.950754 -0.227960
+v 5.638369 0.904402 -0.222548
+v 5.546347 0.916044 -0.246782
+v 5.757506 0.957900 -0.210732
+v 5.748613 0.920490 -0.205099
+f 1621 1622 1620
+f 1620 1622 1623
+f 1625 1622 1624
+f 1621 1624 1622
+v 5.480649 0.941387 -0.316248
+v 5.546347 0.916044 -0.246782
+v 5.511556 0.863525 -0.177613
+v 5.373646 0.885375 -0.208840
+v 5.638369 0.904402 -0.222548
+v 5.603370 0.852748 -0.162335
+v 5.748613 0.920490 -0.205099
+v 5.704630 0.849158 -0.128130
+v 5.250485 1.123029 -0.385234
+v 5.388455 1.119419 -0.351883
+v 5.379461 1.045817 -0.349748
+v 5.241466 1.040469 -0.383965
+v 5.370709 0.980272 -0.337432
+v 5.223571 0.974029 -0.362117
+v 5.299005 0.908991 -0.260177
+v 5.197562 0.922406 -0.302473
+f 1629 1626 1628
+f 1626 1627 1628
+f 1628 1627 1631
+f 1627 1630 1631
+f 1633 1631 1632
+f 1630 1632 1631
+f 1637 1634 1636
+f 1634 1635 1636
+f 1639 1637 1638
+f 1637 1636 1638
+f 1638 1629 1640
+f 1638 1640 1639
+f 1639 1640 1641
+v 5.878630 0.986485 -0.128292
+v 5.851404 0.929008 -0.105362
+v 5.748613 0.920490 -0.205099
+v 5.757506 0.957900 -0.210732
+v 5.871947 1.021428 0.001102
+v 5.836005 0.945722 0.001092
+v 5.897758 1.009309 -0.080583
+f 1642 1643 1645
+f 1643 1644 1645
+f 1646 1647 1648
+f 1648 1647 1642
+f 1647 1643 1642
+v 5.836005 0.945722 0.001092
+v 5.780790 0.891286 0.001059
+v 5.797411 0.880032 -0.072306
+v 5.851404 0.929008 -0.105362
+v 5.704630 0.849158 -0.128130
+v 5.748613 0.920490 -0.205099
+v 5.679621 0.839500 0.000985
+v 5.568745 0.834653 -0.071390
+v 5.579253 0.837796 0.000896
+v 5.449164 0.847535 -0.103909
+v 5.603370 0.852748 -0.162335
+v 5.247762 0.848549 -0.108546
+v 5.213434 0.856784 0.000565
+v 5.112563 0.840686 0.000480
+v 5.137075 0.824518 -0.144842
+v 5.356900 0.851120 -0.138324
+v 5.511556 0.863525 -0.177613
+v 5.264430 0.855571 -0.181694
+v 5.373646 0.885375 -0.208840
+v 5.323232 0.866039 0.000660
+v 5.469641 0.838722 0.000798
+v 5.299005 0.908991 -0.260177
+v 5.197562 0.922406 -0.302473
+v 5.153735 0.831575 -0.218348
+v 4.920855 0.812339 0.000318
+v 4.963526 0.797382 -0.143440
+v 4.996710 0.810560 -0.280771
+v 4.712067 0.770512 -0.333393
+v 4.669690 0.738163 -0.188296
+v 4.655453 0.758022 0.000098
+v 5.004627 0.908637 -0.345273
+v 4.728809 0.878731 -0.405801
+v 5.011084 1.066770 -0.458562
+v 5.241466 1.040469 -0.383965
+v 5.223571 0.974029 -0.362117
+v 5.021254 0.951308 -0.405567
+v 4.733657 1.227371 -0.592883
+v 4.991713 1.163096 -0.504149
+v 4.743250 1.059210 -0.563421
+v 4.744871 0.950945 -0.491082
+v 4.641547 1.285422 -0.622034
+v 4.567896 1.149805 -0.642484
+v 4.496191 1.024566 -0.579491
+v 4.416475 0.921264 -0.458839
+v 4.333503 0.951176 -0.481517
+v 4.399629 0.850459 -0.391855
+v 4.297891 0.911506 -0.447987
+v 4.380854 0.704574 -0.000130
+v 4.359048 0.700414 -0.166651
+v 4.319799 0.731007 -0.291212
+v 4.216374 0.852328 -0.405873
+v 4.449011 1.260929 -0.647431
+v 4.366867 1.131136 -0.630581
+v 4.141189 1.008775 -0.499342
+v 4.277227 1.077746 -0.550819
+v 4.085564 1.288885 -0.544406
+v 4.175444 1.350332 -0.613988
+v 4.247733 1.381058 -0.649596
+v 4.329607 1.464801 -0.661485
+v 4.430999 1.535753 -0.638888
+v 4.522247 1.398278 -0.644892
+v 4.312225 1.683392 -0.639944
+v 4.404221 1.662433 -0.616610
+v 4.303615 1.799914 -0.610388
+v 4.386380 1.770868 -0.596666
+v 4.304562 1.906537 -0.572242
+v 4.377095 1.871713 -0.595743
+v 4.240116 1.770049 -0.583946
+v 4.221814 1.660769 -0.594090
+v 4.121121 1.614451 -0.587188
+v 4.067576 1.572668 -0.534997
+v 4.148883 1.759918 -0.573765
+v 4.076852 1.746601 -0.527436
+v 4.747988 2.300163 -0.000276
+v 4.912303 2.162645 -0.000090
+v 4.971394 2.146686 -0.224781
+v 4.832890 2.262727 -0.283787
+v 5.049690 2.032731 0.000071
+v 5.177545 1.932323 0.000214
+v 5.156645 1.942902 -0.119993
+v 5.680007 1.510009 0.000786
+v 5.743997 1.482739 0.000851
+v 5.741781 1.463956 -0.124891
+v 5.687035 1.499636 -0.110765
+v 5.835498 1.436280 0.000946
+v 5.908842 1.388968 0.001026
+v 5.915025 1.382159 -0.136820
+v 5.842092 1.427708 -0.130724
+v 4.342351 2.581176 -0.140317
+v 4.317602 2.588926 -0.000745
+v 4.454962 2.523303 -0.000603
+v 4.452383 2.524558 -0.130255
+v 4.332083 2.586481 -0.194917
+v 4.440143 2.510529 -0.269164
+v 4.339601 2.592642 -0.258891
+v 4.429895 2.495758 -0.306894
+v 4.187258 2.590221 -0.135844
+v 4.189883 2.606916 -0.000863
+v 4.203325 2.589186 -0.219164
+v 4.211652 2.602538 -0.264011
+v 4.209941 2.600612 -0.337597
+v 4.328606 2.563996 -0.343892
+v 4.410844 2.500167 -0.351972
+f 1652 1649 1651
+f 1649 1650 1651
+f 1654 1652 1653
+f 1652 1651 1653
+f 1651 1650 1655
+f 1656 1653 1655
+f 1651 1655 1653
+f 1655 1657 1656
+f 1658 1659 1656
+f 1653 1656 1659
+f 1663 1660 1662
+f 1660 1661 1662
+f 1659 1658 1665
+f 1658 1664 1665
+f 1665 1664 1667
+f 1664 1666 1667
+f 1668 1661 1660
+f 1658 1656 1669
+f 1656 1657 1669
+f 1660 1658 1668
+f 1658 1669 1668
+f 1664 1658 1660
+f 1664 1660 1666
+f 1670 1667 1666
+f 1671 1670 1672
+f 1670 1666 1672
+f 1660 1663 1666
+f 1666 1663 1672
+f 1673 1674 1662
+f 1663 1662 1674
+f 1675 1672 1674
+f 1672 1663 1674
+f 1674 1677 1675
+f 1676 1675 1677
+f 1674 1673 1677
+f 1673 1678 1677
+f 1679 1671 1675
+f 1671 1672 1675
+f 1680 1679 1676
+f 1679 1675 1676
+f 1682 1683 1681
+f 1681 1683 1684
+f 1684 1683 1679
+f 1683 1671 1679
+f 1685 1686 1687
+f 1686 1681 1687
+f 1688 1687 1684
+f 1687 1681 1684
+f 1688 1684 1680
+f 1684 1679 1680
+f 1687 1690 1685
+f 1689 1685 1690
+f 1688 1691 1687
+f 1690 1687 1691
+f 1692 1691 1680
+f 1691 1688 1680
+f 1694 1695 1692
+f 1693 1692 1695
+f 1677 1678 1697
+f 1678 1696 1697
+f 1698 1676 1697
+f 1676 1677 1697
+f 1694 1676 1698
+f 1698 1699 1694
+f 1694 1699 1695
+f 1676 1694 1680
+f 1694 1692 1680
+f 1691 1701 1690
+f 1700 1690 1701
+f 1702 1695 1699
+f 1703 1693 1702
+f 1702 1693 1695
+f 1705 1703 1704
+f 1704 1703 1702
+f 1693 1691 1692
+f 1693 1703 1691
+f 1703 1701 1691
+f 1703 1705 1701
+f 1705 1706 1701
+f 1701 1706 1700
+f 1706 1707 1700
+f 1700 1707 1709
+f 1707 1708 1709
+f 1707 1710 1708
+f 1710 1711 1708
+f 1712 1713 1710
+f 1713 1711 1710
+f 1714 1715 1712
+f 1715 1713 1712
+f 1717 1716 1710
+f 1716 1712 1710
+f 1706 1717 1707
+f 1717 1710 1707
+f 1717 1706 1718
+f 1718 1706 1705
+f 1704 1719 1705
+f 1719 1718 1705
+f 1718 1720 1717
+f 1720 1716 1717
+f 1719 1721 1718
+f 1721 1720 1718
+f 1722 1723 1725
+f 1723 1724 1725
+f 1726 1727 1728
+f 1731 1732 1730
+f 1729 1730 1732
+f 1735 1736 1734
+f 1733 1734 1736
+f 1738 1739 1737
+f 1737 1739 1740
+f 1742 1741 1740
+f 1741 1737 1740
+f 1741 1742 1743
+f 1743 1742 1744
+f 1737 1745 1738
+f 1745 1746 1738
+f 1737 1741 1745
+f 1747 1745 1741
+f 1743 1748 1741
+f 1748 1747 1741
+f 1750 1749 1743
+f 1749 1748 1743
+f 1743 1744 1750
+f 1750 1744 1751
+v 4.224730 2.624525 -0.491916
+v 4.209941 2.600612 -0.337597
+v 4.328606 2.563996 -0.343892
+v 4.344028 2.585635 -0.470949
+v 4.410844 2.500167 -0.351972
+v 4.407729 2.531640 -0.486692
+v 4.277169 2.652435 -0.591369
+v 4.359483 2.615839 -0.596817
+v 4.423033 2.561337 -0.603562
+v 4.356680 2.682996 -0.719050
+v 4.411541 2.663824 -0.713132
+v 4.476090 2.606654 -0.692301
+v 4.418954 2.707401 -0.782531
+v 4.465268 2.695425 -0.757267
+v 4.520603 2.639162 -0.745542
+v 4.509555 2.719807 -0.819972
+v 4.546655 2.709095 -0.803780
+v 4.574545 2.669863 -0.780363
+f 1752 1753 1755
+f 1753 1754 1755
+f 1754 1756 1755
+f 1755 1756 1757
+f 1752 1755 1758
+f 1758 1755 1759
+f 1755 1757 1759
+f 1759 1757 1760
+f 1758 1759 1761
+f 1761 1759 1762
+f 1762 1759 1763
+f 1759 1760 1763
+f 1764 1761 1765
+f 1761 1762 1765
+f 1763 1766 1762
+f 1762 1766 1765
+f 1765 1768 1764
+f 1767 1764 1768
+f 1766 1769 1765
+f 1765 1769 1768
+v 4.528082 2.467537 -0.000521
+v 4.747988 2.300163 -0.000276
+v 4.634996 2.369115 -0.140117
+v 4.452383 2.524558 -0.130255
+v 4.454962 2.523303 -0.000603
+v 4.577573 2.389535 -0.256196
+v 4.440143 2.510529 -0.269164
+v 4.429895 2.495758 -0.306894
+v 4.474318 2.418432 -0.361347
+v 4.410844 2.500167 -0.351972
+f 1770 1771 1772
+f 1775 1773 1772
+f 1772 1773 1770
+f 1773 1774 1770
+f 1776 1773 1775
+f 1777 1776 1775
+f 1778 1779 1777
+v 4.407729 2.531640 -0.486692
+v 4.410844 2.500167 -0.351972
+v 4.474318 2.418432 -0.361347
+v 4.443850 2.449921 -0.495432
+v 4.423033 2.561337 -0.603562
+v 4.440760 2.490353 -0.629287
+v 4.476090 2.606654 -0.692301
+v 4.484667 2.534451 -0.708888
+v 4.520603 2.639162 -0.745542
+v 4.520165 2.557971 -0.762427
+v 4.574545 2.669863 -0.780363
+v 4.592620 2.569879 -0.790452
+v 4.656565 2.680542 -0.799684
+v 4.674691 2.598833 -0.808006
+v 4.646703 2.728688 -0.822295
+v 4.546655 2.709095 -0.803780
+v 4.636909 2.750501 -0.856859
+v 4.509555 2.719807 -0.819972
+v 4.748031 2.683805 -0.800044
+v 4.729447 2.606204 -0.807513
+v 4.728931 2.721892 -0.832625
+v 4.719171 2.751091 -0.865965
+v 4.821325 2.691794 -0.791887
+v 4.821336 2.621498 -0.789636
+v 4.811798 2.728680 -0.815406
+v 4.801436 2.750224 -0.858918
+v 5.096148 2.759720 -0.774729
+f 1782 1783 1781
+f 1780 1781 1783
+f 1785 1784 1783
+f 1784 1780 1783
+f 1784 1785 1786
+f 1786 1785 1787
+f 1788 1786 1789
+f 1786 1787 1789
+f 1790 1788 1791
+f 1788 1789 1791
+f 1791 1793 1790
+f 1792 1790 1793
+f 1795 1790 1794
+f 1794 1790 1792
+f 1797 1795 1796
+f 1796 1795 1794
+f 1792 1793 1798
+f 1798 1793 1799
+f 1792 1798 1794
+f 1800 1794 1798
+f 1801 1796 1800
+f 1796 1794 1800
+f 1799 1803 1798
+f 1802 1798 1803
+f 1804 1800 1802
+f 1800 1798 1802
+f 1805 1801 1804
+f 1801 1800 1804
+f 1806 1805 1804
+f 1806 1804 1802
+f 1806 1802 1803
+v 4.474318 2.418432 -0.361347
+v 4.429895 2.495758 -0.306894
+v 4.577573 2.389535 -0.256196
+v 4.472349 2.325133 -0.443764
+f 1807 1808 1809
+f 1807 1809 1810
+v 4.442912 2.343263 -0.533220
+v 4.443850 2.449921 -0.495432
+v 4.474318 2.418432 -0.361347
+v 4.472349 2.325133 -0.443764
+v 4.440713 2.398472 -0.629128
+v 4.440760 2.490353 -0.629287
+v 4.484667 2.534451 -0.708888
+v 4.474625 2.465214 -0.751890
+v 4.314039 2.329460 -0.577510
+v 4.320630 2.385528 -0.682583
+v 4.296769 2.260422 -0.528796
+v 4.382053 2.433474 -0.798757
+v 4.520165 2.557971 -0.762427
+v 4.538177 2.513353 -0.776566
+v 4.444739 2.475795 -0.860515
+v 4.592620 2.569879 -0.790452
+v 4.601515 2.533324 -0.794193
+v 4.554459 2.511417 -0.850571
+v 4.674691 2.598833 -0.808006
+v 4.683344 2.554221 -0.821927
+v 4.681847 2.551036 -0.886235
+v 4.737893 2.564648 -0.830389
+v 4.755192 2.568818 -0.876311
+v 4.829566 2.580797 -0.821827
+v 4.856249 2.593812 -0.867067
+v 4.729447 2.606204 -0.807513
+v 4.821336 2.621498 -0.789636
+v 4.662221 2.556346 -0.940618
+v 4.497719 2.547480 -0.937659
+v 4.763337 2.590834 -0.929248
+v 4.883022 2.613658 -0.893163
+v 4.352603 2.524888 -0.890532
+v 4.262798 2.490674 -0.818316
+v 4.192789 2.411967 -0.668016
+v 4.193959 2.370476 -0.616705
+v 4.113935 2.334131 -0.526471
+v 5.096148 2.759720 -0.774729
+v 4.735139 2.645464 -0.950890
+v 4.854957 2.660227 -0.924310
+v 4.615662 2.633870 -0.977986
+v 4.460582 2.622875 -0.957002
+v 4.343217 2.589542 -0.893106
+v 4.244622 2.554467 -0.811726
+v 4.138687 2.474013 -0.642311
+v 4.121994 2.458034 -0.570029
+v 4.078510 2.411810 -0.472193
+v 4.235494 2.636171 -0.803613
+v 4.342998 2.664049 -0.904347
+v 4.460786 2.695616 -0.949972
+v 4.624800 2.708372 -0.989445
+v 4.138494 2.557838 -0.652651
+v 4.104292 2.537976 -0.543437
+v 4.088356 2.510913 -0.453793
+f 1813 1814 1812
+f 1811 1812 1814
+f 1812 1811 1816
+f 1815 1816 1811
+f 1815 1818 1816
+f 1817 1816 1818
+f 1820 1815 1819
+f 1815 1811 1819
+f 1814 1821 1811
+f 1819 1811 1821
+f 1820 1822 1815
+f 1818 1815 1822
+f 1818 1824 1817
+f 1823 1817 1824
+f 1824 1818 1825
+f 1818 1822 1825
+f 1826 1823 1827
+f 1823 1824 1827
+f 1825 1828 1824
+f 1827 1824 1828
+f 1830 1829 1827
+f 1829 1826 1827
+f 1828 1831 1827
+f 1830 1827 1831
+f 1833 1832 1831
+f 1832 1830 1831
+f 1833 1835 1832
+f 1834 1832 1835
+f 1832 1836 1830
+f 1836 1829 1830
+f 1837 1836 1834
+f 1836 1832 1834
+f 1839 1838 1828
+f 1838 1831 1828
+f 1840 1833 1838
+f 1831 1838 1833
+f 1841 1835 1840
+f 1835 1833 1840
+f 1842 1839 1825
+f 1828 1825 1839
+f 1843 1842 1822
+f 1842 1825 1822
+f 1843 1822 1844
+f 1822 1820 1844
+f 1819 1845 1820
+f 1844 1820 1845
+f 1821 1846 1819
+f 1846 1845 1819
+f 1841 1847 1835
+f 1841 1840 1849
+f 1840 1848 1849
+f 1850 1848 1838
+f 1838 1848 1840
+f 1838 1839 1850
+f 1839 1851 1850
+f 1839 1842 1851
+f 1842 1852 1851
+f 1853 1852 1843
+f 1843 1852 1842
+f 1853 1843 1854
+f 1844 1854 1843
+f 1841 1849 1847
+f 1855 1854 1845
+f 1854 1844 1845
+f 1845 1846 1855
+f 1855 1846 1856
+f 1857 1858 1853
+f 1853 1858 1852
+f 1852 1858 1851
+f 1858 1859 1851
+f 1859 1860 1851
+f 1851 1860 1850
+f 1854 1861 1853
+f 1861 1857 1853
+f 1862 1861 1855
+f 1861 1854 1855
+f 1855 1856 1862
+f 1863 1862 1856
+v 4.063205 2.509679 -0.342987
+v 4.088356 2.510913 -0.453793
+v 4.078510 2.411810 -0.472193
+v 4.043796 2.386524 -0.400392
+v 4.055262 2.505284 -0.297282
+v 4.035753 2.399538 -0.343957
+f 1864 1865 1867
+f 1865 1866 1867
+f 1864 1867 1868
+f 1868 1867 1869
+v 4.624800 2.708372 -0.989445
+v 4.753015 2.699695 -0.973279
+v 4.735139 2.645464 -0.950890
+v 4.615662 2.633870 -0.977986
+v 4.863709 2.722151 -0.936660
+v 4.854957 2.660227 -0.924310
+f 1871 1872 1870
+f 1870 1872 1873
+f 1872 1871 1875
+f 1871 1874 1875
+v 4.187258 2.590221 -0.135844
+v 4.084506 2.570978 -0.218168
+v 4.079812 2.571649 -0.000951
+v 4.189883 2.606916 -0.000863
+v 4.203325 2.589186 -0.219164
+v 4.101754 2.557092 -0.265856
+v 4.211652 2.602538 -0.264011
+v 4.100907 2.560626 -0.302396
+v 4.209941 2.600612 -0.337597
+v 4.117367 2.568514 -0.384500
+f 1877 1878 1876
+f 1876 1878 1879
+f 1876 1880 1877
+f 1880 1881 1877
+f 1883 1881 1882
+f 1882 1881 1880
+f 1883 1882 1885
+f 1884 1885 1882
+v 4.224730 2.624525 -0.491916
+v 4.151183 2.579059 -0.494606
+v 4.117367 2.568514 -0.384500
+v 4.209941 2.600612 -0.337597
+v 4.636909 2.750501 -0.856859
+v 4.616626 2.749486 -0.939333
+v 4.462368 2.725999 -0.882675
+v 4.509555 2.719807 -0.819972
+v 4.354196 2.711836 -0.826545
+v 4.418954 2.707401 -0.782531
+v 4.273414 2.686575 -0.753674
+v 4.356680 2.682996 -0.719050
+v 4.277169 2.652435 -0.591369
+v 4.176065 2.636883 -0.618384
+f 1889 1886 1888
+f 1886 1887 1888
+f 1891 1892 1890
+f 1890 1892 1893
+f 1892 1894 1893
+f 1893 1894 1895
+f 1896 1897 1894
+f 1895 1894 1897
+f 1887 1886 1899
+f 1886 1898 1899
+v 4.035753 2.399538 -0.343957
+v 4.000110 2.424158 -0.313254
+v 4.029016 2.519175 -0.249385
+v 4.055262 2.505284 -0.297282
+v 4.024214 2.527933 -0.000987
+v 3.988172 2.489642 -0.001008
+v 4.079812 2.571649 -0.000951
+v 4.084506 2.570978 -0.218168
+v 4.101754 2.557092 -0.265856
+v 4.100907 2.560626 -0.302396
+v 4.063205 2.509679 -0.342987
+v 4.117367 2.568514 -0.384500
+v 4.088356 2.510913 -0.453793
+f 1902 1903 1901
+f 1900 1901 1903
+f 1901 1905 1902
+f 1904 1902 1905
+f 1904 1906 1902
+f 1906 1907 1902
+f 1907 1908 1902
+f 1902 1908 1903
+f 1910 1903 1909
+f 1903 1908 1909
+f 1912 1910 1911
+f 1910 1909 1911
+v 4.088356 2.510913 -0.453793
+v 4.117367 2.568514 -0.384500
+v 4.151183 2.579059 -0.494606
+v 4.104292 2.537976 -0.543437
+v 4.176065 2.636883 -0.618384
+v 4.277169 2.652435 -0.591369
+v 4.356680 2.682996 -0.719050
+v 4.273414 2.686575 -0.753674
+v 4.138494 2.557838 -0.652651
+v 4.235494 2.636171 -0.803613
+v 4.354196 2.711836 -0.826545
+v 4.342998 2.664049 -0.904347
+v 4.462368 2.725999 -0.882675
+v 4.460786 2.695616 -0.949972
+v 4.636909 2.750501 -0.856859
+v 4.719171 2.751091 -0.865965
+v 4.735445 2.749285 -0.940329
+v 4.616626 2.749486 -0.939333
+v 4.801436 2.750224 -0.858918
+v 4.827733 2.754390 -0.905049
+v 5.096148 2.759720 -0.774729
+v 4.624800 2.708372 -0.989445
+v 4.753015 2.699695 -0.973279
+v 4.863709 2.722151 -0.936660
+f 1914 1915 1913
+f 1913 1915 1916
+f 1917 1918 1920
+f 1918 1919 1920
+f 1915 1917 1916
+f 1916 1917 1921
+f 1921 1917 1922
+f 1917 1920 1922
+f 1922 1920 1924
+f 1920 1923 1924
+f 1924 1923 1926
+f 1923 1925 1926
+f 1929 1930 1928
+f 1927 1928 1930
+f 1929 1928 1932
+f 1931 1932 1928
+f 1932 1931 1933
+f 1926 1925 1934
+f 1925 1930 1934
+f 1935 1934 1929
+f 1930 1929 1934
+f 1935 1929 1936
+f 1936 1929 1932
+f 1936 1932 1933
+v 3.787342 2.396113 -0.001159
+v 3.988172 2.489642 -0.001008
+v 4.000110 2.424158 -0.313254
+v 3.828001 2.352540 -0.233341
+v 3.961908 2.347745 -0.374747
+v 3.870548 2.292106 -0.368964
+v 4.035753 2.399538 -0.343957
+v 4.043796 2.386524 -0.400392
+v 4.025364 2.359300 -0.402597
+v 4.077563 2.305187 -0.510338
+v 3.967085 2.280648 -0.537643
+v 3.903911 2.241501 -0.512468
+v 3.857922 2.141554 -0.521067
+v 3.823349 2.141733 -0.428356
+v 4.078510 2.411810 -0.472193
+v 4.113935 2.334131 -0.526471
+v 4.112302 2.285832 -0.595500
+v 4.010847 2.270246 -0.622149
+v 3.928869 2.223919 -0.615683
+v 3.892378 2.149432 -0.603589
+v 4.146067 2.278102 -0.707372
+v 4.044730 2.254459 -0.744209
+v 3.990744 2.205448 -0.710795
+v 3.945464 2.130100 -0.689536
+v 4.296769 2.260422 -0.528796
+v 4.212974 2.303184 -0.587113
+v 4.212058 2.279450 -0.625927
+v 4.229332 2.274522 -0.672749
+v 4.172143 2.303394 -0.778972
+v 4.079122 2.264104 -0.845010
+v 4.024700 2.187859 -0.814219
+v 4.273005 2.310529 -0.762172
+v 4.215419 2.350484 -0.885764
+v 4.104864 2.298353 -0.915735
+v 4.059714 2.194906 -0.888152
+v 4.061989 2.231988 -1.178382
+v 4.102304 2.299960 -1.025862
+v 4.155551 2.388662 -1.091960
+v 4.097362 2.366600 -1.239986
+v 4.194233 2.408334 -1.008471
+v 4.307092 2.367482 -0.877202
+v 4.266263 2.421651 -1.054799
+v 4.228523 2.435029 -1.098575
+v 4.170470 2.458441 -1.241846
+v 4.094116 2.426172 -1.381032
+v 4.058311 2.293363 -1.338054
+v 4.046673 2.341349 -1.452530
+v 4.047406 2.207209 -1.015108
+v 3.989434 2.118832 -0.765086
+v 4.022592 2.123052 -0.903284
+v 4.020299 2.141675 -1.002365
+v 4.036947 1.992167 -1.072561
+v 4.024858 2.106568 -1.208099
+v 4.082988 2.175805 -1.450930
+v 4.103303 2.038565 -1.363737
+v 4.152166 1.868775 -1.225002
+v 4.031515 1.968248 -0.918460
+v 4.127903 1.828359 -1.090512
+v 3.922437 1.972461 -0.483563
+v 3.966639 1.969285 -0.549291
+v 3.982910 1.987391 -0.639809
+v 4.094112 1.889281 -0.578435
+v 4.059885 1.860460 -0.470087
+v 4.017509 1.996169 -0.731654
+v 4.150297 1.820575 -0.917046
+v 4.472349 2.325133 -0.443764
+v 4.389484 2.190421 -0.473320
+v 4.314791 2.142163 -0.540650
+v 4.342700 2.112281 -0.516692
+v 4.305411 2.059245 -0.539407
+v 4.433020 2.024714 -0.563794
+v 4.148927 2.388726 -1.376879
+v 4.101726 2.312318 -1.438163
+v 4.149438 2.340550 -1.353693
+v 4.169404 2.306276 -1.284031
+v 4.140097 2.295949 -1.367196
+v 4.129926 2.308770 -1.402259
+v 4.141759 2.279958 -1.295340
+v 4.197644 2.394643 -1.248646
+v 4.197516 2.349135 -1.253043
+v 4.199317 2.304652 -1.174540
+v 4.274886 2.220030 -0.679075
+v 4.267320 2.121987 -0.614940
+v 4.380990 2.207701 -0.839016
+v 4.354411 2.102985 -0.802580
+v 4.369751 2.298204 -0.921894
+v 4.303193 2.347123 -1.044413
+v 4.245861 2.375093 -1.141312
+v 4.218457 2.356834 -1.142444
+v 4.275405 2.319905 -1.046400
+v 4.296538 2.243779 -0.925459
+v 4.289048 2.172969 -0.858693
+v 4.211815 2.282490 -1.039137
+v 4.278045 1.976660 -0.537351
+v 4.290375 2.112337 -0.800190
+v 4.222795 2.228178 -0.952752
+v 4.197609 2.164063 -0.857433
+v 4.153175 2.084823 -0.799668
+v 4.151090 2.102939 -0.889759
+v 4.148865 2.148829 -0.986567
+v 4.154566 2.190480 -1.129552
+v 4.152557 2.235471 -1.217046
+v 4.131949 2.050757 -0.921856
+v 4.119993 2.063095 -1.049178
+v 4.126160 2.120930 -1.172520
+v 4.133175 2.175231 -1.259323
+v 4.137657 1.944837 -1.061024
+v 4.159229 1.949902 -0.923197
+v 4.143794 2.013720 -1.201386
+v 4.123290 2.086854 -1.295135
+v 4.112680 2.195089 -1.366908
+v 4.111934 2.234814 -1.399949
+v 4.304562 1.906537 -0.572242
+v 4.232341 1.903079 -0.534362
+v 4.240116 1.770049 -0.583946
+v 4.303615 1.799914 -0.610388
+v 4.377095 1.871713 -0.595743
+v 4.432610 1.878873 -0.577888
+v 4.148883 1.759918 -0.573765
+v 4.281287 2.055751 -0.787000
+v 4.354941 2.064161 -0.778851
+v 4.245225 2.008532 -0.772641
+f 1939 1940 1938
+f 1937 1938 1940
+f 1939 1941 1940
+f 1941 1942 1940
+f 1939 1943 1945
+f 1943 1944 1945
+f 1939 1945 1941
+f 1947 1941 1946
+f 1941 1945 1946
+f 1947 1948 1941
+f 1942 1941 1948
+f 1942 1948 1950
+f 1948 1949 1950
+f 1944 1951 1952
+f 1944 1952 1945
+f 1952 1946 1945
+f 1947 1946 1954
+f 1946 1953 1954
+f 1955 1948 1954
+f 1947 1954 1948
+f 1948 1955 1949
+f 1955 1956 1949
+f 1958 1954 1957
+f 1953 1957 1954
+f 1954 1958 1955
+f 1955 1958 1959
+f 1955 1959 1956
+f 1959 1960 1956
+f 1952 1961 1962
+f 1953 1946 1962
+f 1946 1952 1962
+f 1957 1953 1963
+f 1962 1963 1953
+f 1965 1957 1964
+f 1963 1964 1957
+f 1966 1958 1965
+f 1957 1965 1958
+f 1967 1959 1966
+f 1958 1966 1959
+f 1969 1965 1968
+f 1964 1968 1965
+f 1965 1969 1966
+f 1969 1970 1966
+f 1970 1971 1966
+f 1966 1971 1967
+f 1972 1973 1975
+f 1973 1974 1975
+f 1969 1976 1970
+f 1970 1976 1973
+f 1973 1976 1974
+f 1969 1968 1977
+f 1977 1978 1969
+f 1969 1978 1976
+f 1974 1976 1979
+f 1976 1978 1979
+f 1975 1974 1980
+f 1974 1979 1980
+f 1980 1981 1975
+f 1975 1981 1982
+f 1982 1981 1983
+f 1971 1970 1984
+f 1970 1973 1984
+f 1984 1973 1972
+f 1967 1985 1959
+f 1960 1959 1985
+f 1985 1967 1986
+f 1967 1971 1986
+f 1984 1987 1971
+f 1986 1971 1987
+f 1987 1984 1972
+f 1972 1975 1982
+f 1972 1989 1987
+f 1988 1987 1989
+f 1989 1972 1982
+f 1982 1983 1990
+f 1982 1990 1989
+f 1991 1989 1990
+f 1992 1988 1991
+f 1989 1991 1988
+f 1993 1988 1994
+f 1988 1992 1994
+f 1993 1986 1988
+f 1986 1987 1988
+f 1996 1995 1949
+f 1995 1950 1949
+f 1949 1956 1996
+f 1996 1956 1997
+f 1999 1995 1998
+f 1995 1996 1998
+f 1996 1997 1998
+f 2000 1985 1993
+f 1985 1986 1993
+f 2000 1960 1985
+f 1997 1956 2000
+f 1956 1960 2000
+f 1997 2000 1998
+f 2000 2001 1998
+f 2000 1993 2001
+f 1993 1994 2001
+f 1961 2002 2003
+f 2004 2003 2005
+f 2004 2005 2006
+f 2004 1961 2003
+f 2005 2003 2007
+f 2006 2005 2007
+f 1983 1981 2009
+f 1981 2008 2009
+f 2011 2012 2010
+f 2010 2012 2013
+f 2011 2014 2012
+f 1981 1980 2008
+f 1980 2015 2008
+f 2008 2015 2010
+f 2015 2016 2010
+f 2017 2011 2016
+f 2016 2011 2010
+f 1961 2004 2018
+f 2018 2004 2019
+f 2021 2020 2019
+f 2020 2018 2019
+f 1962 1961 1963
+f 1963 1961 1964
+f 1964 1961 2018
+f 1968 1964 2018
+f 1968 2018 1977
+f 2019 2004 2006
+f 2018 2020 1977
+f 1977 2020 2022
+f 1977 2022 1978
+f 2023 1978 2022
+f 2024 1979 2023
+f 1979 1978 2023
+f 1980 1979 2015
+f 2024 2015 1979
+f 2015 2024 2016
+f 2016 2024 2025
+f 2026 2025 2023
+f 2025 2024 2023
+f 2027 2026 2022
+f 2023 2022 2026
+f 2022 2020 2027
+f 2020 2028 2027
+f 2017 2016 2025
+f 2017 2025 2029
+f 2025 2026 2029
+f 2030 2021 2006
+f 2021 2019 2006
+f 2020 2021 2028
+f 2028 2021 2031
+f 2027 2032 2026
+f 2029 2026 2032
+f 2032 2027 2033
+f 2027 2028 2033
+f 2031 2034 2028
+f 2033 2028 2034
+f 2035 2033 2034
+f 2036 2032 2035
+f 2032 2033 2035
+f 2037 2029 2036
+f 2029 2032 2036
+f 2029 2037 2017
+f 2038 2017 2037
+f 2017 2038 2011
+f 2014 2011 2038
+f 2039 2035 2034
+f 2036 2035 2040
+f 2040 2035 2039
+f 2036 2040 2037
+f 2041 2037 2040
+f 2037 2041 2038
+f 2042 2038 2041
+f 2042 2014 2038
+f 2040 2039 2043
+f 2043 2039 2044
+f 2043 2045 2040
+f 2045 2041 2040
+f 2045 2046 2041
+f 2046 2042 2041
+f 2046 2047 2042
+f 2047 2014 2042
+f 2014 2047 2012
+f 2048 2012 2047
+f 2048 2013 2012
+f 2030 2049 2050
+f 2051 2050 2052
+f 2050 2049 2052
+f 2006 2053 2030
+f 2049 2030 2053
+f 2006 2007 2053
+f 2053 2007 2054
+f 1998 2050 2055
+f 2055 2050 2051
+f 2031 2021 2056
+f 2021 2057 2056
+f 2056 2057 2058
+f 2034 2031 2056
+f 2056 2044 2034
+f 2039 2034 2044
+f 2057 2021 2030
+f 2057 2030 2058
+f 2030 2050 2058
+f 2044 2056 2058
+v 5.998088 1.231874 -0.107334
+v 5.959462 1.157227 -0.187097
+v 5.895899 1.182730 -0.164705
+f 2059 2060 2061
+v 5.998088 1.231874 -0.107334
+v 5.961686 1.110978 -0.090324
+v 5.950684 1.082725 -0.175648
+v 5.959462 1.157227 -0.187097
+v 5.672385 1.007694 -0.341778
+v 5.681086 1.054964 -0.355860
+v 5.763952 1.062109 -0.338641
+v 5.755282 1.004149 -0.307505
+f 2062 2063 2065
+f 2063 2064 2065
+f 2068 2069 2067
+f 2066 2067 2069
+v 5.837875 1.141493 -0.305184
+v 5.773410 1.225861 -0.323025
+v 5.840665 1.221942 -0.187128
+v 5.849792 1.193480 -0.181047
+v 5.535184 0.980180 -0.341257
+v 5.573803 0.952578 -0.243886
+v 5.546347 0.916044 -0.246782
+v 5.480649 0.941387 -0.316248
+f 2073 2070 2072
+f 2070 2071 2072
+f 2077 2074 2076
+f 2074 2075 2076
+v 5.647186 1.394606 -0.257833
+v 5.685194 1.452202 -0.188749
+v 5.730427 1.435668 -0.209848
+v 5.710154 1.360653 -0.290072
+v 5.250485 1.123029 -0.385234
+v 5.241466 1.040469 -0.383965
+v 5.011084 1.066770 -0.458562
+v 4.991713 1.163096 -0.504149
+v 4.567896 1.149805 -0.642484
+v 4.449011 1.260929 -0.647431
+v 4.522247 1.398278 -0.644892
+v 4.641547 1.285422 -0.622034
+v 4.697024 1.862575 -0.604048
+v 4.688114 2.046378 -0.604518
+v 4.728963 2.036146 -0.614307
+v 4.742358 1.882232 -0.621650
+v 4.842883 2.021333 -0.638025
+v 4.861611 2.001639 -0.621913
+v 4.824747 1.946835 -0.626358
+v 4.760921 1.881357 -0.613120
+f 2081 2078 2080
+f 2078 2079 2080
+f 2082 2083 2085
+f 2083 2084 2085
+f 2088 2089 2087
+f 2086 2087 2089
+f 2091 2092 2090
+f 2090 2092 2093
+f 2097 2094 2096
+f 2094 2095 2096
+v 4.897808 1.946794 -0.628057
+v 4.861611 2.001639 -0.621913
+v 4.935561 2.016016 -0.585700
+v 4.925394 1.955229 -0.618837
+f 2100 2101 2099
+f 2098 2099 2101
+v 4.760921 1.881357 -0.613120
+v 4.861618 1.854067 -0.618095
+v 4.852582 1.816115 -0.603105
+v 4.935561 2.016016 -0.585700
+v 4.935880 2.051665 -0.572853
+v 4.991746 2.009819 -0.523206
+v 4.973133 1.992779 -0.533466
+v 4.751519 2.039658 -0.634134
+v 4.788476 2.028047 -0.608619
+v 4.982364 1.873300 -0.536190
+v 5.001903 1.914398 -0.486724
+v 5.011430 1.875569 -0.463205
+v 4.991709 1.844295 -0.520761
+v 4.881574 2.094571 -0.539949
+v 4.918466 2.084725 -0.532713
+v 4.636582 2.263383 -0.471997
+v 4.739441 2.299169 -0.369987
+v 4.837331 2.235678 -0.479332
+v 4.744050 2.179337 -0.556057
+v 5.057495 2.002751 -0.451974
+v 5.067202 2.027704 -0.422291
+v 5.095375 1.961238 -0.401516
+v 5.075994 1.900999 -0.443793
+v 4.082988 2.175805 -1.450930
+v 4.046673 2.341349 -1.452530
+v 4.101726 2.312318 -1.438163
+v 4.129926 2.308770 -1.402259
+v 4.111934 2.234814 -1.399949
+v 4.159229 1.949902 -0.923197
+v 4.245225 2.008532 -0.772641
+v 4.094112 1.889281 -0.578435
+v 4.150297 1.820575 -0.917046
+v 4.137657 1.944837 -1.061024
+v 4.127903 1.828359 -1.090512
+v 4.143794 2.013720 -1.201386
+v 4.152166 1.868775 -1.225002
+v 4.123290 2.086854 -1.295135
+v 4.103303 2.038565 -1.363737
+v 4.112680 2.195089 -1.366908
+f 2102 2103 2104
+f 2106 2107 2105
+f 2105 2107 2108
+f 2109 2110 2102
+f 2113 2114 2112
+f 2111 2112 2114
+f 2107 2113 2112
+f 2115 2116 2106
+f 2118 2119 2117
+f 2117 2119 2120
+f 2124 2121 2123
+f 2121 2122 2123
+f 2125 2126 2127
+f 2127 2128 2125
+f 2125 2128 2129
+f 2133 2130 2132
+f 2130 2131 2132
+f 2135 2134 2133
+f 2134 2130 2133
+f 2136 2134 2137
+f 2134 2135 2137
+f 2137 2139 2136
+f 2138 2136 2139
+f 2125 2140 2139
+f 2140 2138 2139
+f 2129 2140 2125
+v 4.854957 2.660227 -0.924310
+v 4.863709 2.722151 -0.936660
+v 5.096148 2.759720 -0.774729
+f 2141 2142 2143
+v 4.059885 1.860460 -0.470087
+v 4.094112 1.889281 -0.578435
+v 4.148883 1.759918 -0.573765
+v 4.076852 1.746601 -0.527436
+v 4.126565 0.642027 0.000000
+v 4.120842 0.627141 -0.185461
+v 4.359048 0.700414 -0.166651
+v 4.380854 0.704574 -0.000130
+v 3.881998 1.764428 -0.476337
+v 3.886058 1.550141 -0.504830
+v 4.067576 1.572668 -0.534997
+v 3.988510 1.297806 -0.539537
+v 4.085564 1.288885 -0.544406
+v 4.041657 1.039756 -0.496922
+v 4.141189 1.008775 -0.499342
+v 4.068249 0.798926 -0.400813
+v 4.216374 0.852328 -0.405873
+v 4.105198 0.672581 -0.300001
+v 4.319799 0.731007 -0.291212
+v 3.745669 2.266001 -0.241930
+v 3.828001 2.352540 -0.233341
+v 3.870548 2.292106 -0.368964
+v 3.758215 2.206683 -0.323051
+v 3.727093 2.308406 -0.150049
+v 3.716360 2.343387 0.000000
+v 3.787342 2.396113 -0.001159
+v 3.922437 1.972461 -0.483563
+v 3.814876 1.968416 -0.443000
+v 3.823349 2.141733 -0.428356
+f 2144 2145 2147
+f 2145 2146 2147
+f 2149 2150 2148
+f 2148 2150 2151
+f 2152 2144 2147
+f 2153 2152 2154
+f 2152 2147 2154
+f 2154 2156 2153
+f 2155 2153 2156
+f 2158 2157 2156
+f 2157 2155 2156
+f 2157 2158 2159
+f 2159 2158 2160
+f 2162 2161 2160
+f 2161 2159 2160
+f 2150 2149 2162
+f 2149 2161 2162
+f 2164 2165 2163
+f 2163 2165 2166
+f 2164 2167 2169
+f 2167 2168 2169
+f 2163 2167 2164
+f 2170 2144 2152
+f 2170 2152 2171
+f 2172 2170 2171
+f 2172 2171 2166
+f 2165 2172 2166
+v 4.821336 2.621498 -0.789636
+v 4.829566 2.580797 -0.821827
+v 5.096148 2.759720 -0.774729
+v 4.856249 2.593812 -0.867067
+f 2173 2174 2175
+f 2174 2176 2175
+v 4.245225 2.008532 -0.772641
+v 4.232341 1.903079 -0.534362
+v 4.094112 1.889281 -0.578435
+v 1.655948 -2.520927 -0.844269
+v 1.678986 -2.513137 -0.891745
+v 1.718315 -2.775468 -0.921796
+v 1.700797 -2.794792 -0.824250
+v 1.734568 -2.965876 -0.986396
+v 1.705953 -3.006628 -0.832630
+v -1.305099 -1.708460 -0.484230
+v -1.108758 -1.770749 -0.473033
+v -0.977375 -1.793126 -0.498747
+v -0.972514 -1.822778 -0.372649
+v -1.406693 -1.697325 -0.450399
+v -1.397474 -1.693815 -0.570541
+v -1.266738 -1.691944 -0.557922
+f 2177 2178 2179
+f 2183 2180 2182
+f 2180 2181 2182
+f 2184 2185 2182
+f 2182 2185 2183
+f 2186 2187 2189
+f 2187 2188 2189
+f 2190 2191 2186
+f 2191 2192 2186
+v -3.139394 -1.687482 -0.638546
+v -3.008323 -1.759271 -0.655672
+v -2.941731 -1.787431 -0.442574
+v -3.120907 -1.707924 -0.431829
+v -2.709403 -1.879947 -0.508775
+v -2.811581 -1.798210 -0.712737
+v -2.699966 -1.850397 -0.570070
+f 2195 2196 2194
+f 2193 2194 2196
+f 2194 2197 2195
+f 2197 2194 2199
+f 2194 2198 2199
+v -3.392806 1.769365 0.000000
+v -3.413372 1.871604 -0.142309
+v -3.358510 1.810253 -0.380095
+v -3.348274 1.767738 -0.000085
+v -3.380836 1.819691 -0.123273
+v 4.149438 2.340550 -1.353693
+v 4.129926 2.308770 -1.402259
+v 4.101726 2.312318 -1.438163
+v 4.148927 2.388726 -1.376879
+v -2.811581 -1.798210 -0.712737
+v -3.008323 -1.759271 -0.655672
+v -3.066022 -1.953125 -0.719516
+v -2.964215 -1.978727 -0.776572
+v -3.139394 -1.687482 -0.638546
+v -3.211005 -1.850398 -0.700723
+v 2.407309 -0.974980 0.805091
+v 2.410367 -0.777999 0.841105
+v 2.292449 -0.871852 0.882400
+v 2.229345 -0.992723 0.862826
+v 2.520417 -0.954785 0.739445
+v 2.539200 -0.727778 0.750475
+v 2.637655 -0.768176 0.637039
+v 2.514167 -1.077721 0.706614
+v 2.669281 -0.930664 0.557166
+v 2.386465 -1.116066 0.761367
+v 2.180012 -1.130557 0.821812
+v 2.158051 -1.209613 0.783941
+v 2.354287 -1.193746 0.735189
+v 2.126237 -1.330172 0.721011
+v 2.318787 -1.294090 0.673863
+v 2.274533 -1.433487 0.567366
+v 2.457060 -1.400958 0.539866
+v 2.486533 -1.274971 0.627822
+v 2.549322 -1.335209 0.535156
+v 2.617970 -1.235597 0.520238
+v 2.670253 -1.108365 0.544018
+v 2.510841 -1.158786 0.678057
+v 2.710721 -0.830091 0.532493
+v 2.757946 -1.099958 0.471684
+v 2.857666 -0.930625 0.391195
+v 2.803736 -1.255869 0.438328
+v 2.847364 -1.103812 0.402301
+v 2.740886 -1.339225 0.463604
+v 2.663024 -1.440487 0.478149
+v 2.515314 -1.507063 0.483275
+v 2.422296 -1.510915 0.494169
+v 2.249663 -1.492705 0.531270
+v 2.079600 -1.473377 0.654997
+v 2.928787 -1.107467 0.312054
+v 2.960118 -0.941827 0.284743
+v 2.893096 -1.302168 0.332049
+v 2.824356 -1.407256 0.355013
+v 2.721135 -1.520418 0.362378
+v 2.545261 -1.593300 0.386310
+v 2.396607 -1.593239 0.389972
+v 2.243492 -1.584783 0.431143
+v 2.048200 -1.581983 0.555832
+v 2.931756 -1.129655 0.000000
+v 2.970902 -0.959664 0.000000
+v 2.896234 -1.319560 0.000000
+v 2.821376 -1.431534 0.000000
+v 2.706963 -1.528854 0.000000
+v 2.534227 -1.617078 0.000000
+v 2.348182 -1.624595 0.000000
+v 2.167167 -1.596326 0.000000
+v 1.920432 -1.567396 0.000000
+v 2.835437 -0.231101 0.577890
+v 2.736198 -0.346225 0.659345
+v 2.881063 -0.493146 0.521968
+v 2.986408 -0.413503 0.428964
+v 2.910769 -0.638444 0.431191
+v 2.825540 -0.567578 0.552597
+v 2.688131 -0.517509 0.672975
+v 2.647368 -0.611550 0.669485
+v 2.618307 -0.549092 0.805491
+v 2.993075 -0.708434 0.342596
+v 3.045715 -0.767786 0.261741
+v 3.065544 -0.788768 0.000000
+v 3.118124 -0.703925 0.000000
+v 3.107533 -0.691019 0.264602
+v 3.053144 -0.609681 0.326931
+f 2200 2201 2202
+f 2201 2200 2204
+f 2203 2204 2200
+f 2207 2208 2206
+f 2205 2206 2208
+f 2209 2210 2212
+f 2210 2211 2212
+f 2210 2213 2211
+f 2213 2214 2211
+f 2216 2217 2215
+f 2215 2217 2218
+f 2220 2216 2219
+f 2219 2216 2215
+f 2221 2220 2219
+f 2222 2223 2219
+f 2219 2223 2221
+f 2224 2222 2215
+f 2215 2222 2219
+f 2225 2224 2218
+f 2218 2224 2215
+f 2224 2225 2227
+f 2226 2227 2225
+f 2226 2228 2227
+f 2228 2229 2227
+f 2230 2229 2228
+f 2230 2231 2229
+f 2231 2232 2229
+f 2233 2232 2231
+f 2234 2232 2233
+f 2235 2236 2234
+f 2236 2232 2234
+f 2229 2232 2227
+f 2227 2232 2236
+f 2227 2236 2224
+f 2236 2222 2224
+f 2223 2222 2235
+f 2235 2222 2236
+f 2237 2221 2223
+f 2238 2239 2235
+f 2235 2234 2238
+f 2234 2240 2238
+f 2240 2241 2238
+f 2239 2238 2241
+f 2242 2240 2234
+f 2243 2242 2233
+f 2233 2242 2234
+f 2244 2243 2231
+f 2231 2243 2233
+f 2245 2244 2231
+f 2231 2230 2245
+f 2230 2246 2245
+f 2247 2246 2228
+f 2228 2246 2230
+f 2249 2239 2248
+f 2241 2248 2239
+f 2248 2241 2250
+f 2240 2250 2241
+f 2250 2240 2251
+f 2242 2251 2240
+f 2243 2252 2251
+f 2253 2252 2244
+f 2244 2252 2243
+f 2254 2253 2245
+f 2245 2253 2244
+f 2246 2255 2245
+f 2255 2254 2245
+f 2255 2246 2256
+f 2247 2256 2246
+f 2248 2257 2249
+f 2257 2258 2249
+f 2259 2257 2250
+f 2250 2257 2248
+f 2251 2260 2250
+f 2260 2259 2250
+f 2261 2260 2252
+f 2252 2260 2251
+f 2262 2261 2253
+f 2253 2261 2252
+f 2263 2262 2254
+f 2254 2262 2253
+f 2264 2263 2255
+f 2255 2263 2254
+f 2256 2265 2255
+f 2265 2264 2255
+f 2266 2267 2268
+f 2268 2269 2266
+f 2270 2269 2268
+f 2268 2271 2270
+f 2272 2271 2268
+f 2273 2220 2221
+f 2274 2220 2273
+f 2273 2272 2274
+f 2270 2271 2237
+f 2237 2271 2221
+f 2239 2270 2237
+f 2275 2270 2239
+f 2239 2249 2275
+f 2249 2276 2275
+f 2249 2258 2276
+f 2258 2277 2276
+f 2279 2276 2278
+f 2278 2276 2277
+f 2223 2235 2239
+f 2223 2239 2237
+f 2271 2272 2273
+f 2271 2273 2221
+f 2269 2270 2280
+f 2270 2275 2280
+f 2280 2275 2279
+f 2276 2279 2275
+v -2.306662 -1.116976 0.961238
+v -2.119856 -1.128800 0.970960
+v -2.033406 -0.910030 0.964220
+v -2.031698 -1.097344 0.966701
+v -1.782298 -1.020581 0.943381
+v -2.337617 -1.334842 0.966761
+v -2.462835 -1.305500 0.966395
+v -2.161843 -1.325837 0.957465
+v -2.042059 -1.312976 0.940911
+v -1.776785 -1.275107 0.914703
+v -1.709172 -1.283232 0.897427
+v -1.456655 -1.295527 0.894240
+v -2.417777 -1.553136 0.887222
+v -2.591357 -1.510845 0.885470
+v -2.223917 -1.541268 0.879260
+v -2.049879 -1.562369 0.829319
+v -1.778934 -1.550199 0.776454
+v -1.777628 -1.473076 0.845827
+v -1.686329 -1.414405 0.869373
+v -1.592146 -1.408592 0.838483
+v -1.552229 -1.555077 0.735708
+v -1.659758 -1.544361 0.788181
+v -1.376186 -1.661988 0.718954
+v -1.366873 -1.340211 0.907567
+v -1.200688 -1.577575 0.799188
+v -1.198513 -1.456102 0.885435
+v -0.953236 -1.545941 0.899180
+f 2281 2282 2283
+f 2284 2283 2282
+f 2285 2283 2284
+f 2286 2281 2287
+f 2286 2288 2281
+f 2288 2282 2281
+f 2289 2284 2288
+f 2284 2282 2288
+f 2285 2284 2290
+f 2290 2284 2289
+f 2291 2285 2290
+f 2292 2285 2291
+f 2294 2293 2287
+f 2293 2286 2287
+f 2295 2288 2293
+f 2288 2286 2293
+f 2296 2289 2295
+f 2289 2288 2295
+f 2289 2296 2298
+f 2297 2298 2296
+f 2290 2289 2298
+f 2298 2299 2290
+f 2299 2291 2290
+f 2292 2291 2300
+f 2300 2291 2299
+f 2301 2292 2300
+f 2300 2302 2301
+f 2299 2302 2300
+f 2302 2299 2297
+f 2298 2297 2299
+f 2303 2304 2301
+f 2304 2292 2301
+f 2303 2305 2304
+f 2305 2306 2304
+f 2307 2306 2305
+v -1.200688 -1.577575 0.799188
+v -1.226563 -1.655159 0.687343
+v -1.091175 -1.707120 0.727242
+v -0.953236 -1.545941 0.899180
+v -1.376186 -1.661988 0.718954
+v -1.266738 -1.691944 0.557922
+v -1.089642 -1.757196 0.685154
+v -0.972089 -1.774507 0.768570
+v -0.812845 -1.785424 0.768511
+v -0.680046 -1.768325 0.819080
+v -0.535144 -1.615983 0.920556
+v -0.564074 -1.789401 0.803191
+v -0.422877 -1.751200 0.823423
+v -0.078470 -1.688266 0.800230
+v -0.063012 -1.583021 0.865082
+v -0.543078 -1.810473 0.563825
+v -0.094135 -1.769086 0.556924
+v -0.977375 -1.793126 0.498747
+v -1.108758 -1.770749 0.473033
+v -1.305099 -1.708460 0.484230
+v -1.397474 -1.693815 0.570541
+f 2311 2308 2310
+f 2308 2309 2310
+f 2312 2309 2308
+f 2313 2314 2309
+f 2314 2310 2309
+f 2315 2311 2310
+f 2316 2311 2315
+f 2318 2311 2317
+f 2317 2311 2316
+f 2319 2318 2317
+f 2320 2318 2319
+f 2318 2320 2322
+f 2321 2322 2320
+f 2323 2324 2320
+f 2324 2321 2320
+f 2320 2319 2323
+f 2317 2323 2319
+f 2325 2323 2316
+f 2316 2323 2317
+f 2315 2310 2314
+f 2313 2326 2314
+f 2326 2325 2314
+f 2313 2327 2326
+f 2309 2312 2313
+f 2328 2313 2312
+v -1.376186 -1.661988 0.718954
+v -1.480217 -1.656600 0.606638
+v -1.397474 -1.693815 0.570541
+v -1.552229 -1.555077 0.735708
+v -1.601625 -1.593321 0.605607
+v -1.519339 -1.653776 0.501741
+v -1.406693 -1.697325 0.450399
+v -1.576196 -1.696317 0.358146
+v -1.386502 -1.718441 0.350823
+f 2329 2330 2331
+f 2332 2330 2329
+f 2333 2330 2332
+f 2334 2330 2333
+f 2335 2331 2334
+f 2331 2330 2334
+f 2336 2334 2333
+f 2336 2337 2334
+f 2337 2335 2334
+v -1.305099 -1.708460 0.484230
+v -1.406693 -1.697325 0.450399
+v -1.386502 -1.718441 0.350823
+v -0.972514 -1.822778 0.372649
+v -0.523838 -1.850065 0.388007
+v -0.543078 -1.810473 0.563825
+v -0.977375 -1.793126 0.498747
+v -0.112666 -1.806584 0.383324
+v -0.094135 -1.769086 0.556924
+v 0.480235 -1.631521 0.401961
+v 0.489819 -1.524947 0.672392
+v -0.155114 -1.828285 0.000000
+v 0.446550 -1.672950 0.000000
+v -0.530369 -1.860806 0.000000
+v -0.956007 -1.825728 0.000000
+v -1.395728 -1.723811 0.000000
+f 2338 2339 2340
+f 2341 2338 2340
+f 2343 2344 2342
+f 2342 2344 2341
+f 2346 2343 2345
+f 2345 2343 2342
+f 2348 2346 2347
+f 2347 2346 2345
+f 2347 2345 2350
+f 2345 2349 2350
+f 2345 2342 2349
+f 2342 2351 2349
+f 2342 2341 2351
+f 2341 2352 2351
+f 2352 2341 2353
+f 2340 2353 2341
+v -1.576196 -1.696317 0.358146
+v -1.610025 -1.711571 0.000000
+v -1.395728 -1.723811 0.000000
+v -1.386502 -1.718441 0.350823
+v -1.764045 -1.764987 0.406586
+v -1.799827 -1.753136 0.000000
+v -1.601625 -1.593321 0.605607
+v -1.747790 -1.667608 0.606340
+v -1.778934 -1.550199 0.776454
+v -1.659758 -1.544361 0.788181
+v -1.552229 -1.555077 0.735708
+v -2.508885 -1.719933 0.721675
+v -2.417777 -1.553136 0.887222
+v -2.591357 -1.510845 0.885470
+v -2.734184 -1.717948 0.749581
+v -2.267049 -1.753901 0.662106
+v -2.223917 -1.541268 0.879260
+v -2.037371 -1.736360 0.656787
+v -2.049879 -1.562369 0.829319
+v -1.936032 -1.829617 0.488916
+v -1.883160 -1.829718 0.401567
+v -2.027242 -1.813012 0.555232
+v -2.126375 -1.866497 0.502895
+v -2.317557 -1.874200 0.470587
+v -2.176551 -1.873816 0.445782
+v -2.466779 -1.857679 0.570461
+v -2.446375 -1.893261 0.494110
+v -2.547737 -1.833025 0.609321
+v -2.647220 -1.844010 0.594347
+v -2.811581 -1.798210 0.712737
+v -2.699966 -1.850397 0.570070
+v -2.892162 -1.781087 0.000000
+v -2.684452 -1.891207 0.447388
+v -2.709403 -1.879947 0.508775
+v -2.941731 -1.787431 0.442574
+v -2.656867 -1.853045 0.000000
+v -2.614084 -1.905005 0.404925
+v -2.348005 -1.869142 0.000000
+v -2.503818 -1.909806 0.431456
+v -2.147113 -1.903198 0.362462
+v -2.092921 -1.839622 0.000000
+v -2.062725 -1.884246 0.307336
+v -1.946306 -1.872735 0.344251
+f 2355 2356 2354
+f 2354 2356 2357
+f 2358 2359 2354
+f 2359 2355 2354
+f 2360 2361 2354
+f 2354 2361 2358
+f 2362 2361 2360
+f 2360 2363 2362
+f 2364 2363 2360
+f 2368 2365 2367
+f 2365 2366 2367
+f 2369 2370 2365
+f 2370 2366 2365
+f 2369 2371 2370
+f 2371 2372 2370
+f 2361 2362 2371
+f 2362 2372 2371
+f 2374 2358 2373
+f 2373 2358 2361
+f 2371 2375 2361
+f 2361 2375 2373
+f 2376 2375 2369
+f 2369 2375 2371
+f 2377 2378 2369
+f 2378 2376 2369
+f 2377 2369 2380
+f 2369 2379 2380
+f 2365 2381 2369
+f 2381 2379 2369
+f 2368 2382 2365
+f 2382 2381 2365
+f 2383 2384 2368
+f 2384 2382 2368
+f 2387 2388 2386
+f 2385 2386 2388
+f 2386 2385 2390
+f 2389 2390 2385
+f 2389 2391 2390
+f 2391 2392 2390
+f 2377 2380 2391
+f 2380 2392 2391
+f 2377 2391 2378
+f 2391 2393 2378
+f 2395 2393 2394
+f 2394 2393 2391
+f 2394 2359 2395
+f 2359 2396 2395
+f 2358 2374 2359
+f 2374 2396 2359
+v -0.977375 -1.793126 0.498747
+v -0.972089 -1.774507 0.768570
+v -1.089642 -1.757196 0.685154
+v -0.812845 -1.785424 0.768511
+f 2397 2398 2399
+f 2398 2397 2400
+v -3.304804 -1.582192 0.643445
+v -3.314868 -1.599081 0.439626
+v -3.120907 -1.707924 0.431829
+v -3.139394 -1.687482 0.638546
+v -3.387254 -1.486027 0.672861
+v -3.442085 -1.484120 0.406377
+v -3.533910 -1.330455 0.568246
+v -3.557869 -1.325941 0.378030
+v -3.631179 -1.157838 0.505610
+v -3.639586 -1.140102 0.333800
+v -3.667859 -0.964867 0.464702
+v -3.686518 -0.955181 0.320349
+v -3.665774 -0.734080 0.446286
+v -3.676599 -0.729578 0.330724
+v -3.595973 -0.346391 0.426453
+v -3.616627 -0.350374 0.338492
+v -3.529709 -0.065998 0.437217
+v -3.570243 -0.060093 0.344854
+v -3.516840 0.149002 0.430359
+v -3.535416 0.191408 0.338478
+v -3.536654 0.442277 0.322000
+v -3.544507 0.467147 0.000000
+v -3.552320 0.219613 0.000000
+v -3.583763 -0.052271 0.000000
+v -3.673607 -0.720796 0.000000
+v -3.637643 -0.356271 0.000000
+v -3.678793 -0.926816 0.000000
+v -3.650579 -1.142448 0.000000
+v -3.522115 -1.366623 0.000000
+v -3.417689 -1.494416 0.000000
+v -3.271035 -1.609292 0.000000
+v -3.110300 -1.691720 0.000000
+v -2.892162 -1.781087 0.000000
+v -2.941731 -1.787431 0.442574
+v -3.470778 -0.078218 0.546398
+v -3.526766 -0.317542 0.560837
+v -3.569993 -0.731989 0.649435
+v -3.550120 -0.984868 0.675228
+v -3.492599 -1.180646 0.692282
+v -3.335942 -1.365685 0.724590
+v -3.438226 -0.721479 0.728141
+v -3.283698 -0.730967 0.793898
+v -3.415655 -0.308965 0.671045
+v -3.355398 -0.969157 0.766213
+v -3.279790 -1.162072 0.784602
+v -3.251210 -0.948205 0.819868
+v -3.556552 0.704883 0.280630
+v -3.566995 0.656967 0.000000
+v -3.578170 0.837714 0.288502
+v -3.599077 0.796217 0.000000
+f 2403 2404 2402
+f 2401 2402 2404
+f 2405 2406 2401
+f 2406 2402 2401
+f 2406 2405 2408
+f 2407 2408 2405
+f 2407 2409 2408
+f 2409 2410 2408
+f 2409 2411 2410
+f 2411 2412 2410
+f 2412 2411 2414
+f 2413 2414 2411
+f 2415 2416 2413
+f 2416 2414 2413
+f 2416 2415 2418
+f 2417 2418 2415
+f 2420 2418 2419
+f 2419 2418 2417
+f 2421 2420 2419
+f 2420 2421 2423
+f 2422 2423 2421
+f 2423 2424 2420
+f 2424 2418 2420
+f 2416 2426 2414
+f 2425 2414 2426
+f 2414 2425 2412
+f 2427 2412 2425
+f 2410 2412 2428
+f 2428 2412 2427
+f 2429 2408 2428
+f 2408 2410 2428
+f 2406 2408 2430
+f 2430 2408 2429
+f 2402 2406 2431
+f 2431 2406 2430
+f 2402 2431 2403
+f 2432 2403 2431
+f 2433 2434 2432
+f 2434 2403 2432
+f 2426 2416 2424
+f 2416 2418 2424
+f 2417 2435 2419
+f 2415 2436 2417
+f 2436 2435 2417
+f 2437 2436 2413
+f 2413 2436 2415
+f 2438 2437 2411
+f 2411 2437 2413
+f 2439 2438 2409
+f 2409 2438 2411
+f 2440 2439 2407
+f 2407 2439 2409
+f 2405 2440 2407
+f 2441 2442 2443
+f 2436 2443 2435
+f 2436 2437 2443
+f 2437 2441 2443
+f 2444 2441 2438
+f 2438 2441 2437
+f 2439 2445 2438
+f 2445 2444 2438
+f 2440 2445 2439
+f 2446 2444 2445
+f 2447 2448 2421
+f 2448 2422 2421
+f 2450 2448 2449
+f 2449 2448 2447
+f 2444 2446 2441
+f 2442 2441 2446
+v 1.806371 -2.949735 0.984058
+v 1.771416 -2.769024 0.946100
+v 1.718315 -2.775468 0.921796
+v 1.734568 -2.965876 0.986396
+v 2.021366 -2.881725 0.945561
+v 1.960643 -2.712860 0.900890
+v 1.880971 -2.733242 0.890200
+v 1.911792 -2.895773 0.950117
+v 2.057496 -2.887282 0.844225
+v 1.994078 -2.713047 0.824553
+v 1.735077 -3.022732 0.972751
+v 1.721745 -3.116887 0.979111
+v 1.802387 -3.089615 0.961851
+v 1.811797 -3.135641 0.933096
+f 2454 2451 2453
+f 2451 2452 2453
+f 2455 2456 2458
+f 2456 2457 2458
+f 2459 2460 2455
+f 2460 2456 2455
+f 2461 2451 2454
+f 2462 2463 2461
+f 2464 2463 2462
+v 2.031262 -3.256709 1.111122
+v 2.148880 -3.221616 1.076203
+v 2.110033 -3.148257 1.068816
+v 1.970051 -3.141862 1.065178
+v 2.138771 -3.397683 1.214726
+v 2.247981 -3.342804 1.127459
+v 2.254361 -3.550931 1.235118
+v 2.343303 -3.507846 1.195262
+v 1.981186 -3.441282 1.180532
+v 2.025468 -3.556842 1.204841
+v 1.926176 -3.288880 1.093746
+v 1.886443 -3.191742 1.047318
+v 2.201939 -3.226457 0.996503
+v 2.281229 -3.338250 1.043475
+v 2.170039 -3.134504 0.978866
+v 2.217369 -3.156093 0.888927
+v 2.113587 -3.011851 0.851648
+v 2.091539 -3.032437 0.947029
+v 1.865135 -3.353827 1.054981
+v 1.841888 -3.246003 1.014774
+v 1.919391 -3.487078 1.110869
+v 1.980621 -3.043895 0.964237
+f 2468 2465 2467
+f 2465 2466 2467
+f 2465 2469 2466
+f 2469 2470 2466
+f 2470 2469 2472
+f 2471 2472 2469
+f 2474 2471 2473
+f 2469 2473 2471
+f 2469 2465 2473
+f 2465 2475 2473
+f 2465 2468 2475
+f 2468 2476 2475
+f 2466 2470 2477
+f 2477 2470 2478
+f 2467 2466 2479
+f 2479 2466 2477
+f 2480 2481 2479
+f 2481 2482 2479
+f 2475 2476 2483
+f 2483 2476 2484
+f 2475 2483 2473
+f 2473 2483 2485
+f 2485 2474 2473
+f 2467 2479 2486
+v 2.091539 -3.032437 0.947029
+v 2.113587 -3.011851 0.851648
+v 2.057496 -2.887282 0.844225
+v 2.021366 -2.881725 0.945561
+v 1.880971 -2.733242 0.890200
+v 1.830669 -2.736121 0.903313
+v 1.848272 -2.927260 0.996966
+v 1.911792 -2.895773 0.950117
+v 1.771416 -2.769024 0.946100
+v 1.806371 -2.949735 0.984058
+v 1.709173 -3.133145 0.807940
+v 1.721745 -3.116887 0.979111
+v 1.735077 -3.022732 0.972751
+v 1.705953 -3.006628 0.832630
+v 1.806407 -3.173343 0.834455
+v 1.811797 -3.135641 0.933096
+f 2490 2487 2489
+f 2487 2488 2489
+f 2493 2494 2492
+f 2491 2492 2494
+f 2492 2495 2493
+f 2493 2495 2496
+f 2498 2499 2497
+f 2497 2499 2500
+f 2498 2497 2502
+f 2501 2502 2497
+v 1.832790 -3.296508 0.865078
+v 1.841888 -3.246003 1.014774
+v 1.811797 -3.135641 0.933096
+v 1.806407 -3.173343 0.834455
+v 2.078928 -3.584991 0.917088
+v 2.025468 -3.556842 1.204841
+v 1.919391 -3.487078 1.110869
+v 1.933899 -3.546253 0.912438
+v 1.839523 -3.405292 0.883488
+v 1.865135 -3.353827 1.054981
+f 2504 2505 2503
+f 2503 2505 2506
+f 2507 2508 2510
+f 2508 2509 2510
+f 2512 2504 2511
+f 2511 2504 2503
+f 2510 2509 2511
+f 2509 2512 2511
+v 1.900481 -3.131932 0.728621
+v 1.806407 -3.173343 0.834455
+v 1.709173 -3.133145 0.807940
+v 1.741854 -3.114181 0.700705
+f 2513 2514 2516
+f 2514 2515 2516
+v 1.806407 -3.173343 0.834455
+v 1.900481 -3.131932 0.728621
+v 1.929730 -3.298418 0.689538
+v 1.832790 -3.296508 0.865078
+v 1.941325 -3.434803 0.701314
+v 1.839523 -3.405292 0.883488
+v 2.002745 -3.523420 0.688103
+v 1.933899 -3.546253 0.912438
+v 2.126553 -3.549679 0.701005
+v 2.078928 -3.584991 0.917088
+v 2.244147 -3.545557 0.732888
+v 2.197935 -3.583948 0.936437
+f 2519 2520 2518
+f 2517 2518 2520
+f 2519 2521 2520
+f 2521 2522 2520
+f 2524 2522 2523
+f 2523 2522 2521
+f 2524 2523 2526
+f 2525 2526 2523
+f 2526 2525 2528
+f 2527 2528 2525
+v 1.776024 -2.980086 0.707575
+v 1.741854 -3.114181 0.700705
+v 1.709173 -3.133145 0.807940
+v 1.705953 -3.006628 0.832630
+v 1.700797 -2.794792 0.824250
+v 1.736425 -2.743683 0.736866
+v 1.911792 -2.895773 0.950117
+v 1.980621 -3.043895 0.964237
+v 2.091539 -3.032437 0.947029
+v 2.021366 -2.881725 0.945561
+f 2529 2530 2532
+f 2530 2531 2532
+f 2534 2529 2533
+f 2532 2533 2529
+f 2537 2538 2536
+f 2535 2536 2538
+v 1.970051 -3.141862 1.065178
+v 2.110033 -3.148257 1.068816
+v 1.980621 -3.043895 0.964237
+v 1.898573 -3.068274 0.994338
+f 2540 2541 2539
+f 2539 2541 2542
+v 1.911792 -2.895773 0.950117
+v 1.848272 -2.927260 0.996966
+v 1.898573 -3.068274 0.994338
+v 1.980621 -3.043895 0.964237
+v 1.806371 -2.949735 0.984058
+v 1.855134 -3.083228 0.986129
+f 2546 2543 2545
+f 2543 2544 2545
+f 2544 2547 2545
+f 2547 2548 2545
+v 1.886443 -3.191742 1.047318
+v 1.970051 -3.141862 1.065178
+v 1.898573 -3.068274 0.994338
+v 1.855134 -3.083228 0.986129
+v 1.841888 -3.246003 1.014774
+v 1.811797 -3.135641 0.933096
+f 2550 2551 2549
+f 2549 2551 2552
+f 2553 2549 2554
+f 2549 2552 2554
+v 1.811797 -3.135641 0.933096
+v 1.855134 -3.083228 0.986129
+v 1.802387 -3.089615 0.961851
+v 1.806371 -2.949735 0.984058
+v 1.735077 -3.022732 0.972751
+v 1.734568 -2.965876 0.986396
+v 1.705953 -3.006628 0.832630
+f 2555 2556 2557
+f 2558 2559 2556
+f 2557 2556 2559
+f 2560 2561 2559
+v 2.187495 -3.161535 0.800285
+v 2.073690 -3.020848 0.782654
+v 2.113587 -3.011851 0.851648
+v 2.217369 -3.156093 0.888927
+f 2565 2562 2564
+f 2562 2563 2564
+v 2.073690 -3.020848 0.782654
+v 2.001343 -2.847715 0.762517
+v 2.057496 -2.887282 0.844225
+v 2.113587 -3.011851 0.851648
+f 2567 2568 2566
+f 2566 2568 2569
+v 2.201939 -3.226457 0.996503
+v 2.236407 -3.220054 0.892030
+v 2.217369 -3.156093 0.888927
+v 2.170039 -3.134504 0.978866
+v 2.343303 -3.507846 1.195262
+v 2.386827 -3.462222 1.136480
+v 2.281229 -3.338250 1.043475
+v 2.247981 -3.342804 1.127459
+v 2.440236 -3.509564 1.019417
+v 2.327021 -3.352317 0.958234
+v 2.377814 -3.484109 0.800332
+v 2.309358 -3.345468 0.801508
+v 2.235942 -3.243103 0.823955
+v 2.187495 -3.161535 0.800285
+f 2573 2570 2572
+f 2570 2571 2572
+f 2574 2575 2577
+f 2575 2576 2577
+f 2578 2579 2575
+f 2579 2576 2575
+f 2571 2570 2579
+f 2570 2576 2579
+f 2578 2580 2579
+f 2580 2581 2579
+f 2581 2582 2579
+f 2582 2571 2579
+f 2583 2572 2582
+f 2572 2571 2582
+v 1.857471 -2.950722 0.669988
+v 1.900481 -3.131932 0.728621
+v 1.741854 -3.114181 0.700705
+v 1.776024 -2.980086 0.707575
+v 1.945632 -2.876710 0.703118
+v 1.998099 -3.039955 0.718855
+v 2.001343 -2.847715 0.762517
+v 2.073690 -3.020848 0.782654
+v 1.841282 -2.716008 0.708009
+v 1.884318 -2.724404 0.701999
+v 1.972647 -2.728848 0.772496
+f 2584 2585 2586
+f 2587 2584 2586
+f 2585 2584 2589
+f 2584 2588 2589
+f 2590 2591 2588
+f 2588 2591 2589
+f 2592 2593 2584
+f 2593 2588 2584
+f 2593 2594 2588
+f 2594 2590 2588
+v 1.998099 -3.039955 0.718855
+v 2.059222 -3.230076 0.674936
+v 1.929730 -3.298418 0.689538
+v 1.900481 -3.131932 0.728621
+v 2.073690 -3.020848 0.782654
+v 2.187495 -3.161535 0.800285
+v 2.107985 -3.363571 0.677007
+v 1.941325 -3.434803 0.701314
+v 2.235942 -3.243103 0.823955
+f 2595 2596 2598
+f 2596 2597 2598
+f 2596 2595 2600
+f 2599 2600 2595
+f 2602 2597 2601
+f 2596 2601 2597
+f 2603 2601 2600
+f 2600 2601 2596
+v 1.736425 -2.743683 0.736866
+v 1.841282 -2.716008 0.708009
+v 1.857471 -2.950722 0.669988
+v 1.776024 -2.980086 0.707575
+f 2605 2606 2604
+f 2604 2606 2607
+v 2.002745 -3.523420 0.688103
+v 1.941325 -3.434803 0.701314
+v 2.107985 -3.363571 0.677007
+v 2.126553 -3.549679 0.701005
+v 2.309358 -3.345468 0.801508
+v 2.235942 -3.243103 0.823955
+v 2.244147 -3.545557 0.732888
+v 2.377814 -3.484109 0.800332
+v 2.197935 -3.583948 0.936437
+v 2.440236 -3.509564 1.019417
+v 2.254361 -3.550931 1.235118
+v 2.025468 -3.556842 1.204841
+v 2.078928 -3.584991 0.917088
+f 2608 2609 2610
+f 2608 2610 2611
+f 2612 2610 2613
+f 2610 2614 2611
+f 2614 2610 2615
+f 2610 2612 2615
+f 2616 2614 2617
+f 2614 2615 2617
+f 2618 2619 2616
+f 2616 2619 2620
+v -2.687162 -1.539807 0.988048
+v -2.837147 -1.791733 0.921563
+v -2.734184 -1.717948 0.749581
+v -2.591357 -1.510845 0.885470
+v -2.765069 -1.561164 1.084313
+v -2.918293 -1.904184 1.004659
+v -2.862576 -1.546894 1.117139
+v -3.010917 -1.884498 1.083510
+v -2.955052 -1.496840 1.128812
+v -3.117476 -1.866892 1.108034
+v -3.063133 -1.440555 1.090926
+v -3.232610 -1.834299 1.087832
+v -3.387254 -1.486027 0.672861
+v -3.498521 -1.762078 0.762472
+v -3.490520 -1.760417 0.903104
+v -3.365990 -1.485170 0.888076
+v -3.319817 -1.365015 0.886015
+v -3.335942 -1.365685 0.724590
+v -3.068444 -2.260195 1.035070
+v -3.177824 -2.279173 1.047580
+v -3.162498 -2.556375 1.058409
+v -3.078699 -2.553982 1.046834
+v -3.047974 -2.109628 1.063497
+v -3.169489 -2.110039 1.076796
+v -3.207447 -2.103206 1.071366
+v -3.281816 -2.305055 1.001878
+v -3.251541 -2.564050 1.023627
+v -3.327526 -2.075729 1.005328
+v -3.357996 -1.811803 0.975625
+v -3.389388 -2.305625 0.950348
+v -3.347304 -2.573628 0.955211
+v -3.451965 -2.077314 0.931974
+v -3.007483 -2.270712 0.984279
+v -3.022819 -2.522240 0.979148
+v -2.969687 -2.097941 0.982836
+v -2.892438 -1.950810 0.878120
+v -2.981187 -2.142718 0.858353
+v -3.030605 -2.311222 0.884330
+v -3.046610 -2.510881 0.900772
+v -3.040398 -2.156239 0.808208
+v -2.964215 -1.978727 0.776572
+v -3.144012 -2.333635 0.829994
+v -3.120761 -2.157770 0.766432
+v -3.066022 -1.953125 0.719516
+v -3.253309 -2.137354 0.760713
+v -3.211005 -1.850398 0.700723
+v -3.235873 -2.335338 0.820588
+v -3.132772 -2.528669 0.848639
+v -3.240554 -2.555467 0.856262
+v -3.381262 -1.828189 0.697034
+v -3.304804 -1.582192 0.643445
+v -3.139394 -1.687482 0.638546
+v -3.422698 -2.070796 0.773898
+v -3.339489 -2.328145 0.827572
+v -3.297886 -2.549020 0.861657
+v -3.463753 -2.079892 0.844667
+v -3.412068 -2.356105 0.865813
+v -3.372066 -2.569159 0.904785
+v -3.342096 -1.533989 0.921628
+v 2.024530 -2.195334 0.811284
+v 1.985330 -2.221319 0.893145
+v 1.930747 -2.463535 0.894743
+v 1.953911 -2.462233 0.830594
+v 2.047696 -2.050138 0.814712
+v 2.013095 -2.051912 0.911043
+v 2.053108 -1.738285 0.824853
+v 2.021591 -1.755289 0.912093
+v 2.059844 -1.561331 0.858957
+v 2.036036 -1.579080 0.967151
+v 1.718315 -2.775468 0.921796
+v 1.771416 -2.769024 0.946100
+v 1.737623 -2.485017 0.918334
+v 1.678986 -2.513137 0.891745
+v 1.710406 -2.272223 0.954296
+v 1.648793 -2.280014 0.929365
+v 1.720031 -2.105568 0.971354
+v 1.624900 -2.087301 0.963391
+v 1.717145 -1.809530 1.004092
+v 1.572979 -1.827591 0.985823
+v 1.650318 -1.645881 1.053347
+v 1.541750 -1.643613 1.014190
+v 1.655948 -2.520927 0.844269
+v 1.586321 -2.273752 0.880969
+v 1.529305 -2.092083 0.887353
+v 1.508714 -1.808578 0.934359
+v 1.480629 -1.640132 0.953447
+v 1.663494 -2.485963 0.790773
+v 1.601290 -2.267132 0.787696
+v 1.544087 -2.080722 0.786432
+v 1.473886 -1.818947 0.799576
+v 1.451825 -1.576856 0.702758
+v 1.756349 -2.446399 0.705428
+v 1.677597 -2.237953 0.696318
+v 1.643403 -2.076583 0.689565
+v 1.596751 -1.722028 0.684655
+v 1.599889 -1.595526 0.623185
+v 1.960643 -2.712860 0.900890
+v 1.994078 -2.713047 0.824553
+v 1.880971 -2.733242 0.890200
+v 1.864064 -2.469953 0.935601
+v 1.937009 -1.625419 1.026843
+v 1.941767 -1.759457 0.997454
+v 1.918641 -2.083654 1.001275
+v 1.906370 -2.282284 0.964887
+v 1.830669 -2.736121 0.903313
+v 1.801127 -2.484690 0.938593
+v 1.818846 -1.756976 1.023593
+v 1.804927 -1.581954 1.089198
+v 1.839224 -2.109267 0.998351
+v 1.818266 -2.313852 0.968652
+f 2622 2623 2621
+f 2621 2623 2624
+f 2625 2626 2621
+f 2626 2622 2621
+f 2626 2625 2628
+f 2627 2628 2625
+f 2629 2630 2627
+f 2630 2628 2627
+f 2631 2632 2629
+f 2632 2630 2629
+f 2636 2633 2635
+f 2633 2634 2635
+f 2633 2636 2638
+f 2636 2637 2638
+f 2642 2639 2641
+f 2639 2640 2641
+f 2640 2639 2644
+f 2643 2644 2639
+f 2630 2644 2628
+f 2628 2644 2643
+f 2644 2645 2640
+f 2644 2630 2645
+f 2630 2632 2645
+f 2641 2640 2647
+f 2640 2646 2647
+f 2648 2646 2645
+f 2645 2646 2640
+f 2649 2648 2632
+f 2632 2648 2645
+f 2650 2651 2646
+f 2646 2651 2647
+f 2652 2650 2648
+f 2648 2650 2646
+f 2635 2652 2649
+f 2649 2652 2648
+f 2639 2642 2653
+f 2653 2642 2654
+f 2653 2655 2639
+f 2655 2643 2639
+f 2628 2643 2626
+f 2626 2643 2655
+f 2622 2626 2656
+f 2657 2656 2655
+f 2655 2656 2626
+f 2655 2653 2657
+f 2653 2658 2657
+f 2653 2654 2658
+f 2654 2659 2658
+f 2656 2657 2661
+f 2657 2660 2661
+f 2658 2660 2657
+f 2658 2662 2660
+f 2662 2663 2660
+f 2664 2661 2663
+f 2660 2663 2661
+f 2666 2664 2665
+f 2663 2665 2664
+f 2665 2663 2667
+f 2662 2667 2663
+f 2669 2667 2668
+f 2668 2667 2662
+f 2633 2671 2634
+f 2670 2634 2671
+f 2671 2672 2670
+f 2672 2666 2670
+f 2665 2673 2666
+f 2673 2670 2666
+f 2673 2665 2674
+f 2667 2674 2665
+f 2667 2669 2674
+f 2669 2675 2674
+f 2676 2634 2673
+f 2673 2634 2670
+f 2676 2673 2677
+f 2674 2677 2673
+f 2674 2675 2677
+f 2675 2678 2677
+f 2676 2677 2652
+f 2677 2650 2652
+f 2651 2650 2678
+f 2678 2650 2677
+f 2634 2676 2635
+f 2676 2652 2635
+f 2636 2635 2679
+f 2679 2635 2649
+f 2680 2681 2683
+f 2681 2682 2683
+f 2681 2680 2685
+f 2684 2685 2680
+f 2684 2686 2685
+f 2686 2687 2685
+f 2689 2687 2688
+f 2688 2687 2686
+f 2691 2692 2690
+f 2690 2692 2693
+f 2693 2692 2695
+f 2692 2694 2695
+f 2695 2694 2697
+f 2694 2696 2697
+f 2696 2698 2697
+f 2697 2698 2699
+f 2698 2700 2699
+f 2699 2700 2701
+f 2702 2693 2703
+f 2693 2695 2703
+f 2697 2704 2695
+f 2703 2695 2704
+f 2704 2697 2705
+f 2697 2699 2705
+f 2699 2701 2705
+f 2705 2701 2706
+f 2703 2708 2702
+f 2707 2702 2708
+f 2708 2703 2709
+f 2703 2704 2709
+f 2705 2710 2704
+f 2709 2704 2710
+f 2706 2711 2705
+f 2710 2705 2711
+f 2712 2707 2713
+f 2707 2708 2713
+f 2709 2714 2708
+f 2713 2708 2714
+f 2715 2714 2710
+f 2714 2709 2710
+f 2711 2716 2710
+f 2715 2710 2716
+f 2717 2718 2682
+f 2718 2683 2682
+f 2719 2717 2720
+f 2717 2682 2720
+f 2689 2721 2687
+f 2687 2721 2722
+f 2723 2685 2722
+f 2685 2687 2722
+f 2681 2724 2682
+f 2720 2682 2724
+f 2724 2681 2723
+f 2681 2685 2723
+f 2692 2691 2726
+f 2725 2726 2691
+f 2720 2726 2719
+f 2725 2719 2726
+f 2728 2700 2727
+f 2727 2700 2698
+f 2727 2698 2729
+f 2729 2698 2696
+f 2729 2696 2730
+f 2730 2696 2694
+f 2694 2692 2730
+f 2726 2730 2692
+f 2727 2722 2728
+f 2722 2721 2728
+f 2729 2723 2727
+f 2723 2722 2727
+f 2730 2724 2729
+f 2724 2723 2729
+f 2724 2730 2720
+f 2720 2730 2726
+v 2.170039 -3.134504 0.978866
+v 2.091539 -3.032437 0.947029
+v 1.980621 -3.043895 0.964237
+v 2.440236 -3.509564 1.019417
+v 2.386827 -3.462222 1.136480
+v 2.343303 -3.507846 1.195262
+v 2.254361 -3.550931 1.235118
+v 2.197935 -3.583948 0.936437
+f 2731 2732 2733
+f 2737 2738 2736
+f 2736 2738 2735
+f 2734 2735 2738
+v 1.736425 -2.743683 0.736866
+v 1.663494 -2.485963 0.790773
+v 1.756349 -2.446399 0.705428
+v 1.841282 -2.716008 0.708009
+v 1.596751 -1.722028 0.684655
+v 1.599889 -1.595526 0.623185
+v 1.721211 -1.590185 0.601932
+v 1.740323 -1.679830 0.664098
+v 1.643403 -2.076583 0.689565
+v 1.747671 -2.067518 0.638841
+v 1.677597 -2.237953 0.696318
+v 1.772999 -2.230292 0.644940
+v 1.700797 -2.794792 0.824250
+v 1.655948 -2.520927 0.844269
+v 2.001343 -2.847715 0.762517
+v 1.972647 -2.728848 0.772496
+v 1.994078 -2.713047 0.824553
+v 2.057496 -2.887282 0.844225
+v 1.947264 -2.443232 0.732587
+v 1.884318 -2.724404 0.701999
+v 1.828658 -2.477348 0.673470
+v 1.921881 -2.157616 0.692678
+v 1.953911 -2.462233 0.830594
+v 1.963153 -1.588839 0.612861
+v 1.991892 -1.748400 0.652770
+v 1.945206 -2.015769 0.672724
+v 2.059844 -1.561331 0.858957
+v 2.053108 -1.738285 0.824853
+v 2.047696 -2.050138 0.814712
+v 2.024530 -2.195334 0.811284
+v 2.126237 -1.330172 0.721011
+v 2.158051 -1.209613 0.783941
+v 2.141273 -1.234642 0.941254
+v 2.111557 -1.376942 0.896570
+v 2.099566 -1.259996 1.055763
+v 2.071448 -1.410118 1.006192
+v 1.966698 -1.228160 1.153716
+v 1.974215 -1.469208 1.068951
+v 1.805207 -1.268427 1.165317
+v 1.801794 -1.465464 1.129277
+v 1.601721 -1.262359 1.141420
+v 1.612396 -1.485728 1.099731
+v 1.497480 -1.283201 1.088258
+v 1.516700 -1.453050 1.068516
+v 1.430817 -1.301205 1.024924
+v 1.454817 -1.430228 0.976569
+v 1.348219 -1.282064 0.845204
+v 1.328862 -1.352627 0.758733
+v 2.180012 -1.130557 0.821812
+v 2.177450 -1.127765 0.974416
+v 2.148553 -1.103067 1.065410
+v 2.024692 -1.074646 1.172465
+v 1.838895 -1.087204 1.201408
+v 1.645819 -1.087442 1.173773
+v 1.524407 -1.125312 1.142248
+v 1.438439 -1.148029 1.098069
+v 1.310865 -1.136322 0.914838
+v 2.048200 -1.581983 0.555832
+v 2.079600 -1.473377 0.654997
+v 1.650318 -1.645881 1.053347
+v 1.804927 -1.581954 1.089198
+v 1.937009 -1.625419 1.026843
+v 2.036036 -1.579080 0.967151
+v 2.229345 -0.992723 0.862826
+v 2.222082 -0.957342 1.014137
+v 1.867657 -0.920633 1.206933
+v 1.635139 -0.965221 1.184968
+v 2.058189 -0.931238 1.163518
+v 2.158585 -0.955809 1.113647
+v 1.451825 -1.576856 0.702758
+v 1.480629 -1.640132 0.953447
+v 1.428883 -0.986690 1.133905
+v 1.337875 -0.945716 1.021299
+v 1.541750 -1.643613 1.014190
+v 1.536037 -0.985876 1.185597
+v 3.247406 2.073333 0.000000
+v 2.985371 1.982663 0.000000
+v 3.009101 1.971604 0.034220
+v 3.233975 2.059193 0.072431
+v 3.036361 1.913989 0.169838
+v 3.252224 2.026347 0.148215
+v 3.058366 1.773346 0.297337
+v 3.276333 1.863773 0.294266
+v 3.086666 1.632991 0.338863
+v 3.337545 1.748927 0.340210
+v 3.115383 1.492390 0.380228
+v 3.377233 1.587800 0.400781
+v 3.163181 1.209972 0.462438
+v 3.473410 1.366149 0.454658
+v 3.189664 0.907503 0.500122
+v 3.528445 1.060127 0.489443
+v 3.280681 0.510802 0.499434
+v 3.559394 0.706516 0.452535
+v 3.321825 0.266690 0.465750
+v 3.619650 0.472046 0.391742
+v 3.360040 0.165487 0.412685
+v 3.641195 0.407454 0.362198
+v 3.378799 0.073736 0.355362
+v 3.674710 0.338839 0.307840
+v 3.438950 -0.082580 0.257015
+v 3.700363 0.265794 0.240762
+v 3.514981 -0.121886 0.187589
+v 3.737014 0.181837 0.176819
+v 3.486028 -0.141683 0.000000
+v 3.731689 0.186391 0.000000
+v 3.454971 2.169877 0.000000
+v 3.458300 2.151656 0.102662
+v 3.727093 2.308406 0.150049
+v 3.716360 2.343387 0.000000
+v 3.955635 0.432417 0.197586
+v 3.929251 0.411689 0.000000
+v 4.126565 0.642027 0.000000
+v 4.120842 0.627141 0.185461
+v 3.889626 0.475277 0.247365
+v 3.861841 0.560638 0.311961
+v 4.105198 0.672581 0.300001
+v 3.849352 0.664451 0.387198
+v 4.068249 0.798926 0.400813
+v 3.823137 0.853054 0.461519
+v 4.041657 1.039756 0.496922
+v 3.747724 1.184933 0.518662
+v 3.988510 1.297806 0.539537
+v 3.650974 1.463740 0.478617
+v 3.886058 1.550141 0.504830
+v 3.590526 1.701090 0.411994
+v 3.881998 1.764428 0.476337
+v 3.541188 1.849183 0.386366
+v 3.814876 1.968416 0.443000
+v 3.479418 1.978250 0.317478
+v 3.758215 2.206683 0.323051
+v 3.460196 2.103494 0.180368
+v 3.745669 2.266001 0.241930
+v 3.335210 -0.375755 0.000000
+v 3.342159 -0.384674 0.201349
+v 3.107533 -0.691019 0.264602
+v 3.118124 -0.703925 0.000000
+v 2.715712 1.828219 0.167709
+v 2.723503 1.898839 0.000000
+v 2.339597 1.807702 0.000000
+v 2.361089 1.766660 0.202595
+v 2.738132 1.687333 0.295046
+v 2.406969 1.645328 0.341479
+v 2.775680 1.538710 0.352829
+v 2.519027 1.485931 0.422962
+v 2.815366 1.377583 0.413399
+v 2.553871 1.284278 0.512335
+v 2.854291 1.093951 0.494650
+v 2.637461 1.017260 0.581611
+v 2.948387 0.783357 0.515058
+v 2.747937 0.712253 0.615674
+v 3.061090 0.397226 0.574193
+v 2.811504 0.469098 0.657443
+v 2.898733 0.271916 0.651298
+v 3.136321 0.171237 0.539896
+v 2.919870 0.084875 0.642460
+v 3.166160 0.021310 0.457261
+v 2.953029 -0.127690 0.520499
+v 3.199571 -0.153739 0.380150
+v 2.986408 -0.413503 0.428964
+v 3.286426 -0.300744 0.276331
+v 3.053144 -0.609681 0.326931
+v 2.835437 -0.231101 0.577890
+v 2.679445 0.687427 0.720573
+v 2.753156 0.400829 0.713141
+v 2.790681 0.219187 0.718263
+v 2.790657 0.044324 0.717488
+v 2.743995 -0.129852 0.718277
+v 2.736198 -0.346225 0.659345
+v 2.396355 1.242239 0.597722
+v 2.482917 0.997637 0.702425
+v 2.514162 0.988713 0.674527
+v 2.543372 -0.548031 0.937182
+v 2.410367 -0.777999 0.841105
+v 2.539200 -0.727778 0.750475
+v 2.618307 -0.549092 0.805491
+v 2.594499 -0.422948 0.981263
+v 2.690576 -0.368057 0.819343
+v 2.607430 -0.208248 0.974218
+v 2.702577 -0.197406 0.795611
+v 2.649413 0.031535 1.024796
+v 2.734183 0.038769 0.865810
+v 2.668936 0.206182 1.014371
+v 2.731512 0.219003 0.891585
+v 2.616001 0.447717 0.960748
+v 2.706960 0.393597 0.849582
+v 2.570400 0.738683 0.830405
+v 2.604217 0.728827 0.769671
+v 2.688131 -0.517509 0.672975
+v 2.542439 0.999928 0.648592
+v 2.128139 1.788397 0.000000
+v 2.132390 1.755821 0.180271
+v 2.183003 1.654070 0.341767
+v 2.301359 1.397721 0.546015
+v 2.346081 -0.745350 1.013296
+v 2.245624 -0.864372 0.995778
+v 2.292449 -0.871852 0.882400
+v 2.069379 1.727818 0.212746
+v 2.096552 1.678482 0.326810
+v 2.189848 1.468992 0.517501
+v 2.266003 1.273253 0.663332
+v 2.347317 1.066114 0.758763
+v 2.399389 0.782091 0.915279
+v 2.448969 0.529858 1.037335
+v 2.495354 0.250522 1.132081
+v 2.500490 -0.035029 1.170179
+v 2.452588 -0.244072 1.138797
+v 2.439827 -0.395385 1.131324
+v 2.384638 -0.591919 1.043058
+v 2.013534 -0.662303 1.191491
+v 2.108912 -0.357128 1.259691
+v 1.794465 1.787719 0.000000
+v 1.807583 1.756546 0.177627
+v 2.042206 1.777154 0.000000
+v 2.136269 -0.187666 1.278057
+v 2.141790 -0.055306 1.295565
+v 2.081700 0.283249 1.259461
+v 2.023441 0.529338 1.144399
+v 1.975941 0.827957 1.018423
+v 1.958254 1.130271 0.861813
+v 1.859443 1.450393 0.632222
+v 1.821946 1.618209 0.403751
+v 1.798719 1.714447 0.259352
+v 0.733818 1.740873 0.000000
+v 0.234527 1.730117 0.000000
+v 0.223642 1.684075 0.160743
+v 0.737904 1.604213 0.281713
+v 0.237330 1.595746 0.288672
+v 0.725959 1.478055 0.461804
+v 0.289039 1.496446 0.430055
+v 0.760722 1.205036 0.700545
+v 0.305671 1.298417 0.629719
+v 0.857323 0.985001 0.874029
+v 0.243473 1.134082 0.819993
+v 0.921312 0.755659 0.999330
+v 0.316341 0.785311 1.086260
+v 0.939271 0.379986 1.185872
+v 0.539252 0.353984 1.254493
+v 0.927775 0.195225 1.233043
+v 0.539150 0.148262 1.321014
+v 0.950215 0.042751 1.256188
+v 0.516872 -0.020713 1.356627
+v 0.943855 -0.101127 1.274771
+v 0.542386 -0.188227 1.370375
+v 0.960321 -0.308052 1.243133
+v 0.546875 -0.390940 1.363244
+v 0.974530 -0.525273 1.140353
+v 0.550658 -0.633015 1.331311
+v 0.948819 -0.638568 1.102958
+v 0.527724 -0.862854 1.253811
+v 0.939974 -0.894739 1.019809
+v 0.544825 -1.133123 1.096902
+v 0.956456 -1.070504 0.921063
+v 0.530629 -1.316423 0.929842
+v 0.930660 -1.216516 0.831196
+v 0.538756 -1.408602 0.764911
+v 0.922703 -1.296032 0.728307
+v 0.489819 -1.524947 0.672392
+v 0.912699 -1.455066 0.576185
+v 0.480235 -1.631521 0.401961
+v 0.912989 -1.499314 0.419547
+v 0.446550 -1.672950 0.000000
+v 0.927497 -1.558489 0.000000
+v -0.228904 1.734267 0.000000
+v -0.547248 1.742126 0.000000
+v -0.559706 1.694180 0.186107
+v -0.221516 1.686349 0.151403
+v -0.557624 1.641278 0.271462
+v -0.267035 1.627058 0.266577
+v -0.626493 1.585426 0.443136
+v -0.247999 1.565146 0.389142
+v -0.597781 1.489620 0.641047
+v -0.179548 1.471301 0.544513
+v -0.674657 1.333008 0.761059
+v -0.192546 1.305535 0.700080
+v -0.910602 1.204118 0.837740
+v -0.406155 1.005088 0.971088
+v -0.969076 0.901205 1.146223
+v -0.115190 0.458427 1.346197
+v -0.752416 0.438132 1.467349
+v 0.005537 0.163519 1.472265
+v -0.645496 0.179261 1.584316
+v 0.018086 0.002865 1.523199
+v -0.536767 -0.144454 1.682232
+v 0.034087 -0.225059 1.542949
+v -0.533528 -0.582280 1.701405
+v 0.010486 -0.502317 1.576297
+v -0.505045 -0.913827 1.645612
+v 0.021051 -0.831931 1.511548
+v -0.487217 -1.193519 1.504026
+v -0.041570 -1.143825 1.395176
+v -0.524231 -1.399266 1.313019
+v -0.071941 -1.346991 1.237379
+v -0.526127 -1.495000 1.167736
+v -0.072300 -1.450245 1.087397
+v -0.535144 -1.615983 0.920556
+v -0.063012 -1.583021 0.865082
+v -0.866132 1.754670 0.000000
+v -1.179474 1.786649 0.000000
+v -1.215563 1.757097 0.133494
+v -0.894132 1.712652 0.151911
+v -1.227613 1.709095 0.276029
+v -0.954897 1.677544 0.293034
+v -1.292756 1.656509 0.514030
+v -1.017767 1.607824 0.541965
+v -1.338488 1.613735 0.725441
+v -1.046070 1.509097 0.761060
+v -1.403848 1.533059 0.902827
+v -1.115594 1.392380 0.819623
+v -1.551526 1.400025 1.050193
+v -1.278903 1.192051 0.946843
+v -1.552899 1.128654 1.151040
+v -1.200768 0.978822 1.103391
+v -1.454529 0.875045 1.238858
+v -1.147922 0.807955 1.254191
+v -1.405685 0.573835 1.352181
+v -1.120716 0.424016 1.456990
+v -1.479588 0.295746 1.440042
+v -1.077307 0.165008 1.553393
+v -1.489699 -0.024215 1.510987
+v -1.053434 -0.342553 1.690245
+v -1.395501 -0.698702 1.553257
+v -1.077209 -0.869649 1.633144
+v -1.376176 -0.948757 1.451608
+v -1.061272 -1.141877 1.496230
+v -1.402349 -1.127845 1.309055
+v -1.001366 -1.335897 1.353338
+v -1.407658 -1.236026 1.112930
+v -0.952525 -1.440582 1.168650
+v 1.640095 -0.674556 1.246804
+v 1.644178 -0.857872 1.208494
+v 1.456656 1.785879 0.000000
+v 1.462507 1.745481 0.222394
+v 1.483832 1.697594 0.288781
+v 1.497138 1.618935 0.401108
+v 1.504951 1.483493 0.585976
+v 1.517126 1.334367 0.741076
+v 1.570685 0.938327 0.989108
+v 1.582203 0.771083 1.068180
+v 1.630080 0.420236 1.172369
+v 1.649027 0.224458 1.211969
+v 1.660355 0.019397 1.246002
+v 1.664159 -0.189659 1.266729
+v 1.678622 -0.410061 1.291177
+v 1.920432 -1.567396 0.000000
+v 1.604939 -1.556997 0.000000
+v 1.192040 -1.330605 0.678707
+v 1.210555 -1.460061 0.576841
+v 1.223415 -1.532658 0.434522
+v 1.289448 -1.546597 0.000000
+v 1.219163 -1.218342 0.823029
+v 1.373216 -0.564620 1.106245
+v 1.252961 -0.928825 1.001643
+v 1.230116 -1.085439 0.894543
+v -0.078470 -1.688266 0.800230
+v -0.094135 -1.769086 0.556924
+v -0.953236 -1.545941 0.899180
+v 2.881063 -0.493146 0.521968
+v 2.824356 -1.407256 0.355013
+v 2.740886 -1.339225 0.463604
+v 2.663024 -1.440487 0.478149
+v -1.350950 1.807009 0.000000
+v -1.365948 1.769608 0.133901
+v -1.396332 1.723782 0.267642
+v -1.417595 1.676180 0.529265
+v -1.465432 1.655336 0.722125
+v -1.582187 1.567542 0.982349
+v -1.721806 1.391264 1.113307
+v -1.733703 1.083864 1.181489
+v -1.807421 0.657142 1.209422
+v -1.796156 0.452382 1.243643
+v -1.810920 0.287592 1.292257
+v -1.795130 0.033439 1.371160
+v -1.802864 -0.282523 1.401315
+v -1.837859 -0.540871 1.295851
+v -1.782928 -0.770786 1.173619
+v -1.757573 -0.945337 1.075832
+v -1.676510 1.826886 0.000000
+v -1.683863 1.789041 0.121501
+v -1.714432 1.747956 0.247594
+v -1.744732 1.734849 0.433807
+v -1.929731 1.617188 0.806390
+v -1.996117 1.387891 1.064104
+v -1.980388 1.134038 1.143196
+v -2.013663 0.810726 1.158827
+v -2.030191 0.547622 1.189762
+v -2.021159 0.411979 1.234679
+v -1.932916 0.232972 1.304589
+v -1.897394 0.037852 1.365798
+v -1.950547 -0.275573 1.377028
+v -2.033655 -0.526012 1.277639
+v -2.050292 -0.755566 1.114167
+v -2.043593 -0.875823 1.028879
+v -2.033406 -0.910030 0.964220
+v -1.782298 -1.020581 0.943381
+v -1.198513 -1.456102 0.885435
+v -1.456655 -1.295527 0.894240
+v -1.366873 -1.340211 0.907567
+v -2.057387 1.841308 0.000000
+v -2.079597 1.817785 0.138375
+v -2.100170 1.789980 0.229245
+v -2.137524 1.753182 0.433142
+v -2.172139 1.623010 0.805318
+v -2.205791 1.356023 1.081662
+v -2.296056 1.062810 1.171139
+v -2.298249 0.768333 1.203884
+v -2.256285 0.547326 1.238301
+v -2.158400 0.381542 1.272962
+v -2.070413 0.207766 1.335106
+v -2.064786 0.018789 1.411866
+v -2.187634 -0.375454 1.406902
+v -2.276341 -0.689823 1.268026
+v -2.292049 -0.933921 1.128136
+v -2.299356 -1.025449 1.044687
+v -2.306662 -1.116976 0.961238
+v -2.629466 1.918204 0.000000
+v -2.672899 1.905110 0.067168
+v -2.697367 1.871291 0.218796
+v -2.703112 1.825435 0.395127
+v -2.715246 1.746763 0.604653
+v -2.717480 1.576797 0.875971
+v -2.684930 1.262021 1.110490
+v -2.572286 0.835495 1.252192
+v -2.536112 0.656633 1.269661
+v -2.520947 0.559036 1.273617
+v -2.473750 0.300945 1.316695
+v -2.433366 0.078222 1.371269
+v -2.414730 -0.108377 1.395384
+v -2.382920 -0.417450 1.375045
+v -2.430508 -0.822313 1.254486
+v -2.566746 -1.211312 1.167101
+v -3.037562 2.001526 0.000000
+v -3.053102 1.968810 0.051104
+v -3.077669 1.871112 0.217368
+v -3.075310 1.846000 0.363149
+v -3.109047 1.789477 0.565323
+v -3.085650 1.657340 0.784479
+v -3.028932 1.461517 0.941324
+v -2.930312 1.103580 1.125876
+v -2.825835 0.755899 1.209042
+v -2.790630 0.468810 1.224273
+v -2.787011 0.264495 1.237352
+v -2.687022 0.076781 1.290565
+v -2.649338 -0.241719 1.339644
+v -2.616467 -0.511373 1.344133
+v -2.624856 -0.888200 1.261176
+v -2.725776 -1.214862 1.190384
+v -2.862576 -1.546894 1.117139
+v -2.765069 -1.561164 1.084313
+v -3.392806 1.769365 0.000000
+v -3.507689 1.700214 0.000000
+v -3.519716 1.685231 0.317130
+v -3.358510 1.810253 0.380095
+v -3.527168 1.583508 0.512679
+v -3.395381 1.726325 0.554770
+v -3.512997 1.448050 0.611386
+v -3.338742 1.598933 0.689636
+v -3.476235 1.287798 0.704766
+v -3.278080 1.432418 0.853958
+v -3.442151 1.105486 0.762934
+v -3.244771 1.195540 0.910945
+v -3.379131 0.767915 0.885996
+v -3.196410 0.797564 0.985913
+v -3.306875 0.379713 0.987620
+v -3.112555 0.457376 1.084816
+v -3.251181 0.175063 1.053445
+v -3.044646 0.224321 1.164934
+v -3.160225 -0.018852 1.113626
+v -2.971546 0.032038 1.215971
+v -3.101125 -0.354760 1.162409
+v -2.907080 -0.345582 1.281557
+v -3.096267 -0.668100 1.140081
+v -2.901159 -0.619504 1.284058
+v -3.122061 -0.998702 1.065015
+v -2.937658 -1.002749 1.219413
+v -3.150210 -1.259588 1.001021
+v -2.982676 -1.264649 1.133596
+v -3.188954 -1.408279 0.963611
+v -3.063133 -1.440555 1.090926
+v -3.690685 1.602080 0.000000
+v -3.734989 1.589433 0.295202
+v -3.697974 1.466697 0.433432
+v -3.684619 1.350690 0.501428
+v -3.655148 1.190938 0.573692
+v -3.639878 1.015186 0.615203
+v -3.582867 0.734419 0.697787
+v -3.504525 0.405574 0.847066
+v -3.424258 0.158638 0.918279
+v -3.365413 -0.113447 0.952400
+v -3.290393 -0.424259 0.984153
+v -3.233333 -0.683782 1.015512
+v -3.238094 -0.979377 0.961631
+v -3.277510 -1.177346 0.915300
+v -3.319817 -1.365015 0.886015
+v -3.709827 1.417763 0.000000
+v -3.709741 1.351194 0.211745
+v -3.701634 1.272650 0.270469
+v -3.695872 1.156978 0.316829
+v -3.672431 1.044224 0.364991
+v -3.664355 0.932851 0.370749
+v -3.631292 0.701013 0.420276
+v -3.570384 0.385564 0.524480
+v -3.520188 0.140164 0.618561
+v -3.458251 -0.125950 0.731712
+v -3.406618 -0.343461 0.746456
+v -3.283698 -0.730967 0.793898
+v -2.687162 -1.539807 0.988048
+v -2.462835 -1.305500 0.966395
+v -2.591357 -1.510845 0.885470
+v -2.955052 -1.496840 1.128812
+v -3.357996 -1.811803 0.975625
+v -3.232610 -1.834299 1.087832
+v -3.365990 -1.485170 0.888076
+v -3.342096 -1.533989 0.921628
+v -2.964215 -1.978727 0.776572
+v -2.811581 -1.798210 0.712737
+v -2.734184 -1.717948 0.749581
+v -2.892438 -1.950810 0.878120
+v -2.837147 -1.791733 0.921563
+v -3.046610 -2.510881 0.900772
+v -3.132772 -2.528669 0.848639
+v -3.144012 -2.333635 0.829994
+v -3.030605 -2.311222 0.884330
+v -3.223286 -3.001780 1.126176
+v -3.261810 -2.821069 1.088218
+v -3.320330 -2.827513 1.063914
+v -3.302419 -3.017921 1.128514
+v -2.986345 -2.933770 1.087679
+v -3.053267 -2.764905 1.043008
+v -3.141072 -2.785287 1.032318
+v -3.107105 -2.947818 1.092235
+v -2.946527 -2.939327 0.986343
+v -3.016419 -2.765091 0.966671
+v -3.301857 -3.074776 1.114869
+v -3.316551 -3.168932 1.121229
+v -3.227676 -3.141660 1.103969
+v -3.217306 -3.187686 1.075214
+f 2741 2742 2740
+f 2739 2740 2742
+f 2744 2745 2743
+f 2743 2745 2746
+f 2746 2748 2743
+f 2747 2743 2748
+f 2748 2750 2747
+f 2749 2747 2750
+f 2739 2751 2740
+f 2751 2752 2740
+f 2755 2756 2754
+f 2753 2754 2756
+f 2754 2758 2757
+f 2757 2758 2759
+f 2757 2759 2760
+f 2760 2759 2750
+f 2741 2759 2742
+f 2758 2742 2759
+f 2759 2741 2750
+f 2741 2749 2750
+f 2757 2761 2754
+f 2755 2754 2761
+f 2762 2763 2745
+f 2746 2745 2763
+f 2748 2746 2764
+f 2746 2763 2764
+f 2762 2765 2763
+f 2763 2765 2766
+f 2766 2767 2763
+f 2764 2763 2767
+f 2764 2767 2760
+f 2760 2767 2768
+f 2760 2768 2757
+f 2757 2768 2761
+f 2769 2770 2772
+f 2770 2771 2772
+f 2773 2774 2771
+f 2772 2771 2774
+f 2775 2776 2773
+f 2774 2773 2776
+f 2776 2775 2778
+f 2775 2777 2778
+f 2779 2780 2777
+f 2778 2777 2780
+f 2779 2781 2780
+f 2780 2781 2782
+f 2781 2783 2782
+f 2782 2783 2784
+f 2784 2783 2786
+f 2783 2785 2786
+f 2771 2770 2788
+f 2770 2787 2788
+f 2789 2773 2788
+f 2771 2788 2773
+f 2773 2789 2775
+f 2789 2790 2775
+f 2791 2777 2790
+f 2775 2790 2777
+f 2779 2777 2792
+f 2777 2791 2792
+f 2792 2793 2779
+f 2779 2793 2781
+f 2793 2794 2781
+f 2781 2794 2783
+f 2794 2795 2783
+f 2783 2795 2785
+f 2765 2762 2797
+f 2762 2796 2797
+f 2780 2798 2778
+f 2778 2798 2799
+f 2800 2776 2799
+f 2776 2778 2799
+f 2801 2774 2800
+f 2774 2776 2800
+f 2765 2772 2801
+f 2772 2774 2801
+f 2765 2797 2772
+f 2797 2769 2772
+f 2788 2787 2803
+f 2802 2803 2787
+f 2804 2805 2791
+f 2805 2792 2791
+f 2791 2790 2804
+f 2806 2804 2790
+f 2789 2807 2790
+f 2807 2806 2790
+f 2788 2803 2789
+f 2803 2807 2789
+f 2808 2809 2786
+f 2809 2784 2786
+f 2795 2794 2811
+f 2794 2810 2811
+f 2782 2812 2780
+f 2812 2798 2780
+f 2784 2809 2782
+f 2809 2812 2782
+f 2793 2792 2813
+f 2792 2805 2813
+f 2794 2793 2810
+f 2793 2813 2810
+f 2814 2815 2817
+f 2815 2816 2817
+f 2816 2818 2817
+f 2817 2818 2819
+f 2819 2818 2821
+f 2818 2820 2821
+f 2822 2823 2820
+f 2821 2820 2823
+f 2823 2822 2825
+f 2822 2824 2825
+f 2826 2827 2824
+f 2825 2824 2827
+f 2828 2829 2826
+f 2827 2826 2829
+f 2830 2831 2828
+f 2829 2828 2831
+f 2832 2833 2830
+f 2831 2830 2833
+f 2832 2834 2833
+f 2833 2834 2835
+f 2836 2837 2834
+f 2835 2834 2837
+f 2838 2839 2836
+f 2837 2836 2839
+f 2839 2838 2841
+f 2838 2840 2841
+f 2842 2843 2840
+f 2841 2840 2843
+f 2846 2847 2845
+f 2844 2845 2847
+f 2850 2851 2849
+f 2848 2849 2851
+f 2852 2848 2851
+f 2851 2854 2852
+f 2853 2852 2854
+f 2854 2856 2853
+f 2855 2853 2856
+f 2858 2857 2856
+f 2857 2855 2856
+f 2859 2857 2860
+f 2857 2858 2860
+f 2861 2859 2862
+f 2859 2860 2862
+f 2864 2863 2862
+f 2863 2861 2862
+f 2866 2865 2864
+f 2865 2863 2864
+f 2868 2867 2866
+f 2867 2865 2866
+f 2867 2868 2869
+f 2869 2868 2870
+f 2870 2846 2869
+f 2845 2869 2846
+f 2873 2874 2872
+f 2871 2872 2874
+f 2877 2878 2876
+f 2875 2876 2878
+f 2878 2880 2875
+f 2879 2875 2880
+f 2880 2882 2879
+f 2881 2879 2882
+f 2884 2883 2882
+f 2883 2881 2882
+f 2883 2884 2885
+f 2885 2884 2886
+f 2885 2886 2887
+f 2887 2886 2888
+f 2889 2887 2890
+f 2887 2888 2890
+f 2889 2890 2891
+f 2889 2891 2892
+f 2892 2891 2893
+f 2895 2894 2893
+f 2894 2892 2893
+f 2897 2896 2895
+f 2896 2894 2895
+f 2899 2898 2897
+f 2898 2896 2897
+f 2898 2899 2872
+f 2872 2899 2873
+f 2817 2845 2814
+f 2814 2845 2844
+f 2840 2872 2842
+f 2842 2872 2871
+f 2816 2815 2876
+f 2818 2816 2875
+f 2816 2876 2875
+f 2820 2818 2879
+f 2818 2875 2879
+f 2879 2881 2820
+f 2822 2820 2881
+f 2883 2824 2881
+f 2824 2822 2881
+f 2885 2826 2883
+f 2826 2824 2883
+f 2826 2885 2828
+f 2828 2885 2887
+f 2828 2887 2830
+f 2830 2887 2889
+f 2830 2889 2832
+f 2832 2889 2892
+f 2894 2834 2892
+f 2834 2832 2892
+f 2896 2836 2894
+f 2836 2834 2894
+f 2836 2896 2838
+f 2838 2896 2898
+f 2840 2838 2872
+f 2838 2898 2872
+f 2848 2841 2849
+f 2841 2843 2849
+f 2841 2848 2839
+f 2839 2848 2852
+f 2853 2837 2852
+f 2837 2839 2852
+f 2835 2837 2853
+f 2853 2855 2835
+f 2833 2835 2855
+f 2833 2855 2831
+f 2831 2855 2857
+f 2831 2857 2829
+f 2829 2857 2859
+f 2829 2859 2827
+f 2827 2859 2861
+f 2863 2825 2861
+f 2825 2827 2861
+f 2825 2863 2823
+f 2823 2863 2865
+f 2867 2821 2865
+f 2821 2823 2865
+f 2821 2867 2819
+f 2819 2867 2869
+f 2845 2817 2869
+f 2817 2819 2869
+f 2895 2900 2897
+f 2902 2890 2901
+f 2890 2888 2901
+f 2891 2890 2903
+f 2890 2902 2903
+f 2891 2903 2893
+f 2893 2903 2904
+f 2905 2906 2900
+f 2905 2900 2893
+f 2900 2895 2893
+f 2893 2904 2905
+f 2907 2908 2909
+f 2911 2912 2910
+f 2910 2912 2913
+f 2915 2914 2913
+f 2914 2910 2913
+f 2914 2915 2916
+f 2916 2915 2917
+f 2917 2919 2916
+f 2918 2916 2919
+f 2919 2921 2918
+f 2920 2918 2921
+f 2922 2920 2923
+f 2920 2921 2923
+f 2923 2925 2922
+f 2924 2922 2925
+f 2908 2924 2909
+f 2924 2925 2909
+f 2913 2926 2915
+f 2926 2906 2915
+f 2927 2907 2909
+f 2927 2909 2901
+f 2901 2909 2925
+f 2923 2902 2925
+f 2902 2901 2925
+f 2921 2903 2923
+f 2903 2902 2923
+f 2903 2921 2904
+f 2904 2921 2919
+f 2917 2905 2919
+f 2905 2904 2919
+f 2905 2917 2906
+f 2906 2917 2915
+f 2901 2888 2927
+f 2888 2886 2927
+f 2878 2877 2929
+f 2877 2928 2929
+f 2929 2930 2878
+f 2880 2878 2930
+f 2930 2931 2880
+f 2882 2880 2931
+f 2882 2931 2884
+f 2884 2931 2907
+f 2884 2907 2886
+f 2886 2907 2927
+f 2932 2933 2911
+f 2911 2933 2934
+f 2930 2929 2936
+f 2929 2935 2936
+f 2931 2930 2937
+f 2930 2936 2937
+f 2937 2938 2931
+f 2907 2931 2938
+f 2908 2907 2939
+f 2907 2938 2939
+f 2939 2940 2908
+f 2924 2908 2940
+f 2922 2924 2941
+f 2924 2940 2941
+f 2941 2942 2922
+f 2920 2922 2942
+f 2942 2943 2920
+f 2918 2920 2943
+f 2916 2918 2944
+f 2918 2943 2944
+f 2916 2944 2914
+f 2914 2944 2945
+f 2945 2946 2914
+f 2910 2914 2946
+f 2910 2946 2911
+f 2911 2946 2932
+f 2934 2933 2802
+f 2933 2803 2802
+f 2947 2933 2932
+f 2948 2947 2946
+f 2947 2932 2946
+f 2935 2951 2950
+f 2949 2950 2951
+f 2946 2945 2948
+f 2952 2948 2945
+f 2952 2945 2944
+f 2944 2943 2952
+f 2953 2952 2943
+f 2954 2953 2942
+f 2953 2943 2942
+f 2955 2954 2941
+f 2954 2942 2941
+f 2955 2941 2956
+f 2956 2941 2940
+f 2940 2939 2956
+f 2957 2956 2939
+f 2958 2957 2938
+f 2957 2939 2938
+f 2938 2937 2958
+f 2959 2958 2937
+f 2937 2936 2959
+f 2960 2959 2936
+f 2936 2935 2960
+f 2950 2960 2935
+f 2964 2961 2963
+f 2961 2962 2963
+f 2963 2965 2964
+f 2964 2965 2966
+f 2968 2966 2967
+f 2966 2965 2967
+f 2970 2968 2969
+f 2968 2967 2969
+f 2972 2970 2971
+f 2970 2969 2971
+f 2971 2973 2972
+f 2972 2973 2974
+f 2973 2975 2974
+f 2974 2975 2976
+f 2978 2976 2977
+f 2976 2975 2977
+f 2980 2978 2979
+f 2978 2977 2979
+f 2982 2980 2981
+f 2980 2979 2981
+f 2984 2982 2983
+f 2982 2981 2983
+f 2985 2986 2983
+f 2984 2983 2986
+f 2988 2986 2987
+f 2986 2985 2987
+f 2989 2990 2987
+f 2988 2987 2990
+f 2991 2992 2989
+f 2990 2989 2992
+f 2991 2993 2992
+f 2992 2993 2994
+f 2995 2996 2993
+f 2994 2993 2996
+f 2997 2998 2995
+f 2996 2995 2998
+f 2999 3000 2997
+f 2998 2997 3000
+f 3002 3003 3001
+f 3001 3003 3004
+f 3004 3003 3006
+f 3003 3005 3006
+f 3007 3008 3005
+f 3006 3005 3008
+f 3010 3008 3009
+f 3008 3007 3009
+f 3011 3012 3009
+f 3010 3009 3012
+f 3013 3014 3011
+f 3012 3011 3014
+f 3016 3014 3015
+f 3014 3013 3015
+f 3015 3017 3016
+f 3016 3017 3018
+f 3017 3019 3018
+f 3018 3019 3020
+f 3019 3021 3020
+f 3020 3021 3022
+f 3021 3023 3022
+f 3022 3023 3024
+f 3023 3025 3024
+f 3024 3025 3026
+f 3026 3025 3028
+f 3025 3027 3028
+f 3029 3030 3027
+f 3028 3027 3030
+f 3030 3029 3032
+f 3029 3031 3032
+f 3034 3032 3033
+f 3032 3031 3033
+f 3038 3035 3037
+f 3035 3036 3037
+f 3038 3037 3040
+f 3037 3039 3040
+f 3040 3039 3042
+f 3039 3041 3042
+f 3044 3042 3043
+f 3042 3041 3043
+f 3043 3045 3044
+f 3044 3045 3046
+f 3046 3045 3048
+f 3045 3047 3048
+f 3050 3048 3049
+f 3048 3047 3049
+f 3050 3049 3052
+f 3049 3051 3052
+f 3052 3051 3054
+f 3051 3053 3054
+f 3055 3056 3053
+f 3054 3053 3056
+f 3058 3056 3057
+f 3056 3055 3057
+f 3057 3059 3058
+f 3058 3059 3060
+f 3062 3060 3061
+f 3060 3059 3061
+f 3064 3062 3063
+f 3062 3061 3063
+f 3066 3064 3065
+f 3064 3063 3065
+f 2947 3067 3068
+f 3070 2950 3069
+f 2950 2949 3069
+f 2950 3070 2960
+f 2960 3070 3071
+f 2959 2960 3072
+f 2960 3071 3072
+f 2958 2959 3073
+f 2959 3072 3073
+f 2957 2958 3074
+f 2958 3073 3074
+f 3074 3075 2957
+f 2956 2957 3075
+f 2956 3075 3076
+f 3077 2955 3076
+f 2955 2956 3076
+f 2955 3077 2954
+f 2954 3077 3078
+f 2953 2954 3079
+f 2954 3078 3079
+f 3079 3080 2953
+f 2952 2953 3080
+f 2952 3080 2948
+f 2948 3080 3081
+f 2948 3081 2947
+f 2947 3081 3067
+f 2803 2947 2807
+f 2947 2806 2807
+f 2947 2803 2933
+f 2947 3068 2805
+f 2947 2805 2804
+f 2947 2804 2806
+f 3083 3082 2745
+f 3082 2762 2745
+f 2808 2786 3085
+f 2786 3084 3085
+f 2744 2808 3086
+f 2808 3085 3086
+f 3082 2796 2762
+f 2744 3086 3083
+f 3086 3087 3083
+f 2745 2744 3083
+f 3088 3084 2785
+f 2786 2785 3084
+f 2811 3089 3090
+f 2795 2811 3091
+f 2811 3090 3091
+f 2785 2795 3088
+f 2795 3091 3088
+f 2813 2805 3068
+f 2810 2813 3067
+f 2813 3068 3067
+f 3067 3081 3089
+f 2810 3067 3089
+f 2961 3070 3069
+f 3087 3086 3000
+f 2998 3000 3086
+f 3086 3085 2998
+f 2996 2998 3085
+f 2994 2996 3084
+f 2996 3085 3084
+f 3084 3088 2994
+f 2992 2994 3088
+f 2992 3088 2990
+f 2990 3088 3091
+f 2988 2990 3090
+f 2990 3091 3090
+f 3089 2986 3090
+f 2986 2988 3090
+f 2984 2986 3089
+f 2982 2984 3081
+f 2984 3089 3081
+f 2980 2982 3080
+f 2982 3081 3080
+f 3080 3079 2980
+f 2978 2980 3079
+f 2976 2978 3078
+f 2978 3079 3078
+f 3078 3077 2976
+f 2974 2976 3077
+f 2972 2974 3076
+f 2974 3077 3076
+f 2970 2972 3075
+f 2972 3076 3075
+f 2968 2970 3075
+f 3075 3074 2968
+f 2966 2968 3074
+f 3074 3073 2966
+f 2964 2966 3073
+f 2964 3073 3072
+f 2961 2964 3071
+f 2964 3072 3071
+f 2961 3071 3070
+f 3001 3004 2962
+f 2962 3004 2963
+f 2965 2963 3006
+f 2963 3004 3006
+f 2967 2965 3008
+f 2965 3006 3008
+f 3008 3010 2967
+f 2967 3010 2969
+f 3010 3012 2969
+f 2969 3012 2971
+f 2973 2971 3014
+f 2971 3012 3014
+f 3014 3016 2973
+f 2973 3016 2975
+f 3016 3018 2975
+f 2975 3018 2977
+f 3018 3020 2977
+f 2977 3020 2979
+f 3020 3022 2979
+f 2979 3022 2981
+f 3022 3024 2981
+f 2981 3024 2983
+f 3024 3026 2983
+f 2983 3026 2985
+f 3028 2987 3026
+f 2985 3026 2987
+f 3030 2989 3028
+f 2987 3028 2989
+f 2989 3030 2991
+f 3030 3032 2991
+f 3032 3034 2991
+f 2991 3034 2993
+f 3034 3092 2993
+f 2993 3092 2995
+f 3092 3093 2995
+f 3003 3002 3038
+f 3002 3035 3038
+f 3040 3005 3038
+f 3003 3038 3005
+f 3042 3007 3040
+f 3005 3040 3007
+f 3009 3007 3044
+f 3007 3042 3044
+f 3009 3044 3011
+f 3044 3046 3011
+f 3011 3046 3013
+f 3046 3048 3013
+f 3015 3013 3050
+f 3013 3048 3050
+f 3017 3015 3052
+f 3015 3050 3052
+f 3052 3054 3017
+f 3017 3054 3019
+f 3021 3019 3056
+f 3019 3054 3056
+f 3056 3058 3021
+f 3021 3058 3023
+f 3058 3060 3023
+f 3023 3060 3025
+f 3027 3025 3062
+f 3025 3060 3062
+f 3027 3062 3029
+f 3062 3064 3029
+f 3029 3064 3031
+f 3064 3066 3031
+f 3066 3094 3031
+f 3031 3094 3033
+f 3095 2906 2926
+f 3096 3097 3098
+f 2811 2810 3089
+f 3036 3099 3037
+f 3099 3100 3037
+f 3101 3039 3100
+f 3037 3100 3039
+f 3039 3101 3041
+f 3101 3102 3041
+f 3043 3041 3103
+f 3041 3102 3103
+f 3103 3104 3043
+f 3043 3104 3045
+f 3105 3047 3104
+f 3045 3104 3047
+f 3106 3049 3105
+f 3047 3105 3049
+f 3107 3051 3106
+f 3049 3106 3051
+f 3051 3107 3053
+f 3107 3108 3053
+f 3053 3108 3055
+f 3108 3109 3055
+f 3057 3055 3110
+f 3055 3109 3110
+f 3059 3057 3111
+f 3057 3110 3111
+f 3061 3059 3112
+f 3059 3111 3112
+f 3112 3113 3061
+f 3061 3113 3063
+f 3113 3114 3063
+f 3063 3114 3065
+f 3099 3115 3100
+f 3115 3116 3100
+f 3100 3116 3101
+f 3116 3117 3101
+f 3102 3101 3118
+f 3101 3117 3118
+f 3119 3103 3118
+f 3102 3118 3103
+f 3103 3119 3104
+f 3119 3120 3104
+f 3104 3120 3105
+f 3120 3121 3105
+f 3122 3106 3121
+f 3105 3121 3106
+f 3106 3122 3107
+f 3122 3123 3107
+f 3108 3107 3124
+f 3107 3123 3124
+f 3124 3125 3108
+f 3108 3125 3109
+f 3109 3125 3110
+f 3125 3126 3110
+f 3111 3110 3127
+f 3110 3126 3127
+f 3128 3112 3127
+f 3111 3127 3112
+f 3113 3112 3129
+f 3112 3128 3129
+f 3114 3113 3130
+f 3113 3129 3130
+f 3114 3130 3132
+f 3130 3131 3132
+f 3065 3133 3066
+f 3094 3066 3133
+f 3065 3114 3134
+f 3114 3132 3134
+f 3065 3134 3135
+f 3065 3135 3133
+f 3137 3116 3136
+f 3115 3136 3116
+f 3116 3137 3117
+f 3137 3138 3117
+f 3139 3118 3138
+f 3117 3138 3118
+f 3118 3139 3119
+f 3139 3140 3119
+f 3141 3120 3140
+f 3119 3140 3120
+f 3142 3121 3141
+f 3120 3141 3121
+f 3121 3142 3122
+f 3142 3143 3122
+f 3122 3143 3123
+f 3143 3144 3123
+f 3144 3145 3123
+f 3123 3145 3124
+f 3125 3124 3146
+f 3124 3145 3146
+f 3147 3126 3146
+f 3125 3146 3126
+f 3147 3148 3126
+f 3126 3148 3127
+f 3149 3128 3148
+f 3127 3148 3128
+f 3150 3129 3149
+f 3128 3149 3129
+f 3129 3150 3130
+f 3150 3151 3130
+f 3131 3130 3152
+f 3130 3151 3152
+f 3154 3137 3153
+f 3136 3153 3137
+f 3155 3138 3154
+f 3137 3154 3138
+f 3138 3155 3139
+f 3155 3156 3139
+f 3140 3139 3157
+f 3139 3156 3157
+f 3141 3140 3158
+f 3140 3157 3158
+f 3158 3159 3141
+f 3141 3159 3142
+f 3159 3160 3142
+f 3142 3160 3143
+f 3144 3143 3161
+f 3143 3160 3161
+f 3145 3144 3162
+f 3144 3161 3162
+f 3163 3146 3162
+f 3145 3162 3146
+f 3146 3163 3147
+f 3163 3164 3147
+f 3148 3147 3165
+f 3147 3164 3165
+f 3165 3166 3148
+f 3148 3166 3149
+f 3166 3167 3149
+f 3149 3167 3150
+f 3167 3168 3150
+f 3150 3168 3151
+f 3153 3169 3154
+f 3169 3170 3154
+f 3170 3171 3154
+f 3154 3171 3155
+f 3156 3155 3172
+f 3155 3171 3172
+f 3157 3156 3173
+f 3156 3172 3173
+f 3157 3173 3158
+f 3173 3174 3158
+f 3159 3158 3175
+f 3158 3174 3175
+f 3160 3159 3176
+f 3159 3175 3176
+f 3176 3177 3160
+f 3160 3177 3161
+f 3177 3178 3161
+f 3161 3178 3162
+f 3162 3178 3163
+f 3178 3179 3163
+f 3163 3179 3164
+f 3179 3180 3164
+f 3180 3181 3164
+f 3164 3181 3165
+f 3166 3165 3182
+f 3165 3181 3182
+f 3182 3183 3166
+f 3166 3183 3167
+f 3168 3167 3184
+f 3167 3183 3184
+f 3186 3168 3185
+f 3168 3184 3185
+f 3190 3187 3189
+f 3187 3188 3189
+f 3191 3192 3189
+f 3190 3189 3192
+f 3193 3194 3191
+f 3192 3191 3194
+f 3195 3196 3193
+f 3194 3193 3196
+f 3196 3195 3198
+f 3195 3197 3198
+f 3198 3197 3200
+f 3197 3199 3200
+f 3199 3201 3200
+f 3200 3201 3202
+f 3204 3202 3203
+f 3202 3201 3203
+f 3203 3205 3204
+f 3204 3205 3206
+f 3206 3205 3208
+f 3205 3207 3208
+f 3209 3210 3207
+f 3208 3207 3210
+f 3210 3209 3212
+f 3209 3211 3212
+f 3212 3211 3214
+f 3211 3213 3214
+f 3214 3213 3216
+f 3213 3215 3216
+f 3188 3217 3189
+f 3217 3218 3189
+f 3189 3218 3191
+f 3218 3219 3191
+f 3191 3219 3193
+f 3219 3220 3193
+f 3221 3195 3220
+f 3193 3220 3195
+f 3222 3197 3221
+f 3195 3221 3197
+f 3199 3197 3223
+f 3197 3222 3223
+f 3201 3199 3224
+f 3199 3223 3224
+f 3224 3225 3201
+f 3201 3225 3203
+f 3225 3226 3203
+f 3203 3226 3205
+f 3205 3226 3207
+f 3226 3227 3207
+f 3207 3227 3209
+f 3227 3228 3209
+f 3209 3228 3211
+f 3228 3229 3211
+f 3213 3211 3230
+f 3211 3229 3230
+f 3230 3231 3213
+f 3213 3231 3215
+f 3217 3232 3218
+f 3232 3233 3218
+f 3219 3218 3234
+f 3218 3233 3234
+f 3220 3219 3235
+f 3219 3234 3235
+f 3221 3220 3236
+f 3220 3235 3236
+f 3221 3236 3222
+f 3236 3237 3222
+f 3222 3237 3223
+f 3237 3238 3223
+f 3224 3223 3239
+f 3223 3238 3239
+f 3239 3240 3224
+f 3224 3240 3225
+f 3240 3241 3225
+f 3225 3241 3226
+f 3226 3241 3227
+f 3241 3242 3227
+f 3242 3243 3227
+f 3227 3243 3228
+f 3183 3212 3184
+f 3212 3214 3184
+f 3183 3182 3212
+f 3210 3212 3182
+f 3182 3181 3210
+f 3208 3210 3181
+f 3208 3181 3206
+f 3206 3181 3180
+f 3180 3179 3206
+f 3204 3206 3179
+f 3202 3204 3178
+f 3204 3179 3178
+f 3200 3202 3177
+f 3202 3178 3177
+f 3177 3176 3200
+f 3198 3200 3176
+f 3175 3196 3176
+f 3196 3198 3176
+f 3174 3194 3175
+f 3194 3196 3175
+f 3173 3192 3174
+f 3192 3194 3174
+f 3192 3173 3190
+f 3190 3173 3172
+f 3244 3168 3186
+f 3151 3168 3152
+f 3245 3152 3168
+f 3244 3246 3168
+f 3246 3245 3168
+f 2748 2764 2750
+f 2750 2764 2760
+f 2935 2929 2951
+f 2929 2928 2951
+f 3185 3184 3247
+f 3248 3249 3215
+f 3216 3215 3249
+f 3184 3214 3247
+f 3214 3216 3247
+f 3251 3215 3250
+f 3215 3231 3250
+f 3215 3251 3248
+f 3254 3255 3253
+f 3252 3253 3255
+f 3254 3256 3255
+f 3260 3257 3259
+f 3257 3258 3259
+f 3263 3264 3262
+f 3261 3262 3264
+f 3265 3266 3268
+f 3266 3267 3268
+f 3269 3270 3265
+f 3270 3266 3265
+f 3271 3261 3264
+f 3272 3273 3271
+f 3274 3273 3272
+v -2.975439 -3.308754 1.253240
+v -2.845816 -3.273661 1.218321
+v -2.888628 -3.200302 1.210934
+v -3.042899 -3.193907 1.207296
+v -2.856957 -3.449728 1.356844
+v -2.736599 -3.394849 1.269577
+v -2.729567 -3.602976 1.377236
+v -2.631547 -3.559891 1.337380
+v -3.030627 -3.493327 1.322650
+v -2.981824 -3.608887 1.346959
+v -3.091252 -3.340925 1.235864
+v -3.135041 -3.243787 1.189436
+v -2.787341 -3.278502 1.138621
+v -2.699957 -3.390295 1.185593
+v -2.822497 -3.186549 1.120984
+v -2.770335 -3.208138 1.031045
+v -2.884711 -3.063896 0.993766
+v -2.909010 -3.084482 1.089147
+v -3.158524 -3.405872 1.197099
+v -3.184143 -3.298048 1.156892
+v -3.098730 -3.539123 1.252987
+v -3.031250 -3.095940 1.106355
+f 3278 3275 3277
+f 3275 3276 3277
+f 3275 3279 3276
+f 3279 3280 3276
+f 3280 3279 3282
+f 3281 3282 3279
+f 3284 3281 3283
+f 3279 3283 3281
+f 3279 3275 3283
+f 3275 3285 3283
+f 3275 3278 3285
+f 3278 3286 3285
+f 3276 3280 3287
+f 3287 3280 3288
+f 3277 3276 3289
+f 3289 3276 3287
+f 3290 3291 3289
+f 3291 3292 3289
+f 3285 3286 3293
+f 3293 3286 3294
+f 3285 3293 3283
+f 3283 3293 3295
+f 3295 3284 3283
+f 3277 3289 3296
+v -2.909010 -3.084482 1.089147
+v -2.884711 -3.063896 0.993766
+v -2.946527 -2.939327 0.986343
+v -2.986345 -2.933770 1.087679
+v -3.141072 -2.785287 1.032318
+v -3.196508 -2.788166 1.045431
+v -3.177108 -2.979305 1.139084
+v -3.107105 -2.947818 1.092235
+v -3.261810 -2.821069 1.088218
+v -3.223286 -3.001780 1.126176
+v -3.330406 -3.185190 0.950058
+v -3.316551 -3.168932 1.121229
+v -3.301857 -3.074776 1.114869
+v -3.333954 -3.058673 0.974748
+v -3.223246 -3.225388 0.976573
+v -3.217306 -3.187686 1.075214
+f 3300 3297 3299
+f 3297 3298 3299
+f 3303 3304 3302
+f 3301 3302 3304
+f 3302 3305 3303
+f 3303 3305 3306
+f 3308 3309 3307
+f 3307 3309 3310
+f 3308 3307 3312
+f 3311 3312 3307
+v -3.194170 -3.348553 1.007196
+v -3.184143 -3.298048 1.156892
+v -3.217306 -3.187686 1.075214
+v -3.223246 -3.225388 0.976573
+v -2.922908 -3.637036 1.059206
+v -2.981824 -3.608887 1.346959
+v -3.098730 -3.539123 1.252987
+v -3.082741 -3.598298 1.054556
+v -3.186750 -3.457336 1.025606
+v -3.158524 -3.405872 1.197099
+f 3314 3315 3313
+f 3313 3315 3316
+f 3317 3318 3320
+f 3318 3319 3320
+f 3321 3322 3313
+f 3322 3314 3313
+f 3320 3319 3321
+f 3319 3322 3321
+v -3.119570 -3.183977 0.870739
+v -3.223246 -3.225388 0.976573
+v -3.330406 -3.185190 0.950058
+v -3.294389 -3.166225 0.842823
+f 3323 3324 3326
+f 3324 3325 3326
+v -3.223246 -3.225388 0.976573
+v -3.119570 -3.183977 0.870739
+v -3.087335 -3.350463 0.831656
+v -3.194170 -3.348553 1.007196
+v -3.074557 -3.486847 0.843432
+v -3.186750 -3.457336 1.025606
+v -3.006867 -3.575464 0.830221
+v -3.082741 -3.598298 1.054556
+v -2.870422 -3.601724 0.843123
+v -2.922908 -3.637036 1.059206
+v -2.740824 -3.597601 0.875006
+v -2.791754 -3.635993 1.078555
+f 3329 3330 3328
+f 3327 3328 3330
+f 3329 3331 3330
+f 3331 3332 3330
+f 3332 3331 3334
+f 3333 3334 3331
+f 3334 3333 3336
+f 3335 3336 3333
+f 3336 3335 3338
+f 3337 3338 3335
+v -3.256731 -3.032131 0.849693
+v -3.294389 -3.166225 0.842823
+v -3.330406 -3.185190 0.950058
+v -3.333954 -3.058673 0.974748
+v -3.339637 -2.846837 0.966368
+v -3.300372 -2.795728 0.878984
+v -3.107105 -2.947818 1.092235
+v -3.031250 -3.095940 1.106355
+v -2.909010 -3.084482 1.089147
+v -2.986345 -2.933770 1.087679
+f 3339 3340 3342
+f 3340 3341 3342
+f 3344 3339 3343
+f 3342 3343 3339
+f 3345 3346 3348
+f 3346 3347 3348
+v -3.042899 -3.193907 1.207296
+v -2.888628 -3.200302 1.210934
+v -3.031250 -3.095940 1.106355
+v -3.121673 -3.120319 1.136456
+f 3350 3351 3349
+f 3349 3351 3352
+v -3.107105 -2.947818 1.092235
+v -3.177108 -2.979305 1.139084
+v -3.121673 -3.120319 1.136456
+v -3.031250 -3.095940 1.106355
+v -3.223286 -3.001780 1.126176
+v -3.169546 -3.135273 1.128247
+f 3356 3353 3355
+f 3353 3354 3355
+f 3354 3357 3355
+f 3357 3358 3355
+v -3.135041 -3.243787 1.189436
+v -3.042899 -3.193907 1.207296
+v -3.121673 -3.120319 1.136456
+v -3.169546 -3.135273 1.128247
+v -3.184143 -3.298048 1.156892
+v -3.217306 -3.187686 1.075214
+f 3360 3361 3359
+f 3359 3361 3362
+f 3363 3359 3364
+f 3359 3362 3364
+v -3.217306 -3.187686 1.075214
+v -3.169546 -3.135273 1.128247
+v -3.227676 -3.141660 1.103969
+v -3.223286 -3.001780 1.126176
+v -3.301857 -3.074776 1.114869
+v -3.302419 -3.017921 1.128514
+v -3.333954 -3.058673 0.974748
+v -3.320330 -2.827513 1.063914
+v -3.339637 -2.846837 0.966368
+f 3365 3366 3367
+f 3368 3369 3366
+f 3367 3366 3369
+f 3370 3371 3369
+f 3370 3372 3371
+f 3371 3372 3373
+v -2.803260 -3.213580 0.942403
+v -2.928681 -3.072892 0.924772
+v -2.884711 -3.063896 0.993766
+v -2.770335 -3.208138 1.031045
+f 3375 3376 3374
+f 3374 3376 3377
+v -2.928681 -3.072892 0.924772
+v -3.008412 -2.899760 0.904635
+v -2.946527 -2.939327 0.986343
+v -2.884711 -3.063896 0.993766
+f 3379 3380 3378
+f 3378 3380 3381
+v -2.787341 -3.278502 1.138621
+v -2.749355 -3.272099 1.034148
+v -2.770335 -3.208138 1.031045
+v -2.822497 -3.186549 1.120984
+v -2.631547 -3.559891 1.337380
+v -2.583580 -3.514267 1.278598
+v -2.699957 -3.390295 1.185593
+v -2.736599 -3.394849 1.269577
+v -2.524720 -3.561609 1.161535
+v -2.649491 -3.404362 1.100352
+v -2.593513 -3.536154 0.942450
+v -2.668957 -3.397513 0.943626
+v -2.749867 -3.295148 0.966073
+v -2.803260 -3.213580 0.942403
+f 3385 3382 3384
+f 3382 3383 3384
+f 3386 3387 3389
+f 3387 3388 3389
+f 3390 3391 3387
+f 3391 3388 3387
+f 3383 3382 3391
+f 3382 3388 3391
+f 3392 3393 3390
+f 3393 3391 3390
+f 3393 3394 3391
+f 3394 3383 3391
+f 3395 3384 3394
+f 3384 3383 3394
+v -3.166971 -3.002766 0.812106
+v -3.119570 -3.183977 0.870739
+v -3.294389 -3.166225 0.842823
+v -3.256731 -3.032131 0.849693
+v -3.069810 -2.928755 0.845236
+v -3.011987 -3.092000 0.860973
+v -3.008412 -2.899760 0.904635
+v -2.928681 -3.072892 0.924772
+v -3.184812 -2.768053 0.850127
+v -3.137383 -2.776449 0.844117
+v -3.040038 -2.780893 0.914614
+f 3396 3397 3398
+f 3399 3396 3398
+f 3397 3396 3401
+f 3396 3400 3401
+f 3402 3403 3400
+f 3400 3403 3401
+f 3404 3405 3396
+f 3405 3400 3396
+f 3405 3406 3400
+f 3406 3402 3400
+v -3.011987 -3.092000 0.860973
+v -2.944625 -3.282121 0.817054
+v -3.087335 -3.350463 0.831656
+v -3.119570 -3.183977 0.870739
+v -2.928681 -3.072892 0.924772
+v -2.803260 -3.213580 0.942403
+v -2.890885 -3.415616 0.819125
+v -3.074557 -3.486847 0.843432
+v -2.749867 -3.295148 0.966073
+f 3407 3408 3410
+f 3408 3409 3410
+f 3412 3408 3411
+f 3411 3408 3407
+f 3413 3414 3408
+f 3408 3414 3409
+f 3415 3413 3412
+f 3412 3413 3408
+v -3.300372 -2.795728 0.878984
+v -3.184812 -2.768053 0.850127
+v -3.166971 -3.002766 0.812106
+v -3.256731 -3.032131 0.849693
+f 3417 3418 3416
+f 3416 3418 3419
+v -3.006867 -3.575464 0.830221
+v -3.074557 -3.486847 0.843432
+v -2.890885 -3.415616 0.819125
+v -2.870422 -3.601724 0.843123
+v -2.668957 -3.397513 0.943626
+v -2.749867 -3.295148 0.966073
+v -2.740824 -3.597601 0.875006
+v -2.593513 -3.536154 0.942450
+v -2.791754 -3.635993 1.078555
+v -2.524720 -3.561609 1.161535
+v -2.729567 -3.602976 1.377236
+v -2.981824 -3.608887 1.346959
+v -2.922908 -3.637036 1.059206
+v -2.822497 -3.186549 1.120984
+v -2.909010 -3.084482 1.089147
+v -3.031250 -3.095940 1.106355
+v -2.583580 -3.514267 1.278598
+v -2.631547 -3.559891 1.337380
+f 3420 3421 3422
+f 3420 3422 3423
+f 3424 3422 3425
+f 3422 3426 3423
+f 3426 3422 3427
+f 3422 3424 3427
+f 3429 3428 3427
+f 3428 3426 3427
+f 3431 3432 3430
+f 3428 3430 3432
+f 3433 3434 3435
+f 3430 3428 3437
+f 3437 3428 3436
+f 3429 3436 3428
+v -3.008412 -2.899760 0.904635
+v -3.040038 -2.780893 0.914614
+v -3.016419 -2.765091 0.966671
+v -2.946527 -2.939327 0.986343
+v -3.078699 -2.553982 1.046834
+v -3.162498 -2.556375 1.058409
+v -3.141072 -2.785287 1.032318
+v -3.053267 -2.764905 1.043008
+v -3.347304 -2.573628 0.955211
+v -3.372066 -2.569159 0.904785
+v -3.339637 -2.846837 0.966368
+v -3.320330 -2.827513 1.063914
+v -3.251541 -2.564050 1.023627
+v -3.261810 -2.821069 1.088218
+v -3.196508 -2.788166 1.045431
+v -3.022819 -2.522240 0.979148
+v -3.300372 -2.795728 0.878984
+v -3.297886 -2.549020 0.861657
+v -3.184812 -2.768053 0.850127
+v -3.240554 -2.555467 0.856262
+v -3.137383 -2.776449 0.844117
+v -3.132772 -2.528669 0.848639
+v -3.046610 -2.510881 0.900772
+v -3.335942 -1.365685 0.724590
+v -3.319817 -1.365015 0.886015
+v -3.277510 -1.177346 0.915300
+v -3.279790 -1.162072 0.784602
+v -3.238094 -0.979377 0.961631
+v -3.233333 -0.683782 1.015512
+v -3.283698 -0.730967 0.793898
+v -3.251210 -0.948205 0.819868
+v -3.406618 -0.343461 0.746456
+v -3.415655 -0.308965 0.671045
+v -3.631292 0.701013 0.420276
+v -3.664355 0.932851 0.370749
+v -3.578170 0.837714 0.288502
+v -3.556552 0.704883 0.280630
+v -3.570384 0.385564 0.524480
+v -3.536654 0.442277 0.322000
+v -3.520188 0.140164 0.618561
+v -3.516840 0.149002 0.430359
+v -3.458251 -0.125950 0.731712
+v -3.470778 -0.078218 0.546398
+v -3.599077 0.796217 0.000000
+v -3.623861 0.911561 0.000000
+v -3.709741 1.351194 0.211745
+v -3.709827 1.417763 0.000000
+v -3.601668 1.293049 0.000000
+v -3.701634 1.272650 0.270469
+v -3.695872 1.156978 0.316829
+v -3.608593 1.163581 0.000000
+v -3.672431 1.044224 0.364991
+v -3.622326 1.005378 0.000000
+f 3441 3438 3440
+f 3438 3439 3440
+f 3443 3444 3442
+f 3442 3444 3445
+f 3447 3448 3446
+f 3446 3448 3449
+f 3446 3449 3450
+f 3450 3449 3451
+f 3450 3451 3443
+f 3443 3451 3452
+f 3443 3452 3444
+f 3440 3453 3445
+f 3445 3453 3442
+f 3448 3447 3454
+f 3454 3447 3455
+f 3454 3455 3456
+f 3456 3455 3457
+f 3458 3456 3459
+f 3456 3457 3459
+f 3439 3458 3460
+f 3458 3459 3460
+f 3439 3460 3440
+f 3440 3460 3453
+f 3462 3463 3461
+f 3461 3463 3464
+f 3466 3467 3465
+f 3465 3467 3468
+f 3464 3463 3468
+f 3463 3465 3468
+f 3467 3469 3470
+f 3472 3473 3471
+f 3471 3473 3474
+f 3475 3471 3476
+f 3471 3474 3476
+f 3478 3477 3476
+f 3477 3475 3476
+f 3477 3478 3479
+f 3479 3478 3480
+f 3480 3470 3479
+f 3469 3479 3470
+f 3472 3482 3473
+f 3481 3473 3482
+f 3483 3484 3485
+f 3486 3483 3485
+f 3487 3486 3488
+f 3486 3485 3488
+f 3489 3487 3490
+f 3487 3488 3490
+f 3489 3490 3472
+f 3472 3490 3482
+v -3.676450 -0.551317 0.077574
+v -3.740631 -0.558176 0.085478
+v -3.729470 -0.869371 0.096946
+v -3.699784 -0.759901 0.088664
+v -3.697889 -0.951955 0.098793
+v -3.733767 -1.141917 0.111139
+v -3.666536 -1.140372 0.078261
+v -3.743747 -1.367219 0.100951
+v -3.639696 -1.242349 0.057190
+v -3.823638 -1.557534 0.081533
+v -3.581963 -1.413947 -0.104371
+v -3.683069 -1.591975 -0.115233
+v -3.890388 -1.750102 0.017612
+v -3.828485 -1.786559 -0.114095
+v -3.778908 -0.541975 0.064258
+v -3.805841 -0.798961 0.099237
+v -3.843256 -0.981402 0.116282
+v -3.884588 -1.261469 0.148322
+v -3.914006 -1.486854 0.149147
+v -4.015306 -1.659952 0.130331
+v -4.107191 -1.836520 0.120149
+v -3.818598 -0.522690 0.055572
+v -3.900964 -0.780883 0.091579
+v -3.949814 -0.963797 0.140806
+v -3.974499 -1.169600 0.164243
+v -4.018866 -1.413191 0.154149
+v -4.154334 -1.677827 0.165852
+v -4.207566 -1.922824 0.155104
+v -3.896204 -0.629183 0.077883
+v -3.978115 -0.823440 0.099280
+v -4.029726 -1.043238 0.136305
+v -4.129295 -1.228786 0.120745
+v -4.184154 -1.598080 0.151191
+v -4.297769 -1.889903 0.177707
+v -3.932489 -0.556566 0.037354
+v -4.070739 -0.947648 0.110554
+v -4.227645 -1.227895 0.069894
+v -4.229164 -1.473093 0.111560
+v -4.309744 -1.743848 0.150329
+v -4.405365 -1.921443 0.192978
+v -3.975337 -0.554961 -0.014407
+v -4.112449 -0.875765 0.016326
+v -4.233834 -1.166542 0.022074
+v -4.333831 -1.548255 0.056938
+v -4.424122 -1.831742 0.130839
+v -4.445835 -2.015127 0.189702
+v -3.921874 -0.538502 -0.145307
+v -4.042715 -0.876710 -0.168968
+v -4.216296 -1.160854 -0.104034
+v -4.252683 -1.437854 -0.145620
+v -4.331331 -1.692590 -0.043593
+v -4.387148 -1.967814 0.045602
+v -3.910546 -0.601719 -0.163159
+v -3.988138 -0.962789 -0.223649
+v -4.111927 -1.333141 -0.267160
+v -4.201904 -1.668554 -0.214859
+v -4.273069 -1.798884 -0.099878
+v -4.351543 -1.947675 0.025020
+v -3.873622 -0.759035 -0.197169
+v -3.917882 -1.082831 -0.289171
+v -4.001496 -1.375703 -0.285641
+v -4.073086 -1.649491 -0.238382
+v -4.175757 -1.808223 -0.140659
+v -4.321269 -1.963488 0.025072
+v -3.742608 -0.729374 -0.149361
+v -3.777709 -1.051411 -0.240495
+v -3.820370 -1.239135 -0.269807
+v -4.000019 -1.567512 -0.275350
+v -3.977657 -1.750845 -0.184909
+v -4.075028 -1.904403 -0.041324
+v -4.192486 -1.953852 0.017313
+f 3491 3492 3493
+f 3491 3493 3494
+f 3494 3493 3495
+f 3495 3493 3496
+f 3495 3496 3497
+f 3497 3496 3498
+f 3497 3498 3499
+f 3499 3498 3500
+f 3499 3500 3501
+f 3501 3500 3502
+f 3502 3500 3503
+f 3502 3503 3504
+f 3492 3505 3493
+f 3505 3506 3493
+f 3493 3506 3496
+f 3506 3507 3496
+f 3507 3508 3496
+f 3496 3508 3498
+f 3508 3509 3498
+f 3498 3509 3500
+f 3509 3510 3500
+f 3500 3510 3503
+f 3510 3511 3503
+f 3505 3512 3513
+f 3505 3513 3506
+f 3506 3513 3514
+f 3506 3514 3507
+f 3507 3514 3515
+f 3507 3515 3508
+f 3508 3515 3516
+f 3508 3516 3509
+f 3509 3516 3517
+f 3509 3517 3510
+f 3510 3517 3518
+f 3510 3518 3511
+f 3512 3519 3520
+f 3512 3520 3513
+f 3513 3520 3521
+f 3513 3521 3514
+f 3514 3521 3515
+f 3515 3521 3522
+f 3515 3522 3516
+f 3516 3522 3523
+f 3516 3523 3517
+f 3517 3523 3524
+f 3517 3524 3518
+f 3519 3525 3526
+f 3519 3526 3520
+f 3520 3526 3527
+f 3520 3527 3521
+f 3521 3527 3528
+f 3521 3528 3522
+f 3522 3528 3529
+f 3522 3529 3523
+f 3523 3529 3530
+f 3523 3530 3524
+f 3525 3531 3532
+f 3525 3532 3526
+f 3526 3532 3533
+f 3526 3533 3527
+f 3527 3533 3534
+f 3527 3534 3528
+f 3528 3534 3535
+f 3528 3535 3529
+f 3529 3535 3536
+f 3529 3536 3530
+f 3531 3537 3538
+f 3531 3538 3532
+f 3532 3538 3539
+f 3532 3539 3533
+f 3533 3539 3540
+f 3533 3540 3534
+f 3534 3540 3541
+f 3534 3541 3535
+f 3535 3541 3542
+f 3535 3542 3536
+f 3537 3543 3544
+f 3537 3544 3538
+f 3538 3544 3545
+f 3538 3545 3539
+f 3539 3545 3546
+f 3539 3546 3540
+f 3540 3546 3547
+f 3540 3547 3541
+f 3541 3547 3548
+f 3541 3548 3542
+f 3543 3549 3550
+f 3543 3550 3544
+f 3544 3550 3551
+f 3544 3551 3545
+f 3545 3551 3552
+f 3545 3552 3546
+f 3546 3552 3553
+f 3546 3553 3547
+f 3547 3553 3554
+f 3547 3554 3548
+f 3549 3555 3550
+f 3555 3556 3550
+f 3550 3556 3551
+f 3556 3557 3551
+f 3557 3558 3551
+f 3551 3558 3552
+f 3558 3559 3552
+f 3552 3559 3553
+f 3559 3560 3553
+f 3553 3560 3554
+f 3560 3561 3554
+v -3.860740 -0.188349 -0.024962
+v -3.845990 -0.188820 0.019164
+v -3.817430 0.150343 0.048629
+v -3.828633 0.149083 0.000000
+v -3.844470 0.498176 0.053132
+v -3.856649 0.496801 0.000000
+v -3.887340 1.003866 0.057635
+v -3.900566 1.002504 0.000000
+v -3.860820 1.479723 0.062137
+v -3.875140 1.480358 0.000000
+v -3.698925 1.787941 0.066640
+v -3.712832 1.794492 0.000000
+v -3.469715 1.961504 0.071141
+v -3.478430 1.975409 0.000000
+v -3.238225 2.005405 0.075645
+v -3.242148 2.021387 0.000000
+v -3.805688 -0.190106 0.051472
+v -3.786822 0.153783 0.084233
+v -3.811194 0.501935 0.092033
+v -3.851206 1.007586 0.099831
+v -3.821694 1.477989 0.107631
+v -3.660928 1.770041 0.115431
+v -3.445903 1.923509 0.123229
+v -3.227504 1.961738 0.131029
+v -3.750630 -0.191863 0.063305
+v -3.745007 0.158482 0.097274
+v -3.765736 0.507070 0.106281
+v -3.801840 1.012668 0.115288
+v -3.768245 1.475619 0.124295
+v -3.609021 1.745588 0.133304
+v -3.413372 1.871604 0.142309
+v -3.695565 -0.193620 0.051497
+v -3.703185 0.163182 0.084262
+v -3.720269 0.512205 0.092064
+v -3.752468 1.017751 0.099865
+v -3.714787 1.473248 0.107668
+v -3.557104 1.721130 0.115470
+v -3.380836 1.819691 0.123273
+v -3.655240 -0.194907 0.019209
+v -3.672559 0.166625 0.048678
+v -3.686972 0.515966 0.053185
+v -3.716312 1.021474 0.057693
+v -3.675638 1.471512 0.062201
+v -3.519086 1.703220 0.066709
+v -3.357009 1.781675 0.071216
+v -3.640457 -0.195379 -0.024909
+v -3.661331 0.167886 0.000058
+v -3.674766 0.517345 -0.000063
+v -3.703058 1.022838 -0.000069
+v -3.661286 1.470876 -0.000074
+v -3.507689 1.700214 0.000000
+v -3.348274 1.767738 -0.000085
+v -3.655175 -0.194909 -0.069044
+v -3.672510 0.166630 -0.048579
+v -3.686972 0.515966 -0.053185
+v -3.695452 -0.193624 -0.101369
+v -3.703099 0.163192 -0.084205
+v -3.720269 0.512205 -0.092064
+v -3.750500 -0.191867 -0.113230
+v -3.744907 0.158493 -0.097274
+v -3.765736 0.507070 -0.106281
+v -3.805575 -0.190109 -0.101447
+v -3.786736 0.153792 -0.084291
+v -3.811194 0.501935 -0.092033
+v -3.845923 -0.188822 -0.069180
+v -3.817381 0.150348 -0.048728
+v -3.844470 0.498176 -0.053132
+f 3564 3565 3563
+f 3562 3563 3565
+f 3564 3566 3565
+f 3565 3566 3567
+f 3567 3566 3569
+f 3566 3568 3569
+f 3569 3568 3571
+f 3568 3570 3571
+f 3573 3571 3572
+f 3571 3570 3572
+f 3573 3572 3575
+f 3572 3574 3575
+f 3575 3574 3577
+f 3574 3576 3577
+f 3578 3579 3563
+f 3563 3579 3564
+f 3579 3580 3564
+f 3564 3580 3566
+f 3566 3580 3568
+f 3580 3581 3568
+f 3568 3581 3570
+f 3581 3582 3570
+f 3570 3582 3572
+f 3582 3583 3572
+f 3572 3583 3574
+f 3583 3584 3574
+f 3576 3574 3585
+f 3574 3584 3585
+f 3586 3587 3578
+f 3578 3587 3579
+f 3587 3588 3579
+f 3579 3588 3580
+f 3580 3588 3581
+f 3588 3589 3581
+f 3581 3589 3582
+f 3589 3590 3582
+f 3583 3582 3591
+f 3582 3590 3591
+f 3584 3583 3592
+f 3583 3591 3592
+f 3584 3592 3585
+f 3594 3587 3593
+f 3586 3593 3587
+f 3587 3594 3588
+f 3594 3595 3588
+f 3588 3595 3589
+f 3595 3596 3589
+f 3589 3596 3590
+f 3596 3597 3590
+f 3590 3597 3591
+f 3597 3598 3591
+f 3592 3591 3599
+f 3591 3598 3599
+f 3601 3594 3600
+f 3593 3600 3594
+f 3602 3595 3601
+f 3594 3601 3595
+f 3595 3602 3596
+f 3602 3603 3596
+f 3596 3603 3597
+f 3603 3604 3597
+f 3597 3604 3598
+f 3604 3605 3598
+f 3598 3605 3599
+f 3605 3606 3599
+f 3607 3608 3600
+f 3600 3608 3601
+f 3601 3608 3602
+f 3608 3609 3602
+f 3602 3609 3603
+f 3609 3610 3603
+f 3603 3610 3604
+f 3610 3611 3604
+f 3604 3611 3605
+f 3611 3612 3605
+f 3606 3605 3613
+f 3605 3612 3613
+f 3608 3607 3615
+f 3607 3614 3615
+f 3615 3616 3608
+f 3608 3616 3609
+f 3615 3614 3618
+f 3614 3617 3618
+f 3616 3615 3619
+f 3615 3618 3619
+f 3618 3617 3621
+f 3617 3620 3621
+f 3621 3622 3618
+f 3618 3622 3619
+f 3620 3623 3621
+f 3623 3624 3621
+f 3621 3624 3622
+f 3624 3625 3622
+f 3623 3626 3624
+f 3626 3627 3624
+f 3624 3627 3625
+f 3627 3628 3625
+f 3626 3562 3627
+f 3562 3565 3627
+f 3627 3565 3628
+f 3565 3567 3628
+v -3.655240 -0.194907 0.019209
+v -3.695565 -0.193620 0.051497
+v -3.740631 -0.558176 0.085478
+v -3.676450 -0.551317 0.077574
+v -3.805688 -0.190106 0.051472
+v -3.975337 -0.554961 -0.014407
+v -3.932489 -0.556566 0.037354
+v -3.896204 -0.629183 0.077883
+v -3.818598 -0.522690 0.055572
+v -3.750630 -0.191863 0.063305
+v -3.778908 -0.541975 0.064258
+v -3.845990 -0.188820 0.019164
+v -3.860740 -0.188349 -0.024962
+v -3.695452 -0.193624 -0.101369
+v -3.742608 -0.729374 -0.149361
+v -3.873622 -0.759035 -0.197169
+v -3.750500 -0.191867 -0.113230
+v -3.805575 -0.190109 -0.101447
+v -3.910546 -0.601719 -0.163159
+v -3.921874 -0.538502 -0.145307
+v -3.845923 -0.188822 -0.069180
+v -3.655175 -0.194909 -0.069044
+v -3.640457 -0.195379 -0.024909
+v -3.569386 -0.761644 -0.035893
+v -3.697889 -0.951955 0.098793
+v -3.666536 -1.140372 0.078261
+v -3.820370 -1.239135 -0.269807
+v -3.777709 -1.051411 -0.240495
+v -3.581963 -1.413947 -0.104371
+v -3.639696 -1.242349 0.057190
+v -3.977657 -1.750845 -0.184909
+v -3.890388 -1.750102 0.017612
+v -4.075028 -1.904403 -0.041324
+v -4.000019 -1.567512 -0.275350
+v -3.683069 -1.591975 -0.115233
+v -3.828485 -1.786559 -0.114095
+v -4.107191 -1.836520 0.120149
+v -4.207566 -1.922824 0.155104
+v -4.405365 -1.921443 0.192978
+v -4.387148 -1.967814 0.045602
+v -4.297769 -1.889903 0.177707
+v -4.192486 -1.953852 0.017313
+v -4.321269 -1.963488 0.025072
+v -4.351543 -1.947675 0.025020
+v -4.445835 -2.015127 0.189702
+f 3631 3632 3630
+f 3629 3630 3632
+f 3633 3634 3635
+f 3633 3635 3636
+f 3633 3636 3637
+f 3638 3633 3637
+f 3638 3637 3639
+f 3630 3639 3631
+f 3640 3641 3634
+f 3642 3643 3644
+f 3645 3642 3644
+f 3646 3645 3644
+f 3646 3644 3647
+f 3646 3647 3648
+f 3649 3646 3648
+f 3641 3648 3634
+f 3643 3650 3651
+f 3643 3642 3650
+f 3629 3632 3652
+f 3652 3643 3651
+f 3632 3653 3654
+f 3655 3656 3657
+f 3652 3632 3654
+f 3652 3654 3658
+f 3652 3658 3657
+f 3643 3652 3657
+f 3656 3643 3657
+f 3659 3660 3661
+f 3659 3662 3655
+f 3655 3657 3663
+f 3655 3663 3664
+f 3655 3664 3660
+f 3659 3655 3660
+f 3660 3665 3661
+f 3665 3666 3661
+f 3667 3668 3669
+f 3670 3661 3666
+f 3670 3666 3669
+f 3671 3670 3669
+f 3672 3671 3669
+f 3668 3672 3669
+f 3667 3673 3668
+f 3630 3638 3639
+f 3633 3640 3634
+f 3641 3649 3648
+f 3652 3651 3629
+v -3.413372 1.871604 0.142309
+v -3.077669 1.871112 0.217368
+v -3.227504 1.961738 0.131029
+v -3.053102 1.968810 0.051104
+v -3.037562 2.001526 0.000000
+v -3.242148 2.021387 0.000000
+v -3.238225 2.005405 0.075645
+v -3.358510 1.810253 0.380095
+v -3.075310 1.846000 0.363149
+f 3674 3675 3676
+f 3679 3680 3678
+f 3677 3678 3680
+f 3677 3680 3676
+f 3675 3677 3676
+f 3674 3681 3675
+f 3681 3682 3675
+v -1.936032 -1.829617 0.488916
+v -1.971059 -1.992958 0.500845
+v -1.933565 -1.993029 0.438902
+v -1.883160 -1.829718 0.401567
+v -2.027242 -1.813012 0.555232
+v -2.035740 -1.981182 0.547873
+v -2.126375 -1.866497 0.502895
+v -2.106039 -2.019111 0.510759
+v -2.176551 -1.873816 0.445782
+v -2.141621 -2.024301 0.470257
+v -2.147113 -1.903198 0.362462
+v -2.120746 -2.045137 0.411171
+v -2.062725 -1.884246 0.307336
+v -2.060902 -2.031698 0.372079
+v -1.946306 -1.872735 0.344251
+v -1.978344 -2.023535 0.398257
+v -2.466779 -1.857679 0.570461
+v -2.513608 -2.012858 0.558673
+v -2.499138 -2.038090 0.504529
+v -2.446375 -1.893261 0.494110
+v -2.547737 -1.833025 0.609321
+v -2.571019 -1.995375 0.586230
+v -2.647220 -1.844010 0.594347
+v -2.641567 -2.003164 0.575611
+v -2.699966 -1.850397 0.570070
+v -2.678971 -2.007694 0.558395
+v -2.709403 -1.879947 0.508775
+v -2.685663 -2.028649 0.514928
+v -2.684452 -1.891207 0.447388
+v -2.667969 -2.036634 0.471396
+v -2.614084 -1.905005 0.404925
+v -2.618068 -2.046419 0.441284
+v -2.503818 -1.909806 0.431456
+v -2.539874 -2.049824 0.460098
+v -1.985123 -2.116661 0.394256
+v -2.065655 -2.124623 0.368720
+v -2.124030 -2.137733 0.406853
+v -2.144393 -2.117408 0.464489
+v -2.109684 -2.112345 0.503997
+v -2.041110 -2.075348 0.540201
+v -1.978016 -2.086834 0.494327
+v -1.941442 -2.086904 0.433904
+v -2.513187 -2.130859 0.497920
+v -2.552923 -2.142304 0.454579
+v -2.629199 -2.138983 0.436227
+v -2.677875 -2.129439 0.465600
+v -2.695135 -2.121650 0.508064
+v -2.688607 -2.101208 0.550465
+v -2.652120 -2.096790 0.567258
+v -2.583303 -2.089191 0.577616
+v -2.527301 -2.106246 0.550735
+v -2.048681 -2.165282 0.450843
+v -2.603284 -2.176802 0.510638
+f 3686 3683 3685
+f 3683 3684 3685
+f 3687 3688 3683
+f 3688 3684 3683
+f 3687 3689 3688
+f 3689 3690 3688
+f 3691 3692 3689
+f 3692 3690 3689
+f 3691 3693 3692
+f 3693 3694 3692
+f 3695 3696 3693
+f 3696 3694 3693
+f 3695 3697 3696
+f 3697 3698 3696
+f 3686 3685 3697
+f 3685 3698 3697
+f 3702 3699 3701
+f 3699 3700 3701
+f 3703 3704 3699
+f 3704 3700 3699
+f 3703 3705 3704
+f 3705 3706 3704
+f 3707 3708 3705
+f 3708 3706 3705
+f 3707 3709 3708
+f 3709 3710 3708
+f 3709 3711 3710
+f 3711 3712 3710
+f 3711 3713 3712
+f 3713 3714 3712
+f 3715 3716 3713
+f 3716 3714 3713
+f 3702 3701 3715
+f 3701 3716 3715
+f 3698 3717 3696
+f 3717 3718 3696
+f 3696 3718 3694
+f 3718 3719 3694
+f 3719 3720 3694
+f 3694 3720 3692
+f 3720 3721 3692
+f 3692 3721 3690
+f 3688 3690 3722
+f 3690 3721 3722
+f 3722 3723 3688
+f 3688 3723 3684
+f 3684 3723 3685
+f 3723 3724 3685
+f 3685 3724 3698
+f 3724 3717 3698
+f 3701 3725 3716
+f 3725 3726 3716
+f 3716 3726 3714
+f 3726 3727 3714
+f 3712 3714 3728
+f 3714 3727 3728
+f 3710 3712 3729
+f 3712 3728 3729
+f 3729 3730 3710
+f 3710 3730 3708
+f 3730 3731 3708
+f 3708 3731 3706
+f 3706 3731 3704
+f 3731 3732 3704
+f 3732 3733 3704
+f 3704 3733 3700
+f 3700 3733 3701
+f 3733 3725 3701
+f 3734 3724 3723
+f 3734 3723 3722
+f 3734 3722 3721
+f 3734 3721 3720
+f 3734 3720 3719
+f 3734 3719 3718
+f 3734 3718 3717
+f 3734 3717 3724
+f 3735 3725 3733
+f 3735 3733 3732
+f 3735 3732 3731
+f 3735 3731 3730
+f 3735 3730 3729
+f 3735 3729 3728
+f 3735 3728 3727
+f 3735 3727 3726
+f 3735 3726 3725
+v 4.925499 1.917814 0.613413
+v 4.953403 1.907939 0.605609
+v 4.971872 1.924079 0.586026
+v 4.953739 1.952580 0.592256
+v 4.925394 1.955229 0.618837
+v 4.897808 1.946794 0.628057
+v 5.001903 1.914398 0.486724
+v 4.973133 1.992779 0.533466
+v 4.982364 1.873300 0.536190
+v 4.926194 1.859813 0.582137
+v 4.852578 1.889721 0.605031
+v 4.824747 1.946835 0.626358
+v 4.861611 2.001639 0.621913
+v 4.935561 2.016016 0.585700
+f 3741 3736 3740
+f 3740 3736 3739
+f 3736 3737 3739
+f 3737 3738 3739
+f 3739 3738 3743
+f 3738 3742 3743
+f 3742 3738 3744
+f 3737 3744 3738
+f 3745 3744 3737
+f 3746 3745 3736
+f 3745 3737 3736
+f 3747 3746 3741
+f 3746 3736 3741
+f 3748 3747 3741
+f 3743 3749 3739
+f 3740 3739 3749
+v 4.861618 1.854067 0.618095
+v 4.852578 1.889721 0.605031
+v 4.824747 1.946835 0.626358
+v 4.760921 1.881357 0.613120
+v 4.935561 2.016016 0.585700
+v 4.935880 2.051665 0.572853
+v 4.842883 2.021333 0.638025
+v 4.861611 2.001639 0.621913
+v 4.973133 1.992779 0.533466
+v 5.001903 1.914398 0.486724
+v 4.991746 2.009819 0.523206
+v 4.944706 1.840663 0.575374
+v 4.926194 1.859813 0.582137
+v 4.991709 1.844295 0.520761
+v 4.982364 1.873300 0.536190
+v 4.852582 1.816115 0.603105
+v 4.908019 1.796041 0.587882
+v 4.963546 1.783161 0.553515
+v 4.983034 1.806343 0.505779
+v 5.011430 1.875569 0.463205
+v 4.964945 2.053575 0.499903
+v 4.918466 2.084725 0.532713
+v 5.020077 1.978170 0.480978
+v 4.881574 2.094571 0.539949
+v 4.825996 2.089176 0.576083
+v 4.788476 2.028047 0.608619
+v 4.798297 2.118191 0.591085
+v 4.751519 2.039658 0.634134
+v 4.872539 2.159259 0.542891
+v 4.927885 2.156560 0.516579
+v 5.002440 2.105746 0.468233
+v 5.057495 2.002751 0.451974
+v 5.075994 1.900999 0.443793
+v 5.030289 1.827419 0.440803
+v 4.991904 1.760829 0.510386
+v 4.936066 1.737668 0.557276
+v 4.871155 1.741238 0.592326
+v 4.816181 1.797860 0.604026
+v 5.085813 1.888503 0.408327
+v 5.095375 1.961238 0.401516
+v 5.058179 1.788186 0.417387
+v 5.019836 1.739907 0.485562
+v 4.917973 1.681480 0.544201
+v 4.862636 1.684144 0.570155
+v 4.752337 1.723388 0.591296
+v 4.697607 1.768061 0.576663
+v 5.067202 2.027704 0.422291
+v 5.030641 2.102197 0.432329
+v 4.937950 2.181155 0.486939
+v 4.881855 2.194544 0.530288
+v 4.807794 2.143653 0.570393
+v 4.728963 2.036146 0.614307
+v 4.742358 1.882232 0.621650
+v 4.688114 2.046378 0.604518
+v 4.744050 2.179337 0.556057
+v 4.837331 2.235678 0.479332
+v 4.893850 2.220523 0.417713
+v 4.995978 2.148785 0.344534
+v 5.060840 2.053335 0.309324
+v 5.097062 1.954206 0.328795
+v 5.105589 1.864086 0.347113
+v 4.697024 1.862575 0.604048
+v 4.832890 2.262727 0.283787
+v 4.739441 2.299169 0.369987
+v 4.971394 2.146686 0.224781
+v 5.072165 2.043630 0.209228
+v 5.127157 1.942759 0.211214
+v 5.152698 1.830661 0.287042
+v 5.133171 1.715563 0.334258
+v 5.103427 1.624404 0.434275
+v 4.982822 1.503071 0.507606
+v 4.927282 1.486953 0.526327
+v 4.798410 1.473149 0.570618
+v 4.715646 1.502195 0.584339
+v 4.615408 1.639641 0.577768
+v 4.560751 1.785154 0.562428
+v 4.551484 1.841749 0.575191
+v 4.533113 1.989009 0.578975
+v 4.561299 2.133066 0.547248
+v 4.636582 2.263383 0.471997
+v 5.049690 2.032731 0.000071
+v 4.912303 2.162645 -0.000090
+v 5.156645 1.942902 0.119993
+v 5.218821 1.803552 0.199306
+v 5.216855 1.636645 0.279797
+v 5.233176 1.442459 0.362988
+v 4.596478 1.512987 0.598982
+v 4.679116 1.438434 0.589658
+v 4.560024 1.604023 0.589333
+v 4.477781 1.687858 0.597407
+v 4.459682 1.778884 0.588185
+v 4.432610 1.878873 0.577888
+v 4.433020 2.024714 0.563794
+v 4.747988 2.300163 -0.000276
+v 4.634996 2.369115 0.140117
+v 4.577573 2.389535 0.256196
+v 4.472349 2.325133 0.443764
+v 4.389484 2.190421 0.473320
+v 5.223191 1.371491 0.388069
+v 5.158322 1.236770 0.418043
+v 4.955360 1.236724 0.505230
+v 4.761601 1.363013 0.571370
+v 5.321136 1.795562 0.119606
+v 5.177545 1.932323 0.000214
+v 5.378289 1.768448 0.000441
+v 5.421809 1.685349 0.123555
+v 5.424281 1.721152 0.000496
+v 5.383208 1.619661 0.202452
+v 5.373133 1.541142 0.246712
+v 5.334328 1.402713 0.332639
+v 5.296963 1.322443 0.357984
+v 5.260653 1.184173 0.352062
+v 5.250485 1.123029 0.385234
+v 4.991713 1.163096 0.504149
+v 4.733657 1.227371 0.592883
+v 4.641547 1.285422 0.622034
+v 4.522247 1.398278 0.644892
+v 4.430999 1.535753 0.638888
+v 4.404221 1.662433 0.616610
+v 4.386380 1.770868 0.596666
+v 4.377095 1.871713 0.595743
+v 5.604888 1.546091 0.113773
+v 5.588763 1.573846 0.000686
+v 5.566339 1.498677 0.190905
+v 5.528186 1.440180 0.250666
+v 5.471928 1.345179 0.313899
+v 5.425783 1.264372 0.329687
+v 5.397967 1.174238 0.346802
+v 5.388455 1.119419 0.351883
+v 5.685194 1.452202 0.188749
+v 5.730427 1.435668 0.209848
+v 5.741781 1.463956 0.124891
+v 5.687035 1.499636 0.110765
+v 5.647186 1.394606 0.257833
+v 5.608974 1.317869 0.319719
+v 5.710154 1.360653 0.290072
+v 5.563253 1.235295 0.317238
+v 5.681726 1.282503 0.333871
+v 5.580797 1.174135 0.351054
+v 5.672187 1.164767 0.354080
+v 5.680007 1.510009 0.000786
+v 5.479630 1.111310 0.364188
+v 5.813217 1.415581 0.195261
+v 5.886832 1.385674 0.172365
+v 5.915025 1.382159 0.136820
+v 5.842092 1.427708 0.130724
+v 5.979357 1.325532 0.125337
+v 5.963117 1.307775 0.001098
+v 5.908842 1.388968 0.001026
+v 5.941384 1.330818 0.178936
+v 5.835498 1.436280 0.000946
+v 5.743997 1.482739 0.000851
+v 5.783731 1.341471 0.284590
+v 5.847989 1.311569 0.261476
+v 5.931474 1.233483 0.215613
+v 5.998088 1.231874 0.107334
+v 5.963527 1.232407 0.001121
+v 5.961686 1.110978 0.090324
+v 5.927110 1.131195 0.001118
+v 5.934596 1.054796 0.077039
+v 5.908782 1.066916 0.001121
+f 3750 3751 3753
+f 3751 3752 3753
+f 3755 3756 3754
+f 3754 3756 3757
+f 3758 3759 3760
+f 3761 3762 3750
+f 3751 3750 3762
+f 3762 3761 3764
+f 3761 3763 3764
+f 3761 3750 3766
+f 3765 3766 3750
+f 3763 3761 3767
+f 3766 3767 3761
+f 3767 3768 3763
+f 3768 3769 3763
+f 3760 3770 3755
+f 3755 3770 3771
+f 3760 3772 3770
+f 3769 3772 3760
+f 3755 3773 3756
+f 3773 3774 3756
+f 3753 3756 3775
+f 3775 3756 3774
+f 3777 3775 3776
+f 3775 3774 3776
+f 3776 3774 3778
+f 3774 3773 3778
+f 3779 3778 3771
+f 3773 3771 3778
+f 3779 3771 3780
+f 3771 3770 3780
+f 3781 3780 3772
+f 3770 3772 3780
+f 3769 3782 3772
+f 3772 3782 3781
+f 3769 3783 3782
+f 3784 3783 3768
+f 3768 3783 3769
+f 3785 3784 3767
+f 3767 3784 3768
+f 3786 3785 3766
+f 3785 3767 3766
+f 3787 3786 3765
+f 3786 3766 3765
+f 3787 3765 3753
+f 3788 3789 3782
+f 3788 3782 3790
+f 3783 3790 3782
+f 3784 3791 3783
+f 3791 3790 3783
+f 3792 3791 3785
+f 3785 3791 3784
+f 3785 3786 3792
+f 3793 3792 3786
+f 3794 3793 3787
+f 3793 3786 3787
+f 3753 3795 3787
+f 3795 3794 3787
+f 3781 3796 3780
+f 3796 3797 3780
+f 3797 3798 3780
+f 3779 3780 3798
+f 3798 3799 3779
+f 3778 3779 3799
+f 3776 3778 3800
+f 3800 3778 3799
+f 3800 3801 3776
+f 3801 3777 3776
+f 3777 3801 3753
+f 3753 3801 3802
+f 3795 3753 3802
+f 3804 3803 3800
+f 3803 3801 3800
+f 3805 3804 3799
+f 3800 3799 3804
+f 3806 3805 3798
+f 3799 3798 3805
+f 3807 3806 3797
+f 3798 3797 3806
+f 3807 3797 3808
+f 3797 3796 3808
+f 3808 3796 3809
+f 3796 3789 3809
+f 3809 3789 3810
+f 3788 3810 3789
+f 3790 3810 3788
+f 3795 3802 3811
+f 3812 3813 3806
+f 3806 3813 3805
+f 3814 3812 3807
+f 3806 3807 3812
+f 3814 3807 3815
+f 3807 3808 3815
+f 3809 3816 3808
+f 3808 3816 3815
+f 3816 3809 3817
+f 3809 3810 3817
+f 3790 3818 3810
+f 3818 3817 3810
+f 3818 3790 3819
+f 3791 3819 3790
+f 3820 3819 3792
+f 3792 3819 3791
+f 3793 3821 3792
+f 3821 3820 3792
+f 3822 3821 3793
+f 3794 3823 3793
+f 3823 3822 3793
+f 3823 3794 3824
+f 3824 3794 3795
+f 3824 3795 3825
+f 3825 3795 3811
+f 3825 3811 3826
+f 3811 3803 3826
+f 3826 3803 3827
+f 3829 3828 3804
+f 3828 3803 3804
+f 3827 3803 3828
+f 3831 3814 3830
+f 3814 3815 3830
+f 3830 3815 3832
+f 3815 3816 3832
+f 3832 3816 3833
+f 3816 3817 3833
+f 3834 3833 3818
+f 3817 3818 3833
+f 3835 3834 3818
+f 3819 3835 3818
+f 3824 3836 3823
+f 3836 3837 3823
+f 3838 3836 3824
+f 3825 3839 3824
+f 3839 3838 3824
+f 3839 3825 3840
+f 3840 3825 3826
+f 3827 3841 3826
+f 3840 3826 3841
+f 3828 3842 3827
+f 3841 3827 3842
+f 3843 3844 3812
+f 3813 3812 3844
+f 3844 3845 3813
+f 3829 3813 3845
+f 3829 3845 3846
+f 3847 3828 3846
+f 3828 3829 3846
+f 3842 3828 3847
+f 3848 3835 3820
+f 3820 3835 3819
+f 3821 3849 3820
+f 3849 3848 3820
+f 3849 3821 3850
+f 3822 3850 3821
+f 3850 3822 3851
+f 3823 3851 3822
+f 3837 3851 3823
+f 3853 3832 3852
+f 3832 3833 3852
+f 3852 3854 3853
+f 3855 3856 3852
+f 3852 3856 3854
+f 3857 3855 3833
+f 3855 3852 3833
+f 3833 3834 3857
+f 3834 3858 3857
+f 3834 3835 3858
+f 3835 3859 3858
+f 3835 3848 3859
+f 3848 3860 3859
+f 3861 3860 3849
+f 3849 3860 3848
+f 3862 3861 3849
+f 3862 3849 3863
+f 3850 3863 3849
+f 3863 3850 3864
+f 3864 3850 3851
+f 3837 3865 3851
+f 3865 3864 3851
+f 3865 3837 3866
+f 3866 3837 3836
+f 3866 3836 3867
+f 3867 3836 3838
+f 3867 3838 3868
+f 3868 3838 3839
+f 3868 3839 3869
+f 3839 3840 3869
+f 3840 3841 3869
+f 3869 3841 3870
+f 3855 3871 3856
+f 3871 3872 3856
+f 3871 3855 3873
+f 3857 3873 3855
+f 3857 3858 3873
+f 3858 3874 3873
+f 3858 3859 3874
+f 3859 3875 3874
+f 3875 3859 3876
+f 3860 3876 3859
+f 3860 3861 3876
+f 3861 3877 3876
+f 3862 3878 3861
+f 3878 3877 3861
+f 3882 3879 3881
+f 3879 3880 3881
+f 3883 3884 3885
+f 3886 3887 3884
+f 3887 3885 3884
+f 3889 3887 3888
+f 3888 3887 3886
+f 3890 3872 3882
+f 3872 3871 3882
+f 3873 3879 3871
+f 3879 3882 3871
+f 3883 3879 3874
+f 3873 3874 3879
+f 3875 3884 3874
+f 3884 3883 3874
+f 3876 3886 3875
+f 3886 3884 3875
+f 3888 3886 3877
+f 3877 3886 3876
+f 3888 3877 3891
+f 3878 3891 3877
+f 3895 3892 3894
+f 3892 3893 3894
+f 3894 3896 3898
+f 3896 3897 3898
+f 3899 3896 3893
+f 3893 3896 3894
+f 3895 3900 3881
+f 3881 3900 3901
+f 3881 3880 3895
+f 3880 3892 3895
+f 3892 3880 3902
+f 3885 3902 3880
+f 3893 3892 3903
+f 3902 3903 3892
+f 3904 3899 3903
+f 3903 3899 3893
+f 3899 3905 3896
+f 3896 3905 3897
+f 3905 3906 3897
+f 3904 3905 3899
+f 3905 3907 3906
+f 3907 3908 3906
+f 3908 3907 3910
+f 3907 3909 3910
+v 5.934596 1.054796 0.077039
+v 5.897758 1.009309 0.080583
+v 5.871947 1.021428 0.001102
+v 5.908782 1.066916 0.001121
+v 5.923808 1.025283 0.153084
+v 5.878630 0.986485 0.128292
+f 3913 3914 3912
+f 3911 3912 3914
+f 3911 3915 3912
+f 3915 3916 3912
+v 5.950684 1.082725 0.175648
+v 5.923808 1.025283 0.153084
+v 5.934596 1.054796 0.077039
+v 5.961686 1.110978 0.090324
+v 5.763952 1.062109 0.338641
+v 5.755282 1.004149 0.307505
+v 5.857750 0.997026 0.236768
+v 5.884856 1.062202 0.249545
+v 5.800778 1.078596 0.319450
+v 5.959462 1.157227 0.187097
+v 5.912147 1.117911 0.254197
+f 3920 3917 3919
+f 3917 3918 3919
+f 3923 3924 3922
+f 3921 3922 3925
+f 3922 3924 3925
+f 3917 3926 3924
+f 3924 3926 3927
+f 3918 3917 3923
+f 3923 3917 3924
+v 5.857750 0.997026 0.236768
+v 5.757506 0.957900 0.210732
+v 5.878630 0.986485 0.128292
+v 5.923808 1.025283 0.153084
+v 5.674999 0.950754 0.227960
+v 5.755282 1.004149 0.307505
+f 3929 3930 3928
+f 3928 3930 3931
+f 3928 3933 3929
+f 3932 3929 3933
+v 5.884856 1.062202 0.249545
+v 5.912147 1.117911 0.254197
+v 5.837875 1.141493 0.305184
+v 5.800778 1.078596 0.319450
+v 5.773410 1.225861 0.323025
+v 5.672187 1.164767 0.354080
+v 5.764774 1.279824 0.308562
+v 5.681726 1.282503 0.333871
+v 5.783731 1.341471 0.284590
+v 5.710154 1.360653 0.290072
+f 3937 3934 3936
+f 3934 3935 3936
+f 3939 3937 3938
+f 3937 3936 3938
+f 3941 3939 3940
+f 3939 3938 3940
+f 3941 3940 3943
+f 3940 3942 3943
+v 5.912147 1.117911 0.254197
+v 5.959462 1.157227 0.187097
+v 5.895899 1.182730 0.164705
+v 5.837875 1.141493 0.305184
+v 5.849792 1.193480 0.181047
+v 5.764774 1.279824 0.308562
+v 5.773410 1.225861 0.323025
+v 5.840665 1.221942 0.187128
+v 5.803425 1.260787 0.210002
+v 5.783731 1.341471 0.284590
+v 5.847989 1.311569 0.261476
+v 5.931474 1.233483 0.215613
+v 5.998088 1.231874 0.107334
+v 5.573803 0.952578 0.243886
+v 5.674999 0.950754 0.227960
+v 5.755282 1.004149 0.307505
+v 5.672385 1.007694 0.341778
+v 5.580727 0.999330 0.349867
+v 5.535184 0.980180 0.341257
+f 3944 3945 3946
+f 3947 3944 3948
+f 3944 3946 3948
+f 3951 3952 3950
+f 3949 3950 3952
+f 3953 3949 3952
+f 3954 3953 3952
+f 3955 3954 3951
+f 3951 3954 3952
+f 3948 3955 3951
+f 3956 3955 3946
+f 3948 3946 3955
+f 3957 3958 3960
+f 3958 3959 3960
+f 3957 3960 3961
+f 3962 3957 3961
+v 5.681086 1.054964 0.355860
+v 5.763952 1.062109 0.338641
+v 5.690122 1.092917 0.370850
+v 5.800778 1.078596 0.319450
+v 5.672187 1.164767 0.354080
+v 5.598282 1.094735 0.386994
+v 5.580797 1.174135 0.351054
+v 5.479630 1.111310 0.364188
+v 5.470775 1.009574 0.355371
+v 5.580223 1.047470 0.372696
+v 5.580727 0.999330 0.349867
+v 5.672385 1.007694 0.341778
+v 5.535184 0.980180 0.341257
+v 5.425352 1.035967 0.342720
+v 5.388455 1.119419 0.351883
+v 5.434594 0.970412 0.330823
+v 5.480649 0.941387 0.316248
+v 5.379461 1.045817 0.349748
+v 5.370709 0.980272 0.337432
+v 5.373646 0.885375 0.208840
+f 3963 3964 3965
+f 3966 3967 3964
+f 3965 3964 3967
+f 3969 3968 3967
+f 3968 3965 3967
+f 3970 3968 3969
+f 3971 3968 3970
+f 3963 3965 3972
+f 3972 3965 3968
+f 3972 3973 3963
+f 3973 3974 3963
+f 3968 3971 3972
+f 3971 3975 3972
+f 3975 3973 3972
+f 3977 3976 3970
+f 3976 3971 3970
+f 3978 3971 3976
+f 3978 3975 3971
+f 3978 3979 3975
+f 3980 3976 3977
+f 3981 3978 3980
+f 3978 3976 3980
+f 3982 3979 3978
+f 3982 3978 3981
+v 5.546347 0.916044 0.246782
+v 5.638369 0.904402 0.222548
+v 5.674999 0.950754 0.227960
+v 5.573803 0.952578 0.243886
+v 5.748613 0.920490 0.205099
+v 5.757506 0.957900 0.210732
+f 3985 3986 3984
+f 3983 3984 3986
+f 3984 3987 3985
+f 3987 3988 3985
+v 5.373646 0.885375 0.208840
+v 5.511556 0.863525 0.177613
+v 5.546347 0.916044 0.246782
+v 5.480649 0.941387 0.316248
+v 5.603370 0.852748 0.162335
+v 5.638369 0.904402 0.222548
+v 5.704630 0.849158 0.128130
+v 5.748613 0.920490 0.205099
+v 5.241466 1.040469 0.383965
+v 5.379461 1.045817 0.349748
+v 5.388455 1.119419 0.351883
+v 5.250485 1.123029 0.385234
+v 5.223571 0.974029 0.362117
+v 5.370709 0.980272 0.337432
+v 5.299005 0.908991 0.260177
+v 5.197562 0.922406 0.302473
+f 3989 3990 3992
+f 3990 3991 3992
+f 3990 3993 3991
+f 3993 3994 3991
+f 3995 3996 3993
+f 3993 3996 3994
+f 3997 3998 4000
+f 3998 3999 4000
+f 4001 4002 3997
+f 4002 3998 3997
+f 4003 3989 4002
+f 4002 4001 4003
+f 4004 4003 4001
+v 5.757506 0.957900 0.210732
+v 5.748613 0.920490 0.205099
+v 5.851404 0.929008 0.105362
+v 5.878630 0.986485 0.128292
+v 5.897758 1.009309 0.080583
+v 5.836005 0.945722 0.001092
+v 5.871947 1.021428 0.001102
+f 4008 4005 4007
+f 4005 4006 4007
+f 4009 4010 4011
+f 4009 4008 4010
+f 4008 4007 4010
+v 5.851404 0.929008 0.105362
+v 5.797411 0.880032 0.072306
+v 5.780790 0.891286 0.001059
+v 5.836005 0.945722 0.001092
+v 5.748613 0.920490 0.205099
+v 5.704630 0.849158 0.128130
+v 5.679621 0.839500 0.000985
+v 5.568745 0.834653 0.071390
+v 5.579253 0.837796 0.000896
+v 5.603370 0.852748 0.162335
+v 5.449164 0.847535 0.103909
+v 5.137075 0.824518 0.144842
+v 5.112563 0.840686 0.000480
+v 5.213434 0.856784 0.000565
+v 5.247762 0.848549 0.108546
+v 5.511556 0.863525 0.177613
+v 5.356900 0.851120 0.138324
+v 5.373646 0.885375 0.208840
+v 5.264430 0.855571 0.181694
+v 5.323232 0.866039 0.000660
+v 5.469641 0.838722 0.000798
+v 5.299005 0.908991 0.260177
+v 5.153735 0.831575 0.218348
+v 5.197562 0.922406 0.302473
+v 4.963526 0.797382 0.143440
+v 4.920855 0.812339 0.000318
+v 4.996710 0.810560 0.280771
+v 4.669690 0.738163 0.188296
+v 4.712067 0.770512 0.333393
+v 4.655453 0.758022 0.000098
+v 5.004627 0.908637 0.345273
+v 4.728809 0.878731 0.405801
+v 5.021254 0.951308 0.405567
+v 5.223571 0.974029 0.362117
+v 5.241466 1.040469 0.383965
+v 5.011084 1.066770 0.458562
+v 4.743250 1.059210 0.563421
+v 4.991713 1.163096 0.504149
+v 4.733657 1.227371 0.592883
+v 4.744871 0.950945 0.491082
+v 4.567896 1.149805 0.642484
+v 4.641547 1.285422 0.622034
+v 4.496191 1.024566 0.579491
+v 4.416475 0.921264 0.458839
+v 4.297891 0.911506 0.447987
+v 4.399629 0.850459 0.391855
+v 4.333503 0.951176 0.481517
+v 4.359048 0.700414 0.166651
+v 4.380854 0.704574 -0.000130
+v 4.319799 0.731007 0.291212
+v 4.216374 0.852328 0.405873
+v 4.366867 1.131136 0.630581
+v 4.449011 1.260929 0.647431
+v 4.141189 1.008775 0.499342
+v 4.277227 1.077746 0.550819
+v 4.175444 1.350332 0.613988
+v 4.085564 1.288885 0.544406
+v 4.247733 1.381058 0.649596
+v 4.329607 1.464801 0.661485
+v 4.522247 1.398278 0.644892
+v 4.430999 1.535753 0.638888
+v 4.404221 1.662433 0.616610
+v 4.312225 1.683392 0.639944
+v 4.386380 1.770868 0.596666
+v 4.303615 1.799914 0.610388
+v 4.377095 1.871713 0.595743
+v 4.304562 1.906537 0.572242
+v 4.221814 1.660769 0.594090
+v 4.240116 1.770049 0.583946
+v 4.121121 1.614451 0.587188
+v 4.067576 1.572668 0.534997
+v 4.148883 1.759918 0.573765
+v 4.076852 1.746601 0.527436
+v 4.832890 2.262727 0.283787
+v 4.971394 2.146686 0.224781
+v 4.912303 2.162645 -0.000090
+v 4.747988 2.300163 -0.000276
+v 5.156645 1.942902 0.119993
+v 5.177545 1.932323 0.000214
+v 5.049690 2.032731 0.000071
+v 5.687035 1.499636 0.110765
+v 5.741781 1.463956 0.124891
+v 5.743997 1.482739 0.000851
+v 5.680007 1.510009 0.000786
+v 5.842092 1.427708 0.130724
+v 5.915025 1.382159 0.136820
+v 5.908842 1.388968 0.001026
+v 5.835498 1.436280 0.000946
+v 4.452383 2.524558 0.130255
+v 4.454962 2.523303 -0.000603
+v 4.317602 2.588926 -0.000745
+v 4.342351 2.581176 0.140317
+v 4.440143 2.510529 0.269164
+v 4.332083 2.586481 0.194917
+v 4.429895 2.495758 0.306894
+v 4.339601 2.592642 0.258891
+v 4.189883 2.606916 -0.000863
+v 4.187258 2.590221 0.135844
+v 4.203325 2.589186 0.219164
+v 4.211652 2.602538 0.264011
+v 4.328606 2.563996 0.343892
+v 4.209941 2.600612 0.337597
+v 4.410844 2.500167 0.351972
+f 4012 4013 4015
+f 4013 4014 4015
+f 4016 4017 4012
+f 4017 4013 4012
+f 4018 4014 4013
+f 4019 4018 4017
+f 4017 4018 4013
+f 4019 4020 4018
+f 4022 4019 4021
+f 4021 4019 4017
+f 4023 4024 4026
+f 4024 4025 4026
+f 4021 4027 4022
+f 4027 4028 4022
+f 4027 4029 4028
+f 4029 4030 4028
+f 4026 4025 4031
+f 4022 4032 4019
+f 4032 4020 4019
+f 4026 4031 4022
+f 4031 4032 4022
+f 4026 4022 4028
+f 4030 4026 4028
+f 4030 4029 4033
+f 4035 4034 4033
+f 4034 4030 4033
+f 4034 4023 4030
+f 4023 4026 4030
+f 4037 4024 4036
+f 4036 4024 4023
+f 4038 4036 4034
+f 4036 4023 4034
+f 4036 4038 4039
+f 4039 4038 4040
+f 4039 4041 4036
+f 4041 4037 4036
+f 4042 4038 4035
+f 4038 4034 4035
+f 4038 4042 4040
+f 4040 4042 4043
+f 4046 4047 4045
+f 4044 4045 4047
+f 4044 4042 4045
+f 4042 4035 4045
+f 4050 4048 4049
+f 4048 4047 4049
+f 4051 4044 4048
+f 4044 4047 4048
+f 4051 4043 4044
+f 4043 4042 4044
+f 4048 4050 4052
+f 4052 4050 4053
+f 4051 4048 4054
+f 4054 4048 4052
+f 4055 4043 4054
+f 4043 4051 4054
+f 4057 4055 4056
+f 4056 4055 4058
+f 4039 4059 4041
+f 4059 4060 4041
+f 4061 4059 4040
+f 4059 4039 4040
+f 4061 4040 4057
+f 4061 4057 4062
+f 4056 4062 4057
+f 4040 4043 4057
+f 4043 4055 4057
+f 4054 4052 4063
+f 4063 4052 4064
+f 4062 4056 4065
+f 4066 4065 4058
+f 4056 4058 4065
+f 4065 4066 4068
+f 4066 4067 4068
+f 4055 4054 4058
+f 4058 4054 4066
+f 4054 4063 4066
+f 4066 4063 4067
+f 4063 4069 4067
+f 4063 4064 4069
+f 4064 4070 4069
+f 4064 4071 4070
+f 4071 4072 4070
+f 4070 4072 4074
+f 4072 4073 4074
+f 4076 4074 4075
+f 4074 4073 4075
+f 4078 4076 4077
+f 4076 4075 4077
+f 4079 4074 4080
+f 4074 4076 4080
+f 4069 4070 4079
+f 4070 4074 4079
+f 4079 4081 4069
+f 4067 4069 4081
+f 4068 4067 4082
+f 4067 4081 4082
+f 4081 4079 4083
+f 4079 4080 4083
+f 4082 4081 4084
+f 4081 4083 4084
+f 4088 4085 4087
+f 4085 4086 4087
+f 4089 4090 4091
+f 4093 4094 4092
+f 4092 4094 4095
+f 4097 4098 4096
+f 4096 4098 4099
+f 4102 4103 4101
+f 4100 4101 4103
+f 4104 4100 4105
+f 4100 4103 4105
+f 4105 4107 4104
+f 4106 4104 4107
+f 4103 4102 4109
+f 4102 4108 4109
+f 4103 4109 4105
+f 4105 4109 4110
+f 4107 4105 4111
+f 4105 4110 4111
+f 4112 4107 4113
+f 4107 4111 4113
+f 4107 4112 4106
+f 4114 4106 4112
+v 4.344028 2.585635 0.470949
+v 4.328606 2.563996 0.343892
+v 4.209941 2.600612 0.337597
+v 4.224730 2.624525 0.491916
+v 4.407729 2.531640 0.486692
+v 4.410844 2.500167 0.351972
+v 4.359483 2.615839 0.596817
+v 4.277169 2.652435 0.591369
+v 4.423033 2.561337 0.603562
+v 4.411541 2.663824 0.713132
+v 4.356680 2.682996 0.719050
+v 4.476090 2.606654 0.692301
+v 4.465268 2.695425 0.757267
+v 4.418954 2.707401 0.782531
+v 4.520603 2.639162 0.745542
+v 4.546655 2.709095 0.803780
+v 4.509555 2.719807 0.819972
+v 4.574545 2.669863 0.780363
+f 4117 4118 4116
+f 4115 4116 4118
+f 4116 4115 4120
+f 4119 4120 4115
+f 4118 4122 4115
+f 4121 4115 4122
+f 4115 4121 4119
+f 4123 4119 4121
+f 4122 4125 4121
+f 4124 4121 4125
+f 4121 4124 4123
+f 4126 4123 4124
+f 4128 4127 4125
+f 4127 4124 4125
+f 4126 4124 4129
+f 4127 4129 4124
+f 4127 4128 4130
+f 4130 4128 4131
+f 4130 4132 4127
+f 4132 4129 4127
+v 4.634996 2.369115 0.140117
+v 4.747988 2.300163 -0.000276
+v 4.528082 2.467537 -0.000521
+v 4.577573 2.389535 0.256196
+v 4.454962 2.523303 -0.000603
+v 4.452383 2.524558 0.130255
+v 4.440143 2.510529 0.269164
+v 4.429895 2.495758 0.306894
+v 4.410844 2.500167 0.351972
+v 4.474318 2.418432 0.361347
+f 4133 4134 4135
+f 4136 4133 4138
+f 4133 4135 4138
+f 4135 4137 4138
+f 4136 4138 4139
+f 4136 4139 4140
+f 4140 4141 4142
+v 4.443850 2.449921 0.495432
+v 4.474318 2.418432 0.361347
+v 4.410844 2.500167 0.351972
+v 4.407729 2.531640 0.486692
+v 4.440760 2.490353 0.629287
+v 4.423033 2.561337 0.603562
+v 4.484667 2.534451 0.708888
+v 4.476090 2.606654 0.692301
+v 4.520165 2.557971 0.762427
+v 4.520603 2.639162 0.745542
+v 4.592620 2.569879 0.790452
+v 4.574545 2.669863 0.780363
+v 4.674691 2.598833 0.808006
+v 4.656565 2.680542 0.799684
+v 4.546655 2.709095 0.803780
+v 4.646703 2.728688 0.822295
+v 4.509555 2.719807 0.819972
+v 4.636909 2.750501 0.856859
+v 4.729447 2.606204 0.807513
+v 4.748031 2.683805 0.800044
+v 4.728931 2.721892 0.832625
+v 4.719171 2.751091 0.865965
+v 4.821336 2.621498 0.789636
+v 4.821325 2.691794 0.791887
+v 4.811798 2.728680 0.815406
+v 4.801436 2.750224 0.858918
+v 5.096148 2.759720 0.774729
+f 4144 4145 4143
+f 4143 4145 4146
+f 4147 4143 4148
+f 4143 4146 4148
+f 4148 4150 4147
+f 4149 4147 4150
+f 4152 4151 4150
+f 4151 4149 4150
+f 4154 4153 4152
+f 4153 4151 4152
+f 4153 4154 4155
+f 4155 4154 4156
+f 4157 4158 4154
+f 4156 4154 4158
+f 4159 4160 4157
+f 4158 4157 4160
+f 4156 4162 4155
+f 4161 4155 4162
+f 4156 4158 4162
+f 4162 4158 4163
+f 4164 4163 4160
+f 4163 4158 4160
+f 4161 4162 4165
+f 4165 4162 4166
+f 4167 4166 4163
+f 4166 4162 4163
+f 4168 4167 4164
+f 4167 4163 4164
+f 4167 4168 4169
+f 4166 4167 4169
+f 4165 4166 4169
+v 4.577573 2.389535 0.256196
+v 4.429895 2.495758 0.306894
+v 4.474318 2.418432 0.361347
+v 4.472349 2.325133 0.443764
+f 4170 4171 4172
+f 4173 4170 4172
+v 4.472349 2.325133 0.443764
+v 4.474318 2.418432 0.361347
+v 4.443850 2.449921 0.495432
+v 4.442912 2.343263 0.533220
+v 4.440760 2.490353 0.629287
+v 4.440713 2.398472 0.629128
+v 4.474625 2.465214 0.751890
+v 4.484667 2.534451 0.708888
+v 4.320630 2.385528 0.682583
+v 4.314039 2.329460 0.577510
+v 4.296769 2.260422 0.528796
+v 4.382053 2.433474 0.798757
+v 4.538177 2.513353 0.776566
+v 4.520165 2.557971 0.762427
+v 4.444739 2.475795 0.860515
+v 4.601515 2.533324 0.794193
+v 4.592620 2.569879 0.790452
+v 4.554459 2.511417 0.850571
+v 4.683344 2.554221 0.821927
+v 4.674691 2.598833 0.808006
+v 4.681847 2.551036 0.886235
+v 4.755192 2.568818 0.876311
+v 4.737893 2.564648 0.830389
+v 4.856249 2.593812 0.867067
+v 4.829566 2.580797 0.821827
+v 4.729447 2.606204 0.807513
+v 4.821336 2.621498 0.789636
+v 4.497719 2.547480 0.937659
+v 4.662221 2.556346 0.940618
+v 4.763337 2.590834 0.929248
+v 4.883022 2.613658 0.893163
+v 4.352603 2.524888 0.890532
+v 4.262798 2.490674 0.818316
+v 4.192789 2.411967 0.668016
+v 4.193959 2.370476 0.616705
+v 4.113935 2.334131 0.526471
+v 5.096148 2.759720 0.774729
+v 4.854957 2.660227 0.924310
+v 4.735139 2.645464 0.950890
+v 4.615662 2.633870 0.977986
+v 4.460582 2.622875 0.957002
+v 4.343217 2.589542 0.893106
+v 4.244622 2.554467 0.811726
+v 4.138687 2.474013 0.642311
+v 4.121994 2.458034 0.570029
+v 4.078510 2.411810 0.472193
+v 4.342998 2.664049 0.904347
+v 4.235494 2.636171 0.803613
+v 4.460786 2.695616 0.949972
+v 4.624800 2.708372 0.989445
+v 4.138494 2.557838 0.652651
+v 4.104292 2.537976 0.543437
+v 4.088356 2.510913 0.453793
+f 4175 4176 4174
+f 4174 4176 4177
+f 4176 4178 4177
+f 4177 4178 4179
+f 4179 4178 4180
+f 4180 4178 4181
+f 4182 4183 4179
+f 4183 4177 4179
+f 4174 4177 4184
+f 4184 4177 4183
+f 4182 4179 4185
+f 4185 4179 4180
+f 4180 4181 4186
+f 4186 4181 4187
+f 4186 4188 4180
+f 4188 4185 4180
+f 4190 4189 4187
+f 4189 4186 4187
+f 4188 4186 4191
+f 4191 4186 4189
+f 4192 4189 4193
+f 4189 4190 4193
+f 4191 4189 4194
+f 4194 4189 4192
+f 4195 4194 4196
+f 4194 4192 4196
+f 4195 4196 4197
+f 4197 4196 4198
+f 4196 4192 4199
+f 4192 4193 4199
+f 4200 4198 4199
+f 4198 4196 4199
+f 4201 4191 4202
+f 4191 4194 4202
+f 4203 4202 4195
+f 4195 4202 4194
+f 4204 4203 4197
+f 4203 4195 4197
+f 4205 4188 4201
+f 4201 4188 4191
+f 4206 4185 4205
+f 4185 4188 4205
+f 4206 4207 4185
+f 4207 4182 4185
+f 4183 4182 4208
+f 4208 4182 4207
+f 4184 4183 4209
+f 4183 4208 4209
+f 4197 4210 4204
+f 4204 4211 4203
+f 4211 4212 4203
+f 4213 4202 4212
+f 4203 4212 4202
+f 4202 4213 4201
+f 4213 4214 4201
+f 4201 4214 4205
+f 4214 4215 4205
+f 4216 4206 4215
+f 4205 4215 4206
+f 4216 4217 4206
+f 4206 4217 4207
+f 4210 4211 4204
+f 4218 4208 4217
+f 4208 4207 4217
+f 4208 4218 4209
+f 4219 4209 4218
+f 4221 4216 4220
+f 4215 4220 4216
+f 4215 4214 4220
+f 4214 4222 4220
+f 4222 4214 4223
+f 4213 4223 4214
+f 4217 4216 4224
+f 4216 4221 4224
+f 4225 4218 4224
+f 4218 4217 4224
+f 4218 4225 4219
+f 4219 4225 4226
+v 4.043796 2.386524 0.400392
+v 4.078510 2.411810 0.472193
+v 4.088356 2.510913 0.453793
+v 4.063205 2.509679 0.342987
+v 4.035753 2.399538 0.343957
+v 4.055262 2.505284 0.297282
+f 4230 4227 4229
+f 4227 4228 4229
+f 4230 4232 4227
+f 4231 4227 4232
+v 4.615662 2.633870 0.977986
+v 4.735139 2.645464 0.950890
+v 4.753015 2.699695 0.973279
+v 4.624800 2.708372 0.989445
+v 4.854957 2.660227 0.924310
+v 4.863709 2.722151 0.936660
+f 4233 4234 4236
+f 4234 4235 4236
+f 4234 4237 4235
+f 4237 4238 4235
+v 4.189883 2.606916 -0.000863
+v 4.079812 2.571649 -0.000951
+v 4.084506 2.570978 0.218168
+v 4.187258 2.590221 0.135844
+v 4.101754 2.557092 0.265856
+v 4.203325 2.589186 0.219164
+v 4.100907 2.560626 0.302396
+v 4.211652 2.602538 0.264011
+v 4.117367 2.568514 0.384500
+v 4.209941 2.600612 0.337597
+f 4241 4242 4240
+f 4239 4240 4242
+f 4242 4241 4244
+f 4241 4243 4244
+f 4245 4246 4243
+f 4244 4243 4246
+f 4245 4247 4246
+f 4246 4247 4248
+v 4.209941 2.600612 0.337597
+v 4.117367 2.568514 0.384500
+v 4.151183 2.579059 0.494606
+v 4.224730 2.624525 0.491916
+v 4.509555 2.719807 0.819972
+v 4.462368 2.725999 0.882675
+v 4.616626 2.749486 0.939333
+v 4.636909 2.750501 0.856859
+v 4.418954 2.707401 0.782531
+v 4.354196 2.711836 0.826545
+v 4.356680 2.682996 0.719050
+v 4.273414 2.686575 0.753674
+v 4.176065 2.636883 0.618384
+v 4.277169 2.652435 0.591369
+f 4249 4250 4252
+f 4250 4251 4252
+f 4255 4256 4254
+f 4253 4254 4256
+f 4254 4253 4258
+f 4257 4258 4253
+f 4260 4258 4259
+f 4259 4258 4257
+f 4251 4261 4252
+f 4261 4262 4252
+v 4.055262 2.505284 0.297282
+v 4.029016 2.519175 0.249385
+v 4.000110 2.424158 0.313254
+v 4.035753 2.399538 0.343957
+v 3.988172 2.489642 -0.001008
+v 4.024214 2.527933 -0.000987
+v 4.084506 2.570978 0.218168
+v 4.079812 2.571649 -0.000951
+v 4.101754 2.557092 0.265856
+v 4.063205 2.509679 0.342987
+v 4.100907 2.560626 0.302396
+v 4.088356 2.510913 0.453793
+v 4.117367 2.568514 0.384500
+f 4264 4265 4263
+f 4263 4265 4266
+f 4265 4264 4267
+f 4267 4264 4268
+f 4268 4264 4270
+f 4264 4269 4270
+f 4269 4264 4271
+f 4263 4271 4264
+f 4272 4273 4263
+f 4273 4271 4263
+f 4274 4275 4272
+f 4275 4273 4272
+v 4.104292 2.537976 0.543437
+v 4.151183 2.579059 0.494606
+v 4.117367 2.568514 0.384500
+v 4.088356 2.510913 0.453793
+v 4.273414 2.686575 0.753674
+v 4.356680 2.682996 0.719050
+v 4.277169 2.652435 0.591369
+v 4.176065 2.636883 0.618384
+v 4.138494 2.557838 0.652651
+v 4.235494 2.636171 0.803613
+v 4.342998 2.664049 0.904347
+v 4.354196 2.711836 0.826545
+v 4.460786 2.695616 0.949972
+v 4.462368 2.725999 0.882675
+v 4.616626 2.749486 0.939333
+v 4.735445 2.749285 0.940329
+v 4.719171 2.751091 0.865965
+v 4.636909 2.750501 0.856859
+v 4.827733 2.754390 0.905049
+v 4.801436 2.750224 0.858918
+v 5.096148 2.759720 0.774729
+v 4.624800 2.708372 0.989445
+v 4.753015 2.699695 0.973279
+v 4.863709 2.722151 0.936660
+f 4278 4279 4277
+f 4276 4277 4279
+f 4283 4280 4282
+f 4280 4281 4282
+f 4277 4276 4283
+f 4284 4283 4276
+f 4284 4285 4283
+f 4285 4280 4283
+f 4285 4286 4280
+f 4286 4287 4280
+f 4286 4288 4287
+f 4288 4289 4287
+f 4291 4292 4290
+f 4290 4292 4293
+f 4291 4294 4292
+f 4292 4294 4295
+f 4296 4295 4294
+f 4288 4297 4289
+f 4297 4290 4289
+f 4298 4291 4297
+f 4297 4291 4290
+f 4298 4299 4291
+f 4294 4291 4299
+f 4296 4294 4299
+v 3.828001 2.352540 0.233341
+v 4.000110 2.424158 0.313254
+v 3.988172 2.489642 -0.001008
+v 3.787342 2.396113 -0.001159
+v 3.870548 2.292106 0.368964
+v 3.961908 2.347745 0.374747
+v 4.025364 2.359300 0.402597
+v 4.043796 2.386524 0.400392
+v 4.035753 2.399538 0.343957
+v 3.967085 2.280648 0.537643
+v 4.077563 2.305187 0.510338
+v 3.903911 2.241501 0.512468
+v 3.823349 2.141733 0.428356
+v 3.857922 2.141554 0.521067
+v 4.113935 2.334131 0.526471
+v 4.078510 2.411810 0.472193
+v 4.010847 2.270246 0.622149
+v 4.112302 2.285832 0.595500
+v 3.928869 2.223919 0.615683
+v 3.892378 2.149432 0.603589
+v 4.044730 2.254459 0.744209
+v 4.146067 2.278102 0.707372
+v 3.990744 2.205448 0.710795
+v 3.945464 2.130100 0.689536
+v 4.212974 2.303184 0.587113
+v 4.296769 2.260422 0.528796
+v 4.212058 2.279450 0.625927
+v 4.172143 2.303394 0.778972
+v 4.229332 2.274522 0.672749
+v 4.079122 2.264104 0.845010
+v 4.024700 2.187859 0.814219
+v 4.215419 2.350484 0.885764
+v 4.273005 2.310529 0.762172
+v 4.104864 2.298353 0.915735
+v 4.059714 2.194906 0.888152
+v 4.097362 2.366600 1.239986
+v 4.155551 2.388662 1.091960
+v 4.102304 2.299960 1.025862
+v 4.061989 2.231988 1.178382
+v 4.194233 2.408334 1.008471
+v 4.307092 2.367482 0.877202
+v 4.266263 2.421651 1.054799
+v 4.228523 2.435029 1.098575
+v 4.170470 2.458441 1.241846
+v 4.058311 2.293363 1.338054
+v 4.094116 2.426172 1.381032
+v 4.046673 2.341349 1.452530
+v 4.047406 2.207209 1.015108
+v 3.989434 2.118832 0.765086
+v 4.022592 2.123052 0.903284
+v 4.020299 2.141675 1.002365
+v 4.024858 2.106568 1.208099
+v 4.036947 1.992167 1.072561
+v 4.082988 2.175805 1.450930
+v 4.103303 2.038565 1.363737
+v 4.152166 1.868775 1.225002
+v 4.127903 1.828359 1.090512
+v 4.031515 1.968248 0.918460
+v 3.966639 1.969285 0.549291
+v 3.922437 1.972461 0.483563
+v 3.982910 1.987391 0.639809
+v 4.059885 1.860460 0.470087
+v 4.094112 1.889281 0.578435
+v 4.017509 1.996169 0.731654
+v 4.150297 1.820575 0.917046
+v 4.389484 2.190421 0.473320
+v 4.472349 2.325133 0.443764
+v 4.342700 2.112281 0.516692
+v 4.314791 2.142163 0.540650
+v 4.305411 2.059245 0.539407
+v 4.433020 2.024714 0.563794
+v 4.101726 2.312318 1.438163
+v 4.148927 2.388726 1.376879
+v 4.129926 2.308770 1.402259
+v 4.140097 2.295949 1.367196
+v 4.169404 2.306276 1.284031
+v 4.149438 2.340550 1.353693
+v 4.141759 2.279958 1.295340
+v 4.197644 2.394643 1.248646
+v 4.197516 2.349135 1.253043
+v 4.199317 2.304652 1.174540
+v 4.267320 2.121987 0.614940
+v 4.274886 2.220030 0.679075
+v 4.354411 2.102985 0.802580
+v 4.380990 2.207701 0.839016
+v 4.369751 2.298204 0.921894
+v 4.303193 2.347123 1.044413
+v 4.245861 2.375093 1.141312
+v 4.218457 2.356834 1.142444
+v 4.275405 2.319905 1.046400
+v 4.296538 2.243779 0.925459
+v 4.289048 2.172969 0.858693
+v 4.211815 2.282490 1.039137
+v 4.278045 1.976660 0.537351
+v 4.290375 2.112337 0.800190
+v 4.222795 2.228178 0.952752
+v 4.197609 2.164063 0.857433
+v 4.153175 2.084823 0.799668
+v 4.151090 2.102939 0.889759
+v 4.148865 2.148829 0.986567
+v 4.154566 2.190480 1.129552
+v 4.152557 2.235471 1.217046
+v 4.131949 2.050757 0.921856
+v 4.119993 2.063095 1.049178
+v 4.126160 2.120930 1.172520
+v 4.133175 2.175231 1.259323
+v 4.159229 1.949902 0.923197
+v 4.137657 1.944837 1.061024
+v 4.143794 2.013720 1.201386
+v 4.123290 2.086854 1.295135
+v 4.112680 2.195089 1.366908
+v 4.111934 2.234814 1.399949
+v 4.232341 1.903079 0.534362
+v 4.304562 1.906537 0.572242
+v 4.303615 1.799914 0.610388
+v 4.240116 1.770049 0.583946
+v 4.377095 1.871713 0.595743
+v 4.432610 1.878873 0.577888
+v 4.148883 1.759918 0.573765
+v 4.281287 2.055751 0.787000
+v 4.354941 2.064161 0.778851
+v 4.245225 2.008532 0.772641
+f 4301 4302 4300
+f 4300 4302 4303
+f 4301 4300 4305
+f 4300 4304 4305
+f 4301 4306 4308
+f 4306 4307 4308
+f 4305 4306 4301
+f 4309 4310 4305
+f 4310 4306 4305
+f 4309 4305 4311
+f 4311 4305 4304
+f 4304 4312 4311
+f 4312 4313 4311
+f 4314 4315 4307
+f 4307 4306 4314
+f 4306 4310 4314
+f 4309 4316 4310
+f 4316 4317 4310
+f 4318 4316 4311
+f 4311 4316 4309
+f 4311 4313 4318
+f 4313 4319 4318
+f 4320 4321 4316
+f 4316 4321 4317
+f 4316 4318 4320
+f 4322 4320 4318
+f 4318 4319 4322
+f 4319 4323 4322
+f 4324 4325 4314
+f 4317 4324 4310
+f 4324 4314 4310
+f 4321 4326 4317
+f 4317 4326 4324
+f 4327 4328 4321
+f 4321 4328 4326
+f 4329 4327 4320
+f 4320 4327 4321
+f 4330 4329 4322
+f 4322 4329 4320
+f 4331 4332 4327
+f 4327 4332 4328
+f 4327 4329 4331
+f 4329 4333 4331
+f 4333 4329 4334
+f 4330 4334 4329
+f 4338 4335 4337
+f 4335 4336 4337
+f 4331 4333 4339
+f 4337 4339 4333
+f 4336 4339 4337
+f 4340 4332 4331
+f 4340 4331 4341
+f 4339 4341 4331
+f 4336 4342 4339
+f 4342 4341 4339
+f 4335 4343 4336
+f 4343 4342 4336
+f 4343 4335 4345
+f 4344 4345 4335
+f 4346 4345 4344
+f 4334 4347 4333
+f 4347 4337 4333
+f 4338 4337 4347
+f 4330 4322 4348
+f 4348 4322 4323
+f 4348 4349 4330
+f 4349 4334 4330
+f 4347 4334 4350
+f 4350 4334 4349
+f 4338 4347 4350
+f 4344 4335 4338
+f 4338 4350 4351
+f 4351 4350 4352
+f 4344 4338 4351
+f 4353 4346 4344
+f 4344 4351 4353
+f 4353 4351 4354
+f 4355 4354 4352
+f 4352 4354 4351
+f 4357 4356 4352
+f 4356 4355 4352
+f 4357 4352 4349
+f 4352 4350 4349
+f 4358 4313 4359
+f 4313 4312 4359
+f 4313 4358 4319
+f 4360 4319 4358
+f 4361 4362 4359
+f 4362 4358 4359
+f 4362 4360 4358
+f 4363 4357 4348
+f 4357 4349 4348
+f 4348 4323 4363
+f 4360 4363 4319
+f 4363 4323 4319
+f 4362 4363 4360
+f 4362 4364 4363
+f 4363 4364 4357
+f 4364 4356 4357
+f 4365 4366 4325
+f 4367 4365 4368
+f 4369 4367 4368
+f 4365 4325 4368
+f 4370 4365 4367
+f 4370 4367 4369
+f 4346 4371 4345
+f 4371 4372 4345
+f 4375 4376 4374
+f 4373 4374 4376
+f 4374 4377 4375
+f 4345 4372 4343
+f 4372 4378 4343
+f 4372 4376 4378
+f 4376 4379 4378
+f 4376 4375 4379
+f 4375 4380 4379
+f 4325 4382 4368
+f 4381 4368 4382
+f 4383 4381 4384
+f 4381 4382 4384
+f 4326 4325 4324
+f 4328 4325 4326
+f 4382 4325 4328
+f 4382 4328 4332
+f 4340 4382 4332
+f 4369 4368 4381
+f 4382 4340 4384
+f 4385 4384 4340
+f 4340 4341 4385
+f 4385 4341 4386
+f 4387 4386 4342
+f 4386 4341 4342
+f 4343 4378 4342
+f 4342 4378 4387
+f 4378 4379 4387
+f 4388 4387 4379
+f 4389 4386 4388
+f 4386 4387 4388
+f 4390 4385 4389
+f 4389 4385 4386
+f 4385 4390 4384
+f 4390 4391 4384
+f 4388 4379 4380
+f 4380 4392 4388
+f 4392 4389 4388
+f 4393 4369 4383
+f 4369 4381 4383
+f 4384 4391 4383
+f 4394 4383 4391
+f 4390 4389 4395
+f 4395 4389 4392
+f 4395 4396 4390
+f 4396 4391 4390
+f 4394 4391 4397
+f 4397 4391 4396
+f 4397 4396 4398
+f 4399 4398 4395
+f 4398 4396 4395
+f 4400 4399 4392
+f 4399 4395 4392
+f 4392 4380 4400
+f 4400 4380 4401
+f 4380 4375 4401
+f 4401 4375 4377
+f 4397 4398 4402
+f 4399 4403 4398
+f 4402 4398 4403
+f 4399 4400 4403
+f 4403 4400 4404
+f 4400 4401 4404
+f 4404 4401 4405
+f 4401 4377 4405
+f 4403 4407 4402
+f 4406 4402 4407
+f 4407 4403 4408
+f 4403 4404 4408
+f 4408 4404 4409
+f 4404 4405 4409
+f 4409 4405 4410
+f 4405 4377 4410
+f 4377 4374 4410
+f 4410 4374 4411
+f 4374 4373 4411
+f 4412 4413 4393
+f 4415 4414 4412
+f 4414 4413 4412
+f 4369 4393 4416
+f 4416 4393 4413
+f 4369 4416 4370
+f 4417 4370 4416
+f 4362 4418 4412
+f 4415 4412 4418
+f 4419 4383 4394
+f 4419 4420 4383
+f 4421 4420 4419
+f 4419 4394 4397
+f 4419 4397 4406
+f 4406 4397 4402
+f 4393 4383 4420
+f 4420 4421 4393
+f 4421 4412 4393
+f 4421 4419 4406
+v 5.895899 1.182730 0.164705
+v 5.959462 1.157227 0.187097
+v 5.998088 1.231874 0.107334
+f 4422 4423 4424
+v 5.959462 1.157227 0.187097
+v 5.950684 1.082725 0.175648
+v 5.961686 1.110978 0.090324
+v 5.998088 1.231874 0.107334
+v 5.755282 1.004149 0.307505
+v 5.763952 1.062109 0.338641
+v 5.681086 1.054964 0.355860
+v 5.672385 1.007694 0.341778
+f 4428 4425 4427
+f 4425 4426 4427
+f 4430 4431 4429
+f 4429 4431 4432
+v 5.849792 1.193480 0.181047
+v 5.840665 1.221942 0.187128
+v 5.773410 1.225861 0.323025
+v 5.837875 1.141493 0.305184
+v 5.480649 0.941387 0.316248
+v 5.546347 0.916044 0.246782
+v 5.573803 0.952578 0.243886
+v 5.535184 0.980180 0.341257
+f 4433 4434 4436
+f 4434 4435 4436
+f 4437 4438 4440
+f 4438 4439 4440
+v 5.710154 1.360653 0.290072
+v 5.730427 1.435668 0.209848
+v 5.685194 1.452202 0.188749
+v 5.647186 1.394606 0.257833
+v 4.991713 1.163096 0.504149
+v 5.011084 1.066770 0.458562
+v 5.241466 1.040469 0.383965
+v 5.250485 1.123029 0.385234
+v 4.641547 1.285422 0.622034
+v 4.522247 1.398278 0.644892
+v 4.449011 1.260929 0.647431
+v 4.567896 1.149805 0.642484
+v 4.742358 1.882232 0.621650
+v 4.728963 2.036146 0.614307
+v 4.688114 2.046378 0.604518
+v 4.697024 1.862575 0.604048
+v 4.760921 1.881357 0.613120
+v 4.824747 1.946835 0.626358
+v 4.861611 2.001639 0.621913
+v 4.842883 2.021333 0.638025
+f 4441 4442 4444
+f 4442 4443 4444
+f 4448 4445 4447
+f 4445 4446 4447
+f 4450 4451 4449
+f 4449 4451 4452
+f 4455 4456 4454
+f 4453 4454 4456
+f 4457 4458 4460
+f 4458 4459 4460
+v 4.925394 1.955229 0.618837
+v 4.935561 2.016016 0.585700
+v 4.861611 2.001639 0.621913
+v 4.897808 1.946794 0.628057
+f 4462 4463 4461
+f 4461 4463 4464
+v 4.852582 1.816115 0.603105
+v 4.861618 1.854067 0.618095
+v 4.760921 1.881357 0.613120
+v 4.973133 1.992779 0.533466
+v 4.991746 2.009819 0.523206
+v 4.935880 2.051665 0.572853
+v 4.935561 2.016016 0.585700
+v 4.788476 2.028047 0.608619
+v 4.751519 2.039658 0.634134
+v 4.991709 1.844295 0.520761
+v 5.011430 1.875569 0.463205
+v 5.001903 1.914398 0.486724
+v 4.982364 1.873300 0.536190
+v 4.918466 2.084725 0.532713
+v 4.881574 2.094571 0.539949
+v 4.744050 2.179337 0.556057
+v 4.837331 2.235678 0.479332
+v 4.739441 2.299169 0.369987
+v 4.636582 2.263383 0.471997
+v 5.075994 1.900999 0.443793
+v 5.095375 1.961238 0.401516
+v 5.067202 2.027704 0.422291
+v 5.057495 2.002751 0.451974
+v 4.101726 2.312318 1.438163
+v 4.046673 2.341349 1.452530
+v 4.082988 2.175805 1.450930
+v 4.111934 2.234814 1.399949
+v 4.129926 2.308770 1.402259
+v 4.150297 1.820575 0.917046
+v 4.094112 1.889281 0.578435
+v 4.245225 2.008532 0.772641
+v 4.159229 1.949902 0.923197
+v 4.127903 1.828359 1.090512
+v 4.137657 1.944837 1.061024
+v 4.152166 1.868775 1.225002
+v 4.143794 2.013720 1.201386
+v 4.103303 2.038565 1.363737
+v 4.123290 2.086854 1.295135
+v 4.112680 2.195089 1.366908
+f 4465 4466 4467
+f 4470 4471 4469
+f 4468 4469 4471
+f 4467 4472 4473
+f 4475 4476 4474
+f 4474 4476 4477
+f 4476 4475 4469
+f 4470 4478 4479
+f 4482 4483 4481
+f 4480 4481 4483
+f 4484 4485 4487
+f 4485 4486 4487
+f 4488 4489 4490
+f 4488 4490 4492
+f 4491 4492 4490
+f 4493 4494 4496
+f 4494 4495 4496
+f 4497 4493 4498
+f 4493 4496 4498
+f 4500 4499 4498
+f 4499 4497 4498
+f 4499 4500 4501
+f 4501 4500 4502
+f 4490 4501 4503
+f 4501 4502 4503
+f 4490 4503 4491
+v 5.096148 2.759720 0.774729
+v 4.863709 2.722151 0.936660
+v 4.854957 2.660227 0.924310
+f 4504 4505 4506
+v 4.076852 1.746601 0.527436
+v 4.148883 1.759918 0.573765
+v 4.094112 1.889281 0.578435
+v 4.059885 1.860460 0.470087
+v 4.380854 0.704574 -0.000130
+v 4.359048 0.700414 0.166651
+v 4.120842 0.627141 0.185461
+v 4.126565 0.642027 0.000000
+v 3.881998 1.764428 0.476337
+v 4.067576 1.572668 0.534997
+v 3.886058 1.550141 0.504830
+v 4.085564 1.288885 0.544406
+v 3.988510 1.297806 0.539537
+v 4.141189 1.008775 0.499342
+v 4.041657 1.039756 0.496922
+v 4.216374 0.852328 0.405873
+v 4.068249 0.798926 0.400813
+v 4.319799 0.731007 0.291212
+v 4.105198 0.672581 0.300001
+v 3.758215 2.206683 0.323051
+v 3.870548 2.292106 0.368964
+v 3.828001 2.352540 0.233341
+v 3.745669 2.266001 0.241930
+v 3.787342 2.396113 -0.001159
+v 3.716360 2.343387 0.000000
+v 3.727093 2.308406 0.150049
+v 3.922437 1.972461 0.483563
+v 3.814876 1.968416 0.443000
+v 3.823349 2.141733 0.428356
+f 4510 4507 4509
+f 4507 4508 4509
+f 4511 4512 4514
+f 4512 4513 4514
+f 4507 4510 4515
+f 4517 4516 4515
+f 4516 4507 4515
+f 4516 4517 4518
+f 4518 4517 4519
+f 4520 4518 4521
+f 4518 4519 4521
+f 4521 4523 4520
+f 4522 4520 4523
+f 4524 4522 4525
+f 4522 4523 4525
+f 4512 4524 4513
+f 4524 4525 4513
+f 4528 4529 4527
+f 4526 4527 4529
+f 4528 4530 4532
+f 4530 4531 4532
+f 4528 4532 4529
+f 4515 4510 4533
+f 4534 4515 4533
+f 4534 4533 4535
+f 4526 4534 4535
+f 4526 4535 4527
+v 5.096148 2.759720 0.774729
+v 4.829566 2.580797 0.821827
+v 4.821336 2.621498 0.789636
+v 4.856249 2.593812 0.867067
+f 4536 4537 4538
+f 4536 4539 4537
+v 4.094112 1.889281 0.578435
+v 4.232341 1.903079 0.534362
+v 4.245225 2.008532 0.772641
+v 1.700797 -2.794792 0.824250
+v 1.718315 -2.775468 0.921796
+v 1.678986 -2.513137 0.891745
+v 1.655948 -2.520927 0.844269
+v 1.705953 -3.006628 0.832630
+v 1.734568 -2.965876 0.986396
+v -0.972514 -1.822778 0.372649
+v -0.977375 -1.793126 0.498747
+v -1.108758 -1.770749 0.473033
+v -1.305099 -1.708460 0.484230
+v -1.266738 -1.691944 0.557922
+v -1.397474 -1.693815 0.570541
+v -1.406693 -1.697325 0.450399
+f 4540 4541 4542
+f 4543 4544 4546
+f 4544 4545 4546
+f 4548 4544 4547
+f 4543 4547 4544
+f 4552 4549 4551
+f 4549 4550 4551
+f 4555 4552 4554
+f 4552 4553 4554
+v -3.120907 -1.707924 0.431829
+v -2.941731 -1.787431 0.442574
+v -3.008323 -1.759271 0.655672
+v -3.139394 -1.687482 0.638546
+v -2.709403 -1.879947 0.508775
+v -2.699966 -1.850397 0.570070
+v -2.811581 -1.798210 0.712737
+v -3.697889 -0.951955 0.098793
+v -3.676450 -0.551317 0.077574
+v -3.699784 -0.759901 0.088664
+f 4557 4558 4556
+f 4556 4558 4559
+f 4557 4560 4558
+f 4560 4561 4558
+f 4561 4562 4558
+f 4563 4564 4565
+v -3.358510 1.810253 0.380095
+v -3.413372 1.871604 0.142309
+v -3.392806 1.769365 0.000000
+v -3.380836 1.819691 0.123273
+v -3.348274 1.767738 -0.000085
+v 4.148927 2.388726 1.376879
+v 4.101726 2.312318 1.438163
+v 4.129926 2.308770 1.402259
+v 4.149438 2.340550 1.353693
+v -2.964215 -1.978727 0.776572
+v -3.066022 -1.953125 0.719516
+v -3.008323 -1.759271 0.655672
+v -2.811581 -1.798210 0.712737
+v -3.211005 -1.850398 0.700723
+v -3.139394 -1.687482 0.638546
+v -3.357009 1.781675 0.071216
+v -3.357009 1.781675 -0.071216
+v -3.380836 1.819691 -0.123273
+f 4566 4567 4568
+f 4567 4569 4568
+f 4568 4569 4570
+f 4572 4573 4571
+f 4571 4573 4574
+f 4578 4575 4577
+f 4575 4576 4577
+f 4579 4580 4576
+f 4576 4580 4577
+f 4569 4581 4570
+f 4582 4583 4570
diff --git a/test/data/example.asc b/test/data/example.asc
new file mode 100644
index 0000000..03d3bc7
--- /dev/null
+++ b/test/data/example.asc
@@ -0,0 +1,13 @@
+ncols 4
+nrows 6
+xllcorner 0.0
+yllcorner 0.0
+cellsize 50.0
+NODATA_value -9999
+-9999 -9999 5 2
+-9999 20 100 36
+3 8 35 10
+32 42 50 6
+88 75 27 9
+13 5 1 -9999
+
diff --git a/test/data/out.teapot.obj b/test/data/out.teapot.obj
new file mode 100644
index 0000000..3599235
--- /dev/null
+++ b/test/data/out.teapot.obj
@@ -0,0 +1,9964 @@
+v -3 1.8 0
+v -2.9916 1.8 -0.081
+v -2.9916 1.8 0.081
+v -2.98945 1.66616 0
+v -2.985 1.92195 0
+v -2.985 1.92195 0
+v -2.98117 1.66784 -0.081
+v -2.98117 1.66784 0.081
+v -2.97669 1.92024 -0.081
+v -2.97669 1.92024 0.081
+v -2.9688 1.8 -0.144
+v -2.9688 1.8 0.144
+v -2.95871 1.67241 -0.144
+v -2.95871 1.67241 0.144
+v -2.9576 1.5348 0
+v -2.9576 1.5348 0
+v -2.95412 1.91561 -0.144
+v -2.95412 1.91561 0.144
+v -2.94969 1.53779 -0.081
+v -2.94969 1.53779 0.081
+v -2.94 2.0196 0
+v -2.9352 1.8 -0.189
+v -2.9352 1.8 0.189
+v -2.93196 2.01653 0.081
+v -2.93196 2.01653 -0.081
+v -2.92823 1.54591 -0.144
+v -2.92823 1.54591 0.144
+v -2.92561 1.67913 -0.189
+v -2.92561 1.67913 0.189
+v -2.92087 1.90878 -0.189
+v -2.92087 1.90878 0.189
+v -2.91013 2.00818 -0.144
+v -2.91013 2.00818 0.144
+v -2.90415 1.40614 0
+v -2.90415 1.40614 0
+v -2.89685 1.41013 0.081
+v -2.89685 1.41013 -0.081
+v -2.8966 1.55787 -0.189
+v -2.8966 1.55787 0.189
+v -2.8944 1.8 -0.216
+v -2.8944 1.8 0.216
+v -2.88542 1.6873 -0.216
+v -2.88542 1.6873 0.216
+v -2.88049 1.90049 -0.216
+v -2.88049 1.90049 0.216
+v -2.87797 1.99588 -0.189
+v -2.87797 1.99588 0.189
+v -2.87702 1.42098 -0.144
+v -2.87702 1.42098 0.144
+v -2.865 2.09565 0
+v -2.85819 1.57239 0.216
+v -2.85819 1.57239 -0.216
+v -2.85743 2.09151 -0.081
+v -2.85743 2.09151 0.081
+v -2.85 1.8 -0.225
+v -2.85 1.8 0.225
+v -2.84781 1.43697 0.189
+v -2.84781 1.43697 -0.189
+v -2.84167 1.69618 0.225
+v -2.84167 1.69618 -0.225
+v -2.83891 1.98095 -0.216
+v -2.83891 1.98095 0.216
+v -2.83689 2.08028 -0.144
+v -2.83689 2.08028 0.144
+v -2.83655 1.89146 -0.225
+v -2.83655 1.89146 0.225
+v -2.8288 1.2804 0
+v -2.82233 1.28517 -0.081
+v -2.82233 1.28517 0.081
+v -2.8164 1.5882 -0.225
+v -2.8164 1.5882 0.225
+v -2.81233 1.45639 0.216
+v -2.81233 1.45639 -0.216
+v -2.80661 2.06372 -0.189
+v -2.80661 2.06372 0.189
+v -2.8056 1.8 -0.216
+v -2.8056 1.8 0.216
+v -2.80476 1.29812 -0.144
+v -2.80476 1.29812 0.144
+v -2.79793 1.70507 -0.216
+v -2.79793 1.70507 0.216
+v -2.7964 1.9647 0.225
+v -2.7964 1.9647 -0.225
+v -2.79261 1.88244 -0.216
+v -2.79261 1.88244 0.216
+v -2.77886 1.31721 -0.189
+v -2.77886 1.31721 0.189
+v -2.77461 1.60401 0.216
+v -2.77461 1.60401 -0.216
+v -2.77373 1.47752 0.225
+v -2.77373 1.47752 -0.225
+v -2.76985 2.04362 -0.216
+v -2.76985 2.04362 0.216
+v -2.7648 1.8 -0.189
+v -2.7648 1.8 0.189
+v -2.76 2.1528 0
+v -2.76 2.1528 0
+v -2.75774 1.71323 -0.189
+v -2.75774 1.71323 0.189
+v -2.75389 1.94845 -0.216
+v -2.75389 1.94845 0.216
+v -2.75312 2.14786 -0.081
+v -2.75312 2.14786 0.081
+v -2.75223 1.87415 -0.189
+v -2.75223 1.87415 0.189
+v -2.74742 1.34038 -0.216
+v -2.74742 1.34038 0.216
+v -2.7362 1.61853 -0.189
+v -2.7362 1.61853 0.189
+v -2.73512 1.49865 0.216
+v -2.73512 1.49865 -0.216
+v -2.73446 2.13445 -0.144
+v -2.73446 2.13445 0.144
+v -2.73125 1.15781 0
+v -2.73125 1.15781 0
+v -2.7312 1.8 -0.144
+v -2.7312 1.8 0.144
+v -2.72985 2.02174 -0.225
+v -2.72985 2.02174 0.225
+v -2.72582 1.16319 0.081
+v -2.72582 1.16319 -0.081
+v -2.72464 1.71996 -0.144
+v -2.72464 1.71996 0.144
+v -2.71898 1.86732 -0.144
+v -2.71898 1.86732 0.144
+v -2.71483 1.93352 -0.189
+v -2.71483 1.93352 0.189
+v -2.7132 1.3656 -0.225
+v -2.7132 1.3656 0.225
+v -2.7111 1.1778 -0.144
+v -2.7111 1.1778 0.144
+v -2.7084 1.8 -0.081
+v -2.7084 1.8 0.081
+v -2.70695 2.1147 -0.189
+v -2.70695 2.1147 0.189
+v -2.70457 1.63049 -0.144
+v -2.70457 1.63049 0.144
+v -2.70217 1.72452 -0.081
+v -2.70217 1.72452 0.081
+v -2.7 1.8 0
+v -2.69964 1.51806 0.189
+v -2.69964 1.51806 -0.189
+v -2.69641 1.86268 -0.081
+v -2.69641 1.86268 0.081
+v -2.6939 1.7262 0
+v -2.68985 1.99986 -0.216
+v -2.68985 1.99986 0.216
+v -2.6894 1.19932 -0.189
+v -2.6894 1.19932 0.189
+v -2.6881 1.86098 0
+v -2.6881 1.86098 0
+v -2.68311 1.63861 -0.081
+v -2.68311 1.63861 0.081
+v -2.68267 1.92122 -0.144
+v -2.68267 1.92122 0.144
+v -2.67898 1.39082 -0.216
+v -2.67898 1.39082 0.216
+v -2.6752 1.6416 0
+v -2.6752 1.6416 0
+v -2.67355 2.09071 -0.216
+v -2.67355 2.09071 0.216
+v -2.67043 1.53405 -0.144
+v -2.67043 1.53405 0.144
+v -2.66305 1.22546 -0.216
+v -2.66305 1.22546 0.216
+v -2.66084 1.91287 0.081
+v -2.66084 1.91287 -0.081
+v -2.65308 1.97975 -0.189
+v -2.65308 1.97975 0.189
+v -2.6528 1.9098 0
+v -2.6528 1.9098 0
+v -2.6506 1.5449 0.081
+v -2.6506 1.5449 -0.081
+v -2.64754 1.41399 -0.189
+v -2.64754 1.41399 0.189
+v -2.6433 1.5489 0
+v -2.6372 2.0646 -0.225
+v -2.6372 2.0646 0.225
+v -2.63437 1.25391 0.225
+v -2.63437 1.25391 -0.225
+v -2.625 2.19375 0
+v -2.62281 1.9632 -0.144
+v -2.62281 1.9632 0.144
+v -2.62165 1.43308 -0.144
+v -2.62165 1.43308 0.144
+v -2.61905 2.18824 -0.081
+v -2.61905 2.18824 0.081
+v -2.6112 1.0386 0
+v -2.6112 1.0386 0
+v -2.60703 1.0445 0.081
+v -2.60703 1.0445 -0.081
+v -2.6057 1.28235 -0.216
+v -2.6057 1.28235 0.216
+v -2.60407 1.44603 -0.081
+v -2.60407 1.44603 0.081
+v -2.6029 2.17327 -0.144
+v -2.6029 2.17327 0.144
+v -2.60227 1.95196 -0.081
+v -2.60227 1.95196 0.081
+v -2.60085 2.03849 -0.216
+v -2.60085 2.03849 0.216
+v -2.5976 1.4508 0
+v -2.59572 1.0605 -0.144
+v -2.59572 1.0605 0.144
+v -2.5947 1.94782 0
+v -2.57935 1.30849 -0.189
+v -2.57935 1.30849 0.189
+v -2.5791 2.15123 -0.189
+v -2.5791 2.15123 0.189
+v -2.57906 1.08409 -0.189
+v -2.57906 1.08409 0.189
+v -2.56745 2.0145 -0.189
+v -2.56745 2.0145 0.189
+v -2.55882 1.11273 0.216
+v -2.55882 1.11273 -0.216
+v -2.55765 1.33001 -0.144
+v -2.55765 1.33001 0.144
+v -2.5502 2.12445 -0.216
+v -2.5502 2.12445 0.216
+v -2.54292 1.34462 0.081
+v -2.54292 1.34462 -0.081
+v -2.53994 1.99475 -0.144
+v -2.53994 1.99475 0.144
+v -2.5375 1.35 0
+v -2.5375 1.35 0
+v -2.5368 1.1439 0.225
+v -2.5368 1.1439 -0.225
+v -2.52128 1.98134 -0.081
+v -2.52128 1.98134 0.081
+v -2.51875 2.09531 -0.225
+v -2.51875 2.09531 0.225
+v -2.51478 1.17507 0.216
+v -2.51478 1.17507 -0.216
+v -2.5144 1.9764 0
+v -2.5144 1.9764 0
+v -2.49454 1.20371 -0.189
+v -2.49454 1.20371 0.189
+v -2.4873 2.06617 -0.216
+v -2.4873 2.06617 0.216
+v -2.47788 1.2273 -0.144
+v -2.47788 1.2273 0.144
+v -2.46835 0.922987 0
+v -2.46657 1.2433 0.081
+v -2.46657 1.2433 -0.081
+v -2.46564 0.929375 -0.081
+v -2.46564 0.929375 0.081
+v -2.4624 1.2492 0
+v -2.4624 1.2492 0
+v -2.46 2.2212 0
+v -2.46 2.2212 0
+v -2.4584 2.0394 -0.189
+v -2.4584 2.0394 0.189
+v -2.4583 0.946711 -0.144
+v -2.4583 0.946711 0.144
+v -2.45523 2.2153 -0.081
+v -2.45523 2.2153 0.081
+v -2.44747 0.97226 0.189
+v -2.44747 0.97226 -0.189
+v -2.44228 2.1993 -0.144
+v -2.44228 2.1993 0.144
+v -2.4346 2.01735 -0.144
+v -2.4346 2.01735 0.144
+v -2.43433 1.00328 -0.216
+v -2.43433 1.00328 0.216
+v -2.42319 2.17571 -0.189
+v -2.42319 2.17571 0.189
+v -2.42002 1.03704 -0.225
+v -2.42002 1.03704 0.225
+v -2.41845 2.00239 -0.081
+v -2.41845 2.00239 0.081
+v -2.4125 1.99687 0
+v -2.4125 1.99687 0
+v -2.40572 1.0708 -0.216
+v -2.40572 1.0708 0.216
+v -2.40002 2.14707 -0.216
+v -2.40002 2.14707 0.216
+v -2.39258 1.10183 -0.189
+v -2.39258 1.10183 0.189
+v -2.38175 1.12738 -0.144
+v -2.38175 1.12738 0.144
+v -2.3748 2.1159 -0.225
+v -2.3748 2.1159 0.225
+v -2.37441 1.14471 0.081
+v -2.37441 1.14471 -0.081
+v -2.3717 1.1511 0
+v -2.34958 2.08473 -0.216
+v -2.34958 2.08473 0.216
+v -2.32641 2.05609 -0.189
+v -2.32641 2.05609 0.189
+v -2.30732 2.0325 -0.144
+v -2.30732 2.0325 0.144
+v -2.3024 0.8112 0
+v -2.3024 0.8112 0
+v -2.30135 0.818122 0.081
+v -2.30135 0.818122 -0.081
+v -2.29849 0.836909 0.144
+v -2.29849 0.836909 -0.144
+v -2.29437 2.0165 -0.081
+v -2.29437 2.0165 0.081
+v -2.29428 0.864595 0.189
+v -2.29428 0.864595 -0.189
+v -2.2896 2.0106 0
+v -2.2896 2.0106 0
+v -2.28917 0.898214 0.216
+v -2.28917 0.898214 -0.216
+v -2.2836 0.9348 0.225
+v -2.2836 0.9348 -0.225
+v -2.27804 0.971386 0.216
+v -2.27804 0.971386 -0.216
+v -2.27292 1.005 0.189
+v -2.27292 1.005 -0.189
+v -2.26871 1.03269 -0.144
+v -2.26871 1.03269 0.144
+v -2.26585 1.05148 0.081
+v -2.26585 1.05148 -0.081
+v -2.265 2.23785 0
+v -2.2648 1.0584 0
+v -2.2648 1.0584 0
+v -2.26168 2.23172 -0.081
+v -2.26168 2.23172 0.081
+v -2.25265 2.21508 -0.144
+v -2.25265 2.21508 0.144
+v -2.23936 2.19056 -0.189
+v -2.23936 2.19056 0.189
+v -2.22322 2.16079 -0.216
+v -2.22322 2.16079 0.216
+v -2.20565 2.12839 0.225
+v -2.20565 2.12839 -0.225
+v -2.18808 2.09599 -0.216
+v -2.18808 2.09599 0.216
+v -2.17194 2.06621 -0.189
+v -2.17194 2.06621 0.189
+v -2.15864 2.04169 -0.144
+v -2.15864 2.04169 0.144
+v -2.14962 2.02506 -0.081
+v -2.14962 2.02506 0.081
+v -2.1463 2.01892 0
+v -2.1411 0.9738 0
+v -2.1411 0.9738 0
+v -2.14032 0.966231 0.081
+v -2.14032 0.966231 -0.081
+v -2.13818 0.945685 0.144
+v -2.13818 0.945685 -0.144
+v -2.13504 0.915407 0.189
+v -2.13504 0.915407 -0.189
+v -2.13123 0.878641 0.216
+v -2.13123 0.878641 -0.216
+v -2.12708 0.838631 0.225
+v -2.12708 0.838631 -0.225
+v -2.12292 0.798621 0.216
+v -2.12292 0.798621 -0.216
+v -2.11911 0.761855 0.189
+v -2.11911 0.761855 -0.189
+v -2.11597 0.731578 0.144
+v -2.11597 0.731578 -0.144
+v -2.11383 0.711032 0.081
+v -2.11383 0.711032 -0.081
+v -2.11305 0.703463 0
+v -2.11305 0.703463 0
+v -2.04 2.2464 0
+v -2.04 2.2464 0
+v -2.03841 2.24015 -0.081
+v -2.03841 2.24015 0.081
+v -2.03409 2.22319 -0.144
+v -2.03409 2.22319 0.144
+v -2.02773 2.19819 -0.189
+v -2.02773 2.19819 0.189
+v -2.02001 2.16783 0.216
+v -2.02001 2.16783 -0.216
+v -2.0116 2.1348 0.225
+v -2.0116 2.1348 -0.225
+v -2.00319 2.10177 0.216
+v -2.00319 2.10177 -0.216
+v -2 0.9 0
+v -2 0.9 0
+v -2 0.9 0
+v -1.9972 0.8916 0.081
+v -1.9972 0.8916 -0.081
+v -1.99547 2.07141 -0.189
+v -1.99547 2.07141 0.189
+v -1.99275 1.03717 -0
+v -1.99275 1.03717 0
+v -1.9896 0.8688 0.144
+v -1.9896 0.8688 -0.144
+v -1.98911 2.04641 0.144
+v -1.98911 2.04641 -0.144
+v -1.986 0.771675 0
+v -1.986 0.771675 0
+v -1.98479 2.02945 -0.081
+v -1.98479 2.02945 0.081
+v -1.9832 2.0232 0
+v -1.9832 2.0232 0
+v -1.9784 0.8352 0.189
+v -1.9784 0.8352 -0.189
+v -1.97424 0.9 -0.32816
+v -1.97424 0.9 -0.32816
+v -1.97424 0.9 0.32816
+v -1.972 1.1784 -0
+v -1.972 1.1784 0
+v -1.96708 1.03717 -0.32697
+v -1.96708 1.03717 0.32697
+v -1.9648 0.7944 0.216
+v -1.9648 0.7944 -0.216
+v -1.96042 0.771675 -0.325863
+v -1.96042 0.771675 0.325863
+v -1.95 0.75 -0.225
+v -1.95 0.75 0.225
+v -1.948 0.6564 0
+v -1.948 0.6564 0
+v -1.9466 1.1784 -0.323566
+v -1.9466 1.1784 0.323566
+v -1.93925 1.32323 0
+v -1.93925 1.32323 0
+v -1.9352 0.7056 0.216
+v -1.9352 0.7056 -0.216
+v -1.92291 0.6564 -0.319628
+v -1.92291 0.6564 0.319628
+v -1.9216 0.6648 0.189
+v -1.9216 0.6648 -0.189
+v -1.91427 1.32323 -0.318192
+v -1.91427 1.32323 0.318192
+v -1.9104 0.6312 0.144
+v -1.9104 0.6312 -0.144
+v -1.9028 0.6084 0.081
+v -1.9028 0.6084 -0.081
+v -1.9 0.6 0
+v -1.9 0.6 0
+v -1.89952 0.9 -0.63808
+v -1.89952 0.9 -0.63808
+v -1.89952 0.9 0.63808
+v -1.89952 0.9 0.63808
+v -1.896 1.4712 0
+v -1.896 1.4712 0
+v -1.89263 1.03717 -0.635767
+v -1.89263 1.03717 0.635767
+v -1.892 0.553725 0
+v -1.892 0.553725 0
+v -1.88622 0.771675 -0.633613
+v -1.88622 0.771675 0.633613
+v -1.87293 1.1784 -0.629147
+v -1.87293 1.1784 0.629147
+v -1.87158 1.4712 -0.311096
+v -1.87158 1.4712 0.311096
+v -1.86763 0.553725 -0.310439
+v -1.86763 0.553725 0.310439
+v -1.85013 0.6564 -0.62149
+v -1.85013 0.6564 0.62149
+v -1.84375 1.62187 0
+v -1.84375 1.62187 0
+v -1.84182 1.32323 -0.618698
+v -1.84182 1.32323 0.618698
+v -1.824 0.4632 -0
+v -1.824 0.4632 0
+v -1.82 1.62187 -0.302522
+v -1.82 1.62187 0.302523
+v -1.8009 2.02477 0
+v -1.80075 1.4712 -0.6049
+v -1.80075 1.4712 0.6049
+v -1.80051 0.4632 -0.299282
+v -1.80051 0.4632 0.299282
+v -1.80045 2.03107 -0.081
+v -1.80045 2.03107 0.081
+v -1.79925 2.04815 -0.144
+v -1.79925 2.04815 0.144
+v -1.79747 2.07333 -0.189
+v -1.79747 2.07333 0.189
+v -1.79695 0.553725 -0.603624
+v -1.79695 0.553725 0.603624
+v -1.7953 2.1039 -0.216
+v -1.7953 2.1039 0.216
+v -1.79295 2.13716 -0.225
+v -1.79295 2.13716 0.225
+v -1.7906 2.17043 -0.216
+v -1.7906 2.17043 0.216
+v -1.78843 2.201 -0.189
+v -1.78843 2.201 0.189
+v -1.78665 2.22617 -0.144
+v -1.78665 2.22617 0.144
+v -1.78544 2.24326 -0.081
+v -1.78544 2.24326 0.081
+v -1.785 2.24955 0
+v -1.784 1.7748 -0
+v -1.784 1.7748 0
+v -1.77968 0.9 -0.92592
+v -1.77968 0.9 -0.92592
+v -1.77968 0.9 0.92592
+v -1.77968 0.9 0.92592
+v -1.77323 1.03717 -0.922564
+v -1.77323 1.03717 0.922564
+v -1.76722 0.771675 -0.919439
+v -1.76722 0.771675 0.919439
+v -1.76102 1.7748 -0.292719
+v -1.76102 1.7748 0.292719
+v -1.75476 1.1784 -0.912957
+v -1.75476 1.1784 0.912957
+v -1.75112 1.62187 -0.58823
+v -1.75112 1.62187 0.58823
+v -1.75 0.384375 -0
+v -1.75 0.384375 0
+v -1.73341 0.6564 -0.901846
+v -1.73341 0.6564 0.901846
+v -1.73236 0.4632 -0.581929
+v -1.73236 0.4632 0.581929
+v -1.72746 0.384375 -0.28714
+v -1.72746 0.384375 0.28714
+v -1.72562 1.32323 -0.897795
+v -1.72562 1.32323 0.897795
+v -1.71825 1.92952 -0
+v -1.71825 1.92952 0
+v -1.69612 1.92952 -0.28193
+v -1.69612 1.92952 0.28193
+v -1.69437 1.7748 -0.569167
+v -1.69437 1.7748 0.569167
+v -1.68714 1.4712 -0.877772
+v -1.68714 1.4712 0.877772
+v -1.68358 0.553725 -0.87592
+v -1.68358 0.553725 0.87592
+v -1.676 0.3168 0
+v -1.676 0.3168 0
+v -1.66208 0.384375 -0.55832
+v -1.66208 0.384375 0.55832
+v -1.65441 0.3168 -0.274998
+v -1.65441 0.3168 0.274998
+v -1.648 2.0856 0
+v -1.648 2.0856 0
+v -1.64064 1.62187 -0.853583
+v -1.64064 1.62187 0.853583
+v -1.63193 1.92952 -0.54819
+v -1.63193 1.92952 0.54819
+v -1.62677 2.0856 -0.270404
+v -1.62677 2.0856 0.270404
+v -1.62307 0.4632 -0.844439
+v -1.62307 0.4632 0.844439
+v -1.61856 0.9 -1.18784
+v -1.61856 0.9 -1.18784
+v -1.61856 0.9 1.18784
+v -1.61856 0.9 1.18784
+v -1.61269 1.03717 -1.18353
+v -1.61269 1.03717 1.18353
+v -1.608 0.260025 -0
+v -1.608 0.260025 0
+v -1.60723 0.771675 -1.17952
+v -1.60723 0.771675 1.17952
+v -1.6 2.025 0
+v -1.5972 2.0313 -0.081
+v -1.5972 2.0313 0.081
+v -1.5959 1.1784 -1.17121
+v -1.5959 1.1784 1.17121
+v -1.5918 0.3168 -0.534711
+v -1.5918 0.3168 0.534711
+v -1.5896 2.0484 -0.144
+v -1.5896 2.0484 0.144
+v -1.58747 1.7748 -0.825921
+v -1.58747 1.7748 0.825921
+v -1.58729 0.260025 0.263841
+v -1.58729 0.260025 -0.263841
+v -1.5784 2.0736 -0.189
+v -1.5784 2.0736 0.189
+v -1.57648 0.6564 -1.15696
+v -1.57648 0.6564 1.15696
+v -1.57475 2.24257 0
+v -1.57475 2.24257 0
+v -1.5694 1.32323 -1.15176
+v -1.5694 1.32323 1.15176
+v -1.5652 2.0856 -0.525778
+v -1.5652 2.0856 0.525778
+v -1.5648 2.1042 -0.216
+v -1.5648 2.1042 0.216
+v -1.55722 0.384375 -0.81018
+v -1.55722 0.384375 0.81018
+v -1.55447 2.24257 -0.258385
+v -1.55447 2.24257 0.258385
+v -1.552 0.2136 0
+v -1.552 0.2136 0
+v -1.55 2.1375 -0.225
+v -1.55 2.1375 0.225
+v -1.5352 2.1708 -0.216
+v -1.5352 2.1708 0.216
+v -1.53439 1.4712 -1.12607
+v -1.53439 1.4712 1.12607
+v -1.53201 0.2136 0.254652
+v -1.53201 0.2136 -0.254652
+v -1.53116 0.553725 -1.1237
+v -1.53116 0.553725 1.1237
+v -1.52897 1.92952 -0.795481
+v -1.52897 1.92952 0.795481
+v -1.52721 0.260025 -0.513016
+v -1.52721 0.260025 0.513016
+v -1.5216 2.2014 -0.189
+v -1.5216 2.2014 0.189
+v -1.514 0.177075 0
+v -1.514 0.177075 0
+v -1.5104 2.2266 -0.144
+v -1.5104 2.2266 0.144
+v -1.5028 2.2437 -0.081
+v -1.5028 2.2437 0.081
+v -1.5 2.4 0
+v -1.5 0.15 0
+v -1.5 2.25 0
+v -1.5 2.4 0
+v -1.5 0.15 0
+v -1.49647 0.127575 -0
+v -1.49647 0.127575 0
+v -1.49564 2.24257 -0.502408
+v -1.49564 2.24257 0.502408
+v -1.4945 0.177075 0.248417
+v -1.4945 0.177075 -0.248417
+v -1.49211 1.62187 -1.09504
+v -1.49211 1.62187 1.09504
+v -1.49137 0.3168 -0.775921
+v -1.49137 0.3168 0.775921
+v -1.4808 0.1056 0
+v -1.4808 0.1056 -0
+v -1.48068 2.4 -0.24612
+v -1.48068 0.15 0.24612
+v -1.48068 2.4 0.24612
+v -1.48068 0.15 -0.24612
+v -1.48068 0.15 -0.24612
+v -1.48068 0.15 0.24612
+v -1.48032 2.43544 0
+v -1.48032 2.43544 0
+v -1.4772 0.127575 0.245542
+v -1.4772 0.127575 -0.245542
+v -1.47613 0.4632 -1.08331
+v -1.47613 0.4632 1.08331
+v -1.47403 0.2136 0.49515
+v -1.47403 0.2136 -0.49515
+v -1.46646 2.0856 -0.762958
+v -1.46646 2.0856 0.762958
+v -1.46173 0.1056 -0.24297
+v -1.46173 0.1056 0.24297
+v -1.46126 2.43544 -0.242892
+v -1.46126 2.43544 0.242892
+v -1.4596 2.463 0
+v -1.4596 2.463 0
+v -1.44532 0.084525 0
+v -1.44532 0.084525 0
+v -1.44376 1.7748 -1.05955
+v -1.44376 1.7748 1.05955
+v -1.4408 2.463 -0.239491
+v -1.4408 2.463 0.239491
+v -1.43902 2.48269 0
+v -1.43794 0.177075 0.483027
+v -1.43794 0.177075 -0.483027
+v -1.43086 0.260025 0.74444
+v -1.43086 0.260025 -0.74444
+v -1.42671 0.084525 -0.237149
+v -1.42671 0.084525 0.237149
+v -1.42464 2.4 -0.47856
+v -1.42464 0.15 -0.47856
+v -1.42464 0.15 -0.47856
+v -1.42464 0.15 0.47856
+v -1.42464 0.15 0.47856
+v -1.42464 2.4 0.47856
+v -1.42129 0.127575 0.477435
+v -1.42129 0.127575 -0.477435
+v -1.42049 2.48269 -0.236115
+v -1.42049 2.48269 0.236115
+v -1.42 0.9 -1.42
+v -1.42 0.9 -1.42
+v -1.42 0.9 1.42
+v -1.42 0.9 1.42
+v -1.4198 2.4945 0
+v -1.4198 2.4945 0
+v -1.41624 0.384375 -1.03936
+v -1.41624 0.384375 1.03936
+v -1.41485 1.03717 -1.41485
+v -1.41485 1.03717 1.41485
+v -1.41006 0.771675 -1.41006
+v -1.41006 0.771675 1.41006
+v -1.4064 0.1056 -0.472434
+v -1.4064 0.1056 0.472434
+v -1.40595 2.43544 -0.472283
+v -1.40595 2.43544 0.472283
+v -1.40312 2.49844 0
+v -1.40312 2.49844 0
+v -1.40151 2.4945 -0.232961
+v -1.40151 2.4945 0.232961
+v -1.40128 2.24257 -0.729046
+v -1.40128 2.24257 0.729046
+v -1.40012 1.1784 -1.40012
+v -1.40012 1.1784 1.40012
+v -1.4 2.4 0
+v -1.4 2.4 0
+v -1.39054 1.92952 -1.0205
+v -1.39054 1.92952 1.0205
+v -1.3902 2.4945 0
+v -1.3902 2.4945 0
+v -1.38627 2.463 -0.465671
+v -1.38627 2.463 0.465671
+v -1.38593 2.43544 0
+v -1.38593 2.43544 0
+v -1.38505 2.49844 -0.230225
+v -1.38505 2.49844 0.230225
+v -1.38308 0.6564 -1.38308
+v -1.38308 0.6564 1.38308
+v -1.3824 0.0648 -0
+v -1.3824 0.0648 0
+v -1.38223 2.48269 -0
+v -1.38223 2.48269 0
+v -1.38197 2.4 -0.229712
+v -1.38197 2.4 0.229712
+v -1.38103 0.2136 0.718514
+v -1.38103 0.2136 -0.718514
+v -1.3804 2.463 0
+v -1.3804 2.463 0
+v -1.37687 1.32323 -1.37687
+v -1.37687 1.32323 1.37687
+v -1.37271 0.084525 -0.461116
+v -1.37271 0.084525 0.461116
+v -1.37229 2.4945 -0.228104
+v -1.37229 2.4945 0.228104
+v -1.36807 2.43544 -0.227403
+v -1.36807 2.43544 0.227403
+v -1.36673 2.48269 -0.459107
+v -1.36673 2.48269 0.459107
+v -1.3646 0.0648 -0.226824
+v -1.3646 0.0648 0.226824
+v -1.36442 2.48269 -0.226795
+v -1.36442 2.48269 0.226795
+v -1.36262 2.463 -0.226496
+v -1.36262 2.463 0.226496
+v -1.35635 0.3168 -0.99541
+v -1.35635 0.3168 0.99541
+v -1.34847 2.4945 -0.452973
+v -1.34847 2.4945 0.452973
+v -1.34722 0.177075 0.700921
+v -1.34722 0.177075 -0.700921
+v -1.34616 1.4712 -1.34616
+v -1.34616 1.4712 1.34616
+v -1.34332 0.553725 -1.34332
+v -1.34332 0.553725 1.34332
+v -1.33476 2.4 -0.69444
+v -1.33476 0.15 -0.69444
+v -1.33476 0.15 0.69444
+v -1.33476 0.15 0.69444
+v -1.33476 2.4 0.69444
+v -1.33476 0.15 -0.69444
+v -1.33369 2.0856 -0.97878
+v -1.33369 2.0856 0.97878
+v -1.33263 2.49844 -0.447653
+v -1.33263 2.49844 0.447653
+v -1.33162 0.127575 0.692808
+v -1.33162 0.127575 -0.692808
+v -1.32966 2.4 -0.446656
+v -1.32966 2.4 0.446656
+v -1.32036 2.4945 -0.443529
+v -1.32036 2.4945 0.443529
+v -1.31767 0.1056 -0.685551
+v -1.31767 0.1056 0.685551
+v -1.31725 2.43544 -0.685331
+v -1.31725 2.43544 0.685331
+v -1.3163 2.43544 -0.442166
+v -1.3163 2.43544 0.442166
+v -1.31295 0.0648 0.441041
+v -1.31295 0.0648 -0.441041
+v -1.31278 2.48269 -0.440985
+v -1.31278 2.48269 0.440985
+v -1.31105 2.463 -0.440403
+v -1.31105 2.463 0.440403
+v -1.30906 1.62187 -1.30906
+v -1.30906 1.62187 1.30906
+v -1.30132 0.260025 0.955023
+v -1.30132 0.260025 -0.955023
+v -1.3 2.4 0
+v -1.3 2.4 0
+v -1.29881 2.463 -0.675736
+v -1.29881 2.463 0.675736
+v -1.29504 0.4632 -1.29504
+v -1.29504 0.4632 1.29504
+v -1.28611 0.084525 -0.669128
+v -1.28611 0.084525 0.669128
+v -1.28438 0.046875 0
+v -1.28438 0.046875 0
+v -1.28326 2.4 -0.213304
+v -1.28326 2.4 0.213304
+v -1.2805 2.48269 -0.666211
+v -1.2805 2.48269 0.666211
+v -1.2746 2.4408 0
+v -1.2746 2.4408 0
+v -1.27441 2.24257 -0.935276
+v -1.27441 2.24257 0.935276
+v -1.26783 0.046875 -0.21074
+v -1.26783 0.046875 0.21074
+v -1.26664 1.7748 -1.26664
+v -1.26664 1.7748 1.26664
+v -1.2634 2.4945 -0.657311
+v -1.2634 2.4945 0.657311
+v -1.25818 2.4408 0.209136
+v -1.25818 2.4408 -0.209136
+v -1.256 0.2136 0.921764
+v -1.256 0.2136 -0.921764
+v -1.24856 2.49844 -0.649591
+v -1.24856 2.49844 0.649591
+v -1.24578 2.4 -0.648144
+v -1.24578 2.4 0.648144
+v -1.2425 0.384375 -1.2425
+v -1.2425 0.384375 1.2425
+v -1.23706 2.4945 -0.643607
+v -1.23706 2.4945 0.643607
+v -1.23469 2.4 -0.414752
+v -1.23469 2.4 0.414752
+v -1.23325 2.43544 -0.641628
+v -1.23325 2.43544 0.641628
+v -1.23012 0.0648 -0.639996
+v -1.23012 0.0648 0.639996
+v -1.22996 2.48269 -0.639915
+v -1.22996 2.48269 0.639915
+v -1.22833 2.463 -0.63907
+v -1.22833 2.463 0.63907
+v -1.22525 0.177075 0.899195
+v -1.22525 0.177075 -0.899195
+v -1.21996 1.92952 1.21996
+v -1.21996 1.92952 -1.21996
+v -1.21985 0.046875 -0.409767
+v -1.21985 0.046875 0.409767
+v -1.21392 2.4 -0.89088
+v -1.21392 0.15 -0.89088
+v -1.21392 0.15 -0.89088
+v -1.21392 0.15 0.89088
+v -1.21392 0.15 0.89088
+v -1.21392 2.4 0.89088
+v -1.21107 0.127575 0.888786
+v -1.21107 0.127575 -0.888786
+v -1.21056 2.4408 0.406648
+v -1.21056 2.4408 -0.406648
+v -1.2048 2.4744 0
+v -1.2048 2.4744 0
+v -1.19838 0.1056 -0.879477
+v -1.19838 0.1056 0.879477
+v -1.198 2.43544 -0.879195
+v -1.198 2.43544 0.879195
+v -1.18996 0.3168 -1.18996
+v -1.18996 0.3168 1.18996
+v -1.18928 2.4744 -0.197684
+v -1.18928 2.4744 0.197684
+v -1.18784 0.9 -1.61856
+v -1.18784 0.9 -1.61856
+v -1.18784 0.9 1.61856
+v -1.18784 0.9 1.61856
+v -1.18353 1.03717 -1.61269
+v -1.18353 1.03717 1.61269
+v -1.18122 2.463 -0.866886
+v -1.18122 2.463 0.866886
+v -1.17952 0.771675 -1.60723
+v -1.17952 0.771675 1.60723
+v -1.17121 1.1784 -1.5959
+v -1.17121 1.1784 1.5959
+v -1.17008 2.0856 -1.17008
+v -1.17008 2.0856 1.17008
+v -1.16967 0.084525 -0.858407
+v -1.16967 0.084525 0.858407
+v -1.16457 2.48269 -0.854666
+v -1.16457 2.48269 0.854666
+v -1.15696 0.6564 -1.57648
+v -1.15696 0.6564 1.57648
+v -1.15679 2.4 -0.601848
+v -1.15679 2.4 0.601848
+v -1.15176 1.32323 -1.5694
+v -1.15176 1.32323 1.5694
+v -1.14902 2.4945 -0.843248
+v -1.14902 2.4945 0.843248
+v -1.14427 2.4744 -0.384379
+v -1.14427 2.4744 0.384379
+v -1.1436 0.0312 0
+v -1.1436 0.0312 0
+v -1.14289 0.046875 -0.594614
+v -1.14289 0.046875 0.594614
+v -1.14168 0.260025 1.14168
+v -1.14168 0.260025 -1.14168
+v -1.13552 2.49844 -0.833344
+v -1.13552 2.49844 0.833344
+v -1.13419 2.4408 0.590089
+v -1.13419 2.4408 -0.590089
+v -1.13299 2.4 -0.831488
+v -1.13299 2.4 0.831488
+v -1.12887 0.0312 -0.187642
+v -1.12887 0.0312 0.187642
+v -1.12607 1.4712 -1.53439
+v -1.12607 1.4712 1.53439
+v -1.12506 2.4945 -0.825668
+v -1.12506 2.4945 0.825668
+v -1.1237 0.553725 -1.53116
+v -1.1237 0.553725 1.53116
+v -1.1216 2.43544 -0.823129
+v -1.1216 2.43544 0.823129
+v -1.11875 0.0648 -0.821035
+v -1.11875 0.0648 0.821035
+v -1.11861 2.48269 -0.820931
+v -1.11861 2.48269 0.820931
+v -1.11807 2.24257 -1.11807
+v -1.11807 2.24257 1.11807
+v -1.11713 2.463 -0.819847
+v -1.11713 2.463 0.819847
+v -1.10192 0.2136 1.10192
+v -1.10192 0.2136 -1.10192
+v -1.1002 2.5026 0
+v -1.1002 2.5026 0
+v -1.09504 1.62187 -1.49211
+v -1.09504 1.62187 1.49211
+v -1.08615 0.0312 0.364854
+v -1.08615 0.0312 -0.364854
+v -1.08603 2.5026 0.180521
+v -1.08603 2.5026 -0.180521
+v -1.08331 0.4632 -1.47613
+v -1.08331 0.4632 1.47613
+v -1.07494 0.177075 -1.07494
+v -1.07494 0.177075 1.07494
+v -1.07208 2.4744 -0.557774
+v -1.07208 2.4744 0.557774
+v -1.065 2.4 -1.065
+v -1.065 0.15 -1.065
+v -1.065 0.15 1.065
+v -1.065 2.4 1.065
+v -1.0625 0.127575 1.0625
+v -1.0625 0.127575 -1.0625
+v -1.05955 1.7748 -1.44376
+v -1.05955 1.7748 1.44376
+v -1.05206 2.4 -0.772096
+v -1.05206 2.4 0.772096
+v -1.05137 0.1056 -1.05137
+v -1.05137 0.1056 1.05137
+v -1.05103 2.43544 -1.05103
+v -1.05103 2.43544 1.05103
+v -1.04493 2.5026 -0.351008
+v -1.04493 2.5026 0.351008
+v -1.03942 0.046875 -0.762816
+v -1.03942 0.046875 0.762816
+v -1.03936 0.384375 -1.41624
+v -1.03936 0.384375 1.41624
+v -1.03632 2.463 -1.03632
+v -1.03632 2.463 1.03632
+v -1.03151 2.4408 0.75701
+v -1.03151 2.4408 -0.75701
+v -1.02618 0.084525 -1.02618
+v -1.02618 0.084525 1.02618
+v -1.02171 2.48269 -1.02171
+v -1.02171 2.48269 1.02171
+v -1.0205 1.92952 -1.39054
+v -1.0205 1.92952 1.39054
+v -1.01762 0.0312 0.529441
+v -1.01762 0.0312 -0.529441
+v -1.00806 2.4945 -1.00806
+v -1.00806 2.4945 1.00806
+v -0.996219 2.49844 -0.996219
+v -0.996219 2.49844 0.996219
+v -0.99541 0.3168 -1.35635
+v -0.99541 0.3168 1.35635
+v -0.994 2.4 -0.994
+v -0.994 2.4 0.994
+v -0.987042 2.4945 -0.987042
+v -0.987042 2.4945 0.987042
+v -0.984007 2.43544 -0.984007
+v -0.984007 2.43544 0.984007
+v -0.981504 0.0648 0.981504
+v -0.981504 0.0648 -0.981504
+v -0.98138 2.48269 -0.98138
+v -0.98138 2.48269 0.98138
+v -0.980084 2.463 -0.980084
+v -0.980084 2.463 0.980084
+v -0.979002 2.5026 0.509349
+v -0.979002 2.5026 -0.509349
+v -0.97878 2.0856 -1.33369
+v -0.97878 2.0856 1.33369
+v -0.975021 2.4744 -0.715555
+v -0.975021 2.4744 0.715555
+v -0.9704 2.5272 0
+v -0.9704 2.5272 0
+v -0.957901 2.5272 -0.159223
+v -0.957901 2.5272 0.159223
+v -0.955023 0.260025 1.30132
+v -0.955023 0.260025 -1.30132
+v -0.952425 0.018225 -0
+v -0.952425 0.018225 0
+v -0.940158 0.018225 0.156274
+v -0.940158 0.018225 -0.156274
+v -0.935276 2.24257 -1.27441
+v -0.935276 2.24257 1.27441
+v -0.92592 0.9 -1.77968
+v -0.92592 0.9 1.77968
+v -0.92592 0.9 1.77968
+v -0.92592 0.9 -1.77968
+v -0.925493 0.0312 0.679207
+v -0.925493 0.0312 -0.679207
+v -0.923 2.4 -0.923
+v -0.923 2.4 0.923
+v -0.922564 1.03717 1.77323
+v -0.922564 1.03717 -1.77323
+v -0.921764 0.2136 1.256
+v -0.921764 0.2136 -1.256
+v -0.921647 2.5272 -0.309596
+v -0.921647 2.5272 0.309596
+v -0.919439 0.771675 -1.76722
+v -0.919439 0.771675 1.76722
+v -0.912957 1.1784 -1.75476
+v -0.912957 1.1784 1.75476
+v -0.911906 0.046875 -0.911906
+v -0.911906 0.046875 0.911906
+v -0.904966 2.4408 0.904966
+v -0.904966 2.4408 -0.904966
+v -0.904575 0.018225 0.303862
+v -0.904575 0.018225 -0.303862
+v -0.901846 0.6564 -1.73341
+v -0.901846 0.6564 1.73341
+v -0.899195 0.177075 1.22525
+v -0.899195 0.177075 -1.22525
+v -0.897795 1.32323 -1.72562
+v -0.897795 1.32323 1.72562
+v -0.89088 0.15 -1.21392
+v -0.89088 0.15 1.21392
+v -0.89088 2.4 -1.21392
+v -0.89088 0.15 -1.21392
+v -0.89088 0.15 1.21392
+v -0.89088 2.4 1.21392
+v -0.89037 2.5026 -0.653431
+v -0.89037 2.5026 0.653431
+v -0.888786 0.127575 1.21107
+v -0.888786 0.127575 -1.21107
+v -0.879477 0.1056 -1.19838
+v -0.879477 0.1056 1.19838
+v -0.879195 2.43544 -1.198
+v -0.879195 2.43544 1.198
+v -0.877772 1.4712 -1.68714
+v -0.877772 1.4712 1.68714
+v -0.87592 0.553725 -1.68358
+v -0.87592 0.553725 1.68358
+v -0.866886 2.463 -1.18122
+v -0.866886 2.463 1.18122
+v -0.863501 2.5272 -0.449256
+v -0.863501 2.5272 0.449256
+v -0.858407 0.084525 -1.16967
+v -0.858407 0.084525 1.16967
+v -0.855408 2.4744 -0.855408
+v -0.855408 2.4744 0.855408
+v -0.854666 2.48269 -1.16457
+v -0.854666 2.48269 1.16457
+v -0.853583 1.62187 -1.64064
+v -0.853583 1.62187 1.64064
+v -0.847506 0.018225 -0.440935
+v -0.847506 0.018225 0.440935
+v -0.844439 0.4632 1.62307
+v -0.844439 0.4632 -1.62307
+v -0.843248 2.4945 -1.14902
+v -0.843248 2.4945 1.14902
+v -0.833344 2.49844 -1.13552
+v -0.833344 2.49844 1.13552
+v -0.831488 2.4 -1.13299
+v -0.831488 2.4 1.13299
+v -0.825921 1.7748 1.58747
+v -0.825921 1.7748 -1.58747
+v -0.825668 2.4945 -1.12506
+v -0.825668 2.4945 1.12506
+v -0.825 2.55 0
+v -0.825 2.55 0
+v -0.823129 2.43544 -1.1216
+v -0.823129 2.43544 1.1216
+v -0.821035 0.0648 1.11875
+v -0.821035 0.0648 -1.11875
+v -0.820931 2.48269 1.11861
+v -0.820931 2.48269 -1.11861
+v -0.819847 2.463 -1.11713
+v -0.819847 2.463 1.11713
+v -0.814374 2.55 -0.135366
+v -0.814374 2.55 0.135366
+v -0.811956 0.0312 0.811956
+v -0.811956 0.0312 -0.811956
+v -0.81018 0.384375 1.55722
+v -0.81018 0.384375 -1.55722
+v -0.795481 1.92952 1.52897
+v -0.795481 1.92952 -1.52897
+v -0.785325 2.5272 -0.57634
+v -0.785325 2.5272 0.57634
+v -0.783552 2.55 -0.263208
+v -0.783552 2.55 0.263208
+v -0.781142 2.5026 -0.781142
+v -0.781142 2.5026 0.781142
+v -0.775921 0.3168 -1.49137
+v -0.775921 0.3168 1.49137
+v -0.772096 2.4 -1.05206
+v -0.772096 2.4 1.05206
+v -0.770779 0.018225 0.565664
+v -0.770779 0.018225 -0.565664
+v -0.762958 2.0856 -1.46646
+v -0.762958 2.0856 1.46646
+v -0.762816 0.046875 -1.03942
+v -0.762816 0.046875 1.03942
+v -0.75701 2.4408 1.03151
+v -0.75701 2.4408 -1.03151
+v -0.74444 0.260025 1.43086
+v -0.74444 0.260025 -1.43086
+v -0.734118 2.55 -0.381942
+v -0.734118 2.55 0.381942
+v -0.729046 2.24257 -1.40128
+v -0.729046 2.24257 1.40128
+v -0.718514 0.2136 1.38103
+v -0.718514 0.2136 -1.38103
+v -0.715555 2.4744 -0.975021
+v -0.715555 2.4744 0.975021
+v -0.7032 0.0084 0
+v -0.700921 0.177075 1.34722
+v -0.700921 0.177075 -1.34722
+v -0.69444 0.15 -1.33476
+v -0.69444 0.15 1.33476
+v -0.69444 2.4 1.33476
+v -0.69444 0.15 1.33476
+v -0.69444 2.4 -1.33476
+v -0.69444 0.15 -1.33476
+v -0.694143 0.0084 -0.115381
+v -0.694143 0.0084 0.115381
+v -0.692808 0.127575 1.33162
+v -0.692808 0.127575 -1.33162
+v -0.688984 2.5272 -0.688984
+v -0.688984 2.5272 0.688984
+v -0.685551 0.1056 -1.31767
+v -0.685551 0.1056 1.31767
+v -0.685331 2.43544 -1.31725
+v -0.685331 2.43544 1.31725
+v -0.679207 0.0312 -0.925493
+v -0.679207 0.0312 0.925493
+v -0.676222 0.018225 0.676222
+v -0.676222 0.018225 -0.676222
+v -0.675736 2.463 -1.29881
+v -0.675736 2.463 1.29881
+v -0.6736 2.5728 0
+v -0.6736 2.5728 0
+v -0.669128 0.084525 -1.28611
+v -0.669128 0.084525 1.28611
+v -0.667871 0.0084 -0.224349
+v -0.667871 0.0084 0.224349
+v -0.667656 2.55 -0.489984
+v -0.667656 2.55 0.489984
+v -0.666211 2.48269 1.2805
+v -0.666211 2.48269 -1.2805
+v -0.664924 2.5728 -0.110524
+v -0.664924 2.5728 0.110524
+v -0.657311 2.4945 -1.2634
+v -0.657311 2.4945 1.2634
+v -0.653431 2.5026 -0.89037
+v -0.653431 2.5026 0.89037
+v -0.649591 2.49844 -1.24856
+v -0.649591 2.49844 1.24856
+v -0.648144 2.4 -1.24578
+v -0.648144 2.4 1.24578
+v -0.643607 2.4945 -1.23706
+v -0.643607 2.4945 1.23706
+v -0.641628 2.43544 -1.23325
+v -0.641628 2.43544 1.23325
+v -0.639996 0.0648 -1.23012
+v -0.639996 0.0648 1.23012
+v -0.639915 2.48269 1.22996
+v -0.639915 2.48269 -1.22996
+v -0.639758 2.5728 -0.214905
+v -0.639758 2.5728 0.214905
+v -0.63907 2.463 -1.22833
+v -0.63907 2.463 1.22833
+v -0.63808 0.9 -1.89952
+v -0.63808 0.9 -1.89952
+v -0.63808 0.9 1.89952
+v -0.63808 0.9 1.89952
+v -0.635767 1.03717 -1.89263
+v -0.635767 1.03717 1.89263
+v -0.633613 0.771675 -1.88622
+v -0.633613 0.771675 1.88622
+v -0.629147 1.1784 -1.87293
+v -0.629147 1.1784 1.87293
+v -0.625735 0.0084 0.325553
+v -0.625735 0.0084 -0.325553
+v -0.62149 0.6564 -1.85013
+v -0.62149 0.6564 1.85013
+v -0.618698 1.32323 -1.84182
+v -0.618698 1.32323 1.84182
+v -0.6049 1.4712 -1.80075
+v -0.6049 1.4712 1.80075
+v -0.603624 0.553725 -1.79695
+v -0.603624 0.553725 1.79695
+v -0.601848 2.4 -1.15679
+v -0.601848 2.4 1.15679
+v -0.599396 2.5728 -0.31185
+v -0.599396 2.5728 0.31185
+v -0.594614 0.046875 -1.14289
+v -0.594614 0.046875 1.14289
+v -0.590089 2.4408 1.13419
+v -0.590089 2.4408 -1.13419
+v -0.58823 1.62187 -1.75112
+v -0.58823 1.62187 1.75112
+v -0.58575 2.55 -0.58575
+v -0.58575 2.55 0.58575
+v -0.581929 0.4632 -1.73236
+v -0.581929 0.4632 1.73236
+v -0.57634 2.5272 -0.785325
+v -0.57634 2.5272 0.785325
+v -0.569167 1.7748 -1.69437
+v -0.569167 1.7748 1.69437
+v -0.569086 0.0084 -0.417645
+v -0.569086 0.0084 0.417645
+v -0.565664 0.018225 0.770779
+v -0.565664 0.018225 -0.770779
+v -0.55832 0.384375 -1.66208
+v -0.55832 0.384375 1.66208
+v -0.557774 2.4744 -1.07208
+v -0.557774 2.4744 1.07208
+v -0.54819 1.92952 -1.63193
+v -0.54819 1.92952 1.63193
+v -0.545131 2.5728 -0.400065
+v -0.545131 2.5728 0.400065
+v -0.534711 0.3168 -1.5918
+v -0.534711 0.3168 1.5918
+v -0.529441 0.0312 -1.01762
+v -0.529441 0.0312 1.01762
+v -0.5258 2.5974 0
+v -0.5258 2.5974 0
+v -0.525778 2.0856 -1.5652
+v -0.525778 2.0856 1.5652
+v -0.519028 2.5974 0.086273
+v -0.519028 2.5974 -0.086273
+v -0.513016 0.260025 -1.52721
+v -0.513016 0.260025 1.52721
+v -0.509349 2.5026 0.979002
+v -0.509349 2.5026 -0.979002
+v -0.502408 2.24257 -1.49564
+v -0.502408 2.24257 1.49564
+v -0.499384 2.5974 -0.167751
+v -0.499384 2.5974 0.167751
+v -0.499272 0.0084 -0.499272
+v -0.499272 0.0084 0.499272
+v -0.49515 0.2136 -1.47403
+v -0.49515 0.2136 1.47403
+v -0.489984 2.55 -0.667656
+v -0.489984 2.55 0.667656
+v -0.483027 0.177075 -1.43794
+v -0.483027 0.177075 1.43794
+v -0.47856 0.15 1.42464
+v -0.47856 2.4 -1.42464
+v -0.47856 0.15 -1.42464
+v -0.47856 0.15 -1.42464
+v -0.47856 0.15 1.42464
+v -0.47856 2.4 1.42464
+v -0.478256 2.5728 -0.478256
+v -0.478256 2.5728 0.478256
+v -0.477435 0.127575 1.42129
+v -0.477435 0.127575 -1.42129
+v -0.472434 0.1056 1.4064
+v -0.472434 0.1056 -1.4064
+v -0.472283 2.43544 -1.40595
+v -0.472283 2.43544 1.40595
+v -0.467878 2.5974 -0.243424
+v -0.467878 2.5974 0.243424
+v -0.465671 2.463 -1.38627
+v -0.465671 2.463 1.38627
+v -0.461116 0.084525 1.37271
+v -0.461116 0.084525 -1.37271
+v -0.459107 2.48269 -1.36673
+v -0.459107 2.48269 1.36673
+v -0.452973 2.4945 -1.34847
+v -0.452973 2.4945 1.34847
+v -0.449256 2.5272 -0.863501
+v -0.449256 2.5272 0.863501
+v -0.447653 2.49844 -1.33263
+v -0.447653 2.49844 1.33263
+v -0.446656 2.4 -1.32966
+v -0.446656 2.4 1.32966
+v -0.443529 2.4945 -1.32036
+v -0.443529 2.4945 1.32036
+v -0.442166 2.43544 -1.3163
+v -0.442166 2.43544 1.3163
+v -0.441041 0.0648 1.31295
+v -0.441041 0.0648 -1.31295
+v -0.440985 2.48269 -1.31278
+v -0.440985 2.48269 1.31278
+v -0.440935 0.018225 0.847506
+v -0.440935 0.018225 -0.847506
+v -0.440403 2.463 -1.31105
+v -0.440403 2.463 1.31105
+v -0.425519 2.5974 0.312283
+v -0.425519 2.5974 -0.312283
+v -0.417645 0.0084 -0.569086
+v -0.417645 0.0084 0.569086
+v -0.414752 2.4 -1.23469
+v -0.414752 2.4 1.23469
+v -0.409767 0.046875 1.21985
+v -0.409767 0.046875 -1.21985
+v -0.406648 2.4408 -1.21056
+v -0.406648 2.4408 1.21056
+v -0.400065 2.5728 -0.545131
+v -0.400065 2.5728 0.545131
+v -0.3912 2.6256 0
+v -0.3912 2.6256 0
+v -0.388275 0.002175 -0
+v -0.388275 0.002175 0
+v -0.386161 2.6256 -0.064188
+v -0.386161 2.6256 0.064188
+v -0.384379 2.4744 -1.14427
+v -0.384379 2.4744 1.14427
+v -0.383274 0.002175 -0.063708
+v -0.383274 0.002175 0.063708
+v -0.381942 2.55 -0.734118
+v -0.381942 2.55 0.734118
+v -0.373318 2.5974 -0.373318
+v -0.373318 2.5974 0.373318
+v -0.371546 2.6256 -0.124808
+v -0.371546 2.6256 0.124808
+v -0.368768 0.002175 -0.123875
+v -0.368768 0.002175 0.123875
+v -0.364854 0.0312 1.08615
+v -0.364854 0.0312 -1.08615
+v -0.3584 3.0348 0
+v -0.3584 3.0348 0
+v -0.3582 3.08115 0
+v -0.3582 3.08115 0
+v -0.353807 3.0348 -0.059016
+v -0.353807 3.0348 0.059016
+v -0.35361 3.08115 -0.058988
+v -0.35361 3.08115 0.058988
+v -0.351008 2.5026 -1.04493
+v -0.351008 2.5026 1.04493
+v -0.348105 2.6256 -0.18111
+v -0.348105 2.6256 0.18111
+v -0.345503 0.002175 -0.179756
+v -0.345503 0.002175 0.179756
+v -0.340477 3.0348 -0.114676
+v -0.340477 3.0348 0.114676
+v -0.340289 3.08115 -0.114619
+v -0.340289 3.08115 0.114619
+v -0.32816 0.9 -1.97424
+v -0.32816 0.9 1.97424
+v -0.32816 0.9 1.97424
+v -0.32697 1.03717 -1.96708
+v -0.32697 1.03717 1.96708
+v -0.325863 0.771675 -1.96042
+v -0.325863 0.771675 1.96042
+v -0.325553 0.0084 -0.625735
+v -0.325553 0.0084 0.625735
+v -0.325 2.98125 0
+v -0.325 2.98125 0
+v -0.323566 1.1784 -1.9466
+v -0.323566 1.1784 1.9466
+v -0.320834 2.98125 -0.053508
+v -0.320834 2.98125 0.053508
+v -0.319628 0.6564 -1.92291
+v -0.319628 0.6564 1.92291
+v -0.319082 3.0348 -0.166306
+v -0.319082 3.0348 0.166306
+v -0.318907 3.08115 -0.166221
+v -0.318907 3.08115 0.166221
+v -0.318192 1.32323 -1.91427
+v -0.318192 1.32323 1.91427
+v -0.31659 2.6256 -0.232342
+v -0.31659 2.6256 0.232342
+v -0.314223 0.002175 -0.230604
+v -0.314223 0.002175 0.230604
+v -0.312283 2.5974 -0.425519
+v -0.312283 2.5974 0.425519
+v -0.31185 2.5728 -0.599396
+v -0.31185 2.5728 0.599396
+v -0.311096 1.4712 -1.87158
+v -0.311096 1.4712 1.87158
+v -0.310439 0.553725 -1.86763
+v -0.310439 0.553725 1.86763
+v -0.309596 2.5272 -0.921647
+v -0.309596 2.5272 0.921647
+v -0.3088 3.1176 0
+v -0.3088 3.1176 0
+v -0.308744 2.98125 -0.103976
+v -0.308744 2.98125 0.103976
+v -0.304843 3.1176 -0.050855
+v -0.304843 3.1176 0.050855
+v -0.303862 0.018225 0.904575
+v -0.303862 0.018225 -0.904575
+v -0.302523 1.62187 -1.82
+v -0.302522 1.62187 1.82
+v -0.299282 0.4632 -1.80051
+v -0.299282 0.4632 1.80051
+v -0.29336 3.1176 -0.098814
+v -0.29336 3.1176 0.098814
+v -0.292719 1.7748 -1.76102
+v -0.292719 1.7748 1.76102
+v -0.290295 3.0348 -0.213234
+v -0.290295 3.0348 0.213234
+v -0.290138 3.08115 -0.213123
+v -0.290138 3.08115 0.213123
+v -0.28934 2.98125 -0.150793
+v -0.28934 2.98125 0.150793
+v -0.28714 0.384375 -1.72746
+v -0.28714 0.384375 1.72746
+v -0.28193 1.92952 1.69612
+v -0.28193 1.92952 -1.69612
+v -0.2794 2.6592 0
+v -0.277752 2.6256 -0.277752
+v -0.277752 2.6256 0.277752
+v -0.275801 2.6592 -0.045844
+v -0.275801 2.6592 0.045844
+v -0.275675 0.002175 -0.275675
+v -0.275675 0.002175 0.275675
+v -0.274998 0.3168 -1.65441
+v -0.274998 0.3168 1.65441
+v -0.274928 3.1176 -0.143301
+v -0.274928 3.1176 0.143301
+v -0.2736 2.9232 0
+v -0.2736 2.9232 0
+v -0.270404 2.0856 -1.62677
+v -0.270404 2.0856 1.62677
+v -0.270092 2.9232 -0.045032
+v -0.270092 2.9232 0.045032
+v -0.265363 2.6592 -0.08914
+v -0.265363 2.6592 0.08914
+v -0.263841 0.260025 1.58729
+v -0.263841 0.260025 -1.58729
+v -0.263232 2.98125 -0.193348
+v -0.263232 2.98125 0.193348
+v -0.263208 2.55 -0.783552
+v -0.263208 2.55 0.783552
+v -0.25991 2.9232 -0.087511
+v -0.25991 2.9232 0.087511
+v -0.258385 2.24257 -1.55447
+v -0.258385 2.24257 1.55447
+v -0.254788 3.0348 -0.254788
+v -0.254788 3.0348 0.254788
+v -0.254653 3.08115 -0.254653
+v -0.254653 3.08115 0.254653
+v -0.254652 0.2136 -1.53201
+v -0.254652 0.2136 1.53201
+v -0.250127 3.1176 -0.183734
+v -0.250127 3.1176 0.183734
+v -0.248621 2.6592 0.129351
+v -0.248621 2.6592 -0.129351
+v -0.248417 0.177075 -1.4945
+v -0.248417 0.177075 1.4945
+v -0.24612 0.15 1.48068
+v -0.24612 2.4 -1.48068
+v -0.24612 0.15 -1.48068
+v -0.24612 0.15 -1.48068
+v -0.24612 0.15 1.48068
+v -0.24612 2.4 1.48068
+v -0.245542 0.127575 1.4772
+v -0.245542 0.127575 -1.4772
+v -0.243569 2.9232 -0.12692
+v -0.243569 2.9232 0.12692
+v -0.243424 2.5974 0.467878
+v -0.243424 2.5974 -0.467878
+v -0.24297 0.1056 1.46173
+v -0.24297 0.1056 -1.46173
+v -0.242892 2.43544 -1.46126
+v -0.242892 2.43544 1.46126
+v -0.239491 2.463 -1.4408
+v -0.239491 2.463 1.4408
+v -0.237149 0.084525 1.42671
+v -0.237149 0.084525 -1.42671
+v -0.236115 2.48269 -1.42049
+v -0.236115 2.48269 1.42049
+v -0.232961 2.4945 -1.40151
+v -0.232961 2.4945 1.40151
+v -0.232342 2.6256 -0.31659
+v -0.232342 2.6256 0.31659
+v -0.231031 2.98125 -0.231031
+v -0.231031 2.98125 0.231031
+v -0.230604 0.002175 -0.314223
+v -0.230604 0.002175 0.314223
+v -0.230225 2.49844 -1.38505
+v -0.230225 2.49844 1.38505
+v -0.229712 2.4 -1.38197
+v -0.229712 2.4 1.38197
+v -0.228104 2.4945 -1.37229
+v -0.228104 2.4945 1.37229
+v -0.227403 2.43544 -1.36807
+v -0.227403 2.43544 1.36807
+v -0.226824 0.0648 1.3646
+v -0.226824 0.0648 -1.3646
+v -0.226795 2.48269 1.36442
+v -0.226795 2.48269 -1.36442
+v -0.226496 2.463 -1.36262
+v -0.226496 2.463 1.36262
+v -0.226113 2.6592 -0.165941
+v -0.226113 2.6592 0.165941
+v -0.224349 0.0084 0.667871
+v -0.224349 0.0084 -0.667871
+v -0.221585 2.9232 -0.162745
+v -0.221585 2.9232 0.162745
+v -0.2198 2.86335 0
+v -0.2198 2.86335 0
+v -0.219536 3.1176 -0.219536
+v -0.219536 3.1176 0.219536
+v -0.216979 2.86335 0.036157
+v -0.216979 2.86335 -0.036157
+v -0.214905 2.5728 -0.639758
+v -0.214905 2.5728 0.639758
+v -0.213304 2.4 -1.28326
+v -0.213304 2.4 1.28326
+v -0.213234 3.0348 -0.290295
+v -0.213234 3.0348 0.290295
+v -0.213123 3.08115 -0.290138
+v -0.213123 3.08115 0.290138
+v -0.21074 0.046875 -1.26783
+v -0.21074 0.046875 1.26783
+v -0.209136 2.4408 -1.25818
+v -0.209136 2.4408 1.25818
+v -0.208794 2.86335 0.07027
+v -0.208794 2.86335 -0.07027
+v -0.2 2.7 0
+v -0.2 2.7 0
+v -0.2 2.7 0
+v -0.2 2.7 0
+v -0.198374 2.6592 -0.198374
+v -0.198374 2.6592 0.198374
+v -0.197684 2.4744 -1.18928
+v -0.197684 2.4744 1.18928
+v -0.197424 2.7 -0.032816
+v -0.197424 2.7 0.032816
+v -0.197424 2.7 0.032816
+v -0.197424 2.7 -0.032816
+v -0.195658 2.86335 -0.101925
+v -0.195658 2.86335 0.101925
+v -0.1946 3.14145 0
+v -0.1946 3.14145 0
+v -0.194472 2.9232 -0.194472
+v -0.194472 2.9232 0.194472
+v -0.193348 2.98125 -0.263232
+v -0.193348 2.98125 0.263232
+v -0.192107 3.14145 -0.032048
+v -0.192107 3.14145 0.032048
+v -0.189952 2.7 -0.063808
+v -0.189952 2.7 0.063808
+v -0.189952 2.7 0.063808
+v -0.189952 2.7 -0.063808
+v -0.187642 0.0312 1.12887
+v -0.187642 0.0312 -1.12887
+v -0.18487 3.14145 -0.062272
+v -0.18487 3.14145 0.062272
+v -0.183734 3.1176 -0.250127
+v -0.183734 3.1176 0.250127
+v -0.18111 2.6256 0.348105
+v -0.18111 2.6256 -0.348105
+v -0.180521 2.5026 -1.08603
+v -0.180521 2.5026 1.08603
+v -0.179756 0.002175 -0.345503
+v -0.179756 0.002175 0.345503
+v -0.1792 2.8044 0
+v -0.1792 2.8044 0
+v -0.177989 2.86335 -0.130707
+v -0.177989 2.86335 0.130707
+v -0.177968 2.7 -0.092592
+v -0.177968 2.7 0.092592
+v -0.177968 2.7 0.092592
+v -0.177968 2.7 -0.092592
+v -0.176897 2.8044 0.02945
+v -0.176897 2.8044 -0.02945
+v -0.173255 3.14145 -0.090306
+v -0.173255 3.14145 0.090306
+v -0.170215 2.8044 0.057246
+v -0.170215 2.8044 -0.057246
+v -0.167751 2.5974 -0.499384
+v -0.167751 2.5974 0.499384
+v -0.1674 2.74905 0
+v -0.1674 2.74905 0
+v -0.166306 3.0348 -0.319082
+v -0.166306 3.0348 0.319082
+v -0.166221 3.08115 0.318907
+v -0.166221 3.08115 -0.318907
+v -0.165941 2.6592 -0.226113
+v -0.165941 2.6592 0.226113
+v -0.165245 2.74905 0.02748
+v -0.165245 2.74905 -0.02748
+v -0.162745 2.9232 -0.221585
+v -0.162745 2.9232 0.221585
+v -0.161856 2.7 -0.118784
+v -0.161856 2.7 0.118784
+v -0.161856 2.7 0.118784
+v -0.161856 2.7 -0.118784
+v -0.159496 2.8044 0.083047
+v -0.159496 2.8044 -0.083047
+v -0.159223 2.5272 -0.957901
+v -0.159223 2.5272 0.957901
+v -0.158995 2.74905 0.053428
+v -0.158995 2.74905 -0.053428
+v -0.157626 3.14145 -0.115787
+v -0.157626 3.14145 0.115787
+v -0.156274 0.018225 0.940158
+v -0.156274 0.018225 -0.940158
+v -0.1562 2.86335 -0.1562
+v -0.1562 2.86335 0.1562
+v -0.150793 2.98125 -0.28934
+v -0.150793 2.98125 0.28934
+v -0.148969 2.74905 0.077523
+v -0.148969 2.74905 -0.077523
+v -0.145078 2.8044 0.106513
+v -0.145078 2.8044 -0.106513
+v -0.143301 3.1176 -0.274928
+v -0.143301 3.1176 0.274928
+v -0.142 2.7 -0.142
+v -0.142 2.7 0.142
+v -0.142 2.7 0.142
+v -0.142 2.7 -0.142
+v -0.138348 3.14145 -0.138348
+v -0.138348 3.14145 0.138348
+v -0.135489 2.74905 0.099446
+v -0.135489 2.74905 -0.099446
+v -0.135366 2.55 -0.814374
+v -0.135366 2.55 0.814374
+v -0.130707 2.86335 -0.177989
+v -0.130707 2.86335 0.177989
+v -0.129351 2.6592 0.248621
+v -0.129351 2.6592 -0.248621
+v -0.127304 2.8044 0.127304
+v -0.127304 2.8044 -0.127304
+v -0.12692 2.9232 -0.243569
+v -0.12692 2.9232 0.243569
+v -0.124808 2.6256 -0.371546
+v -0.124808 2.6256 0.371546
+v -0.123875 0.002175 0.368768
+v -0.123875 0.002175 -0.368768
+v -0.118874 2.74905 0.118874
+v -0.118874 2.74905 -0.118874
+v -0.118784 2.7 -0.161856
+v -0.118784 2.7 0.161856
+v -0.118784 2.7 0.161856
+v -0.118784 2.7 -0.161856
+v -0.115787 3.14145 -0.157626
+v -0.115787 3.14145 0.157626
+v -0.115381 0.0084 0.694143
+v -0.115381 0.0084 -0.694143
+v -0.114676 3.0348 -0.340477
+v -0.114676 3.0348 0.340477
+v -0.114619 3.08115 -0.340289
+v -0.114619 3.08115 0.340289
+v -0.110524 2.5728 -0.664924
+v -0.110524 2.5728 0.664924
+v -0.106513 2.8044 -0.145078
+v -0.106513 2.8044 0.145078
+v -0.103976 2.98125 -0.308744
+v -0.103976 2.98125 0.308744
+v -0.101925 2.86335 -0.195658
+v -0.101925 2.86335 0.195658
+v -0.099446 2.74905 0.135489
+v -0.099446 2.74905 -0.135489
+v -0.098814 3.1176 -0.29336
+v -0.098814 3.1176 0.29336
+v -0.092592 2.7 -0.177968
+v -0.092592 2.7 0.177968
+v -0.092592 2.7 -0.177968
+v -0.092592 2.7 0.177968
+v -0.090306 3.14145 -0.173255
+v -0.090306 3.14145 0.173255
+v -0.08914 2.6592 -0.265363
+v -0.08914 2.6592 0.265363
+v -0.087511 2.9232 -0.25991
+v -0.087511 2.9232 0.25991
+v -0.086273 2.5974 -0.519028
+v -0.086273 2.5974 0.519028
+v -0.083047 2.8044 -0.159496
+v -0.083047 2.8044 0.159496
+v -0.077523 2.74905 -0.148969
+v -0.077523 2.74905 0.148969
+v -0.07027 2.86335 -0.208794
+v -0.07027 2.86335 0.208794
+v -0.064188 2.6256 -0.386161
+v -0.064188 2.6256 0.386161
+v -0.063808 2.7 -0.189952
+v -0.063808 2.7 0.189952
+v -0.063808 2.7 -0.189952
+v -0.063808 2.7 0.189952
+v -0.063708 0.002175 0.383274
+v -0.063708 0.002175 -0.383274
+v -0.062272 3.14145 -0.18487
+v -0.062272 3.14145 0.18487
+v -0.059016 3.0348 -0.353807
+v -0.059016 3.0348 0.353807
+v -0.058988 3.08115 -0.35361
+v -0.058988 3.08115 0.35361
+v -0.057246 2.8044 -0.170215
+v -0.057246 2.8044 0.170215
+v -0.053508 2.98125 -0.320834
+v -0.053508 2.98125 0.320834
+v -0.053428 2.74905 -0.158995
+v -0.053428 2.74905 0.158995
+v -0.050855 3.1176 -0.304843
+v -0.050855 3.1176 0.304843
+v -0.045844 2.6592 -0.275801
+v -0.045844 2.6592 0.275801
+v -0.045032 2.9232 -0.270092
+v -0.045032 2.9232 0.270092
+v -0.036157 2.86335 -0.216979
+v -0.036157 2.86335 0.216979
+v -0.032816 2.7 -0.197424
+v -0.032816 2.7 0.197424
+v -0.032816 2.7 -0.197424
+v -0.032816 2.7 0.197424
+v -0.032048 3.14145 -0.192107
+v -0.032048 3.14145 0.192107
+v -0.02945 2.8044 -0.176897
+v -0.02945 2.8044 0.176897
+v -0.02748 2.74905 -0.165245
+v -0.02748 2.74905 0.165245
+v -0 0.260025 1.608
+v -0 1.92952 1.71825
+v -0 2.0856 -1.648
+v -0 0.6564 -1.948
+v -0 0.771675 -1.986
+v -0 2.48269 1.38223
+v -0 2.7 -0.2
+v -0 0.127575 1.49647
+v -0 2.4744 -1.2048
+v -0 2.74905 -0.1674
+v -0 0.018225 0.952425
+v -0 0.046875 -1.28438
+v -0 0.0648 1.3824
+v -0 0.384375 1.75
+v -0 0.4632 1.824
+v -0 0.553725 -1.892
+v -0 1.03717 1.99275
+v -0 1.1784 1.972
+v -0 1.32323 -1.93925
+v -0 1.62187 -1.84375
+v -0 1.7748 1.784
+v -0 2.4 -1.3
+v -0 2.43544 -1.48032
+v -0 2.43544 -1.38593
+v -0 2.463 -1.4596
+v -0 2.463 -1.3804
+v -0 2.4945 -1.3902
+v -0 2.5026 -1.1002
+v -0 2.8044 -0.1792
+v -0 2.86335 -0.2198
+v -0 2.5728 -0.6736
+v -0 0.1056 1.4808
+v -0 0.177075 -1.514
+v -0 2.4945 -1.4198
+v -0 2.5272 -0.9704
+v -0 2.9232 -0.2736
+v -0 3.1176 -0.3088
+v -0 2.5974 -0.5258
+v -0 2.7 -0.2
+v -0 2.98125 -0.325
+v -0 3.14145 -0.1946
+v -0 0.002175 0.388275
+v -0 3.08115 -0.3582
+v 0 0 0
+v 0 0.002175 -0.388275
+v 0 0.002175 0.388275
+v 0 0.0084 -0.7032
+v 0 0.0084 0.7032
+v 0 0.018225 -0.952425
+v 0 0.018225 0.952425
+v 0 0.0312 -1.1436
+v 0 0.0312 -1.1436
+v 0 0.0312 1.1436
+v 0 0.0312 1.1436
+v 0 0.046875 -1.28438
+v 0 0.046875 1.28438
+v 0 0.0648 -1.3824
+v 0 0.0648 1.3824
+v 0 0.084525 -1.44532
+v 0 0.084525 -1.44532
+v 0 0.084525 1.44532
+v 0 0.084525 1.44532
+v 0 0.1056 -1.4808
+v 0 0.1056 1.4808
+v 0 0.127575 -1.49647
+v 0 0.127575 1.49647
+v 0 0.15 -1.5
+v 0 0.15 -1.5
+v 0 0.15 1.5
+v 0 0.15 1.5
+v 0 0.177075 -1.514
+v 0 0.177075 1.514
+v 0 0.2136 -1.552
+v 0 0.2136 -1.552
+v 0 0.2136 1.552
+v 0 0.2136 1.552
+v 0 0.260025 -1.608
+v 0 0.260025 1.608
+v 0 0.3168 -1.676
+v 0 0.3168 -1.676
+v 0 0.3168 1.676
+v 0 0.3168 1.676
+v 0 0.384375 -1.75
+v 0 0.384375 1.75
+v 0 0.4632 -1.824
+v 0 0.4632 1.824
+v 0 0.553725 -1.892
+v 0 0.553725 1.892
+v 0 0.6564 -1.948
+v 0 0.6564 1.948
+v 0 0.771675 -1.986
+v 0 0.771675 1.986
+v 0 0.9 -2
+v 0 0.9 -2
+v 0 0.9 2
+v 0 0.9 2
+v 0 1.03717 -1.99275
+v 0 1.03717 1.99275
+v 0 1.1784 -1.972
+v 0 1.1784 1.972
+v 0 1.32323 -1.93925
+v 0 1.32323 1.93925
+v 0 1.4712 -1.896
+v 0 1.4712 -1.896
+v 0 1.4712 1.896
+v 0 1.4712 1.896
+v 0 1.62187 -1.84375
+v 0 1.62187 1.84375
+v 0 1.7748 -1.784
+v 0 1.7748 1.784
+v 0 1.92952 -1.71825
+v 0 1.92952 1.71825
+v 0 2.0856 -1.648
+v 0 2.0856 1.648
+v 0 2.24257 -1.57475
+v 0 2.24257 -1.57475
+v 0 2.24257 1.57475
+v 0 2.24257 1.57475
+v 0 2.4 -1.5
+v 0 2.4 -1.5
+v 0 2.4 -1.4
+v 0 2.4 -1.4
+v 0 2.4 -1.3
+v 0 2.4 1.3
+v 0 2.4 1.4
+v 0 2.4 1.4
+v 0 2.4 1.5
+v 0 2.4 1.5
+v 0 2.43544 -1.48032
+v 0 2.43544 -1.38593
+v 0 2.43544 1.38593
+v 0 2.43544 1.48032
+v 0 2.4408 -1.2746
+v 0 2.4408 -1.2746
+v 0 2.4408 1.2746
+v 0 2.4408 1.2746
+v 0 2.463 -1.4596
+v 0 2.463 -1.3804
+v 0 2.463 1.3804
+v 0 2.463 1.4596
+v 0 2.4744 -1.2048
+v 0 2.4744 1.2048
+v 0 2.48269 -1.43902
+v 0 2.48269 -1.38223
+v 0 2.48269 1.38223
+v 0 2.48269 1.43902
+v 0 2.4945 -1.4198
+v 0 2.4945 -1.3902
+v 0 2.4945 1.3902
+v 0 2.4945 1.4198
+v 0 2.49844 -1.40312
+v 0 2.49844 -1.40312
+v 0 2.49844 1.40312
+v 0 2.49844 1.40312
+v 0 2.5026 -1.1002
+v 0 2.5026 1.1002
+v 0 2.5272 -0.9704
+v 0 2.5272 0.9704
+v 0 2.55 -0.825
+v 0 2.55 -0.825
+v 0 2.55 0.825
+v 0 2.55 0.825
+v 0 2.5728 -0.6736
+v 0 2.5728 0.6736
+v 0 2.5974 -0.5258
+v 0 2.5974 0.5258
+v 0 2.6256 -0.3912
+v 0 2.6256 -0.3912
+v 0 2.6256 0.3912
+v 0 2.6256 0.3912
+v 0 2.6592 -0.2794
+v 0 2.6592 0.2794
+v 0 2.7 -0.2
+v 0 2.7 -0.2
+v 0 2.7 0.2
+v 0 2.7 0.2
+v 0 2.74905 -0.1674
+v 0 2.74905 0.1674
+v 0 2.8044 -0.1792
+v 0 2.8044 0.1792
+v 0 2.86335 -0.2198
+v 0 2.86335 0.2198
+v 0 2.9232 -0.2736
+v 0 2.9232 0.2736
+v 0 2.98125 -0.325
+v 0 2.98125 0.325
+v 0 3.0348 -0.3584
+v 0 3.0348 -0.3584
+v 0 3.0348 0.3584
+v 0 3.0348 0.3584
+v 0 3.08115 -0.3582
+v 0 3.08115 0.3582
+v 0 3.1176 -0.3088
+v 0 3.1176 0.3088
+v 0 3.14145 -0.1946
+v 0 3.14145 0.1946
+v 0 3.15 0
+v 0 0.002175 -0.388275
+v 0 3.08115 0.3582
+v 0 2.5974 0.5258
+v 0 2.7 0.2
+v 0 2.98125 0.325
+v 0 3.14145 0.1946
+v 0 3.1176 0.3088
+v 0 0.1056 -1.4808
+v 0 0.177075 1.514
+v 0 2.4945 1.4198
+v 0 2.5272 0.9704
+v 0 2.9232 0.2736
+v 0 2.5728 0.6736
+v 0 2.86335 0.2198
+v 0 0.018225 -0.952425
+v 0 0.046875 1.28438
+v 0 0.0648 -1.3824
+v 0 0.384375 -1.75
+v 0 0.4632 -1.824
+v 0 0.553725 1.892
+v 0 1.03717 -1.99275
+v 0 1.1784 -1.972
+v 0 1.32323 1.93925
+v 0 1.62187 1.84375
+v 0 1.7748 -1.784
+v 0 2.4 1.3
+v 0 2.43544 1.38593
+v 0 2.43544 1.48032
+v 0 2.463 1.3804
+v 0 2.463 1.4596
+v 0 2.4945 1.3902
+v 0 2.5026 1.1002
+v 0 2.8044 0.1792
+v 0 2.74905 0.1674
+v 0 0.127575 -1.49647
+v 0 2.4744 1.2048
+v 0 0.6564 1.948
+v 0 0.771675 1.986
+v 0 2.48269 -1.38223
+v 0 2.7 0.2
+v 0 0.260025 -1.608
+v 0 1.92952 -1.71825
+v 0 2.0856 1.648
+v 0.02748 2.74905 -0.165245
+v 0.02748 2.74905 0.165245
+v 0.02945 2.8044 -0.176897
+v 0.02945 2.8044 0.176897
+v 0.032048 3.14145 -0.192107
+v 0.032048 3.14145 0.192107
+v 0.032816 2.7 -0.197424
+v 0.032816 2.7 0.197424
+v 0.032816 2.7 -0.197424
+v 0.032816 2.7 0.197424
+v 0.036157 2.86335 -0.216979
+v 0.036157 2.86335 0.216979
+v 0.045032 2.9232 -0.270092
+v 0.045032 2.9232 0.270092
+v 0.045844 2.6592 -0.275801
+v 0.045844 2.6592 0.275801
+v 0.050855 3.1176 -0.304843
+v 0.050855 3.1176 0.304843
+v 0.053428 2.74905 -0.158995
+v 0.053428 2.74905 0.158995
+v 0.053508 2.98125 -0.320834
+v 0.053508 2.98125 0.320834
+v 0.057246 2.8044 -0.170215
+v 0.057246 2.8044 0.170215
+v 0.058988 3.08115 -0.35361
+v 0.058988 3.08115 0.35361
+v 0.059016 3.0348 -0.353807
+v 0.059016 3.0348 0.353807
+v 0.062272 3.14145 -0.18487
+v 0.062272 3.14145 0.18487
+v 0.063708 0.002175 0.383274
+v 0.063708 0.002175 -0.383274
+v 0.063808 2.7 -0.189952
+v 0.063808 2.7 0.189952
+v 0.063808 2.7 -0.189952
+v 0.063808 2.7 0.189952
+v 0.064188 2.6256 -0.386161
+v 0.064188 2.6256 0.386161
+v 0.07027 2.86335 -0.208794
+v 0.07027 2.86335 0.208794
+v 0.077523 2.74905 -0.148969
+v 0.077523 2.74905 0.148969
+v 0.083047 2.8044 -0.159496
+v 0.083047 2.8044 0.159496
+v 0.086273 2.5974 -0.519028
+v 0.086273 2.5974 0.519028
+v 0.087511 2.9232 -0.25991
+v 0.087511 2.9232 0.25991
+v 0.08914 2.6592 -0.265363
+v 0.08914 2.6592 0.265363
+v 0.090306 3.14145 -0.173255
+v 0.090306 3.14145 0.173255
+v 0.092592 2.7 -0.177968
+v 0.092592 2.7 0.177968
+v 0.092592 2.7 -0.177968
+v 0.092592 2.7 0.177968
+v 0.098814 3.1176 -0.29336
+v 0.098814 3.1176 0.29336
+v 0.099446 2.74905 0.135489
+v 0.099446 2.74905 -0.135489
+v 0.101925 2.86335 -0.195658
+v 0.101925 2.86335 0.195658
+v 0.103976 2.98125 -0.308744
+v 0.103976 2.98125 0.308744
+v 0.106513 2.8044 -0.145078
+v 0.106513 2.8044 0.145078
+v 0.110524 2.5728 -0.664924
+v 0.110524 2.5728 0.664924
+v 0.114619 3.08115 -0.340289
+v 0.114619 3.08115 0.340289
+v 0.114676 3.0348 -0.340477
+v 0.114676 3.0348 0.340477
+v 0.115381 0.0084 0.694143
+v 0.115381 0.0084 -0.694143
+v 0.115787 3.14145 -0.157626
+v 0.115787 3.14145 0.157626
+v 0.118784 2.7 0.161856
+v 0.118784 2.7 -0.161856
+v 0.118784 2.7 -0.161856
+v 0.118784 2.7 0.161856
+v 0.118874 2.74905 0.118874
+v 0.118874 2.74905 -0.118874
+v 0.123875 0.002175 0.368768
+v 0.123875 0.002175 -0.368768
+v 0.124808 2.6256 -0.371546
+v 0.124808 2.6256 0.371546
+v 0.12692 2.9232 -0.243569
+v 0.12692 2.9232 0.243569
+v 0.127304 2.8044 0.127304
+v 0.127304 2.8044 -0.127304
+v 0.129351 2.6592 0.248621
+v 0.129351 2.6592 -0.248621
+v 0.130707 2.86335 -0.177989
+v 0.130707 2.86335 0.177989
+v 0.135366 2.55 -0.814374
+v 0.135366 2.55 0.814374
+v 0.135489 2.74905 0.099446
+v 0.135489 2.74905 -0.099446
+v 0.138348 3.14145 -0.138348
+v 0.138348 3.14145 0.138348
+v 0.142 2.7 0.142
+v 0.142 2.7 -0.142
+v 0.142 2.7 -0.142
+v 0.142 2.7 0.142
+v 0.143301 3.1176 -0.274928
+v 0.143301 3.1176 0.274928
+v 0.145078 2.8044 0.106513
+v 0.145078 2.8044 -0.106513
+v 0.148969 2.74905 0.077523
+v 0.148969 2.74905 -0.077523
+v 0.150793 2.98125 -0.28934
+v 0.150793 2.98125 0.28934
+v 0.1562 2.86335 -0.1562
+v 0.1562 2.86335 0.1562
+v 0.156274 0.018225 0.940158
+v 0.156274 0.018225 -0.940158
+v 0.157626 3.14145 -0.115787
+v 0.157626 3.14145 0.115787
+v 0.158995 2.74905 0.053428
+v 0.158995 2.74905 -0.053428
+v 0.159223 2.5272 -0.957901
+v 0.159223 2.5272 0.957901
+v 0.159496 2.8044 0.083047
+v 0.159496 2.8044 -0.083047
+v 0.161856 2.7 0.118784
+v 0.161856 2.7 -0.118784
+v 0.161856 2.7 -0.118784
+v 0.161856 2.7 0.118784
+v 0.162745 2.9232 -0.221585
+v 0.162745 2.9232 0.221585
+v 0.165245 2.74905 0.02748
+v 0.165245 2.74905 -0.02748
+v 0.165941 2.6592 -0.226113
+v 0.165941 2.6592 0.226113
+v 0.166221 3.08115 0.318907
+v 0.166221 3.08115 -0.318907
+v 0.166306 3.0348 -0.319082
+v 0.166306 3.0348 0.319082
+v 0.1674 2.74905 -0
+v 0.1674 2.74905 0
+v 0.167751 2.5974 -0.499384
+v 0.167751 2.5974 0.499384
+v 0.170215 2.8044 0.057246
+v 0.170215 2.8044 -0.057246
+v 0.173255 3.14145 -0.090306
+v 0.173255 3.14145 0.090306
+v 0.176897 2.8044 0.02945
+v 0.176897 2.8044 -0.02945
+v 0.177968 2.7 0.092592
+v 0.177968 2.7 -0.092592
+v 0.177968 2.7 -0.092592
+v 0.177968 2.7 0.092592
+v 0.177989 2.86335 -0.130707
+v 0.177989 2.86335 0.130707
+v 0.1792 2.8044 -0
+v 0.1792 2.8044 0
+v 0.179756 0.002175 -0.345503
+v 0.179756 0.002175 0.345503
+v 0.180521 2.5026 -1.08603
+v 0.180521 2.5026 1.08603
+v 0.18111 2.6256 0.348105
+v 0.18111 2.6256 -0.348105
+v 0.183734 3.1176 -0.250127
+v 0.183734 3.1176 0.250127
+v 0.18487 3.14145 -0.062272
+v 0.18487 3.14145 0.062272
+v 0.187642 0.0312 1.12887
+v 0.187642 0.0312 -1.12887
+v 0.189952 2.7 0.063808
+v 0.189952 2.7 -0.063808
+v 0.189952 2.7 -0.063808
+v 0.189952 2.7 0.063808
+v 0.192107 3.14145 -0.032048
+v 0.192107 3.14145 0.032048
+v 0.193348 2.98125 -0.263232
+v 0.193348 2.98125 0.263232
+v 0.194472 2.9232 -0.194472
+v 0.194472 2.9232 0.194472
+v 0.1946 3.14145 0
+v 0.1946 3.14145 -0
+v 0.195658 2.86335 -0.101925
+v 0.195658 2.86335 0.101925
+v 0.197424 2.7 0.032816
+v 0.197424 2.7 -0.032816
+v 0.197424 2.7 -0.032816
+v 0.197424 2.7 0.032816
+v 0.197684 2.4744 -1.18928
+v 0.197684 2.4744 1.18928
+v 0.198374 2.6592 -0.198374
+v 0.198374 2.6592 0.198374
+v 0.2 2.7 -0
+v 0.2 2.7 0
+v 0.2 2.7 0
+v 0.2 2.7 -0
+v 0.208794 2.86335 0.07027
+v 0.208794 2.86335 -0.07027
+v 0.209136 2.4408 -1.25818
+v 0.209136 2.4408 1.25818
+v 0.21074 0.046875 -1.26783
+v 0.21074 0.046875 1.26783
+v 0.213123 3.08115 -0.290138
+v 0.213123 3.08115 0.290138
+v 0.213234 3.0348 -0.290295
+v 0.213234 3.0348 0.290295
+v 0.213304 2.4 -1.28326
+v 0.213304 2.4 1.28326
+v 0.214905 2.5728 -0.639758
+v 0.214905 2.5728 0.639758
+v 0.216979 2.86335 0.036157
+v 0.216979 2.86335 -0.036157
+v 0.219536 3.1176 -0.219536
+v 0.219536 3.1176 0.219536
+v 0.2198 2.86335 -0
+v 0.2198 2.86335 0
+v 0.221585 2.9232 -0.162745
+v 0.221585 2.9232 0.162745
+v 0.224349 0.0084 0.667871
+v 0.224349 0.0084 -0.667871
+v 0.226113 2.6592 -0.165941
+v 0.226113 2.6592 0.165941
+v 0.226496 2.463 -1.36262
+v 0.226496 2.463 1.36262
+v 0.226795 2.48269 1.36442
+v 0.226795 2.48269 -1.36442
+v 0.226824 0.0648 1.3646
+v 0.226824 0.0648 -1.3646
+v 0.227403 2.43544 -1.36807
+v 0.227403 2.43544 1.36807
+v 0.228104 2.4945 -1.37229
+v 0.228104 2.4945 1.37229
+v 0.229712 2.4 -1.38197
+v 0.229712 2.4 1.38197
+v 0.230225 2.49844 -1.38505
+v 0.230225 2.49844 1.38505
+v 0.230604 0.002175 -0.314223
+v 0.230604 0.002175 0.314223
+v 0.231031 2.98125 -0.231031
+v 0.231031 2.98125 0.231031
+v 0.232342 2.6256 -0.31659
+v 0.232342 2.6256 0.31659
+v 0.232961 2.4945 -1.40151
+v 0.232961 2.4945 1.40151
+v 0.236115 2.48269 -1.42049
+v 0.236115 2.48269 1.42049
+v 0.237149 0.084525 1.42671
+v 0.237149 0.084525 -1.42671
+v 0.239491 2.463 -1.4408
+v 0.239491 2.463 1.4408
+v 0.242892 2.43544 -1.46126
+v 0.242892 2.43544 1.46126
+v 0.24297 0.1056 1.46173
+v 0.24297 0.1056 -1.46173
+v 0.243424 2.5974 0.467878
+v 0.243424 2.5974 -0.467878
+v 0.243569 2.9232 -0.12692
+v 0.243569 2.9232 0.12692
+v 0.245542 0.127575 1.4772
+v 0.245542 0.127575 -1.4772
+v 0.24612 0.15 -1.48068
+v 0.24612 2.4 -1.48068
+v 0.24612 0.15 1.48068
+v 0.24612 0.15 1.48068
+v 0.24612 2.4 1.48068
+v 0.24612 0.15 -1.48068
+v 0.248417 0.177075 -1.4945
+v 0.248417 0.177075 1.4945
+v 0.248621 2.6592 0.129351
+v 0.248621 2.6592 -0.129351
+v 0.250127 3.1176 -0.183734
+v 0.250127 3.1176 0.183734
+v 0.254652 0.2136 -1.53201
+v 0.254652 0.2136 1.53201
+v 0.254653 3.08115 -0.254653
+v 0.254653 3.08115 0.254653
+v 0.254788 3.0348 -0.254788
+v 0.254788 3.0348 0.254788
+v 0.258385 2.24257 -1.55447
+v 0.258385 2.24257 1.55447
+v 0.25991 2.9232 -0.087511
+v 0.25991 2.9232 0.087511
+v 0.263208 2.55 -0.783552
+v 0.263208 2.55 0.783552
+v 0.263232 2.98125 -0.193348
+v 0.263232 2.98125 0.193348
+v 0.263841 0.260025 1.58729
+v 0.263841 0.260025 -1.58729
+v 0.265363 2.6592 -0.08914
+v 0.265363 2.6592 0.08914
+v 0.270092 2.9232 -0.045032
+v 0.270092 2.9232 0.045032
+v 0.270404 2.0856 -1.62677
+v 0.270404 2.0856 1.62677
+v 0.2736 2.9232 -0
+v 0.2736 2.9232 0
+v 0.274928 3.1176 -0.143301
+v 0.274928 3.1176 0.143301
+v 0.274998 0.3168 -1.65441
+v 0.274998 0.3168 1.65441
+v 0.275675 0.002175 -0.275675
+v 0.275675 0.002175 0.275675
+v 0.275801 2.6592 -0.045844
+v 0.275801 2.6592 0.045844
+v 0.277752 2.6256 -0.277752
+v 0.277752 2.6256 0.277752
+v 0.2794 2.6592 0
+v 0.28193 1.92952 1.69612
+v 0.28193 1.92952 -1.69612
+v 0.28714 0.384375 -1.72746
+v 0.28714 0.384375 1.72746
+v 0.28934 2.98125 -0.150793
+v 0.28934 2.98125 0.150793
+v 0.290138 3.08115 -0.213123
+v 0.290138 3.08115 0.213123
+v 0.290295 3.0348 -0.213234
+v 0.290295 3.0348 0.213234
+v 0.292719 1.7748 -1.76102
+v 0.292719 1.7748 1.76102
+v 0.29336 3.1176 -0.098814
+v 0.29336 3.1176 0.098814
+v 0.299282 0.4632 -1.80051
+v 0.299282 0.4632 1.80051
+v 0.302522 1.62187 -1.82
+v 0.302523 1.62187 1.82
+v 0.303862 0.018225 0.904575
+v 0.303862 0.018225 -0.904575
+v 0.304843 3.1176 -0.050855
+v 0.304843 3.1176 0.050855
+v 0.308744 2.98125 -0.103976
+v 0.308744 2.98125 0.103976
+v 0.3088 3.1176 0
+v 0.3088 3.1176 -0
+v 0.309596 2.5272 -0.921647
+v 0.309596 2.5272 0.921647
+v 0.310439 0.553725 -1.86763
+v 0.310439 0.553725 1.86763
+v 0.311096 1.4712 -1.87158
+v 0.311096 1.4712 1.87158
+v 0.31185 2.5728 -0.599396
+v 0.31185 2.5728 0.599396
+v 0.312283 2.5974 -0.425519
+v 0.312283 2.5974 0.425519
+v 0.314223 0.002175 -0.230604
+v 0.314223 0.002175 0.230604
+v 0.31659 2.6256 -0.232342
+v 0.31659 2.6256 0.232342
+v 0.318192 1.32323 -1.91427
+v 0.318192 1.32323 1.91427
+v 0.318907 3.08115 -0.166221
+v 0.318907 3.08115 0.166221
+v 0.319082 3.0348 -0.166306
+v 0.319082 3.0348 0.166306
+v 0.319628 0.6564 -1.92291
+v 0.319628 0.6564 1.92291
+v 0.320834 2.98125 -0.053508
+v 0.320834 2.98125 0.053508
+v 0.323566 1.1784 -1.9466
+v 0.323566 1.1784 1.9466
+v 0.325 2.98125 0
+v 0.325 2.98125 -0
+v 0.325553 0.0084 -0.625735
+v 0.325553 0.0084 0.625735
+v 0.325863 0.771675 -1.96042
+v 0.325863 0.771675 1.96042
+v 0.32697 1.03717 -1.96708
+v 0.32697 1.03717 1.96708
+v 0.32816 0.9 -1.97424
+v 0.32816 0.9 -1.97424
+v 0.32816 0.9 1.97424
+v 0.340289 3.08115 -0.114619
+v 0.340289 3.08115 0.114619
+v 0.340477 3.0348 -0.114676
+v 0.340477 3.0348 0.114676
+v 0.345503 0.002175 -0.179756
+v 0.345503 0.002175 0.179756
+v 0.348105 2.6256 -0.18111
+v 0.348105 2.6256 0.18111
+v 0.351008 2.5026 -1.04493
+v 0.351008 2.5026 1.04493
+v 0.35361 3.08115 -0.058988
+v 0.35361 3.08115 0.058988
+v 0.353807 3.0348 -0.059016
+v 0.353807 3.0348 0.059016
+v 0.3582 3.08115 -0
+v 0.3582 3.08115 0
+v 0.3584 3.0348 0
+v 0.3584 3.0348 0
+v 0.364854 0.0312 1.08615
+v 0.364854 0.0312 -1.08615
+v 0.368768 0.002175 -0.123875
+v 0.368768 0.002175 0.123875
+v 0.371546 2.6256 -0.124808
+v 0.371546 2.6256 0.124808
+v 0.373318 2.5974 -0.373318
+v 0.373318 2.5974 0.373318
+v 0.381942 2.55 -0.734118
+v 0.381942 2.55 0.734118
+v 0.383274 0.002175 -0.063708
+v 0.383274 0.002175 0.063708
+v 0.384379 2.4744 -1.14427
+v 0.384379 2.4744 1.14427
+v 0.386161 2.6256 -0.064188
+v 0.386161 2.6256 0.064188
+v 0.388275 0.002175 0
+v 0.388275 0.002175 0
+v 0.3912 2.6256 0
+v 0.3912 2.6256 0
+v 0.400065 2.5728 -0.545131
+v 0.400065 2.5728 0.545131
+v 0.406648 2.4408 -1.21056
+v 0.406648 2.4408 1.21056
+v 0.409767 0.046875 1.21985
+v 0.409767 0.046875 -1.21985
+v 0.414752 2.4 -1.23469
+v 0.414752 2.4 1.23469
+v 0.417645 0.0084 -0.569086
+v 0.417645 0.0084 0.569086
+v 0.425519 2.5974 0.312283
+v 0.425519 2.5974 -0.312283
+v 0.440403 2.463 -1.31105
+v 0.440403 2.463 1.31105
+v 0.440935 0.018225 0.847506
+v 0.440935 0.018225 -0.847506
+v 0.440985 2.48269 -1.31278
+v 0.440985 2.48269 1.31278
+v 0.441041 0.0648 1.31295
+v 0.441041 0.0648 -1.31295
+v 0.442166 2.43544 -1.3163
+v 0.442166 2.43544 1.3163
+v 0.443529 2.4945 -1.32036
+v 0.443529 2.4945 1.32036
+v 0.446656 2.4 -1.32966
+v 0.446656 2.4 1.32966
+v 0.447653 2.49844 -1.33263
+v 0.447653 2.49844 1.33263
+v 0.449256 2.5272 -0.863501
+v 0.449256 2.5272 0.863501
+v 0.452973 2.4945 -1.34847
+v 0.452973 2.4945 1.34847
+v 0.459107 2.48269 -1.36673
+v 0.459107 2.48269 1.36673
+v 0.461116 0.084525 1.37271
+v 0.461116 0.084525 -1.37271
+v 0.465671 2.463 -1.38627
+v 0.465671 2.463 1.38627
+v 0.467878 2.5974 -0.243424
+v 0.467878 2.5974 0.243424
+v 0.472283 2.43544 -1.40595
+v 0.472283 2.43544 1.40595
+v 0.472434 0.1056 1.4064
+v 0.472434 0.1056 -1.4064
+v 0.477435 0.127575 1.42129
+v 0.477435 0.127575 -1.42129
+v 0.478256 2.5728 -0.478256
+v 0.478256 2.5728 0.478256
+v 0.47856 0.15 -1.42464
+v 0.47856 2.4 -1.42464
+v 0.47856 0.15 1.42464
+v 0.47856 0.15 1.42464
+v 0.47856 0.15 -1.42464
+v 0.47856 2.4 1.42464
+v 0.483027 0.177075 -1.43794
+v 0.483027 0.177075 1.43794
+v 0.489984 2.55 -0.667656
+v 0.489984 2.55 0.667656
+v 0.49515 0.2136 -1.47403
+v 0.49515 0.2136 1.47403
+v 0.499272 0.0084 -0.499272
+v 0.499272 0.0084 0.499272
+v 0.499384 2.5974 -0.167751
+v 0.499384 2.5974 0.167751
+v 0.502408 2.24257 -1.49564
+v 0.502408 2.24257 1.49564
+v 0.509349 2.5026 0.979002
+v 0.509349 2.5026 -0.979002
+v 0.513016 0.260025 -1.52721
+v 0.513016 0.260025 1.52721
+v 0.519028 2.5974 0.086273
+v 0.519028 2.5974 -0.086273
+v 0.525778 2.0856 -1.5652
+v 0.525778 2.0856 1.5652
+v 0.5258 2.5974 -0
+v 0.5258 2.5974 0
+v 0.529441 0.0312 -1.01762
+v 0.529441 0.0312 1.01762
+v 0.534711 0.3168 -1.5918
+v 0.534711 0.3168 1.5918
+v 0.545131 2.5728 -0.400065
+v 0.545131 2.5728 0.400065
+v 0.54819 1.92952 -1.63193
+v 0.54819 1.92952 1.63193
+v 0.557774 2.4744 -1.07208
+v 0.557774 2.4744 1.07208
+v 0.55832 0.384375 -1.66208
+v 0.55832 0.384375 1.66208
+v 0.565664 0.018225 0.770779
+v 0.565664 0.018225 -0.770779
+v 0.569086 0.0084 -0.417645
+v 0.569086 0.0084 0.417645
+v 0.569167 1.7748 -1.69437
+v 0.569167 1.7748 1.69437
+v 0.57634 2.5272 -0.785325
+v 0.57634 2.5272 0.785325
+v 0.581929 0.4632 -1.73236
+v 0.581929 0.4632 1.73236
+v 0.58575 2.55 -0.58575
+v 0.58575 2.55 0.58575
+v 0.58823 1.62187 -1.75112
+v 0.58823 1.62187 1.75112
+v 0.590089 2.4408 1.13419
+v 0.590089 2.4408 -1.13419
+v 0.594614 0.046875 -1.14289
+v 0.594614 0.046875 1.14289
+v 0.599396 2.5728 -0.31185
+v 0.599396 2.5728 0.31185
+v 0.601848 2.4 -1.15679
+v 0.601848 2.4 1.15679
+v 0.603624 0.553725 -1.79695
+v 0.603624 0.553725 1.79695
+v 0.6049 1.4712 -1.80075
+v 0.6049 1.4712 1.80075
+v 0.618698 1.32323 -1.84182
+v 0.618698 1.32323 1.84182
+v 0.62149 0.6564 -1.85013
+v 0.62149 0.6564 1.85013
+v 0.625735 0.0084 0.325553
+v 0.625735 0.0084 -0.325553
+v 0.629147 1.1784 -1.87293
+v 0.629147 1.1784 1.87293
+v 0.633613 0.771675 -1.88622
+v 0.633613 0.771675 1.88622
+v 0.635767 1.03717 -1.89263
+v 0.635767 1.03717 1.89263
+v 0.63808 0.9 -1.89952
+v 0.63808 0.9 -1.89952
+v 0.63808 0.9 1.89952
+v 0.63808 0.9 1.89952
+v 0.63907 2.463 -1.22833
+v 0.63907 2.463 1.22833
+v 0.639758 2.5728 -0.214905
+v 0.639758 2.5728 0.214905
+v 0.639915 2.48269 1.22996
+v 0.639915 2.48269 -1.22996
+v 0.639996 0.0648 -1.23012
+v 0.639996 0.0648 1.23012
+v 0.641628 2.43544 -1.23325
+v 0.641628 2.43544 1.23325
+v 0.643607 2.4945 -1.23706
+v 0.643607 2.4945 1.23706
+v 0.648144 2.4 -1.24578
+v 0.648144 2.4 1.24578
+v 0.649591 2.49844 -1.24856
+v 0.649591 2.49844 1.24856
+v 0.653431 2.5026 -0.89037
+v 0.653431 2.5026 0.89037
+v 0.657311 2.4945 -1.2634
+v 0.657311 2.4945 1.2634
+v 0.664924 2.5728 -0.110524
+v 0.664924 2.5728 0.110524
+v 0.666211 2.48269 1.2805
+v 0.666211 2.48269 -1.2805
+v 0.667656 2.55 -0.489984
+v 0.667656 2.55 0.489984
+v 0.667871 0.0084 -0.224349
+v 0.667871 0.0084 0.224349
+v 0.669128 0.084525 -1.28611
+v 0.669128 0.084525 1.28611
+v 0.6736 2.5728 0
+v 0.6736 2.5728 -0
+v 0.675736 2.463 -1.29881
+v 0.675736 2.463 1.29881
+v 0.676222 0.018225 0.676222
+v 0.676222 0.018225 -0.676222
+v 0.679207 0.0312 -0.925493
+v 0.679207 0.0312 0.925493
+v 0.685331 2.43544 -1.31725
+v 0.685331 2.43544 1.31725
+v 0.685551 0.1056 -1.31767
+v 0.685551 0.1056 1.31767
+v 0.688984 2.5272 -0.688984
+v 0.688984 2.5272 0.688984
+v 0.692808 0.127575 1.33162
+v 0.692808 0.127575 -1.33162
+v 0.694143 0.0084 -0.115381
+v 0.694143 0.0084 0.115381
+v 0.69444 0.15 1.33476
+v 0.69444 0.15 -1.33476
+v 0.69444 2.4 1.33476
+v 0.69444 0.15 -1.33476
+v 0.69444 0.15 1.33476
+v 0.69444 2.4 -1.33476
+v 0.700921 0.177075 1.34722
+v 0.700921 0.177075 -1.34722
+v 0.7032 0.0084 0
+v 0.715555 2.4744 -0.975021
+v 0.715555 2.4744 0.975021
+v 0.718514 0.2136 1.38103
+v 0.718514 0.2136 -1.38103
+v 0.729046 2.24257 -1.40128
+v 0.729046 2.24257 1.40128
+v 0.734118 2.55 -0.381942
+v 0.734118 2.55 0.381942
+v 0.74444 0.260025 1.43086
+v 0.74444 0.260025 -1.43086
+v 0.75701 2.4408 1.03151
+v 0.75701 2.4408 -1.03151
+v 0.762816 0.046875 -1.03942
+v 0.762816 0.046875 1.03942
+v 0.762958 2.0856 -1.46646
+v 0.762958 2.0856 1.46646
+v 0.770779 0.018225 0.565664
+v 0.770779 0.018225 -0.565664
+v 0.772096 2.4 -1.05206
+v 0.772096 2.4 1.05206
+v 0.775921 0.3168 -1.49137
+v 0.775921 0.3168 1.49137
+v 0.781142 2.5026 -0.781142
+v 0.781142 2.5026 0.781142
+v 0.783552 2.55 -0.263208
+v 0.783552 2.55 0.263208
+v 0.785325 2.5272 -0.57634
+v 0.785325 2.5272 0.57634
+v 0.795481 1.92952 1.52897
+v 0.795481 1.92952 -1.52897
+v 0.81018 0.384375 1.55722
+v 0.81018 0.384375 -1.55722
+v 0.811956 0.0312 0.811956
+v 0.811956 0.0312 -0.811956
+v 0.814374 2.55 -0.135366
+v 0.814374 2.55 0.135366
+v 0.819847 2.463 -1.11713
+v 0.819847 2.463 1.11713
+v 0.820931 2.48269 1.11861
+v 0.820931 2.48269 -1.11861
+v 0.821035 0.0648 1.11875
+v 0.821035 0.0648 -1.11875
+v 0.823129 2.43544 -1.1216
+v 0.823129 2.43544 1.1216
+v 0.825 2.55 0
+v 0.825 2.55 0
+v 0.825668 2.4945 -1.12506
+v 0.825668 2.4945 1.12506
+v 0.825921 1.7748 1.58747
+v 0.825921 1.7748 -1.58747
+v 0.831488 2.4 -1.13299
+v 0.831488 2.4 1.13299
+v 0.833344 2.49844 -1.13552
+v 0.833344 2.49844 1.13552
+v 0.843248 2.4945 -1.14902
+v 0.843248 2.4945 1.14902
+v 0.844439 0.4632 1.62307
+v 0.844439 0.4632 -1.62307
+v 0.847506 0.018225 -0.440935
+v 0.847506 0.018225 0.440935
+v 0.853583 1.62187 -1.64064
+v 0.853583 1.62187 1.64064
+v 0.854666 2.48269 -1.16457
+v 0.854666 2.48269 1.16457
+v 0.855408 2.4744 -0.855408
+v 0.855408 2.4744 0.855408
+v 0.858407 0.084525 -1.16967
+v 0.858407 0.084525 1.16967
+v 0.863501 2.5272 -0.449256
+v 0.863501 2.5272 0.449256
+v 0.866886 2.463 -1.18122
+v 0.866886 2.463 1.18122
+v 0.87592 0.553725 -1.68358
+v 0.87592 0.553725 1.68358
+v 0.877772 1.4712 -1.68714
+v 0.877772 1.4712 1.68714
+v 0.879195 2.43544 -1.198
+v 0.879195 2.43544 1.198
+v 0.879477 0.1056 -1.19838
+v 0.879477 0.1056 1.19838
+v 0.888786 0.127575 1.21107
+v 0.888786 0.127575 -1.21107
+v 0.89037 2.5026 -0.653431
+v 0.89037 2.5026 0.653431
+v 0.89088 0.15 -1.21392
+v 0.89088 0.15 1.21392
+v 0.89088 2.4 -1.21392
+v 0.89088 0.15 -1.21392
+v 0.89088 0.15 1.21392
+v 0.89088 2.4 1.21392
+v 0.897795 1.32323 -1.72562
+v 0.897795 1.32323 1.72562
+v 0.899195 0.177075 1.22525
+v 0.899195 0.177075 -1.22525
+v 0.901846 0.6564 -1.73341
+v 0.901846 0.6564 1.73341
+v 0.904575 0.018225 0.303862
+v 0.904575 0.018225 -0.303862
+v 0.904966 2.4408 0.904966
+v 0.904966 2.4408 -0.904966
+v 0.911906 0.046875 -0.911906
+v 0.911906 0.046875 0.911906
+v 0.912957 1.1784 -1.75476
+v 0.912957 1.1784 1.75476
+v 0.919439 0.771675 -1.76722
+v 0.919439 0.771675 1.76722
+v 0.921647 2.5272 -0.309596
+v 0.921647 2.5272 0.309596
+v 0.921764 0.2136 1.256
+v 0.921764 0.2136 -1.256
+v 0.922564 1.03717 1.77323
+v 0.922564 1.03717 -1.77323
+v 0.923 2.4 -0.923
+v 0.923 2.4 0.923
+v 0.925493 0.0312 0.679207
+v 0.925493 0.0312 -0.679207
+v 0.92592 0.9 1.77968
+v 0.92592 0.9 -1.77968
+v 0.92592 0.9 -1.77968
+v 0.92592 0.9 1.77968
+v 0.935276 2.24257 -1.27441
+v 0.935276 2.24257 1.27441
+v 0.940158 0.018225 0.156274
+v 0.940158 0.018225 -0.156274
+v 0.952425 0.018225 0
+v 0.952425 0.018225 0
+v 0.955023 0.260025 1.30132
+v 0.955023 0.260025 -1.30132
+v 0.957901 2.5272 -0.159223
+v 0.957901 2.5272 0.159223
+v 0.9704 2.5272 0
+v 0.9704 2.5272 -0
+v 0.975021 2.4744 -0.715555
+v 0.975021 2.4744 0.715555
+v 0.97878 2.0856 -1.33369
+v 0.97878 2.0856 1.33369
+v 0.979002 2.5026 0.509349
+v 0.979002 2.5026 -0.509349
+v 0.980084 2.463 -0.980084
+v 0.980084 2.463 0.980084
+v 0.98138 2.48269 -0.98138
+v 0.98138 2.48269 0.98138
+v 0.981504 0.0648 0.981504
+v 0.981504 0.0648 -0.981504
+v 0.984007 2.43544 -0.984007
+v 0.984007 2.43544 0.984007
+v 0.987042 2.4945 -0.987042
+v 0.987042 2.4945 0.987042
+v 0.994 2.4 -0.994
+v 0.994 2.4 0.994
+v 0.99541 0.3168 -1.35635
+v 0.99541 0.3168 1.35635
+v 0.996219 2.49844 -0.996219
+v 0.996219 2.49844 0.996219
+v 1.00806 2.4945 -1.00806
+v 1.00806 2.4945 1.00806
+v 1.01762 0.0312 0.529441
+v 1.01762 0.0312 -0.529441
+v 1.0205 1.92952 -1.39054
+v 1.0205 1.92952 1.39054
+v 1.02171 2.48269 -1.02171
+v 1.02171 2.48269 1.02171
+v 1.02618 0.084525 -1.02618
+v 1.02618 0.084525 1.02618
+v 1.03151 2.4408 0.75701
+v 1.03151 2.4408 -0.75701
+v 1.03632 2.463 -1.03632
+v 1.03632 2.463 1.03632
+v 1.03936 0.384375 -1.41624
+v 1.03936 0.384375 1.41624
+v 1.03942 0.046875 -0.762816
+v 1.03942 0.046875 0.762816
+v 1.04493 2.5026 -0.351008
+v 1.04493 2.5026 0.351008
+v 1.05103 2.43544 -1.05103
+v 1.05103 2.43544 1.05103
+v 1.05137 0.1056 -1.05137
+v 1.05137 0.1056 1.05137
+v 1.05206 2.4 -0.772096
+v 1.05206 2.4 0.772096
+v 1.05955 1.7748 -1.44376
+v 1.05955 1.7748 1.44376
+v 1.0625 0.127575 1.0625
+v 1.0625 0.127575 -1.0625
+v 1.065 0.15 -1.065
+v 1.065 0.15 1.065
+v 1.065 2.4 -1.065
+v 1.065 2.4 1.065
+v 1.07208 2.4744 -0.557774
+v 1.07208 2.4744 0.557774
+v 1.07494 0.177075 -1.07494
+v 1.07494 0.177075 1.07494
+v 1.08331 0.4632 -1.47613
+v 1.08331 0.4632 1.47613
+v 1.08603 2.5026 0.180521
+v 1.08603 2.5026 -0.180521
+v 1.08615 0.0312 0.364854
+v 1.08615 0.0312 -0.364854
+v 1.09504 1.62187 -1.49211
+v 1.09504 1.62187 1.49211
+v 1.1002 2.5026 -0
+v 1.1002 2.5026 0
+v 1.10192 0.2136 1.10192
+v 1.10192 0.2136 -1.10192
+v 1.11713 2.463 -0.819847
+v 1.11713 2.463 0.819847
+v 1.11807 2.24257 -1.11807
+v 1.11807 2.24257 1.11807
+v 1.11861 2.48269 -0.820931
+v 1.11861 2.48269 0.820931
+v 1.11875 0.0648 -0.821035
+v 1.11875 0.0648 0.821035
+v 1.1216 2.43544 -0.823129
+v 1.1216 2.43544 0.823129
+v 1.1237 0.553725 -1.53116
+v 1.1237 0.553725 1.53116
+v 1.12506 2.4945 -0.825668
+v 1.12506 2.4945 0.825668
+v 1.12607 1.4712 -1.53439
+v 1.12607 1.4712 1.53439
+v 1.12887 0.0312 -0.187642
+v 1.12887 0.0312 0.187642
+v 1.13299 2.4 -0.831488
+v 1.13299 2.4 0.831488
+v 1.13419 2.4408 0.590089
+v 1.13419 2.4408 -0.590089
+v 1.13552 2.49844 -0.833344
+v 1.13552 2.49844 0.833344
+v 1.14168 0.260025 1.14168
+v 1.14168 0.260025 -1.14168
+v 1.14289 0.046875 -0.594614
+v 1.14289 0.046875 0.594614
+v 1.1436 0.0312 0
+v 1.1436 0.0312 0
+v 1.14427 2.4744 -0.384379
+v 1.14427 2.4744 0.384379
+v 1.14902 2.4945 -0.843248
+v 1.14902 2.4945 0.843248
+v 1.15176 1.32323 -1.5694
+v 1.15176 1.32323 1.5694
+v 1.15679 2.4 -0.601848
+v 1.15679 2.4 0.601848
+v 1.15696 0.6564 -1.57648
+v 1.15696 0.6564 1.57648
+v 1.16457 2.48269 -0.854666
+v 1.16457 2.48269 0.854666
+v 1.16967 0.084525 -0.858407
+v 1.16967 0.084525 0.858407
+v 1.17008 2.0856 -1.17008
+v 1.17008 2.0856 1.17008
+v 1.17121 1.1784 -1.5959
+v 1.17121 1.1784 1.5959
+v 1.17952 0.771675 -1.60723
+v 1.17952 0.771675 1.60723
+v 1.18122 2.463 -0.866886
+v 1.18122 2.463 0.866886
+v 1.18353 1.03717 -1.61269
+v 1.18353 1.03717 1.61269
+v 1.18784 0.9 -1.61856
+v 1.18784 0.9 -1.61856
+v 1.18784 0.9 1.61856
+v 1.18784 0.9 1.61856
+v 1.18928 2.4744 -0.197684
+v 1.18928 2.4744 0.197684
+v 1.18996 0.3168 -1.18996
+v 1.18996 0.3168 1.18996
+v 1.198 2.43544 -0.879195
+v 1.198 2.43544 0.879195
+v 1.19838 0.1056 -0.879477
+v 1.19838 0.1056 0.879477
+v 1.2048 2.4744 0
+v 1.2048 2.4744 -0
+v 1.21056 2.4408 0.406648
+v 1.21056 2.4408 -0.406648
+v 1.21107 0.127575 0.888786
+v 1.21107 0.127575 -0.888786
+v 1.21392 0.15 -0.89088
+v 1.21392 0.15 -0.89088
+v 1.21392 0.15 0.89088
+v 1.21392 0.15 0.89088
+v 1.21392 2.4 -0.89088
+v 1.21392 2.4 0.89088
+v 1.21985 0.046875 -0.409767
+v 1.21985 0.046875 0.409767
+v 1.21996 1.92952 1.21996
+v 1.21996 1.92952 -1.21996
+v 1.22525 0.177075 0.899195
+v 1.22525 0.177075 -0.899195
+v 1.22833 2.463 -0.63907
+v 1.22833 2.463 0.63907
+v 1.22996 2.48269 -0.639915
+v 1.22996 2.48269 0.639915
+v 1.23012 0.0648 -0.639996
+v 1.23012 0.0648 0.639996
+v 1.23325 2.43544 -0.641628
+v 1.23325 2.43544 0.641628
+v 1.23469 2.4 -0.414752
+v 1.23469 2.4 0.414752
+v 1.23706 2.4945 -0.643607
+v 1.23706 2.4945 0.643607
+v 1.2425 0.384375 -1.2425
+v 1.2425 0.384375 1.2425
+v 1.24578 2.4 -0.648144
+v 1.24578 2.4 0.648144
+v 1.24856 2.49844 -0.649591
+v 1.24856 2.49844 0.649591
+v 1.256 0.2136 0.921764
+v 1.256 0.2136 -0.921764
+v 1.25818 2.4408 0.209136
+v 1.25818 2.4408 -0.209136
+v 1.2634 2.4945 -0.657311
+v 1.2634 2.4945 0.657311
+v 1.26664 1.7748 -1.26664
+v 1.26664 1.7748 1.26664
+v 1.26783 0.046875 -0.21074
+v 1.26783 0.046875 0.21074
+v 1.27441 2.24257 -0.935276
+v 1.27441 2.24257 0.935276
+v 1.2746 2.4408 0
+v 1.2746 2.4408 0
+v 1.2805 2.48269 -0.666211
+v 1.2805 2.48269 0.666211
+v 1.28326 2.4 -0.213304
+v 1.28326 2.4 0.213304
+v 1.28438 0.046875 0
+v 1.28438 0.046875 -0
+v 1.28611 0.084525 -0.669128
+v 1.28611 0.084525 0.669128
+v 1.29504 0.4632 -1.29504
+v 1.29504 0.4632 1.29504
+v 1.29881 2.463 -0.675736
+v 1.29881 2.463 0.675736
+v 1.3 2.4 0
+v 1.3 2.4 -0
+v 1.30132 0.260025 0.955023
+v 1.30132 0.260025 -0.955023
+v 1.30906 1.62187 -1.30906
+v 1.30906 1.62187 1.30906
+v 1.31105 2.463 -0.440403
+v 1.31105 2.463 0.440403
+v 1.31278 2.48269 -0.440985
+v 1.31278 2.48269 0.440985
+v 1.31295 0.0648 0.441041
+v 1.31295 0.0648 -0.441041
+v 1.3163 2.43544 -0.442166
+v 1.3163 2.43544 0.442166
+v 1.31725 2.43544 -0.685331
+v 1.31725 2.43544 0.685331
+v 1.31767 0.1056 -0.685551
+v 1.31767 0.1056 0.685551
+v 1.32036 2.4945 -0.443529
+v 1.32036 2.4945 0.443529
+v 1.32966 2.4 -0.446656
+v 1.32966 2.4 0.446656
+v 1.33162 0.127575 0.692808
+v 1.33162 0.127575 -0.692808
+v 1.33263 2.49844 -0.447653
+v 1.33263 2.49844 0.447653
+v 1.33369 2.0856 -0.97878
+v 1.33369 2.0856 0.97878
+v 1.33476 0.15 0.69444
+v 1.33476 0.15 -0.69444
+v 1.33476 0.15 -0.69444
+v 1.33476 0.15 0.69444
+v 1.33476 2.4 -0.69444
+v 1.33476 2.4 0.69444
+v 1.34332 0.553725 -1.34332
+v 1.34332 0.553725 1.34332
+v 1.34616 1.4712 -1.34616
+v 1.34616 1.4712 1.34616
+v 1.34722 0.177075 0.700921
+v 1.34722 0.177075 -0.700921
+v 1.34847 2.4945 -0.452973
+v 1.34847 2.4945 0.452973
+v 1.35635 0.3168 -0.99541
+v 1.35635 0.3168 0.99541
+v 1.36262 2.463 -0.226496
+v 1.36262 2.463 0.226496
+v 1.36442 2.48269 -0.226795
+v 1.36442 2.48269 0.226795
+v 1.3646 0.0648 -0.226824
+v 1.3646 0.0648 0.226824
+v 1.36673 2.48269 -0.459107
+v 1.36673 2.48269 0.459107
+v 1.36807 2.43544 -0.227403
+v 1.36807 2.43544 0.227403
+v 1.37229 2.4945 -0.228104
+v 1.37229 2.4945 0.228104
+v 1.37271 0.084525 -0.461116
+v 1.37271 0.084525 0.461116
+v 1.37687 1.32323 -1.37687
+v 1.37687 1.32323 1.37687
+v 1.3804 2.463 0
+v 1.3804 2.463 -0
+v 1.38103 0.2136 0.718514
+v 1.38103 0.2136 -0.718514
+v 1.38197 2.4 -0.229712
+v 1.38197 2.4 0.229712
+v 1.38223 2.48269 0
+v 1.38223 2.48269 0
+v 1.3824 0.0648 0
+v 1.3824 0.0648 0
+v 1.38308 0.6564 -1.38308
+v 1.38308 0.6564 1.38308
+v 1.38505 2.49844 -0.230225
+v 1.38505 2.49844 0.230225
+v 1.38593 2.43544 0
+v 1.38593 2.43544 -0
+v 1.38627 2.463 -0.465671
+v 1.38627 2.463 0.465671
+v 1.3902 2.4945 0
+v 1.3902 2.4945 -0
+v 1.39054 1.92952 -1.0205
+v 1.39054 1.92952 1.0205
+v 1.4 2.4 0
+v 1.4 2.4 0
+v 1.40012 1.1784 -1.40012
+v 1.40012 1.1784 1.40012
+v 1.40128 2.24257 -0.729046
+v 1.40128 2.24257 0.729046
+v 1.40151 2.4945 -0.232961
+v 1.40151 2.4945 0.232961
+v 1.40312 2.49844 0
+v 1.40312 2.49844 0
+v 1.40595 2.43544 -0.472283
+v 1.40595 2.43544 0.472283
+v 1.4064 0.1056 -0.472434
+v 1.4064 0.1056 0.472434
+v 1.41006 0.771675 -1.41006
+v 1.41006 0.771675 1.41006
+v 1.41485 1.03717 -1.41485
+v 1.41485 1.03717 1.41485
+v 1.41624 0.384375 -1.03936
+v 1.41624 0.384375 1.03936
+v 1.4198 2.4945 0
+v 1.4198 2.4945 -0
+v 1.42 0.9 -1.42
+v 1.42 0.9 -1.42
+v 1.42 0.9 1.42
+v 1.42 0.9 1.42
+v 1.42049 2.48269 -0.236115
+v 1.42049 2.48269 0.236115
+v 1.42129 0.127575 0.477435
+v 1.42129 0.127575 -0.477435
+v 1.42464 0.15 -0.47856
+v 1.42464 0.15 -0.47856
+v 1.42464 0.15 0.47856
+v 1.42464 0.15 0.47856
+v 1.42464 2.4 -0.47856
+v 1.42464 2.4 0.47856
+v 1.42671 0.084525 -0.237149
+v 1.42671 0.084525 0.237149
+v 1.43086 0.260025 0.74444
+v 1.43086 0.260025 -0.74444
+v 1.43794 0.177075 0.483027
+v 1.43794 0.177075 -0.483027
+v 1.43902 2.48269 0
+v 1.4408 2.463 -0.239491
+v 1.4408 2.463 0.239491
+v 1.44376 1.7748 -1.05955
+v 1.44376 1.7748 1.05955
+v 1.44532 0.084525 0
+v 1.44532 0.084525 0
+v 1.4596 2.463 0
+v 1.4596 2.463 -0
+v 1.46126 2.43544 -0.242892
+v 1.46126 2.43544 0.242892
+v 1.46173 0.1056 -0.24297
+v 1.46173 0.1056 0.24297
+v 1.46646 2.0856 -0.762958
+v 1.46646 2.0856 0.762958
+v 1.47403 0.2136 0.49515
+v 1.47403 0.2136 -0.49515
+v 1.47613 0.4632 -1.08331
+v 1.47613 0.4632 1.08331
+v 1.4772 0.127575 0.245542
+v 1.4772 0.127575 -0.245542
+v 1.48032 2.43544 0
+v 1.48032 2.43544 -0
+v 1.48068 0.15 -0.24612
+v 1.48068 0.15 0.24612
+v 1.48068 0.15 0.24612
+v 1.48068 0.15 -0.24612
+v 1.48068 2.4 -0.24612
+v 1.48068 2.4 0.24612
+v 1.4808 0.1056 0
+v 1.4808 0.1056 0
+v 1.49137 0.3168 -0.775921
+v 1.49137 0.3168 0.775921
+v 1.49211 1.62187 -1.09504
+v 1.49211 1.62187 1.09504
+v 1.4945 0.177075 0.248417
+v 1.4945 0.177075 -0.248417
+v 1.49564 2.24257 -0.502408
+v 1.49564 2.24257 0.502408
+v 1.49647 0.127575 0
+v 1.49647 0.127575 0
+v 1.5 0.15 0
+v 1.5 0.15 0
+v 1.5 2.4 0
+v 1.5 2.4 0
+v 1.514 0.177075 -0
+v 1.514 0.177075 0
+v 1.52721 0.260025 -0.513016
+v 1.52721 0.260025 0.513016
+v 1.52897 1.92952 -0.795481
+v 1.52897 1.92952 0.795481
+v 1.53116 0.553725 -1.1237
+v 1.53116 0.553725 1.1237
+v 1.53201 0.2136 0.254652
+v 1.53201 0.2136 -0.254652
+v 1.53439 1.4712 -1.12607
+v 1.53439 1.4712 1.12607
+v 1.552 0.2136 0
+v 1.552 0.2136 0
+v 1.55447 2.24257 -0.258385
+v 1.55447 2.24257 0.258385
+v 1.55722 0.384375 -0.81018
+v 1.55722 0.384375 0.81018
+v 1.5652 2.0856 -0.525778
+v 1.5652 2.0856 0.525778
+v 1.5694 1.32323 -1.15176
+v 1.5694 1.32323 1.15176
+v 1.57475 2.24257 0
+v 1.57475 2.24257 0
+v 1.57648 0.6564 -1.15696
+v 1.57648 0.6564 1.15696
+v 1.58729 0.260025 0.263841
+v 1.58729 0.260025 -0.263841
+v 1.58747 1.7748 -0.825921
+v 1.58747 1.7748 0.825921
+v 1.5918 0.3168 -0.534711
+v 1.5918 0.3168 0.534711
+v 1.5959 1.1784 -1.17121
+v 1.5959 1.1784 1.17121
+v 1.60723 0.771675 -1.17952
+v 1.60723 0.771675 1.17952
+v 1.608 0.260025 0
+v 1.608 0.260025 0
+v 1.61269 1.03717 -1.18353
+v 1.61269 1.03717 1.18353
+v 1.61856 0.9 -1.18784
+v 1.61856 0.9 -1.18784
+v 1.61856 0.9 1.18784
+v 1.61856 0.9 1.18784
+v 1.62307 0.4632 -0.844439
+v 1.62307 0.4632 0.844439
+v 1.62677 2.0856 -0.270404
+v 1.62677 2.0856 0.270404
+v 1.63193 1.92952 -0.54819
+v 1.63193 1.92952 0.54819
+v 1.64064 1.62187 -0.853583
+v 1.64064 1.62187 0.853583
+v 1.648 2.0856 0
+v 1.648 2.0856 -0
+v 1.65441 0.3168 -0.274998
+v 1.65441 0.3168 0.274998
+v 1.66208 0.384375 -0.55832
+v 1.66208 0.384375 0.55832
+v 1.676 0.3168 0
+v 1.676 0.3168 0
+v 1.68358 0.553725 -0.87592
+v 1.68358 0.553725 0.87592
+v 1.68714 1.4712 -0.877772
+v 1.68714 1.4712 0.877772
+v 1.69437 1.7748 -0.569167
+v 1.69437 1.7748 0.569167
+v 1.69612 1.92952 -0.28193
+v 1.69612 1.92952 0.28193
+v 1.7 0.6 0
+v 1.7 0.6 0
+v 1.7 0.6231 0.1782
+v 1.7 0.6231 -0.1782
+v 1.7 0.6858 -0.3168
+v 1.7 0.6858 0.3168
+v 1.7 0.7782 0.4158
+v 1.7 0.7782 -0.4158
+v 1.7 0.8904 -0.4752
+v 1.7 0.8904 0.4752
+v 1.7 1.0125 -0.495
+v 1.7 1.0125 0.495
+v 1.7 1.1346 -0.4752
+v 1.7 1.1346 0.4752
+v 1.7 1.2468 0.4158
+v 1.7 1.2468 -0.4158
+v 1.7 1.3392 -0.3168
+v 1.7 1.3392 0.3168
+v 1.7 1.4019 0.1782
+v 1.7 1.4019 -0.1782
+v 1.7 1.425 0
+v 1.7 1.425 0
+v 1.71825 1.92952 0
+v 1.71825 1.92952 0
+v 1.72562 1.32323 -0.897795
+v 1.72562 1.32323 0.897795
+v 1.72746 0.384375 -0.28714
+v 1.72746 0.384375 0.28714
+v 1.73236 0.4632 -0.581929
+v 1.73236 0.4632 0.581929
+v 1.73341 0.6564 -0.901846
+v 1.73341 0.6564 0.901846
+v 1.75 0.384375 0
+v 1.75 0.384375 0
+v 1.75112 1.62187 -0.58823
+v 1.75112 1.62187 0.58823
+v 1.75476 1.1784 -0.912957
+v 1.75476 1.1784 0.912957
+v 1.76102 1.7748 -0.292719
+v 1.76102 1.7748 0.292719
+v 1.76722 0.771675 -0.919439
+v 1.76722 0.771675 0.919439
+v 1.77323 1.03717 -0.922564
+v 1.77323 1.03717 0.922564
+v 1.77968 0.9 -0.92592
+v 1.77968 0.9 -0.92592
+v 1.77968 0.9 0.92592
+v 1.77968 0.9 0.92592
+v 1.784 1.7748 0
+v 1.784 1.7748 0
+v 1.79695 0.553725 -0.603624
+v 1.79695 0.553725 0.603624
+v 1.80051 0.4632 -0.299282
+v 1.80051 0.4632 0.299282
+v 1.80075 1.4712 -0.6049
+v 1.80075 1.4712 0.6049
+v 1.82 1.62187 -0.302523
+v 1.82 1.62187 0.302522
+v 1.824 0.4632 0
+v 1.824 0.4632 0
+v 1.84182 1.32323 -0.618698
+v 1.84182 1.32323 0.618698
+v 1.84375 1.62187 0
+v 1.84375 1.62187 -0
+v 1.85013 0.6564 -0.62149
+v 1.85013 0.6564 0.62149
+v 1.86763 0.553725 -0.310439
+v 1.86763 0.553725 0.310439
+v 1.87158 1.4712 -0.311096
+v 1.87158 1.4712 0.311096
+v 1.87293 1.1784 -0.629147
+v 1.87293 1.1784 0.629147
+v 1.88622 0.771675 -0.633613
+v 1.88622 0.771675 0.633613
+v 1.892 0.553725 0
+v 1.892 0.553725 -0
+v 1.89263 1.03717 -0.635767
+v 1.89263 1.03717 0.635767
+v 1.896 1.4712 0
+v 1.896 1.4712 0
+v 1.89952 0.9 -0.63808
+v 1.89952 0.9 -0.63808
+v 1.89952 0.9 0.63808
+v 1.89952 0.9 0.63808
+v 1.91427 1.32323 -0.318192
+v 1.91427 1.32323 0.318192
+v 1.92291 0.6564 -0.319628
+v 1.92291 0.6564 0.319628
+v 1.9359 1.4442 0
+v 1.9359 1.4442 0
+v 1.93925 1.32323 0
+v 1.93925 1.32323 -0
+v 1.93939 1.42322 -0.1751
+v 1.93939 1.42322 0.1751
+v 1.9466 1.1784 -0.323566
+v 1.9466 1.1784 0.323566
+v 1.948 0.6564 0
+v 1.948 0.6564 -0
+v 1.94888 1.36628 -0.31129
+v 1.94888 1.36628 0.31129
+v 1.96042 0.771675 -0.325863
+v 1.96042 0.771675 0.325863
+v 1.96286 1.28236 -0.408568
+v 1.96286 1.28236 0.408568
+v 1.96708 1.03717 -0.32697
+v 1.96708 1.03717 0.32697
+v 1.972 1.1784 0
+v 1.972 1.1784 0
+v 1.97424 0.9 -0.32816
+v 1.97424 0.9 0.32816
+v 1.97424 0.9 0.32816
+v 1.97983 1.18046 -0.466934
+v 1.97983 1.18046 0.466934
+v 1.986 0.771675 0
+v 1.986 0.771675 -0
+v 1.99275 1.03717 0
+v 1.99275 1.03717 0
+v 1.9983 1.06957 -0.48639
+v 1.9983 1.06957 0.48639
+v 2 0.9 0
+v 2 0.9 0
+v 2.01677 0.958686 -0.466934
+v 2.01677 0.958686 0.466934
+v 2.03374 0.856788 -0.408568
+v 2.03374 0.856788 0.408568
+v 2.04772 0.772872 0.31129
+v 2.04772 0.772872 -0.31129
+v 2.05721 0.715929 0.1751
+v 2.05721 0.715929 -0.1751
+v 2.0607 0.69495 0
+v 2.0607 0.69495 0
+v 2.1112 1.4976 0
+v 2.1112 1.4976 0
+v 2.11698 1.47912 -0.166687
+v 2.11698 1.47912 0.166687
+v 2.13267 1.42896 -0.296333
+v 2.13267 1.42896 0.296333
+v 2.15578 1.35504 -0.388937
+v 2.15578 1.35504 0.388937
+v 2.18385 1.26528 -0.444499
+v 2.18385 1.26528 0.444499
+v 2.2144 1.1676 -0.46302
+v 2.2144 1.1676 0.46302
+v 2.2373 1.5789 0
+v 2.2373 1.5789 0
+v 2.24446 1.56317 -0.154289
+v 2.24446 1.56317 0.154289
+v 2.24495 1.06992 -0.444499
+v 2.24495 1.06992 0.444499
+v 2.26388 1.52048 -0.274291
+v 2.26388 1.52048 0.274291
+v 2.27302 0.98016 -0.388937
+v 2.27302 0.98016 0.388937
+v 2.29251 1.45756 -0.360007
+v 2.29251 1.45756 0.360007
+v 2.29613 0.90624 -0.296333
+v 2.29613 0.90624 0.296333
+v 2.31182 0.85608 -0.166687
+v 2.31182 0.85608 0.166687
+v 2.3176 0.8376 0
+v 2.3176 0.8376 0
+v 2.3256 1.6818 0
+v 2.3256 1.6818 0
+v 2.32727 1.38116 -0.411437
+v 2.32727 1.38116 0.411437
+v 2.33353 1.66895 -0.139234
+v 2.33353 1.66895 0.139234
+v 2.35505 1.63406 -0.247526
+v 2.35505 1.63406 0.247526
+v 2.3651 1.29802 -0.42858
+v 2.3651 1.29802 0.42858
+v 2.38677 1.58266 -0.324878
+v 2.38677 1.58266 0.324878
+v 2.3875 1.8 0
+v 2.3875 1.8 0
+v 2.3959 1.79002 0.12285
+v 2.3959 1.79002 -0.12285
+v 2.40293 1.21489 -0.411437
+v 2.40293 1.21489 0.411437
+v 2.4187 1.76295 -0.2184
+v 2.4187 1.76295 0.2184
+v 2.42529 1.52023 -0.37129
+v 2.42529 1.52023 0.37129
+v 2.4344 1.9272 0
+v 2.4344 1.9272 0
+v 2.43769 1.13849 -0.360007
+v 2.43769 1.13849 0.360007
+v 2.44327 1.91998 0.106466
+v 2.44327 1.91998 -0.106466
+v 2.4523 1.72305 -0.28665
+v 2.4523 1.72305 0.28665
+v 2.46632 1.07557 -0.274291
+v 2.46632 1.07557 0.274291
+v 2.4672 1.4523 -0.38676
+v 2.4672 1.4523 0.38676
+v 2.46735 1.90037 0.189274
+v 2.46735 1.90037 -0.189274
+v 2.4777 2.0571 0
+v 2.4777 2.0571 0
+v 2.48574 1.03288 -0.154289
+v 2.48574 1.03288 0.154289
+v 2.48734 2.05238 -0.091411
+v 2.48734 2.05238 0.091411
+v 2.4929 1.01715 0
+v 2.4929 1.01715 0
+v 2.4931 1.6746 -0.3276
+v 2.4931 1.6746 0.3276
+v 2.50283 1.87147 0.248422
+v 2.50283 1.87147 -0.248422
+v 2.50911 1.38437 -0.37129
+v 2.50911 1.38437 0.37129
+v 2.51352 2.03955 0.162509
+v 2.51352 2.03955 -0.162509
+v 2.5288 2.1834 0
+v 2.5375 1.62187 -0.34125
+v 2.5375 1.62187 0.34125
+v 2.53982 2.1808 -0.079013
+v 2.53982 2.1808 0.079013
+v 2.54591 1.83638 -0.28391
+v 2.54591 1.83638 0.28391
+v 2.54763 1.32194 -0.324878
+v 2.54763 1.32194 0.324878
+v 2.55209 2.02065 -0.213293
+v 2.55209 2.02065 0.213293
+v 2.56973 2.17373 -0.140467
+v 2.56973 2.17373 0.140467
+v 2.57935 1.27054 -0.247526
+v 2.57935 1.27054 0.247526
+v 2.5819 1.56915 -0.3276
+v 2.5819 1.56915 0.3276
+v 2.5928 1.7982 -0.29574
+v 2.5928 1.7982 0.29574
+v 2.59893 1.9977 -0.243763
+v 2.59893 1.9977 0.243763
+v 2.5991 2.2998 0
+v 2.5991 2.2998 0
+v 2.60087 1.23565 -0.139234
+v 2.60087 1.23565 0.139234
+v 2.6088 1.2228 0
+v 2.6088 1.2228 0
+v 2.61241 2.29881 0.0706
+v 2.61241 2.29881 -0.0706
+v 2.61382 2.16331 -0.184363
+v 2.61382 2.16331 0.184363
+v 2.6227 1.5207 -0.28665
+v 2.6227 1.5207 0.28665
+v 2.63969 1.76002 -0.28391
+v 2.63969 1.76002 0.28391
+v 2.64852 2.29613 0.12551
+v 2.64852 2.29613 -0.12551
+v 2.6499 1.97273 0.25392
+v 2.6499 1.97273 -0.25392
+v 2.6563 1.4808 -0.2184
+v 2.6563 1.4808 0.2184
+v 2.66735 2.15066 -0.210701
+v 2.66735 2.15066 0.210701
+v 2.6791 1.45372 0.12285
+v 2.6791 1.45372 -0.12285
+v 2.68277 1.72493 0.248422
+v 2.68277 1.72493 -0.248422
+v 2.6875 1.44375 0
+v 2.6875 1.44375 0
+v 2.7 2.4 0
+v 2.7 2.4 0
+v 2.7 2.4 0
+v 2.70087 1.94775 -0.243763
+v 2.70087 1.94775 0.243763
+v 2.70174 2.29219 0.164732
+v 2.70174 2.29219 -0.164732
+v 2.7168 2.4 0.0675
+v 2.7168 2.4 -0.0675
+v 2.7168 2.4 -0.0675
+v 2.7168 2.4 0.0675
+v 2.71825 1.69603 0.189274
+v 2.71825 1.69603 -0.189274
+v 2.7256 2.1369 -0.21948
+v 2.7256 2.1369 0.21948
+v 2.7298 2.42025 0
+v 2.74233 1.67642 0.106466
+v 2.74233 1.67642 -0.106466
+v 2.74741 2.42041 -0.066744
+v 2.74741 2.42041 0.066744
+v 2.74771 1.9248 -0.213293
+v 2.74771 1.9248 0.213293
+v 2.7512 1.6692 0
+v 2.7512 1.6692 0
+v 2.7584 2.436 0
+v 2.7624 2.4 0.12
+v 2.7624 2.4 -0.12
+v 2.7624 2.4 -0.12
+v 2.7624 2.4 0.12
+v 2.76637 2.28739 0.188266
+v 2.76637 2.28739 -0.188266
+v 2.77637 2.4363 -0.064692
+v 2.77637 2.4363 0.064692
+v 2.78385 2.12314 -0.210701
+v 2.78385 2.12314 0.210701
+v 2.7846 2.44725 0
+v 2.7846 2.44725 0
+v 2.78628 1.9059 0.162509
+v 2.78628 1.9059 -0.162509
+v 2.7952 2.42083 -0.118656
+v 2.7952 2.42083 0.118656
+v 2.8 2.4 0
+v 2.80253 2.44768 -0.061668
+v 2.80253 2.44768 0.061668
+v 2.8072 2.454 0
+v 2.8112 2.4 -0.0405
+v 2.8112 2.4 0.0405
+v 2.81246 1.89308 0.091411
+v 2.81246 1.89308 -0.091411
+v 2.8221 1.88835 0
+v 2.8221 1.88835 0
+v 2.8242 2.42025 0
+v 2.8242 2.42025 0
+v 2.82475 2.45453 -0.057996
+v 2.82475 2.45453 0.057996
+v 2.825 2.45625 0
+v 2.825 2.45625 0
+v 2.82513 2.43712 -0.115008
+v 2.82513 2.43712 0.115008
+v 2.8296 2.4 0.1575
+v 2.8296 2.4 -0.1575
+v 2.8296 2.4 -0.1575
+v 2.8296 2.4 0.1575
+v 2.83667 2.42052 -0.041256
+v 2.83667 2.42052 0.041256
+v 2.8367 2.28218 0.19611
+v 2.8367 2.28218 -0.19611
+v 2.8368 2.454 0
+v 2.8368 2.454 0
+v 2.83738 2.11049 -0.184363
+v 2.83738 2.11049 0.184363
+v 2.8376 2.436 0
+v 2.8376 2.436 0
+v 2.8414 2.44725 0
+v 2.8414 2.44725 0
+v 2.8416 2.4 -0.072
+v 2.8416 2.4 0.072
+v 2.84189 2.45684 -0.054
+v 2.84189 2.45684 0.054
+v 2.85119 2.44885 -0.109632
+v 2.85119 2.44885 0.109632
+v 2.85133 2.43645 -0.043308
+v 2.85133 2.43645 0.043308
+v 2.85279 2.4546 -0.050004
+v 2.85279 2.4546 0.050004
+v 2.85632 2.44781 -0.046332
+v 2.85632 2.44781 0.046332
+v 2.86563 2.42145 -0.155736
+v 2.86563 2.42145 0.155736
+v 2.87052 2.42125 -0.073344
+v 2.87052 2.42125 0.073344
+v 2.87239 2.45597 -0.103104
+v 2.87239 2.45597 0.103104
+v 2.88147 2.10007 -0.140467
+v 2.88147 2.10007 0.140467
+v 2.8864 2.4 -0.0945
+v 2.8864 2.4 0.0945
+v 2.88773 2.45844 -0.096
+v 2.88773 2.45844 0.096
+v 2.8886 2.43769 -0.076992
+v 2.8886 2.43769 0.076992
+v 2.89621 2.45625 0.088896
+v 2.89621 2.45625 -0.088896
+v 2.89683 2.44934 -0.082368
+v 2.89683 2.44934 0.082368
+v 2.89699 2.43833 -0.150948
+v 2.89699 2.43833 0.150948
+v 2.90703 2.27696 0.188266
+v 2.90703 2.27696 -0.188266
+v 2.9112 2.4 -0.18
+v 2.9112 2.4 -0.18
+v 2.9112 2.4 0.18
+v 2.91138 2.093 -0.079013
+v 2.91138 2.093 0.079013
+v 2.92041 2.42233 -0.096264
+v 2.92041 2.42233 0.096264
+v 2.9224 2.0904 0
+v 2.9229 2.45057 -0.143892
+v 2.9229 2.45057 0.143892
+v 2.9408 2.4 -0.108
+v 2.9408 2.4 0.108
+v 2.94259 2.45808 -0.135324
+v 2.94259 2.45808 0.135324
+v 2.94353 2.4395 -0.101052
+v 2.94353 2.4395 0.101052
+v 2.95115 2.42221 -0.177984
+v 2.95115 2.42221 0.177984
+v 2.95527 2.46081 -0.126
+v 2.95527 2.46081 0.126
+v 2.95652 2.45159 -0.108108
+v 2.95652 2.45159 0.108108
+v 2.96018 2.45867 -0.116676
+v 2.96018 2.45867 0.116676
+v 2.97166 2.27216 0.164732
+v 2.97166 2.27216 -0.164732
+v 2.98099 2.42364 0.110016
+v 2.98099 2.42364 -0.110016
+v 2.98424 2.4398 -0.172512
+v 2.98424 2.4398 0.172512
+v 3 2.4 -0.1875
+v 3 2.4 -0.1875
+v 3 2.4 -0.1125
+v 3 2.4 0.1125
+v 3 2.4 0.1875
+v 3.00998 2.45266 -0.164448
+v 3.00998 2.45266 0.164448
+v 3.01022 2.4417 -0.115488
+v 3.01022 2.4417 0.115488
+v 3.02488 2.26822 0.12551
+v 3.02488 2.26822 -0.12551
+v 3.02783 2.46065 -0.154656
+v 3.02783 2.46065 0.154656
+v 3.02901 2.45432 -0.123552
+v 3.02901 2.45432 0.123552
+v 3.0373 2.46367 -0.144
+v 3.0373 2.46367 0.144
+v 3.03786 2.4616 0.133344
+v 3.03786 2.4616 -0.133344
+v 3.04421 2.42303 -0.1854
+v 3.04421 2.42303 0.1854
+v 3.04691 2.42506 0.1146
+v 3.04691 2.42506 -0.1146
+v 3.0592 2.4 -0.108
+v 3.0592 2.4 0.108
+v 3.06099 2.26554 0.0706
+v 3.06099 2.26554 -0.0706
+v 3.0743 2.26455 0
+v 3.0743 2.26455 0
+v 3.0792 2.4414 -0.1797
+v 3.0792 2.4414 0.1797
+v 3.0828 2.4441 -0.1203
+v 3.0828 2.4441 0.1203
+v 3.0888 2.4 -0.18
+v 3.0888 2.4 -0.18
+v 3.0888 2.4 0.18
+v 3.10474 2.45493 -0.1713
+v 3.10474 2.45493 0.1713
+v 3.10789 2.45729 -0.1287
+v 3.10789 2.45729 0.1287
+v 3.11284 2.42648 0.110016
+v 3.11284 2.42648 -0.110016
+v 3.1136 2.4 -0.0945
+v 3.1136 2.4 0.0945
+v 3.1206 2.46345 0.1611
+v 3.1206 2.46345 -0.1611
+v 3.1224 2.4648 0.1389
+v 3.1224 2.4648 -0.1389
+v 3.12656 2.4668 -0.15
+v 3.12656 2.4668 0.15
+v 3.13728 2.42386 -0.177984
+v 3.13728 2.42386 0.177984
+v 3.15538 2.4465 -0.115488
+v 3.15538 2.4465 0.115488
+v 3.1584 2.4 -0.072
+v 3.1584 2.4 0.072
+v 3.1704 2.4 -0.1575
+v 3.1704 2.4 0.1575
+v 3.1704 2.4 -0.1575
+v 3.17341 2.42779 -0.096264
+v 3.17341 2.42779 0.096264
+v 3.17416 2.443 -0.172512
+v 3.17416 2.443 0.172512
+v 3.18677 2.46026 -0.123552
+v 3.18677 2.46026 0.123552
+v 3.1888 2.4 -0.0405
+v 3.1888 2.4 0.0405
+v 3.1995 2.4572 -0.164448
+v 3.1995 2.4572 0.164448
+v 3.2 2.4 0
+v 3.20694 2.468 0.133344
+v 3.20694 2.468 -0.133344
+v 3.21337 2.46625 -0.154656
+v 3.21337 2.46625 0.154656
+v 3.21583 2.46992 -0.144
+v 3.21583 2.46992 0.144
+v 3.22207 2.4487 -0.101052
+v 3.22207 2.4487 0.101052
+v 3.2228 2.42462 -0.155736
+v 3.2228 2.42462 0.155736
+v 3.2233 2.42887 -0.073344
+v 3.2233 2.42887 0.073344
+v 3.2376 2.4 -0.12
+v 3.2376 2.4 0.12
+v 3.2376 2.4 -0.12
+v 3.25715 2.4296 -0.041256
+v 3.25715 2.4296 0.041256
+v 3.25925 2.46299 -0.108108
+v 3.25925 2.46299 0.108108
+v 3.26141 2.44447 -0.150948
+v 3.26141 2.44447 0.150948
+v 3.26963 2.42987 0
+v 3.26963 2.42987 0
+v 3.277 2.45052 -0.076992
+v 3.277 2.45052 0.076992
+v 3.2832 2.4 -0.0675
+v 3.2832 2.4 0.0675
+v 3.2832 2.4 -0.0675
+v 3.28462 2.47093 -0.116676
+v 3.28462 2.47093 0.116676
+v 3.28658 2.45929 -0.143892
+v 3.28658 2.45929 0.143892
+v 3.29323 2.42524 -0.118656
+v 3.29323 2.42524 0.118656
+v 3.29785 2.47279 -0.126
+v 3.29785 2.47279 0.126
+v 3.29861 2.46882 -0.135324
+v 3.29861 2.46882 0.135324
+v 3.3 2.4 0
+v 3.3 2.4 0
+v 3.31427 2.45175 -0.043308
+v 3.31427 2.45175 0.043308
+v 3.31895 2.46524 -0.082368
+v 3.31895 2.46524 0.082368
+v 3.328 2.4522 0
+v 3.328 2.4522 0
+v 3.33327 2.44568 -0.115008
+v 3.33327 2.44568 0.115008
+v 3.34102 2.42566 -0.066744
+v 3.34102 2.42566 0.066744
+v 3.34859 2.47335 0.088896
+v 3.34859 2.47335 -0.088896
+v 3.35829 2.46101 -0.109632
+v 3.35829 2.46101 0.109632
+v 3.35862 2.42582 0
+v 3.35945 2.46677 -0.046332
+v 3.35945 2.46677 0.046332
+v 3.3654 2.47515 -0.096
+v 3.3654 2.47515 0.096
+v 3.36881 2.47093 -0.103104
+v 3.36881 2.47093 0.103104
+v 3.37438 2.46733 0
+v 3.37438 2.46733 0
+v 3.38204 2.4465 -0.064692
+v 3.38204 2.4465 0.064692
+v 3.39201 2.47499 -0.050004
+v 3.39201 2.47499 0.050004
+v 3.4 2.4468 0
+v 3.40695 2.46218 -0.061668
+v 3.40695 2.46218 0.061668
+v 3.408 2.4756 0
+v 3.408 2.4756 0
+v 3.41124 2.47675 -0.054
+v 3.41124 2.47675 0.054
+v 3.41645 2.47237 -0.057996
+v 3.41645 2.47237 0.057996
+v 3.42488 2.46261 0
+v 3.42813 2.47734 0
+v 3.42813 2.47734 0
+v 3.434 2.4729 0
+f 2909 2921 2939
+f 2939 2931 2909
+f 2869 2877 2921
+f 2921 2909 2869
+f 2819 2827 2877
+f 2877 2869 2819
+f 2737 2747 2827
+f 2827 2819 2737
+f 2669 2673 2747
+f 2747 2737 2669
+f 2567 2575 2673
+f 2673 2669 2567
+f 2476 2480 2575
+f 2575 2567 2476
+f 2358 2362 2480
+f 2480 2476 2358
+f 2158 2162 2362
+f 2362 2358 2158
+f 1715 1812 2162
+f 2162 2158 1715
+f 2901 2909 2931
+f 2931 2917 2901
+f 2863 2869 2909
+f 2909 2901 2863
+f 2813 2819 2869
+f 2869 2863 2813
+f 2729 2737 2819
+f 2819 2813 2729
+f 2663 2669 2737
+f 2737 2729 2663
+f 2561 2567 2669
+f 2669 2663 2561
+f 2468 2476 2567
+f 2567 2561 2468
+f 2350 2358 2476
+f 2476 2468 2350
+f 2152 2158 2358
+f 2358 2350 2152
+f 1717 1715 2158
+f 2158 2152 1717
+f 2903 2901 2917
+f 2917 2923 2903
+f 2865 2863 2901
+f 2901 2903 2865
+f 2815 2813 2863
+f 2863 2865 2815
+f 2733 2729 2813
+f 2813 2815 2733
+f 2665 2663 2729
+f 2729 2733 2665
+f 2564 2561 2663
+f 2663 2665 2564
+f 2473 2468 2561
+f 2561 2564 2473
+f 2354 2350 2468
+f 2468 2473 2354
+f 2155 2152 2350
+f 2350 2354 2155
+f 1927 1717 2152
+f 2152 2155 1927
+f 2911 2903 2923
+f 2923 2935 2911
+f 2875 2865 2903
+f 2903 2911 2875
+f 2823 2815 2865
+f 2865 2875 2823
+f 2741 2733 2815
+f 2815 2823 2741
+f 2671 2665 2733
+f 2733 2741 2671
+f 2571 2564 2665
+f 2665 2671 2571
+f 2478 2473 2564
+f 2564 2571 2478
+f 2360 2354 2473
+f 2473 2478 2360
+f 2160 2155 2354
+f 2354 2360 2160
+f 1718 1927 2155
+f 2155 2160 1718
+f 2929 2911 2935
+f 2935 2947 2929
+f 2881 2875 2911
+f 2911 2929 2881
+f 2829 2823 2875
+f 2875 2881 2829
+f 2751 2741 2823
+f 2823 2829 2751
+f 2677 2671 2741
+f 2741 2751 2677
+f 2577 2571 2671
+f 2671 2677 2577
+f 2482 2478 2571
+f 2571 2577 2482
+f 2364 2360 2478
+f 2478 2482 2364
+f 2164 2160 2360
+f 2360 2364 2164
+f 1842 1718 2160
+f 2160 2164 1842
+f 2945 2929 2947
+f 2947 2959 2945
+f 2897 2881 2929
+f 2929 2945 2897
+f 2835 2829 2881
+f 2881 2897 2835
+f 2761 2751 2829
+f 2829 2835 2761
+f 2679 2677 2751
+f 2751 2761 2679
+f 2579 2577 2677
+f 2677 2679 2579
+f 2486 2482 2577
+f 2577 2579 2486
+f 2368 2364 2482
+f 2482 2486 2368
+f 2172 2164 2364
+f 2364 2368 2172
+f 1725 1842 2164
+f 2164 2172 1725
+f 2965 2945 2959
+f 2959 2981 2965
+f 2907 2897 2945
+f 2945 2965 2907
+f 2845 2835 2897
+f 2897 2907 2845
+f 2769 2761 2835
+f 2835 2845 2769
+f 2685 2679 2761
+f 2761 2769 2685
+f 2587 2579 2679
+f 2679 2685 2587
+f 2491 2486 2579
+f 2579 2587 2491
+f 2370 2368 2486
+f 2486 2491 2370
+f 2174 2172 2368
+f 2368 2370 2174
+f 1834 1725 2172
+f 2172 2174 1834
+f 2982 2965 2981
+f 2981 2988 2982
+f 2933 2907 2965
+f 2965 2982 2933
+f 2855 2845 2907
+f 2907 2933 2855
+f 2779 2769 2845
+f 2845 2855 2779
+f 2691 2685 2769
+f 2769 2779 2691
+f 2595 2587 2685
+f 2685 2691 2595
+f 2500 2491 2587
+f 2587 2595 2500
+f 2374 2370 2491
+f 2491 2500 2374
+f 2178 2174 2370
+f 2370 2374 2178
+f 1716 1834 2174
+f 2174 2178 1716
+f 2990 2982 2988
+f 2988 3002 2990
+f 2949 2933 2982
+f 2982 2990 2949
+f 2871 2855 2933
+f 2933 2949 2871
+f 2791 2779 2855
+f 2855 2871 2791
+f 2699 2691 2779
+f 2779 2791 2699
+f 2601 2595 2691
+f 2691 2699 2601
+f 2506 2500 2595
+f 2595 2601 2506
+f 2378 2374 2500
+f 2500 2506 2378
+f 2180 2178 2374
+f 2374 2378 2180
+f 1714 1716 2178
+f 2178 2180 1714
+f 3008 2990 3002
+f 3002 3024 3008
+f 2973 2949 2990
+f 2990 3008 2973
+f 2889 2871 2949
+f 2949 2973 2889
+f 2805 2791 2871
+f 2871 2889 2805
+f 2711 2699 2791
+f 2791 2805 2711
+f 2611 2601 2699
+f 2699 2711 2611
+f 2521 2506 2601
+f 2601 2611 2521
+f 2387 2378 2506
+f 2506 2521 2387
+f 2191 2180 2378
+f 2378 2387 2191
+f 1810 1714 2180
+f 2180 2191 1810
+f 1464 1460 1813
+f 1813 1821 1464
+f 1264 1260 1460
+f 1460 1464 1264
+f 1146 1142 1260
+f 1260 1264 1146
+f 1055 1047 1142
+f 1142 1146 1055
+f 953 949 1047
+f 1047 1055 953
+f 885 875 949
+f 949 953 885
+f 803 795 875
+f 875 885 803
+f 753 745 795
+f 795 803 753
+f 713 701 745
+f 745 753 713
+f 691 683 701
+f 701 713 691
+f 1470 1464 1821
+f 1821 1829 1470
+f 1272 1264 1464
+f 1464 1470 1272
+f 1154 1146 1264
+f 1264 1272 1154
+f 1061 1055 1146
+f 1146 1154 1061
+f 959 953 1055
+f 1055 1061 959
+f 893 885 953
+f 953 959 893
+f 809 803 885
+f 885 893 809
+f 759 753 803
+f 803 809 759
+f 721 713 753
+f 753 759 721
+f 705 691 713
+f 713 721 705
+f 1469 1470 1829
+f 1829 1835 1469
+f 1268 1272 1470
+f 1470 1469 1268
+f 1151 1154 1272
+f 1272 1268 1151
+f 1060 1061 1154
+f 1154 1151 1060
+f 957 959 1061
+f 1061 1060 957
+f 889 893 959
+f 959 957 889
+f 807 809 893
+f 893 889 807
+f 757 759 809
+f 809 807 757
+f 719 721 759
+f 759 757 719
+f 699 705 721
+f 721 719 699
+f 1462 1469 1835
+f 1835 1839 1462
+f 1262 1268 1469
+f 1469 1462 1262
+f 1144 1151 1268
+f 1268 1262 1144
+f 1051 1060 1151
+f 1151 1144 1051
+f 951 957 1060
+f 1060 1051 951
+f 881 889 957
+f 957 951 881
+f 799 807 889
+f 889 881 799
+f 747 757 807
+f 807 799 747
+f 711 719 757
+f 757 747 711
+f 687 699 719
+f 719 711 687
+f 1458 1462 1839
+f 1839 1843 1458
+f 1258 1262 1462
+f 1462 1458 1258
+f 1140 1144 1262
+f 1262 1258 1140
+f 1045 1051 1144
+f 1144 1140 1045
+f 945 951 1051
+f 1051 1045 945
+f 871 881 951
+f 951 945 871
+f 793 799 881
+f 881 871 793
+f 741 747 799
+f 799 793 741
+f 693 711 747
+f 747 741 693
+f 675 687 711
+f 711 693 675
+f 1450 1458 1843
+f 1843 1838 1450
+f 1254 1258 1458
+f 1458 1450 1254
+f 1136 1140 1258
+f 1258 1254 1136
+f 1043 1045 1140
+f 1140 1136 1043
+f 943 945 1045
+f 1045 1043 943
+f 861 871 945
+f 945 943 861
+f 787 793 871
+f 871 861 787
+f 725 741 793
+f 793 787 725
+f 677 693 741
+f 741 725 677
+f 663 675 693
+f 693 677 663
+f 1448 1450 1838
+f 1838 1834 1448
+f 1252 1254 1450
+f 1450 1448 1252
+f 1133 1136 1254
+f 1254 1252 1133
+f 1035 1043 1136
+f 1136 1133 1035
+f 937 943 1043
+f 1043 1035 937
+f 853 861 943
+f 943 937 853
+f 777 787 861
+f 861 853 777
+f 715 725 787
+f 787 777 715
+f 657 677 725
+f 725 715 657
+f 642 663 677
+f 677 657 642
+f 1444 1448 1834
+f 1834 1828 1444
+f 1248 1252 1448
+f 1448 1444 1248
+f 1122 1133 1252
+f 1252 1248 1122
+f 1027 1035 1133
+f 1133 1122 1027
+f 931 937 1035
+f 1035 1027 931
+f 843 853 937
+f 937 931 843
+f 767 777 853
+f 853 843 767
+f 689 715 777
+f 777 767 689
+f 640 657 715
+f 715 689 640
+f 634 642 657
+f 657 640 634
+f 1442 1444 1828
+f 1828 1820 1442
+f 1244 1248 1444
+f 1444 1442 1244
+f 1116 1122 1248
+f 1248 1244 1116
+f 1021 1027 1122
+f 1122 1116 1021
+f 923 931 1027
+f 1027 1021 923
+f 831 843 931
+f 931 923 831
+f 751 767 843
+f 843 831 751
+f 673 689 767
+f 767 751 673
+f 632 640 689
+f 689 673 632
+f 620 634 640
+f 640 632 620
+f 1429 1442 1820
+f 1820 1811 1429
+f 1233 1244 1442
+f 1442 1429 1233
+f 1106 1116 1244
+f 1244 1233 1106
+f 1011 1021 1116
+f 1116 1106 1011
+f 911 923 1021
+f 1021 1011 911
+f 817 831 923
+f 923 911 817
+f 733 751 831
+f 831 817 733
+f 649 673 751
+f 751 733 649
+f 614 632 673
+f 673 649 614
+f 597 620 632
+f 632 614 597
+f 714 702 684
+f 684 692 714
+f 754 746 702
+f 702 714 754
+f 804 796 746
+f 746 754 804
+f 886 876 796
+f 796 804 886
+f 954 950 876
+f 876 886 954
+f 1056 1048 950
+f 950 954 1056
+f 1147 1143 1048
+f 1048 1056 1147
+f 1265 1261 1143
+f 1143 1147 1265
+f 1465 1461 1261
+f 1261 1265 1465
+f 1915 1817 1461
+f 1461 1465 1915
+f 722 714 692
+f 692 706 722
+f 760 754 714
+f 714 722 760
+f 810 804 754
+f 754 760 810
+f 894 886 804
+f 804 810 894
+f 960 954 886
+f 886 894 960
+f 1062 1056 954
+f 954 960 1062
+f 1155 1147 1056
+f 1056 1062 1155
+f 1273 1265 1147
+f 1147 1155 1273
+f 1471 1465 1265
+f 1265 1273 1471
+f 1917 1915 1465
+f 1465 1471 1917
+f 720 722 706
+f 706 700 720
+f 758 760 722
+f 722 720 758
+f 808 810 760
+f 760 758 808
+f 890 894 810
+f 810 808 890
+f 958 960 894
+f 894 890 958
+f 1059 1062 960
+f 960 958 1059
+f 1150 1155 1062
+f 1062 1059 1150
+f 1269 1273 1155
+f 1155 1150 1269
+f 1468 1471 1273
+f 1273 1269 1468
+f 1697 1917 1471
+f 1471 1468 1697
+f 712 720 700
+f 700 688 712
+f 748 758 720
+f 720 712 748
+f 800 808 758
+f 758 748 800
+f 882 890 808
+f 808 800 882
+f 952 958 890
+f 890 882 952
+f 1052 1059 958
+f 958 952 1052
+f 1145 1150 1059
+f 1059 1052 1145
+f 1263 1269 1150
+f 1150 1145 1263
+f 1463 1468 1269
+f 1269 1263 1463
+f 1919 1697 1468
+f 1468 1463 1919
+f 694 712 688
+f 688 676 694
+f 742 748 712
+f 712 694 742
+f 794 800 748
+f 748 742 794
+f 872 882 800
+f 800 794 872
+f 946 952 882
+f 882 872 946
+f 1046 1052 952
+f 952 946 1046
+f 1141 1145 1052
+f 1052 1046 1141
+f 1259 1263 1145
+f 1145 1141 1259
+f 1459 1463 1263
+f 1263 1259 1459
+f 1845 1919 1463
+f 1463 1459 1845
+f 678 694 676
+f 676 664 678
+f 726 742 694
+f 694 678 726
+f 788 794 742
+f 742 726 788
+f 862 872 794
+f 794 788 862
+f 944 946 872
+f 872 862 944
+f 1044 1046 946
+f 946 944 1044
+f 1137 1141 1046
+f 1046 1044 1137
+f 1255 1259 1141
+f 1141 1137 1255
+f 1451 1459 1259
+f 1259 1255 1451
+f 1898 1845 1459
+f 1459 1451 1898
+f 658 678 664
+f 664 642 658
+f 716 726 678
+f 678 658 716
+f 778 788 726
+f 726 716 778
+f 854 862 788
+f 788 778 854
+f 938 944 862
+f 862 854 938
+f 1036 1044 944
+f 944 938 1036
+f 1132 1137 1044
+f 1044 1036 1132
+f 1253 1255 1137
+f 1137 1132 1253
+f 1449 1451 1255
+f 1255 1253 1449
+f 1837 1898 1451
+f 1451 1449 1837
+f 641 658 642
+f 642 635 641
+f 690 716 658
+f 658 641 690
+f 768 778 716
+f 716 690 768
+f 844 854 778
+f 778 768 844
+f 932 938 854
+f 854 844 932
+f 1028 1036 938
+f 938 932 1028
+f 1123 1132 1036
+f 1036 1028 1123
+f 1249 1253 1132
+f 1132 1123 1249
+f 1445 1449 1253
+f 1253 1249 1445
+f 1918 1837 1449
+f 1449 1445 1918
+f 633 641 635
+f 635 621 633
+f 674 690 641
+f 641 633 674
+f 752 768 690
+f 690 674 752
+f 832 844 768
+f 768 752 832
+f 924 932 844
+f 844 832 924
+f 1022 1028 932
+f 932 924 1022
+f 1117 1123 1028
+f 1028 1022 1117
+f 1245 1249 1123
+f 1123 1117 1245
+f 1443 1445 1249
+f 1249 1245 1443
+f 1916 1918 1445
+f 1445 1443 1916
+f 616 633 621
+f 621 600 616
+f 654 674 633
+f 633 616 654
+f 737 752 674
+f 674 654 737
+f 822 832 752
+f 752 737 822
+f 914 924 832
+f 832 822 914
+f 1014 1022 924
+f 924 914 1014
+f 1104 1117 1022
+f 1022 1014 1104
+f 1237 1245 1117
+f 1117 1104 1237
+f 1433 1443 1245
+f 1245 1237 1433
+f 1819 1916 1443
+f 1443 1433 1819
+f 2159 2163 1816
+f 1816 1822 2159
+f 2359 2363 2163
+f 2163 2159 2359
+f 2477 2481 2363
+f 2363 2359 2477
+f 2568 2576 2481
+f 2481 2477 2568
+f 2670 2674 2576
+f 2576 2568 2670
+f 2738 2748 2674
+f 2674 2670 2738
+f 2820 2828 2748
+f 2748 2738 2820
+f 2870 2878 2828
+f 2828 2820 2870
+f 2910 2922 2878
+f 2878 2870 2910
+f 2932 2940 2922
+f 2922 2910 2932
+f 2153 2159 1822
+f 1822 1830 2153
+f 2351 2359 2159
+f 2159 2153 2351
+f 2469 2477 2359
+f 2359 2351 2469
+f 2562 2568 2477
+f 2477 2469 2562
+f 2664 2670 2568
+f 2568 2562 2664
+f 2730 2738 2670
+f 2670 2664 2730
+f 2814 2820 2738
+f 2738 2730 2814
+f 2864 2870 2820
+f 2820 2814 2864
+f 2902 2910 2870
+f 2870 2864 2902
+f 2918 2932 2910
+f 2910 2902 2918
+f 2154 2153 1830
+f 1830 1836 2154
+f 2355 2351 2153
+f 2153 2154 2355
+f 2472 2469 2351
+f 2351 2355 2472
+f 2563 2562 2469
+f 2469 2472 2563
+f 2666 2664 2562
+f 2562 2563 2666
+f 2734 2730 2664
+f 2664 2666 2734
+f 2816 2814 2730
+f 2730 2734 2816
+f 2866 2864 2814
+f 2814 2816 2866
+f 2904 2902 2864
+f 2864 2866 2904
+f 2924 2918 2902
+f 2902 2904 2924
+f 2161 2154 1836
+f 1836 1840 2161
+f 2361 2355 2154
+f 2154 2161 2361
+f 2479 2472 2355
+f 2355 2361 2479
+f 2572 2563 2472
+f 2472 2479 2572
+f 2672 2666 2563
+f 2563 2572 2672
+f 2742 2734 2666
+f 2666 2672 2742
+f 2824 2816 2734
+f 2734 2742 2824
+f 2876 2866 2816
+f 2816 2824 2876
+f 2912 2904 2866
+f 2866 2876 2912
+f 2936 2924 2904
+f 2904 2912 2936
+f 2165 2161 1840
+f 1840 1844 2165
+f 2365 2361 2161
+f 2161 2165 2365
+f 2483 2479 2361
+f 2361 2365 2483
+f 2578 2572 2479
+f 2479 2483 2578
+f 2678 2672 2572
+f 2572 2578 2678
+f 2752 2742 2672
+f 2672 2678 2752
+f 2830 2824 2742
+f 2742 2752 2830
+f 2882 2876 2824
+f 2824 2830 2882
+f 2930 2912 2876
+f 2876 2882 2930
+f 2948 2936 2912
+f 2912 2930 2948
+f 2173 2165 1844
+f 1844 1841 2173
+f 2369 2365 2165
+f 2165 2173 2369
+f 2487 2483 2365
+f 2365 2369 2487
+f 2580 2578 2483
+f 2483 2487 2580
+f 2680 2678 2578
+f 2578 2580 2680
+f 2762 2752 2678
+f 2678 2680 2762
+f 2836 2830 2752
+f 2752 2762 2836
+f 2898 2882 2830
+f 2830 2836 2898
+f 2946 2930 2882
+f 2882 2898 2946
+f 2960 2948 2930
+f 2930 2946 2960
+f 2175 2173 1841
+f 1841 1837 2175
+f 2371 2369 2173
+f 2173 2175 2371
+f 2490 2487 2369
+f 2369 2371 2490
+f 2588 2580 2487
+f 2487 2490 2588
+f 2686 2680 2580
+f 2580 2588 2686
+f 2770 2762 2680
+f 2680 2686 2770
+f 2846 2836 2762
+f 2762 2770 2846
+f 2908 2898 2836
+f 2836 2846 2908
+f 2966 2946 2898
+f 2898 2908 2966
+f 2981 2960 2946
+f 2946 2966 2981
+f 2179 2175 1837
+f 1837 1831 2179
+f 2375 2371 2175
+f 2175 2179 2375
+f 2501 2490 2371
+f 2371 2375 2501
+f 2596 2588 2490
+f 2490 2501 2596
+f 2692 2686 2588
+f 2588 2596 2692
+f 2780 2770 2686
+f 2686 2692 2780
+f 2856 2846 2770
+f 2770 2780 2856
+f 2934 2908 2846
+f 2846 2856 2934
+f 2983 2966 2908
+f 2908 2934 2983
+f 2989 2981 2966
+f 2966 2983 2989
+f 2181 2179 1831
+f 1831 1823 2181
+f 2379 2375 2179
+f 2179 2181 2379
+f 2507 2501 2375
+f 2375 2379 2507
+f 2602 2596 2501
+f 2501 2507 2602
+f 2700 2692 2596
+f 2596 2602 2700
+f 2792 2780 2692
+f 2692 2700 2792
+f 2872 2856 2780
+f 2780 2792 2872
+f 2950 2934 2856
+f 2856 2872 2950
+f 2991 2983 2934
+f 2934 2950 2991
+f 3003 2989 2983
+f 2983 2991 3003
+f 2194 2181 1823
+f 1823 1818 2194
+f 2391 2379 2181
+f 2181 2194 2391
+f 2518 2507 2379
+f 2379 2391 2518
+f 2614 2602 2507
+f 2507 2518 2614
+f 2712 2700 2602
+f 2602 2614 2712
+f 2806 2792 2700
+f 2700 2712 2806
+f 2890 2872 2792
+f 2792 2806 2890
+f 2974 2950 2872
+f 2872 2890 2974
+f 3009 2991 2950
+f 2950 2974 3009
+f 3025 3003 2991
+f 2991 3009 3025
+f 3040 3008 3024
+f 3024 3048 3040
+f 3018 2973 3008
+f 3008 3040 3018
+f 2943 2889 2973
+f 2973 3018 2943
+f 2841 2805 2889
+f 2889 2943 2841
+f 2731 2711 2805
+f 2805 2841 2731
+f 2645 2611 2711
+f 2711 2731 2645
+f 2529 2521 2611
+f 2611 2645 2529
+f 2402 2387 2521
+f 2521 2529 2402
+f 2208 2191 2387
+f 2387 2402 2208
+f 1806 1810 2191
+f 2191 2208 1806
+f 3072 3040 3048
+f 3048 3078 3072
+f 3044 3018 3040
+f 3040 3072 3044
+f 2994 2943 3018
+f 3018 3044 2994
+f 2883 2841 2943
+f 2943 2994 2883
+f 2773 2731 2841
+f 2841 2883 2773
+f 2659 2645 2731
+f 2731 2773 2659
+f 2539 2529 2645
+f 2645 2659 2539
+f 2410 2402 2529
+f 2529 2539 2410
+f 2222 2208 2402
+f 2402 2410 2222
+f 1694 1806 2208
+f 2208 2222 1694
+f 3092 3072 3078
+f 3078 3116 3092
+f 3074 3044 3072
+f 3072 3092 3074
+f 3030 2994 3044
+f 3044 3074 3030
+f 2937 2883 2994
+f 2994 3030 2937
+f 2810 2773 2883
+f 2883 2937 2810
+f 2683 2659 2773
+f 2773 2810 2683
+f 2554 2539 2659
+f 2659 2683 2554
+f 2420 2410 2539
+f 2539 2554 2420
+f 2238 2222 2410
+f 2410 2420 2238
+f 1930 1694 2222
+f 2222 2238 1930
+f 3132 3092 3116
+f 3116 3142 3132
+f 3090 3074 3092
+f 3092 3132 3090
+f 3054 3030 3074
+f 3074 3090 3054
+f 2984 2937 3030
+f 3030 3054 2984
+f 2837 2810 2937
+f 2937 2984 2837
+f 2705 2683 2810
+f 2810 2837 2705
+f 2574 2554 2683
+f 2683 2705 2574
+f 2430 2420 2554
+f 2554 2574 2430
+f 2247 2238 2420
+f 2420 2430 2247
+f 1913 1930 2238
+f 2238 2247 1913
+f 3150 3132 3142
+f 3142 3156 3150
+f 3128 3090 3132
+f 3132 3150 3128
+f 3076 3054 3090
+f 3090 3128 3076
+f 3014 2984 3054
+f 3054 3076 3014
+f 2861 2837 2984
+f 2984 3014 2861
+f 2723 2705 2837
+f 2837 2861 2723
+f 2585 2574 2705
+f 2705 2723 2585
+f 2438 2430 2574
+f 2574 2585 2438
+f 2253 2247 2430
+f 2430 2438 2253
+f 1711 1913 2247
+f 2247 2253 1711
+f 3162 3150 3156
+f 3156 3172 3162
+f 3148 3128 3150
+f 3150 3162 3148
+f 3088 3076 3128
+f 3128 3148 3088
+f 3036 3014 3076
+f 3076 3088 3036
+f 2893 2861 3014
+f 3014 3036 2893
+f 2743 2723 2861
+f 2861 2893 2743
+f 2599 2585 2723
+f 2723 2743 2599
+f 2450 2438 2585
+f 2585 2599 2450
+f 2267 2253 2438
+f 2438 2450 2267
+f 1794 1711 2253
+f 2253 2267 1794
+f 3178 3162 3172
+f 3172 3184 3178
+f 3154 3148 3162
+f 3162 3178 3154
+f 3118 3088 3148
+f 3148 3154 3118
+f 3046 3036 3088
+f 3088 3118 3046
+f 2915 2893 3036
+f 3036 3046 2915
+f 2763 2743 2893
+f 2893 2915 2763
+f 2615 2599 2743
+f 2743 2763 2615
+f 2452 2450 2599
+f 2599 2615 2452
+f 2277 2267 2450
+f 2450 2452 2277
+f 1710 1794 2267
+f 2267 2277 1710
+f 3188 3178 3184
+f 3184 3200 3188
+f 3164 3154 3178
+f 3178 3188 3164
+f 3130 3118 3154
+f 3154 3164 3130
+f 3058 3046 3118
+f 3118 3130 3058
+f 2941 2915 3046
+f 3046 3058 2941
+f 2775 2763 2915
+f 2915 2941 2775
+f 2627 2615 2763
+f 2763 2775 2627
+f 2458 2452 2615
+f 2615 2627 2458
+f 2287 2277 2452
+f 2452 2458 2287
+f 1910 1710 2277
+f 2277 2287 1910
+f 3198 3188 3200
+f 3200 3209 3198
+f 3170 3164 3188
+f 3188 3198 3170
+f 3136 3130 3164
+f 3164 3170 3136
+f 3064 3058 3130
+f 3130 3136 3064
+f 2955 2941 3058
+f 3058 3064 2955
+f 2781 2775 2941
+f 2941 2955 2781
+f 2636 2627 2775
+f 2775 2781 2636
+f 2462 2458 2627
+f 2627 2636 2462
+f 2295 2287 2458
+f 2458 2462 2295
+f 1909 1910 2287
+f 2287 2295 1909
+f 3202 3198 3209
+f 3209 3213 3202
+f 3174 3170 3198
+f 3198 3202 3174
+f 3138 3136 3170
+f 3170 3174 3138
+f 3066 3064 3136
+f 3136 3138 3066
+f 2961 2955 3064
+f 3064 3066 2961
+f 2783 2781 2955
+f 2955 2961 2783
+f 2642 2636 2781
+f 2781 2783 2642
+f 2464 2462 2636
+f 2636 2642 2464
+f 2297 2295 2462
+f 2462 2464 2297
+f 1784 1909 2295
+f 2295 2297 1784
+f 1414 1429 1811
+f 1811 1807 1414
+f 1220 1233 1429
+f 1429 1414 1220
+f 1093 1106 1233
+f 1233 1220 1093
+f 977 1011 1106
+f 1106 1093 977
+f 891 911 1011
+f 1011 977 891
+f 781 817 911
+f 911 891 781
+f 679 733 817
+f 817 781 679
+f 604 649 733
+f 733 679 604
+f 571 614 649
+f 649 604 571
+f 561 597 614
+f 614 571 561
+f 1400 1414 1807
+f 1807 1804 1400
+f 1212 1220 1414
+f 1414 1400 1212
+f 1083 1093 1220
+f 1220 1212 1083
+f 963 977 1093
+f 1093 1083 963
+f 849 891 977
+f 977 963 849
+f 739 781 891
+f 891 849 739
+f 628 679 781
+f 781 739 628
+f 565 604 679
+f 679 628 565
+f 530 571 604
+f 604 565 530
+f 524 561 571
+f 571 530 524
+f 1386 1400 1804
+f 1804 1802 1386
+f 1202 1212 1400
+f 1400 1386 1202
+f 1070 1083 1212
+f 1212 1202 1070
+f 939 963 1083
+f 1083 1070 939
+f 814 849 963
+f 963 939 814
+f 685 739 849
+f 849 814 685
+f 585 628 739
+f 739 685 585
+f 528 565 628
+f 628 585 528
+f 510 530 565
+f 565 528 510
+f 508 524 530
+f 530 510 508
+f 1375 1386 1802
+f 1802 1800 1375
+f 1192 1202 1386
+f 1386 1375 1192
+f 1050 1070 1202
+f 1202 1192 1050
+f 917 939 1070
+f 1070 1050 917
+f 785 814 939
+f 939 917 785
+f 638 685 814
+f 814 785 638
+f 553 585 685
+f 685 638 553
+f 512 528 585
+f 585 553 512
+f 492 510 528
+f 528 512 492
+f 482 508 510
+f 510 492 482
+f 1369 1375 1800
+f 1800 1798 1369
+f 1184 1192 1375
+f 1375 1369 1184
+f 1037 1050 1192
+f 1192 1184 1037
+f 899 917 1050
+f 1050 1037 899
+f 761 785 917
+f 917 899 761
+f 608 638 785
+f 785 761 608
+f 526 553 638
+f 638 608 526
+f 496 512 553
+f 553 526 496
+f 454 492 512
+f 512 496 454
+f 448 482 492
+f 492 454 448
+f 1355 1369 1798
+f 1798 1795 1355
+f 1172 1184 1369
+f 1369 1355 1172
+f 1023 1037 1184
+f 1184 1172 1023
+f 879 899 1037
+f 1037 1023 879
+f 729 761 899
+f 899 879 729
+f 579 608 761
+f 761 729 579
+f 514 526 608
+f 608 579 514
+f 457 496 526
+f 526 514 457
+f 442 454 496
+f 496 457 442
+f 432 448 454
+f 454 442 432
+f 1345 1355 1795
+f 1795 1792 1345
+f 1170 1172 1355
+f 1355 1345 1170
+f 1007 1023 1172
+f 1172 1170 1007
+f 859 879 1023
+f 1023 1007 859
+f 707 729 879
+f 879 859 707
+f 563 579 729
+f 729 707 563
+f 506 514 579
+f 579 563 506
+f 450 457 514
+f 514 506 450
+f 420 442 457
+f 457 450 420
+f 412 432 442
+f 442 420 412
+f 1335 1345 1792
+f 1792 1790 1335
+f 1164 1170 1345
+f 1345 1335 1164
+f 995 1007 1170
+f 1170 1164 995
+f 847 859 1007
+f 1007 995 847
+f 681 707 859
+f 859 847 681
+f 547 563 707
+f 707 681 547
+f 494 506 563
+f 563 547 494
+f 440 450 506
+f 506 494 440
+f 410 420 450
+f 450 440 410
+f 398 412 420
+f 420 410 398
+f 1327 1335 1790
+f 1790 1788 1327
+f 1160 1164 1335
+f 1335 1327 1160
+f 988 995 1164
+f 1164 1160 988
+f 841 847 995
+f 995 988 841
+f 667 681 847
+f 847 841 667
+f 538 547 681
+f 681 667 538
+f 488 494 547
+f 547 538 488
+f 434 440 494
+f 494 488 434
+f 400 410 440
+f 440 434 400
+f 381 398 410
+f 410 400 381
+f 1324 1327 1788
+f 1788 1785 1324
+f 1156 1160 1327
+f 1327 1324 1156
+f 979 988 1160
+f 1160 1156 979
+f 837 841 988
+f 988 979 837
+f 659 667 841
+f 841 837 659
+f 534 538 667
+f 667 659 534
+f 484 488 538
+f 538 534 484
+f 428 434 488
+f 488 484 428
+f 395 400 434
+f 434 428 395
+f 374 381 400
+f 400 395 374
+f 572 616 600
+f 600 562 572
+f 605 654 616
+f 616 572 605
+f 680 737 654
+f 654 605 680
+f 782 822 737
+f 737 680 782
+f 892 914 822
+f 822 782 892
+f 978 1014 914
+f 914 892 978
+f 1094 1104 1014
+f 1014 978 1094
+f 1221 1237 1104
+f 1104 1094 1221
+f 1415 1433 1237
+f 1237 1221 1415
+f 1809 1819 1433
+f 1433 1415 1809
+f 531 572 562
+f 562 525 531
+f 566 605 572
+f 572 531 566
+f 629 680 605
+f 605 566 629
+f 740 782 680
+f 680 629 740
+f 850 892 782
+f 782 740 850
+f 964 978 892
+f 892 850 964
+f 1084 1094 978
+f 978 964 1084
+f 1213 1221 1094
+f 1094 1084 1213
+f 1401 1415 1221
+f 1221 1213 1401
+f 1931 1809 1415
+f 1415 1401 1931
+f 511 531 525
+f 525 509 511
+f 529 566 531
+f 531 511 529
+f 586 629 566
+f 566 529 586
+f 686 740 629
+f 629 586 686
+f 813 850 740
+f 740 686 813
+f 940 964 850
+f 850 813 940
+f 1069 1084 964
+f 964 940 1069
+f 1203 1213 1084
+f 1084 1069 1203
+f 1385 1401 1213
+f 1213 1203 1385
+f 1693 1931 1401
+f 1401 1385 1693
+f 493 511 509
+f 509 483 493
+f 513 529 511
+f 511 493 513
+f 554 586 529
+f 529 513 554
+f 639 686 586
+f 586 554 639
+f 786 813 686
+f 686 639 786
+f 918 940 813
+f 813 786 918
+f 1049 1069 940
+f 940 918 1049
+f 1193 1203 1069
+f 1069 1049 1193
+f 1376 1385 1203
+f 1203 1193 1376
+f 1712 1693 1385
+f 1385 1376 1712
+f 455 493 483
+f 483 449 455
+f 497 513 493
+f 493 455 497
+f 527 554 513
+f 513 497 527
+f 609 639 554
+f 554 527 609
+f 762 786 639
+f 639 609 762
+f 900 918 786
+f 786 762 900
+f 1038 1049 918
+f 918 900 1038
+f 1185 1193 1049
+f 1049 1038 1185
+f 1370 1376 1193
+f 1193 1185 1370
+f 1912 1712 1376
+f 1376 1370 1912
+f 443 455 449
+f 449 433 443
+f 458 497 455
+f 455 443 458
+f 515 527 497
+f 497 458 515
+f 580 609 527
+f 527 515 580
+f 730 762 609
+f 609 580 730
+f 880 900 762
+f 762 730 880
+f 1024 1038 900
+f 900 880 1024
+f 1173 1185 1038
+f 1038 1024 1173
+f 1356 1370 1185
+f 1185 1173 1356
+f 1797 1912 1370
+f 1370 1356 1797
+f 421 443 433
+f 433 413 421
+f 451 458 443
+f 443 421 451
+f 507 515 458
+f 458 451 507
+f 564 580 515
+f 515 507 564
+f 708 730 580
+f 580 564 708
+f 860 880 730
+f 730 708 860
+f 1008 1024 880
+f 880 860 1008
+f 1171 1173 1024
+f 1024 1008 1171
+f 1346 1356 1173
+f 1173 1171 1346
+f 1911 1797 1356
+f 1356 1346 1911
+f 411 421 413
+f 413 399 411
+f 441 451 421
+f 421 411 441
+f 495 507 451
+f 451 441 495
+f 548 564 507
+f 507 495 548
+f 682 708 564
+f 564 548 682
+f 848 860 708
+f 708 682 848
+f 996 1008 860
+f 860 848 996
+f 1165 1171 1008
+f 1008 996 1165
+f 1336 1346 1171
+f 1171 1165 1336
+f 1709 1911 1346
+f 1346 1336 1709
+f 401 411 399
+f 399 382 401
+f 435 441 411
+f 411 401 435
+f 489 495 441
+f 441 435 489
+f 539 548 495
+f 495 489 539
+f 668 682 548
+f 548 539 668
+f 842 848 682
+f 682 668 842
+f 987 996 848
+f 848 842 987
+f 1161 1165 996
+f 996 987 1161
+f 1328 1336 1165
+f 1165 1161 1328
+f 1708 1709 1336
+f 1336 1328 1708
+f 397 401 382
+f 382 376 397
+f 431 435 401
+f 401 397 431
+f 487 489 435
+f 435 431 487
+f 537 539 489
+f 489 487 537
+f 662 668 539
+f 539 537 662
+f 840 842 668
+f 668 662 840
+f 981 987 842
+f 842 840 981
+f 1159 1161 987
+f 987 981 1159
+f 1326 1328 1161
+f 1161 1159 1326
+f 1787 1708 1328
+f 1328 1326 1787
+f 2209 2194 1818
+f 1818 1808 2209
+f 2403 2391 2194
+f 2194 2209 2403
+f 2530 2518 2391
+f 2391 2403 2530
+f 2646 2614 2518
+f 2518 2530 2646
+f 2732 2712 2614
+f 2614 2646 2732
+f 2842 2806 2712
+f 2712 2732 2842
+f 2944 2890 2806
+f 2806 2842 2944
+f 3019 2974 2890
+f 2890 2944 3019
+f 3041 3009 2974
+f 2974 3019 3041
+f 3049 3025 3009
+f 3009 3041 3049
+f 2223 2209 1808
+f 1808 1805 2223
+f 2411 2403 2209
+f 2209 2223 2411
+f 2540 2530 2403
+f 2403 2411 2540
+f 2660 2646 2530
+f 2530 2540 2660
+f 2774 2732 2646
+f 2646 2660 2774
+f 2884 2842 2732
+f 2732 2774 2884
+f 2995 2944 2842
+f 2842 2884 2995
+f 3045 3019 2944
+f 2944 2995 3045
+f 3073 3041 3019
+f 3019 3045 3073
+f 3079 3049 3041
+f 3041 3073 3079
+f 2237 2223 1805
+f 1805 1803 2237
+f 2421 2411 2223
+f 2223 2237 2421
+f 2553 2540 2411
+f 2411 2421 2553
+f 2684 2660 2540
+f 2540 2553 2684
+f 2809 2774 2660
+f 2660 2684 2809
+f 2938 2884 2774
+f 2774 2809 2938
+f 3031 2995 2884
+f 2884 2938 3031
+f 3075 3045 2995
+f 2995 3031 3075
+f 3093 3073 3045
+f 3045 3075 3093
+f 3117 3079 3073
+f 3073 3093 3117
+f 2248 2237 1803
+f 1803 1801 2248
+f 2431 2421 2237
+f 2237 2248 2431
+f 2573 2553 2421
+f 2421 2431 2573
+f 2706 2684 2553
+f 2553 2573 2706
+f 2838 2809 2684
+f 2684 2706 2838
+f 2985 2938 2809
+f 2809 2838 2985
+f 3055 3031 2938
+f 2938 2985 3055
+f 3091 3075 3031
+f 3031 3055 3091
+f 3133 3093 3075
+f 3075 3091 3133
+f 3143 3117 3093
+f 3093 3133 3143
+f 2254 2248 1801
+f 1801 1799 2254
+f 2439 2431 2248
+f 2248 2254 2439
+f 2586 2573 2431
+f 2431 2439 2586
+f 2724 2706 2573
+f 2573 2586 2724
+f 2862 2838 2706
+f 2706 2724 2862
+f 3015 2985 2838
+f 2838 2862 3015
+f 3077 3055 2985
+f 2985 3015 3077
+f 3129 3091 3055
+f 3055 3077 3129
+f 3151 3133 3091
+f 3091 3129 3151
+f 3157 3143 3133
+f 3133 3151 3157
+f 2268 2254 1799
+f 1799 1796 2268
+f 2451 2439 2254
+f 2254 2268 2451
+f 2600 2586 2439
+f 2439 2451 2600
+f 2744 2724 2586
+f 2586 2600 2744
+f 2894 2862 2724
+f 2724 2744 2894
+f 3037 3015 2862
+f 2862 2894 3037
+f 3089 3077 3015
+f 3015 3037 3089
+f 3149 3129 3077
+f 3077 3089 3149
+f 3163 3151 3129
+f 3129 3149 3163
+f 3173 3157 3151
+f 3151 3163 3173
+f 2278 2268 1796
+f 1796 1793 2278
+f 2453 2451 2268
+f 2268 2278 2453
+f 2616 2600 2451
+f 2451 2453 2616
+f 2764 2744 2600
+f 2600 2616 2764
+f 2916 2894 2744
+f 2744 2764 2916
+f 3047 3037 2894
+f 2894 2916 3047
+f 3119 3089 3037
+f 3037 3047 3119
+f 3155 3149 3089
+f 3089 3119 3155
+f 3179 3163 3149
+f 3149 3155 3179
+f 3185 3173 3163
+f 3163 3179 3185
+f 2288 2278 1793
+f 1793 1791 2288
+f 2459 2453 2278
+f 2278 2288 2459
+f 2628 2616 2453
+f 2453 2459 2628
+f 2776 2764 2616
+f 2616 2628 2776
+f 2942 2916 2764
+f 2764 2776 2942
+f 3059 3047 2916
+f 2916 2942 3059
+f 3131 3119 3047
+f 3047 3059 3131
+f 3165 3155 3119
+f 3119 3131 3165
+f 3189 3179 3155
+f 3155 3165 3189
+f 3201 3185 3179
+f 3179 3189 3201
+f 2296 2288 1791
+f 1791 1789 2296
+f 2463 2459 2288
+f 2288 2296 2463
+f 2635 2628 2459
+f 2459 2463 2635
+f 2782 2776 2628
+f 2628 2635 2782
+f 2956 2942 2776
+f 2776 2782 2956
+f 3065 3059 2942
+f 2942 2956 3065
+f 3137 3131 3059
+f 3059 3065 3137
+f 3171 3165 3131
+f 3131 3137 3171
+f 3199 3189 3165
+f 3165 3171 3199
+f 3210 3201 3189
+f 3189 3199 3210
+f 2299 2296 1789
+f 1789 1786 2299
+f 2467 2463 2296
+f 2296 2299 2467
+f 2644 2635 2463
+f 2463 2467 2644
+f 2786 2782 2635
+f 2635 2644 2786
+f 2964 2956 2782
+f 2782 2786 2964
+f 3069 3065 2956
+f 2956 2964 3069
+f 3141 3137 3065
+f 3065 3069 3141
+f 3177 3171 3137
+f 3137 3141 3177
+f 3204 3199 3171
+f 3171 3177 3204
+f 3214 3210 3199
+f 3199 3204 3214
+f 3194 3202 3213
+f 3213 3207 3194
+f 3166 3175 3202
+f 3202 3194 3166
+f 3134 3139 3175
+f 3175 3166 3134
+f 3060 3067 3139
+f 3139 3134 3060
+f 2953 2962 3067
+f 3067 3060 2953
+f 2777 2784 2962
+f 2962 2953 2777
+f 2629 2643 2784
+f 2784 2777 2629
+f 2460 2465 2643
+f 2643 2629 2460
+f 2293 2298 2465
+f 2465 2460 2293
+f 1696 1785 2298
+f 2298 2293 1696
+f 3180 3194 3207
+f 3207 3190 3180
+f 3158 3166 3194
+f 3194 3180 3158
+f 3124 3134 3166
+f 3166 3158 3124
+f 3050 3060 3134
+f 3134 3124 3050
+f 2927 2953 3060
+f 3060 3050 2927
+f 2767 2777 2953
+f 2953 2927 2767
+f 2619 2629 2777
+f 2777 2767 2619
+f 2454 2460 2629
+f 2629 2619 2454
+f 2283 2293 2460
+f 2460 2454 2283
+f 1695 1696 2293
+f 2293 2283 1695
+f 3160 3180 3190
+f 3190 3168 3160
+f 3144 3158 3180
+f 3180 3160 3144
+f 3086 3124 3158
+f 3158 3144 3086
+f 3032 3050 3124
+f 3124 3086 3032
+f 2891 2927 3050
+f 3050 3032 2891
+f 2739 2767 2927
+f 2927 2891 2739
+f 2597 2619 2767
+f 2767 2739 2597
+f 2448 2454 2619
+f 2619 2597 2448
+f 2265 2283 2454
+f 2454 2448 2265
+f 1707 1695 2283
+f 2283 2265 1707
+f 3146 3160 3168
+f 3168 3152 3146
+f 3122 3144 3160
+f 3160 3146 3122
+f 3070 3086 3144
+f 3144 3122 3070
+f 2998 3032 3086
+f 3086 3070 2998
+f 2853 2891 3032
+f 3032 2998 2853
+f 2717 2739 2891
+f 2891 2853 2717
+f 2582 2597 2739
+f 2739 2717 2582
+f 2434 2448 2597
+f 2597 2582 2434
+f 2251 2265 2448
+f 2448 2434 2251
+f 1907 1707 2265
+f 2265 2251 1907
+f 3120 3146 3152
+f 3152 3126 3120
+f 3082 3122 3146
+f 3146 3120 3082
+f 3042 3070 3122
+f 3122 3082 3042
+f 2957 2998 3070
+f 3070 3042 2957
+f 2825 2853 2998
+f 2998 2957 2825
+f 2693 2717 2853
+f 2853 2825 2693
+f 2556 2582 2717
+f 2717 2693 2556
+f 2424 2434 2582
+f 2582 2556 2424
+f 2239 2251 2434
+f 2434 2424 2239
+f 1906 1907 2251
+f 2251 2239 1906
+f 3080 3120 3126
+f 3126 3084 3080
+f 3056 3082 3120
+f 3120 3080 3056
+f 3012 3042 3082
+f 3082 3056 3012
+f 2899 2957 3042
+f 3042 3012 2899
+f 2789 2825 2957
+f 2957 2899 2789
+f 2675 2693 2825
+f 2825 2789 2675
+f 2545 2556 2693
+f 2693 2675 2545
+f 2416 2424 2556
+f 2556 2545 2416
+f 2228 2239 2424
+f 2424 2416 2228
+f 1770 1906 2239
+f 2239 2228 1770
+f 3053 3080 3084
+f 3084 3062 3053
+f 3028 3056 3080
+f 3080 3053 3028
+f 2978 3012 3056
+f 3056 3028 2978
+f 2860 2899 3012
+f 3012 2978 2860
+f 2754 2789 2899
+f 2899 2860 2754
+f 2652 2675 2789
+f 2789 2754 2652
+f 2534 2545 2675
+f 2675 2652 2534
+f 2406 2416 2545
+f 2545 2534 2406
+f 2217 2228 2416
+f 2416 2406 2217
+f 1929 1770 2228
+f 2228 2217 1929
+f 3035 3053 3062
+f 3062 3039 3035
+f 2997 3028 3053
+f 3053 3035 2997
+f 2920 2978 3028
+f 3028 2997 2920
+f 2832 2860 2978
+f 2978 2920 2832
+f 2728 2754 2860
+f 2860 2832 2728
+f 2634 2652 2754
+f 2754 2728 2634
+f 2528 2534 2652
+f 2652 2634 2528
+f 2396 2406 2534
+f 2534 2528 2396
+f 2202 2217 2406
+f 2406 2396 2202
+f 1765 1929 2217
+f 2217 2202 1765
+f 3017 3035 3039
+f 3039 3027 3017
+f 2980 2997 3035
+f 3035 3017 2980
+f 2896 2920 2997
+f 2997 2980 2896
+f 2812 2832 2920
+f 2920 2896 2812
+f 2715 2728 2832
+f 2832 2812 2715
+f 2618 2634 2728
+f 2728 2715 2618
+f 2523 2528 2634
+f 2634 2618 2523
+f 2392 2396 2528
+f 2528 2523 2392
+f 2196 2202 2396
+f 2396 2392 2196
+f 1724 1765 2202
+f 2202 2196 1724
+f 3007 3017 3027
+f 3027 3023 3007
+f 2969 2980 3017
+f 3017 3007 2969
+f 2887 2896 2980
+f 2980 2969 2887
+f 2802 2812 2896
+f 2896 2887 2802
+f 2709 2715 2812
+f 2812 2802 2709
+f 2609 2618 2715
+f 2715 2709 2609
+f 2519 2523 2618
+f 2618 2609 2519
+f 2386 2392 2523
+f 2523 2519 2386
+f 2190 2196 2392
+f 2392 2386 2190
+f 1759 1724 2196
+f 2196 2190 1759
+f 1329 1324 1785
+f 1785 1782 1329
+f 1162 1157 1324
+f 1324 1329 1162
+f 993 982 1157
+f 1157 1162 993
+f 845 838 982
+f 982 993 845
+f 669 660 838
+f 838 845 669
+f 542 535 660
+f 660 669 542
+f 490 485 535
+f 535 542 490
+f 438 429 485
+f 485 490 438
+f 404 396 429
+f 429 438 404
+f 387 376 396
+f 396 404 387
+f 1339 1329 1782
+f 1782 1780 1339
+f 1168 1162 1329
+f 1329 1339 1168
+f 1003 993 1162
+f 1162 1168 1003
+f 855 845 993
+f 993 1003 855
+f 695 669 845
+f 845 855 695
+f 559 542 669
+f 669 695 559
+f 500 490 542
+f 542 559 500
+f 446 438 490
+f 490 500 446
+f 416 404 438
+f 438 446 416
+f 408 387 404
+f 404 416 408
+f 1357 1339 1780
+f 1780 1778 1357
+f 1174 1168 1339
+f 1339 1357 1174
+f 1025 1003 1168
+f 1168 1174 1025
+f 883 855 1003
+f 1003 1025 883
+f 731 695 855
+f 855 883 731
+f 583 559 695
+f 695 731 583
+f 516 500 559
+f 559 583 516
+f 467 446 500
+f 500 516 467
+f 444 416 446
+f 446 467 444
+f 436 408 416
+f 416 444 436
+f 1371 1357 1778
+f 1778 1776 1371
+f 1188 1174 1357
+f 1357 1371 1188
+f 1042 1025 1174
+f 1174 1188 1042
+f 905 883 1025
+f 1025 1042 905
+f 769 731 883
+f 883 905 769
+f 624 583 731
+f 731 769 624
+f 532 516 583
+f 583 624 532
+f 502 467 516
+f 516 532 502
+f 459 444 467
+f 467 502 459
+f 452 436 444
+f 444 459 452
+f 1383 1371 1776
+f 1776 1774 1383
+f 1198 1188 1371
+f 1371 1383 1198
+f 1068 1042 1188
+f 1188 1198 1068
+f 929 905 1042
+f 1042 1068 929
+f 797 769 905
+f 905 929 797
+f 665 624 769
+f 769 797 665
+f 569 532 624
+f 624 665 569
+f 520 502 532
+f 532 569 520
+f 504 459 502
+f 502 520 504
+f 498 452 459
+f 459 504 498
+f 1394 1383 1774
+f 1774 1771 1394
+f 1206 1198 1383
+f 1383 1394 1206
+f 1077 1068 1198
+f 1198 1206 1077
+f 947 929 1068
+f 1068 1077 947
+f 833 797 929
+f 929 947 833
+f 723 665 797
+f 797 833 723
+f 610 569 665
+f 665 723 610
+f 549 520 569
+f 569 610 549
+f 522 504 520
+f 520 549 522
+f 518 498 504
+f 504 522 518
+f 1407 1394 1771
+f 1771 1768 1407
+f 1216 1206 1394
+f 1394 1407 1216
+f 1090 1077 1206
+f 1206 1216 1090
+f 972 947 1077
+f 1077 1090 972
+f 870 833 947
+f 947 972 870
+f 764 723 833
+f 833 870 764
+f 646 610 723
+f 723 764 646
+f 587 549 610
+f 610 646 587
+f 556 522 549
+f 549 587 556
+f 540 518 522
+f 522 556 540
+f 1420 1407 1768
+f 1768 1764 1420
+f 1226 1216 1407
+f 1407 1420 1226
+f 1096 1090 1216
+f 1216 1226 1096
+f 990 972 1090
+f 1090 1096 990
+f 896 870 972
+f 972 990 896
+f 792 764 870
+f 870 896 792
+f 704 646 764
+f 764 792 704
+f 627 587 646
+f 646 704 627
+f 582 556 587
+f 587 627 582
+f 574 540 556
+f 556 582 574
+f 1426 1420 1764
+f 1764 1762 1426
+f 1230 1226 1420
+f 1420 1426 1230
+f 1101 1096 1226
+f 1226 1230 1101
+f 1006 990 1096
+f 1096 1101 1006
+f 907 896 990
+f 990 1006 907
+f 812 792 896
+f 896 907 812
+f 728 704 792
+f 792 812 728
+f 644 627 704
+f 704 728 644
+f 607 582 627
+f 627 644 607
+f 592 574 582
+f 582 607 592
+f 1430 1426 1762
+f 1762 1758 1430
+f 1234 1230 1426
+f 1426 1430 1234
+f 1107 1101 1230
+f 1230 1234 1107
+f 1012 1006 1101
+f 1101 1107 1012
+f 912 907 1006
+f 1006 1012 912
+f 819 812 907
+f 907 912 819
+f 738 728 812
+f 812 819 738
+f 651 644 728
+f 728 738 651
+f 618 607 644
+f 644 651 618
+f 601 592 607
+f 607 618 601
+f 405 397 376
+f 376 388 405
+f 439 430 397
+f 397 405 439
+f 491 486 430
+f 430 439 491
+f 543 536 486
+f 486 491 543
+f 670 661 536
+f 536 543 670
+f 846 839 661
+f 661 670 846
+f 994 980 839
+f 839 846 994
+f 1163 1158 980
+f 980 994 1163
+f 1330 1325 1158
+f 1158 1163 1330
+f 1926 1786 1325
+f 1325 1330 1926
+f 417 405 388
+f 388 409 417
+f 447 439 405
+f 405 417 447
+f 501 491 439
+f 439 447 501
+f 560 543 491
+f 491 501 560
+f 696 670 543
+f 543 560 696
+f 856 846 670
+f 670 696 856
+f 1004 994 846
+f 846 856 1004
+f 1169 1163 994
+f 994 1004 1169
+f 1340 1330 1163
+f 1163 1169 1340
+f 1925 1926 1330
+f 1330 1340 1925
+f 445 417 409
+f 409 437 445
+f 468 447 417
+f 417 445 468
+f 517 501 447
+f 447 468 517
+f 584 560 501
+f 501 517 584
+f 732 696 560
+f 560 584 732
+f 884 856 696
+f 696 732 884
+f 1026 1004 856
+f 856 884 1026
+f 1175 1169 1004
+f 1004 1026 1175
+f 1358 1340 1169
+f 1169 1175 1358
+f 1908 1925 1340
+f 1340 1358 1908
+f 460 445 437
+f 437 453 460
+f 503 468 445
+f 445 460 503
+f 533 517 468
+f 468 503 533
+f 625 584 517
+f 517 533 625
+f 770 732 584
+f 584 625 770
+f 906 884 732
+f 732 770 906
+f 1041 1026 884
+f 884 906 1041
+f 1189 1175 1026
+f 1026 1041 1189
+f 1372 1358 1175
+f 1175 1189 1372
+f 1706 1908 1358
+f 1358 1372 1706
+f 505 460 453
+f 453 499 505
+f 521 503 460
+f 460 505 521
+f 570 533 503
+f 503 521 570
+f 666 625 533
+f 533 570 666
+f 798 770 625
+f 625 666 798
+f 930 906 770
+f 770 798 930
+f 1067 1041 906
+f 906 930 1067
+f 1199 1189 1041
+f 1041 1067 1199
+f 1384 1372 1189
+f 1189 1199 1384
+f 1705 1706 1372
+f 1372 1384 1705
+f 523 505 499
+f 499 519 523
+f 550 521 505
+f 505 523 550
+f 611 570 521
+f 521 550 611
+f 724 666 570
+f 570 611 724
+f 834 798 666
+f 666 724 834
+f 948 930 798
+f 798 834 948
+f 1078 1067 930
+f 930 948 1078
+f 1207 1199 1067
+f 1067 1078 1207
+f 1395 1384 1199
+f 1199 1207 1395
+f 1773 1705 1384
+f 1384 1395 1773
+f 555 523 519
+f 519 541 555
+f 588 550 523
+f 523 555 588
+f 645 611 550
+f 550 588 645
+f 763 724 611
+f 611 645 763
+f 869 834 724
+f 724 763 869
+f 971 948 834
+f 834 869 971
+f 1089 1078 948
+f 948 971 1089
+f 1217 1207 1078
+f 1078 1089 1217
+f 1406 1395 1207
+f 1207 1217 1406
+f 1692 1773 1395
+f 1395 1406 1692
+f 581 555 541
+f 541 573 581
+f 626 588 555
+f 555 581 626
+f 703 645 588
+f 588 626 703
+f 791 763 645
+f 645 703 791
+f 895 869 763
+f 763 791 895
+f 989 971 869
+f 869 895 989
+f 1095 1089 971
+f 971 989 1095
+f 1227 1217 1089
+f 1089 1095 1227
+f 1421 1406 1217
+f 1217 1227 1421
+f 1766 1692 1406
+f 1406 1421 1766
+f 606 581 573
+f 573 591 606
+f 643 626 581
+f 581 606 643
+f 727 703 626
+f 626 643 727
+f 811 791 703
+f 703 727 811
+f 908 895 791
+f 791 811 908
+f 1005 989 895
+f 895 908 1005
+f 1100 1095 989
+f 989 1005 1100
+f 1231 1227 1095
+f 1095 1100 1231
+f 1427 1421 1227
+f 1227 1231 1427
+f 1897 1766 1421
+f 1421 1427 1897
+f 615 606 591
+f 591 598 615
+f 653 643 606
+f 606 615 653
+f 735 727 643
+f 643 653 735
+f 820 811 727
+f 727 735 820
+f 913 908 811
+f 811 820 913
+f 1013 1005 908
+f 908 913 1013
+f 1103 1100 1005
+f 1005 1013 1103
+f 1236 1231 1100
+f 1100 1103 1236
+f 1432 1427 1231
+f 1231 1236 1432
+f 1760 1897 1427
+f 1427 1432 1760
+f 2294 2299 1786
+f 1786 1783 2294
+f 2461 2466 2299
+f 2299 2294 2461
+f 2630 2641 2466
+f 2466 2461 2630
+f 2778 2785 2641
+f 2641 2630 2778
+f 2954 2963 2785
+f 2785 2778 2954
+f 3061 3068 2963
+f 2963 2954 3061
+f 3135 3140 3068
+f 3068 3061 3135
+f 3167 3176 3140
+f 3140 3135 3167
+f 3195 3203 3176
+f 3176 3167 3195
+f 3208 3213 3203
+f 3203 3195 3208
+f 2284 2294 1783
+f 1783 1781 2284
+f 2455 2461 2294
+f 2294 2284 2455
+f 2620 2630 2461
+f 2461 2455 2620
+f 2768 2778 2630
+f 2630 2620 2768
+f 2928 2954 2778
+f 2778 2768 2928
+f 3051 3061 2954
+f 2954 2928 3051
+f 3125 3135 3061
+f 3061 3051 3125
+f 3159 3167 3135
+f 3135 3125 3159
+f 3181 3195 3167
+f 3167 3159 3181
+f 3191 3208 3195
+f 3195 3181 3191
+f 2266 2284 1781
+f 1781 1779 2266
+f 2449 2455 2284
+f 2284 2266 2449
+f 2598 2620 2455
+f 2455 2449 2598
+f 2740 2768 2620
+f 2620 2598 2740
+f 2892 2928 2768
+f 2768 2740 2892
+f 3033 3051 2928
+f 2928 2892 3033
+f 3087 3125 3051
+f 3051 3033 3087
+f 3145 3159 3125
+f 3125 3087 3145
+f 3161 3181 3159
+f 3159 3145 3161
+f 3169 3191 3181
+f 3181 3161 3169
+f 2252 2266 1779
+f 1779 1777 2252
+f 2435 2449 2266
+f 2266 2252 2435
+f 2581 2598 2449
+f 2449 2435 2581
+f 2718 2740 2598
+f 2598 2581 2718
+f 2854 2892 2740
+f 2740 2718 2854
+f 2999 3033 2892
+f 2892 2854 2999
+f 3071 3087 3033
+f 3033 2999 3071
+f 3123 3145 3087
+f 3087 3071 3123
+f 3147 3161 3145
+f 3145 3123 3147
+f 3153 3169 3161
+f 3161 3147 3153
+f 2240 2252 1777
+f 1777 1775 2240
+f 2425 2435 2252
+f 2252 2240 2425
+f 2555 2581 2435
+f 2435 2425 2555
+f 2694 2718 2581
+f 2581 2555 2694
+f 2826 2854 2718
+f 2718 2694 2826
+f 2958 2999 2854
+f 2854 2826 2958
+f 3043 3071 2999
+f 2999 2958 3043
+f 3083 3123 3071
+f 3071 3043 3083
+f 3121 3147 3123
+f 3123 3083 3121
+f 3127 3153 3147
+f 3147 3121 3127
+f 2229 2240 1775
+f 1775 1772 2229
+f 2417 2425 2240
+f 2240 2229 2417
+f 2546 2555 2425
+f 2425 2417 2546
+f 2676 2694 2555
+f 2555 2546 2676
+f 2790 2826 2694
+f 2694 2676 2790
+f 2900 2958 2826
+f 2826 2790 2900
+f 3013 3043 2958
+f 2958 2900 3013
+f 3057 3083 3043
+f 3043 3013 3057
+f 3081 3121 3083
+f 3083 3057 3081
+f 3085 3127 3121
+f 3121 3081 3085
+f 2216 2229 1772
+f 1772 1769 2216
+f 2407 2417 2229
+f 2229 2216 2407
+f 2533 2546 2417
+f 2417 2407 2533
+f 2651 2676 2546
+f 2546 2533 2651
+f 2753 2790 2676
+f 2676 2651 2753
+f 2859 2900 2790
+f 2790 2753 2859
+f 2977 3013 2900
+f 2900 2859 2977
+f 3029 3057 3013
+f 3013 2977 3029
+f 3052 3081 3057
+f 3057 3029 3052
+f 3063 3085 3081
+f 3081 3052 3063
+f 2203 2216 1769
+f 1769 1767 2203
+f 2397 2407 2216
+f 2216 2203 2397
+f 2527 2533 2407
+f 2407 2397 2527
+f 2633 2651 2533
+f 2533 2527 2633
+f 2727 2753 2651
+f 2651 2633 2727
+f 2831 2859 2753
+f 2753 2727 2831
+f 2919 2977 2859
+f 2859 2831 2919
+f 2996 3029 2977
+f 2977 2919 2996
+f 3034 3052 3029
+f 3029 2996 3034
+f 3038 3063 3052
+f 3052 3034 3038
+f 2197 2203 1767
+f 1767 1763 2197
+f 2393 2397 2203
+f 2203 2197 2393
+f 2522 2527 2397
+f 2397 2393 2522
+f 2617 2633 2527
+f 2527 2522 2617
+f 2716 2727 2633
+f 2633 2617 2716
+f 2811 2831 2727
+f 2727 2716 2811
+f 2895 2919 2831
+f 2831 2811 2895
+f 2979 2996 2919
+f 2919 2895 2979
+f 3016 3034 2996
+f 2996 2979 3016
+f 3026 3038 3034
+f 3034 3016 3026
+f 2193 2197 1763
+f 1763 1761 2193
+f 2389 2393 2197
+f 2197 2193 2389
+f 2516 2522 2393
+f 2393 2389 2516
+f 2610 2617 2522
+f 2522 2516 2610
+f 2710 2716 2617
+f 2617 2610 2710
+f 2803 2811 2716
+f 2716 2710 2803
+f 2885 2895 2811
+f 2811 2803 2885
+f 2971 2979 2895
+f 2895 2885 2971
+f 3005 3016 2979
+f 2979 2971 3005
+f 3022 3026 3016
+f 3016 3005 3022
+f 461 545 544
+f 544 456 461
+f 463 551 545
+f 545 461 463
+f 465 557 551
+f 551 463 465
+f 469 567 557
+f 557 465 469
+f 471 575 567
+f 567 469 471
+f 473 577 575
+f 575 471 473
+f 475 589 577
+f 577 473 475
+f 477 593 589
+f 589 475 477
+f 479 595 593
+f 593 477 479
+f 481 599 595
+f 595 479 481
+f 389 461 456
+f 456 392 389
+f 386 463 461
+f 461 389 386
+f 379 465 463
+f 463 386 379
+f 373 469 465
+f 465 379 373
+f 371 471 469
+f 469 373 371
+f 369 473 471
+f 471 371 369
+f 366 475 473
+f 473 369 366
+f 364 477 475
+f 475 366 364
+f 362 479 477
+f 477 364 362
+f 361 481 479
+f 479 362 361
+f 335 389 392
+f 392 337 335
+f 333 386 389
+f 389 335 333
+f 331 379 386
+f 386 333 331
+f 329 373 379
+f 379 331 329
+f 328 371 373
+f 373 329 328
+f 325 369 371
+f 371 328 325
+f 323 366 369
+f 369 325 323
+f 321 364 366
+f 366 323 321
+f 319 362 364
+f 364 321 319
+f 316 361 362
+f 362 319 316
+f 298 335 337
+f 337 302 298
+f 290 333 335
+f 335 298 290
+f 288 331 333
+f 333 290 288
+f 286 329 331
+f 331 288 286
+f 281 328 329
+f 329 286 281
+f 275 325 328
+f 328 281 275
+f 265 323 325
+f 325 275 265
+f 259 321 323
+f 323 265 259
+f 255 319 321
+f 321 259 255
+f 249 316 319
+f 319 255 249
+f 269 298 302
+f 302 271 269
+f 261 290 298
+f 298 269 261
+f 251 288 290
+f 290 261 251
+f 238 286 288
+f 288 251 238
+f 230 281 286
+f 286 238 230
+f 218 275 281
+f 281 230 218
+f 208 265 275
+f 275 218 208
+f 196 259 265
+f 265 208 196
+f 186 255 259
+f 259 196 186
+f 181 249 255
+f 255 186 181
+f 228 269 271
+f 271 234 228
+f 222 261 269
+f 269 228 222
+f 212 251 261
+f 261 222 212
+f 200 238 251
+f 251 212 200
+f 177 230 238
+f 238 200 177
+f 160 218 230
+f 230 177 160
+f 134 208 218
+f 218 160 134
+f 112 196 208
+f 208 134 112
+f 102 186 196
+f 196 112 102
+f 96 181 186
+f 186 102 96
+f 198 228 234
+f 234 205 198
+f 182 222 228
+f 228 198 182
+f 168 212 222
+f 222 182 168
+f 146 200 212
+f 212 168 146
+f 118 177 200
+f 200 146 118
+f 92 160 177
+f 177 118 92
+f 74 134 160
+f 160 92 74
+f 63 112 134
+f 134 74 63
+f 53 102 112
+f 112 63 53
+f 50 96 102
+f 102 53 50
+f 167 198 205
+f 205 170 167
+f 154 182 198
+f 198 167 154
+f 126 168 182
+f 182 154 126
+f 100 146 168
+f 168 126 100
+f 83 118 146
+f 146 100 83
+f 61 92 118
+f 118 83 61
+f 46 74 92
+f 92 61 46
+f 32 63 74
+f 74 46 32
+f 25 53 63
+f 63 32 25
+f 21 50 53
+f 53 25 21
+f 143 167 170
+f 170 150 143
+f 124 154 167
+f 167 143 124
+f 104 126 154
+f 154 124 104
+f 84 100 126
+f 126 104 84
+f 65 83 100
+f 100 84 65
+f 44 61 83
+f 83 65 44
+f 30 46 61
+f 61 44 30
+f 17 32 46
+f 46 30 17
+f 9 25 32
+f 32 17 9
+f 5 21 25
+f 25 9 5
+f 132 143 150
+f 150 140 132
+f 116 124 143
+f 143 132 116
+f 94 104 124
+f 124 116 94
+f 76 84 104
+f 104 94 76
+f 55 65 84
+f 84 76 55
+f 40 44 65
+f 65 55 40
+f 22 30 44
+f 44 40 22
+f 11 17 30
+f 30 22 11
+f 2 9 17
+f 17 11 2
+f 1 5 9
+f 9 2 1
+f 480 596 599
+f 599 481 480
+f 478 594 596
+f 596 480 478
+f 476 590 594
+f 594 478 476
+f 474 578 590
+f 590 476 474
+f 472 576 578
+f 578 474 472
+f 470 568 576
+f 576 472 470
+f 466 558 568
+f 568 470 466
+f 464 552 558
+f 558 466 464
+f 462 546 552
+f 552 464 462
+f 456 544 546
+f 546 462 456
+f 363 480 481
+f 481 360 363
+f 365 478 480
+f 480 363 365
+f 367 476 478
+f 478 365 367
+f 368 474 476
+f 476 367 368
+f 370 472 474
+f 474 368 370
+f 372 470 472
+f 472 370 372
+f 380 466 470
+f 470 372 380
+f 385 464 466
+f 466 380 385
+f 390 462 464
+f 464 385 390
+f 391 456 462
+f 462 390 391
+f 320 363 360
+f 360 316 320
+f 322 365 363
+f 363 320 322
+f 324 367 365
+f 365 322 324
+f 326 368 367
+f 367 324 326
+f 327 370 368
+f 368 326 327
+f 330 372 370
+f 370 327 330
+f 332 380 372
+f 372 330 332
+f 334 385 380
+f 380 332 334
+f 336 390 385
+f 385 334 336
+f 337 391 390
+f 390 336 337
+f 256 320 316
+f 316 250 256
+f 260 322 320
+f 320 256 260
+f 266 324 322
+f 322 260 266
+f 276 326 324
+f 324 266 276
+f 282 327 326
+f 326 276 282
+f 287 330 327
+f 327 282 287
+f 289 332 330
+f 330 287 289
+f 291 334 332
+f 332 289 291
+f 299 336 334
+f 334 291 299
+f 303 337 336
+f 336 299 303
+f 187 256 250
+f 250 181 187
+f 197 260 256
+f 256 187 197
+f 209 266 260
+f 260 197 209
+f 219 276 266
+f 266 209 219
+f 231 282 276
+f 276 219 231
+f 239 287 282
+f 282 231 239
+f 252 289 287
+f 287 239 252
+f 262 291 289
+f 289 252 262
+f 270 299 291
+f 291 262 270
+f 272 303 299
+f 299 270 272
+f 103 187 181
+f 181 97 103
+f 113 197 187
+f 187 103 113
+f 135 209 197
+f 197 113 135
+f 161 219 209
+f 209 135 161
+f 178 231 219
+f 219 161 178
+f 201 239 231
+f 231 178 201
+f 213 252 239
+f 239 201 213
+f 223 262 252
+f 252 213 223
+f 229 270 262
+f 262 223 229
+f 235 272 270
+f 270 229 235
+f 54 103 97
+f 97 50 54
+f 64 113 103
+f 103 54 64
+f 75 135 113
+f 113 64 75
+f 93 161 135
+f 135 75 93
+f 119 178 161
+f 161 93 119
+f 147 201 178
+f 178 119 147
+f 169 213 201
+f 201 147 169
+f 183 223 213
+f 213 169 183
+f 199 229 223
+f 223 183 199
+f 205 235 229
+f 229 199 205
+f 24 54 50
+f 50 21 24
+f 33 64 54
+f 54 24 33
+f 47 75 64
+f 64 33 47
+f 62 93 75
+f 75 47 62
+f 82 119 93
+f 93 62 82
+f 101 147 119
+f 119 82 101
+f 127 169 147
+f 147 101 127
+f 155 183 169
+f 169 127 155
+f 166 199 183
+f 183 155 166
+f 171 205 199
+f 199 166 171
+f 10 24 21
+f 21 6 10
+f 18 33 24
+f 24 10 18
+f 31 47 33
+f 33 18 31
+f 45 62 47
+f 47 31 45
+f 66 82 62
+f 62 45 66
+f 85 101 82
+f 82 66 85
+f 105 127 101
+f 101 85 105
+f 125 155 127
+f 127 105 125
+f 144 166 155
+f 155 125 144
+f 151 171 166
+f 166 144 151
+f 3 10 6
+f 6 1 3
+f 12 18 10
+f 10 3 12
+f 23 31 18
+f 18 12 23
+f 41 45 31
+f 31 23 41
+f 56 66 45
+f 45 41 56
+f 77 85 66
+f 66 56 77
+f 95 105 85
+f 85 77 95
+f 117 125 105
+f 105 95 117
+f 133 144 125
+f 125 117 133
+f 140 151 144
+f 144 133 140
+f 138 132 140
+f 140 145 138
+f 122 116 132
+f 132 138 122
+f 98 94 116
+f 116 122 98
+f 80 76 94
+f 94 98 80
+f 60 55 76
+f 76 80 60
+f 42 40 55
+f 55 60 42
+f 28 22 40
+f 40 42 28
+f 13 11 22
+f 22 28 13
+f 7 2 11
+f 11 13 7
+f 4 1 2
+f 2 7 4
+f 152 138 145
+f 145 158 152
+f 136 122 138
+f 138 152 136
+f 108 98 122
+f 122 136 108
+f 89 80 98
+f 98 108 89
+f 70 60 80
+f 80 89 70
+f 52 42 60
+f 60 70 52
+f 38 28 42
+f 42 52 38
+f 26 13 28
+f 28 38 26
+f 19 7 13
+f 13 26 19
+f 15 4 7
+f 7 19 15
+f 173 152 158
+f 158 176 173
+f 162 136 152
+f 152 173 162
+f 142 108 136
+f 136 162 142
+f 111 89 108
+f 108 142 111
+f 91 70 89
+f 89 111 91
+f 73 52 70
+f 70 91 73
+f 58 38 52
+f 52 73 58
+f 48 26 38
+f 38 58 48
+f 37 19 26
+f 26 48 37
+f 35 15 19
+f 19 37 35
+f 194 173 176
+f 176 202 194
+f 184 162 173
+f 173 194 184
+f 174 142 162
+f 162 184 174
+f 156 111 142
+f 142 174 156
+f 128 91 111
+f 111 156 128
+f 106 73 91
+f 91 128 106
+f 86 58 73
+f 73 106 86
+f 78 48 58
+f 58 86 78
+f 68 37 48
+f 48 78 68
+f 67 35 37
+f 37 68 67
+f 221 194 202
+f 202 225 221
+f 216 184 194
+f 194 221 216
+f 206 174 184
+f 184 216 206
+f 192 156 174
+f 174 206 192
+f 180 128 156
+f 156 192 180
+f 164 106 128
+f 128 180 164
+f 148 86 106
+f 106 164 148
+f 130 78 86
+f 86 148 130
+f 121 68 78
+f 78 130 121
+f 115 67 68
+f 68 121 115
+f 244 221 225
+f 225 247 244
+f 240 216 221
+f 221 244 240
+f 236 206 216
+f 216 240 236
+f 233 192 206
+f 206 236 233
+f 227 180 192
+f 192 233 227
+f 215 164 180
+f 180 227 215
+f 210 148 164
+f 164 215 210
+f 203 130 148
+f 148 210 203
+f 191 121 130
+f 130 203 191
+f 188 115 121
+f 121 191 188
+f 284 244 247
+f 247 285 284
+f 279 240 244
+f 244 284 279
+f 277 236 240
+f 240 279 277
+f 273 233 236
+f 236 277 273
+f 267 227 233
+f 233 273 267
+f 263 215 227
+f 227 267 263
+f 258 210 215
+f 215 263 258
+f 253 203 210
+f 210 258 253
+f 245 191 203
+f 203 253 245
+f 242 188 191
+f 191 245 242
+f 315 284 285
+f 285 318 315
+f 312 279 284
+f 284 315 312
+f 311 277 279
+f 279 312 311
+f 309 273 277
+f 277 311 309
+f 307 267 273
+f 273 309 307
+f 305 263 267
+f 267 307 305
+f 301 258 263
+f 263 305 301
+f 297 253 258
+f 258 301 297
+f 295 245 253
+f 253 297 295
+f 293 242 245
+f 245 295 293
+f 341 315 318
+f 318 339 341
+f 343 312 315
+f 315 341 343
+f 345 311 312
+f 312 343 345
+f 347 309 311
+f 311 345 347
+f 349 307 309
+f 309 347 349
+f 351 305 307
+f 307 349 351
+f 353 301 305
+f 305 351 353
+f 355 297 301
+f 301 353 355
+f 357 295 297
+f 297 355 357
+f 359 293 295
+f 295 357 359
+f 378 341 339
+f 339 376 378
+f 384 343 341
+f 341 378 384
+f 394 345 343
+f 343 384 394
+f 403 347 345
+f 345 394 403
+f 406 349 347
+f 347 403 406
+f 415 351 349
+f 349 406 415
+f 419 353 351
+f 351 415 419
+f 423 355 353
+f 353 419 423
+f 425 357 355
+f 355 423 425
+f 427 359 357
+f 357 425 427
+f 8 3 1
+f 1 4 8
+f 14 12 3
+f 3 8 14
+f 29 23 12
+f 12 14 29
+f 43 41 23
+f 23 29 43
+f 59 56 41
+f 41 43 59
+f 81 77 56
+f 56 59 81
+f 99 95 77
+f 77 81 99
+f 123 117 95
+f 95 99 123
+f 139 133 117
+f 117 123 139
+f 145 140 133
+f 133 139 145
+f 20 8 4
+f 4 16 20
+f 27 14 8
+f 8 20 27
+f 39 29 14
+f 14 27 39
+f 51 43 29
+f 29 39 51
+f 71 59 43
+f 43 51 71
+f 88 81 59
+f 59 71 88
+f 109 99 81
+f 81 88 109
+f 137 123 99
+f 99 109 137
+f 153 139 123
+f 123 137 153
+f 159 145 139
+f 139 153 159
+f 36 20 16
+f 16 34 36
+f 49 27 20
+f 20 36 49
+f 57 39 27
+f 27 49 57
+f 72 51 39
+f 39 57 72
+f 90 71 51
+f 51 72 90
+f 110 88 71
+f 71 90 110
+f 141 109 88
+f 88 110 141
+f 163 137 109
+f 109 141 163
+f 172 153 137
+f 137 163 172
+f 176 159 153
+f 153 172 176
+f 69 36 34
+f 34 67 69
+f 79 49 36
+f 36 69 79
+f 87 57 49
+f 49 79 87
+f 107 72 57
+f 57 87 107
+f 129 90 72
+f 72 107 129
+f 157 110 90
+f 90 129 157
+f 175 141 110
+f 110 157 175
+f 185 163 141
+f 141 175 185
+f 195 172 163
+f 163 185 195
+f 202 176 172
+f 172 195 202
+f 120 69 67
+f 67 114 120
+f 131 79 69
+f 69 120 131
+f 149 87 79
+f 79 131 149
+f 165 107 87
+f 87 149 165
+f 179 129 107
+f 107 165 179
+f 193 157 129
+f 129 179 193
+f 207 175 157
+f 157 193 207
+f 217 185 175
+f 175 207 217
+f 220 195 185
+f 185 217 220
+f 224 202 195
+f 195 220 224
+f 190 120 114
+f 114 189 190
+f 204 131 120
+f 120 190 204
+f 211 149 131
+f 131 204 211
+f 214 165 149
+f 149 211 214
+f 226 179 165
+f 165 214 226
+f 232 193 179
+f 179 226 232
+f 237 207 193
+f 193 232 237
+f 241 217 207
+f 207 237 241
+f 243 220 217
+f 217 241 243
+f 248 224 220
+f 220 243 248
+f 246 190 189
+f 189 242 246
+f 254 204 190
+f 190 246 254
+f 257 211 204
+f 204 254 257
+f 264 214 211
+f 211 257 264
+f 268 226 214
+f 214 264 268
+f 274 232 226
+f 226 268 274
+f 278 237 232
+f 232 274 278
+f 280 241 237
+f 237 278 280
+f 283 243 241
+f 241 280 283
+f 285 248 243
+f 243 283 285
+f 294 246 242
+f 242 292 294
+f 296 254 246
+f 246 294 296
+f 300 257 254
+f 254 296 300
+f 304 264 257
+f 257 300 304
+f 306 268 264
+f 264 304 306
+f 308 274 268
+f 268 306 308
+f 310 278 274
+f 274 308 310
+f 313 280 278
+f 278 310 313
+f 314 283 280
+f 280 313 314
+f 317 285 283
+f 283 314 317
+f 356 294 292
+f 292 358 356
+f 354 296 294
+f 294 356 354
+f 352 300 296
+f 296 354 352
+f 350 304 300
+f 300 352 350
+f 348 306 304
+f 304 350 348
+f 346 308 306
+f 306 348 346
+f 344 310 308
+f 308 346 344
+f 342 313 310
+f 310 344 342
+f 340 314 313
+f 313 342 340
+f 338 317 314
+f 314 340 338
+f 424 356 358
+f 358 426 424
+f 422 354 356
+f 356 424 422
+f 418 352 354
+f 354 422 418
+f 414 350 352
+f 352 418 414
+f 407 348 350
+f 350 414 407
+f 402 346 348
+f 348 407 402
+f 393 344 346
+f 346 402 393
+f 383 342 344
+f 344 393 383
+f 377 340 342
+f 342 383 377
+f 375 338 340
+f 340 377 375
+f 3186 3113 3115
+f 3115 3182 3186
+f 3192 3110 3113
+f 3113 3186 3192
+f 3196 3109 3110
+f 3110 3192 3196
+f 3205 3106 3109
+f 3109 3196 3205
+f 3211 3104 3106
+f 3106 3205 3211
+f 3215 3102 3104
+f 3104 3211 3215
+f 3217 3101 3102
+f 3102 3215 3217
+f 3220 3098 3101
+f 3101 3217 3220
+f 3222 3097 3098
+f 3098 3220 3222
+f 3223 3095 3097
+f 3097 3222 3223
+f 3227 3186 3182
+f 3182 3225 3227
+f 3229 3192 3186
+f 3186 3227 3229
+f 3231 3196 3192
+f 3192 3229 3231
+f 3233 3205 3196
+f 3196 3231 3233
+f 3235 3211 3205
+f 3205 3233 3235
+f 3241 3215 3211
+f 3211 3235 3241
+f 3245 3217 3215
+f 3215 3241 3245
+f 3249 3220 3217
+f 3217 3245 3249
+f 3251 3222 3220
+f 3220 3249 3251
+f 3253 3223 3222
+f 3222 3251 3253
+f 3239 3227 3225
+f 3225 3237 3239
+f 3243 3229 3227
+f 3227 3239 3243
+f 3247 3231 3229
+f 3229 3243 3247
+f 3257 3233 3231
+f 3231 3247 3257
+f 3263 3235 3233
+f 3233 3257 3263
+f 3271 3241 3235
+f 3235 3263 3271
+f 3279 3245 3241
+f 3241 3271 3279
+f 3285 3249 3245
+f 3245 3279 3285
+f 3293 3251 3249
+f 3249 3285 3293
+f 3297 3253 3251
+f 3251 3293 3297
+f 3259 3239 3237
+f 3237 3255 3259
+f 3261 3243 3239
+f 3239 3259 3261
+f 3265 3247 3243
+f 3243 3261 3265
+f 3275 3257 3247
+f 3247 3265 3275
+f 3287 3263 3257
+f 3257 3275 3287
+f 3303 3271 3263
+f 3263 3287 3303
+f 3314 3279 3271
+f 3271 3303 3314
+f 3320 3285 3279
+f 3279 3314 3320
+f 3330 3293 3285
+f 3285 3320 3330
+f 3332 3297 3293
+f 3293 3330 3332
+f 3270 3259 3255
+f 3255 3268 3270
+f 3273 3261 3259
+f 3259 3270 3273
+f 3283 3265 3261
+f 3261 3273 3283
+f 3299 3275 3265
+f 3265 3283 3299
+f 3308 3287 3275
+f 3275 3299 3308
+f 3322 3303 3287
+f 3287 3308 3322
+f 3338 3314 3303
+f 3303 3322 3338
+f 3346 3320 3314
+f 3314 3338 3346
+f 3351 3330 3320
+f 3320 3346 3351
+f 3355 3332 3330
+f 3330 3351 3355
+f 3282 3270 3268
+f 3268 3278 3282
+f 3290 3273 3270
+f 3270 3282 3290
+f 3302 3283 3273
+f 3273 3290 3302
+f 3312 3299 3283
+f 3283 3302 3312
+f 3324 3308 3299
+f 3299 3312 3324
+f 3340 3322 3308
+f 3308 3324 3340
+f 3353 3338 3322
+f 3322 3340 3353
+f 3368 3346 3338
+f 3338 3353 3368
+f 3373 3351 3346
+f 3346 3368 3373
+f 3379 3355 3351
+f 3351 3373 3379
+f 3295 3282 3278
+f 3278 3292 3295
+f 3306 3290 3282
+f 3282 3295 3306
+f 3316 3302 3290
+f 3290 3306 3316
+f 3326 3312 3302
+f 3302 3316 3326
+f 3345 3324 3312
+f 3312 3326 3345
+f 3359 3340 3324
+f 3324 3345 3359
+f 3376 3353 3340
+f 3340 3359 3376
+f 3394 3368 3353
+f 3353 3376 3394
+f 3404 3373 3368
+f 3368 3394 3404
+f 3406 3379 3373
+f 3373 3404 3406
+f 3310 3295 3292
+f 3292 3307 3310
+f 3318 3306 3295
+f 3295 3310 3318
+f 3336 3316 3306
+f 3306 3318 3336
+f 3348 3326 3316
+f 3316 3336 3348
+f 3369 3345 3326
+f 3326 3348 3369
+f 3389 3359 3345
+f 3345 3369 3389
+f 3425 3376 3359
+f 3359 3389 3425
+f 3449 3394 3376
+f 3376 3425 3449
+f 3468 3404 3394
+f 3394 3449 3468
+f 3472 3406 3404
+f 3404 3468 3472
+f 3335 3310 3307
+f 3307 3329 3335
+f 3343 3318 3310
+f 3310 3335 3343
+f 3362 3336 3318
+f 3318 3343 3362
+f 3386 3348 3336
+f 3336 3362 3386
+f 3422 3369 3348
+f 3348 3386 3422
+f 3464 3389 3369
+f 3369 3422 3464
+f 3490 3425 3389
+f 3389 3464 3490
+f 3505 3449 3425
+f 3425 3490 3505
+f 3521 3468 3449
+f 3449 3505 3521
+f 3523 3472 3468
+f 3468 3521 3523
+f 3364 3335 3329
+f 3329 3357 3364
+f 3382 3343 3335
+f 3335 3364 3382
+f 3416 3362 3343
+f 3343 3382 3416
+f 3465 3386 3362
+f 3362 3416 3465
+f 3495 3422 3386
+f 3386 3465 3495
+f 3528 3464 3422
+f 3422 3495 3528
+f 3553 3490 3464
+f 3464 3528 3553
+f 3579 3505 3490
+f 3490 3553 3579
+f 3592 3521 3505
+f 3505 3579 3592
+f 3604 3523 3521
+f 3521 3592 3604
+f 3221 3096 3094
+f 3094 3224 3221
+f 3219 3099 3096
+f 3096 3221 3219
+f 3218 3100 3099
+f 3099 3219 3218
+f 3216 3103 3100
+f 3100 3218 3216
+f 3212 3105 3103
+f 3103 3216 3212
+f 3206 3107 3105
+f 3105 3212 3206
+f 3197 3108 3107
+f 3107 3206 3197
+f 3193 3111 3108
+f 3108 3197 3193
+f 3187 3112 3111
+f 3111 3193 3187
+f 3183 3114 3112
+f 3112 3187 3183
+f 3252 3221 3224
+f 3224 3254 3252
+f 3250 3219 3221
+f 3221 3252 3250
+f 3246 3218 3219
+f 3219 3250 3246
+f 3242 3216 3218
+f 3218 3246 3242
+f 3236 3212 3216
+f 3216 3242 3236
+f 3234 3206 3212
+f 3212 3236 3234
+f 3232 3197 3206
+f 3206 3234 3232
+f 3230 3193 3197
+f 3197 3232 3230
+f 3228 3187 3193
+f 3193 3230 3228
+f 3226 3183 3187
+f 3187 3228 3226
+f 3294 3252 3254
+f 3254 3298 3294
+f 3286 3250 3252
+f 3252 3294 3286
+f 3280 3246 3250
+f 3250 3286 3280
+f 3272 3242 3246
+f 3246 3280 3272
+f 3264 3236 3242
+f 3242 3272 3264
+f 3258 3234 3236
+f 3236 3264 3258
+f 3248 3232 3234
+f 3234 3258 3248
+f 3244 3230 3232
+f 3232 3248 3244
+f 3240 3228 3230
+f 3230 3244 3240
+f 3238 3226 3228
+f 3228 3240 3238
+f 3331 3294 3298
+f 3298 3333 3331
+f 3321 3286 3294
+f 3294 3331 3321
+f 3315 3280 3286
+f 3286 3321 3315
+f 3304 3272 3280
+f 3280 3315 3304
+f 3288 3264 3272
+f 3272 3304 3288
+f 3276 3258 3264
+f 3264 3288 3276
+f 3266 3248 3258
+f 3258 3276 3266
+f 3262 3244 3248
+f 3248 3266 3262
+f 3260 3240 3244
+f 3244 3262 3260
+f 3256 3238 3240
+f 3240 3260 3256
+f 3350 3331 3333
+f 3333 3354 3350
+f 3347 3321 3331
+f 3331 3350 3347
+f 3339 3315 3321
+f 3321 3347 3339
+f 3323 3304 3315
+f 3315 3339 3323
+f 3309 3288 3304
+f 3304 3323 3309
+f 3300 3276 3288
+f 3288 3309 3300
+f 3284 3266 3276
+f 3276 3300 3284
+f 3274 3262 3266
+f 3266 3284 3274
+f 3269 3260 3262
+f 3262 3274 3269
+f 3267 3256 3260
+f 3260 3269 3267
+f 3372 3350 3354
+f 3354 3378 3372
+f 3367 3347 3350
+f 3350 3372 3367
+f 3352 3339 3347
+f 3347 3367 3352
+f 3341 3323 3339
+f 3339 3352 3341
+f 3325 3309 3323
+f 3323 3341 3325
+f 3313 3300 3309
+f 3309 3325 3313
+f 3301 3284 3300
+f 3300 3313 3301
+f 3289 3274 3284
+f 3284 3301 3289
+f 3281 3269 3274
+f 3274 3289 3281
+f 3277 3267 3269
+f 3269 3281 3277
+f 3403 3372 3378
+f 3378 3405 3403
+f 3393 3367 3372
+f 3372 3403 3393
+f 3377 3352 3367
+f 3367 3393 3377
+f 3360 3341 3352
+f 3352 3377 3360
+f 3344 3325 3341
+f 3341 3360 3344
+f 3327 3313 3325
+f 3325 3344 3327
+f 3317 3301 3313
+f 3313 3327 3317
+f 3305 3289 3301
+f 3301 3317 3305
+f 3296 3281 3289
+f 3289 3305 3296
+f 3291 3277 3281
+f 3281 3296 3291
+f 3469 3403 3405
+f 3405 3472 3469
+f 3450 3393 3403
+f 3403 3469 3450
+f 3426 3377 3393
+f 3393 3450 3426
+f 3390 3360 3377
+f 3377 3426 3390
+f 3370 3344 3360
+f 3360 3390 3370
+f 3349 3327 3344
+f 3344 3370 3349
+f 3337 3317 3327
+f 3327 3349 3337
+f 3319 3305 3317
+f 3317 3337 3319
+f 3311 3296 3305
+f 3305 3319 3311
+f 3307 3291 3296
+f 3296 3311 3307
+f 3520 3469 3472
+f 3472 3522 3520
+f 3504 3450 3469
+f 3469 3520 3504
+f 3489 3426 3450
+f 3450 3504 3489
+f 3463 3390 3426
+f 3426 3489 3463
+f 3421 3370 3390
+f 3390 3463 3421
+f 3385 3349 3370
+f 3370 3421 3385
+f 3361 3337 3349
+f 3349 3385 3361
+f 3342 3319 3337
+f 3337 3361 3342
+f 3334 3311 3319
+f 3319 3342 3334
+f 3328 3307 3311
+f 3311 3334 3328
+f 3591 3520 3522
+f 3522 3603 3591
+f 3578 3504 3520
+f 3520 3591 3578
+f 3552 3489 3504
+f 3504 3578 3552
+f 3530 3463 3489
+f 3489 3552 3530
+f 3499 3421 3463
+f 3463 3530 3499
+f 3467 3385 3421
+f 3421 3499 3467
+f 3415 3361 3385
+f 3385 3467 3415
+f 3381 3342 3361
+f 3361 3415 3381
+f 3363 3334 3342
+f 3342 3381 3363
+f 3356 3328 3334
+f 3334 3363 3356
+f 3374 3365 3358
+f 3358 3371 3374
+f 3395 3383 3365
+f 3365 3374 3395
+f 3443 3417 3383
+f 3383 3395 3443
+f 3481 3466 3417
+f 3417 3443 3481
+f 3514 3496 3466
+f 3466 3481 3514
+f 3545 3529 3496
+f 3496 3514 3545
+f 3573 3551 3529
+f 3529 3545 3573
+f 3597 3577 3551
+f 3551 3573 3597
+f 3613 3590 3577
+f 3577 3597 3613
+f 3619 3603 3590
+f 3590 3613 3619
+f 3387 3374 3371
+f 3371 3380 3387
+f 3413 3395 3374
+f 3374 3387 3413
+f 3461 3443 3395
+f 3395 3413 3461
+f 3493 3481 3443
+f 3443 3461 3493
+f 3524 3514 3481
+f 3481 3493 3524
+f 3556 3545 3514
+f 3514 3524 3556
+f 3584 3573 3545
+f 3545 3556 3584
+f 3611 3597 3573
+f 3573 3584 3611
+f 3628 3613 3597
+f 3597 3611 3628
+f 3632 3619 3613
+f 3613 3628 3632
+f 3398 3387 3380
+f 3380 3391 3398
+f 3435 3413 3387
+f 3387 3398 3435
+f 3473 3461 3413
+f 3413 3435 3473
+f 3500 3493 3461
+f 3461 3473 3500
+f 3531 3524 3493
+f 3493 3500 3531
+f 3562 3556 3524
+f 3524 3531 3562
+f 3595 3584 3556
+f 3556 3562 3595
+f 3617 3611 3584
+f 3584 3595 3617
+f 3633 3628 3611
+f 3611 3617 3633
+f 3641 3632 3628
+f 3628 3633 3641
+f 3409 3398 3391
+f 3391 3400 3409
+f 3447 3435 3398
+f 3398 3409 3447
+f 3477 3473 3435
+f 3435 3447 3477
+f 3506 3500 3473
+f 3473 3477 3506
+f 3540 3531 3500
+f 3500 3506 3540
+f 3567 3562 3531
+f 3531 3540 3567
+f 3601 3595 3562
+f 3562 3567 3601
+f 3624 3617 3595
+f 3595 3601 3624
+f 3639 3633 3617
+f 3617 3624 3639
+f 3644 3641 3633
+f 3633 3639 3644
+f 3433 3409 3400
+f 3400 3411 3433
+f 3453 3447 3409
+f 3409 3433 3453
+f 3483 3477 3447
+f 3447 3453 3483
+f 3510 3506 3477
+f 3477 3483 3510
+f 3543 3540 3506
+f 3506 3510 3543
+f 3569 3567 3540
+f 3540 3543 3569
+f 3599 3601 3567
+f 3567 3569 3599
+f 3622 3624 3601
+f 3601 3599 3622
+f 3637 3639 3624
+f 3624 3622 3637
+f 3642 3644 3639
+f 3639 3637 3642
+f 3439 3433 3411
+f 3411 3424 3439
+f 3458 3453 3433
+f 3433 3439 3458
+f 3487 3483 3453
+f 3453 3458 3487
+f 3513 3510 3483
+f 3483 3487 3513
+f 3542 3543 3510
+f 3510 3513 3542
+f 3566 3569 3543
+f 3543 3542 3566
+f 3593 3599 3569
+f 3569 3566 3593
+f 3616 3622 3599
+f 3599 3593 3616
+f 3630 3637 3622
+f 3622 3616 3630
+f 3636 3642 3637
+f 3637 3630 3636
+f 3441 3439 3424
+f 3424 3429 3441
+f 3459 3458 3439
+f 3439 3441 3459
+f 3485 3487 3458
+f 3458 3459 3485
+f 3508 3513 3487
+f 3487 3485 3508
+f 3533 3542 3513
+f 3513 3508 3533
+f 3558 3566 3542
+f 3542 3533 3558
+f 3582 3593 3566
+f 3566 3558 3582
+f 3607 3616 3593
+f 3593 3582 3607
+f 3620 3630 3616
+f 3616 3607 3620
+f 3626 3636 3630
+f 3630 3620 3626
+f 3437 3441 3429
+f 3429 3427 3437
+f 3455 3459 3441
+f 3441 3437 3455
+f 3479 3485 3459
+f 3459 3455 3479
+f 3502 3508 3485
+f 3485 3479 3502
+f 3526 3533 3508
+f 3508 3502 3526
+f 3547 3558 3533
+f 3533 3526 3547
+f 3571 3582 3558
+f 3558 3547 3571
+f 3588 3607 3582
+f 3582 3571 3588
+f 3605 3620 3607
+f 3607 3588 3605
+f 3609 3626 3620
+f 3620 3605 3609
+f 3419 3437 3427
+f 3427 3408 3419
+f 3445 3455 3437
+f 3437 3419 3445
+f 3470 3479 3455
+f 3455 3445 3470
+f 3492 3502 3479
+f 3479 3470 3492
+f 3517 3526 3502
+f 3502 3492 3517
+f 3536 3547 3526
+f 3526 3517 3536
+f 3554 3571 3547
+f 3547 3536 3554
+f 3575 3588 3571
+f 3571 3554 3575
+f 3580 3605 3588
+f 3588 3575 3580
+f 3587 3609 3605
+f 3605 3580 3587
+f 3401 3419 3408
+f 3408 3397 3401
+f 3431 3445 3419
+f 3419 3401 3431
+f 3451 3470 3445
+f 3445 3431 3451
+f 3475 3492 3470
+f 3470 3451 3475
+f 3497 3517 3492
+f 3492 3475 3497
+f 3518 3536 3517
+f 3517 3497 3518
+f 3537 3554 3536
+f 3536 3518 3537
+f 3549 3575 3554
+f 3554 3537 3549
+f 3560 3580 3575
+f 3575 3549 3560
+f 3564 3587 3580
+f 3580 3560 3564
+f 3614 3591 3603
+f 3603 3619 3614
+f 3598 3578 3591
+f 3591 3614 3598
+f 3574 3552 3578
+f 3578 3598 3574
+f 3546 3530 3552
+f 3552 3574 3546
+f 3515 3499 3530
+f 3530 3546 3515
+f 3482 3467 3499
+f 3499 3515 3482
+f 3444 3418 3467
+f 3467 3482 3444
+f 3396 3384 3418
+f 3418 3444 3396
+f 3375 3366 3384
+f 3384 3396 3375
+f 3371 3358 3366
+f 3366 3375 3371
+f 3629 3614 3619
+f 3619 3632 3629
+f 3612 3598 3614
+f 3614 3629 3612
+f 3585 3574 3598
+f 3598 3612 3585
+f 3557 3546 3574
+f 3574 3585 3557
+f 3525 3515 3546
+f 3546 3557 3525
+f 3494 3482 3515
+f 3515 3525 3494
+f 3462 3444 3482
+f 3482 3494 3462
+f 3414 3396 3444
+f 3444 3462 3414
+f 3388 3375 3396
+f 3396 3414 3388
+f 3380 3371 3375
+f 3375 3388 3380
+f 3634 3629 3632
+f 3632 3641 3634
+f 3618 3612 3629
+f 3629 3634 3618
+f 3596 3585 3612
+f 3612 3618 3596
+f 3563 3557 3585
+f 3585 3596 3563
+f 3532 3525 3557
+f 3557 3563 3532
+f 3501 3494 3525
+f 3525 3532 3501
+f 3474 3462 3494
+f 3494 3501 3474
+f 3436 3414 3462
+f 3462 3474 3436
+f 3399 3388 3414
+f 3414 3436 3399
+f 3392 3380 3388
+f 3388 3399 3392
+f 3640 3634 3641
+f 3641 3644 3640
+f 3625 3618 3634
+f 3634 3640 3625
+f 3602 3596 3618
+f 3618 3625 3602
+f 3568 3563 3596
+f 3596 3602 3568
+f 3539 3532 3563
+f 3563 3568 3539
+f 3507 3501 3532
+f 3532 3539 3507
+f 3478 3474 3501
+f 3501 3507 3478
+f 3448 3436 3474
+f 3474 3478 3448
+f 3410 3399 3436
+f 3436 3448 3410
+f 3400 3392 3399
+f 3399 3410 3400
+f 3638 3640 3644
+f 3644 3643 3638
+f 3623 3625 3640
+f 3640 3638 3623
+f 3600 3602 3625
+f 3625 3623 3600
+f 3570 3568 3602
+f 3602 3600 3570
+f 3544 3539 3568
+f 3568 3570 3544
+f 3511 3507 3539
+f 3539 3544 3511
+f 3484 3478 3507
+f 3507 3511 3484
+f 3454 3448 3478
+f 3478 3484 3454
+f 3434 3410 3448
+f 3448 3454 3434
+f 3412 3400 3410
+f 3410 3434 3412
+f 3631 3638 3643
+f 3643 3635 3631
+f 3615 3623 3638
+f 3638 3631 3615
+f 3594 3600 3623
+f 3623 3615 3594
+f 3565 3570 3600
+f 3600 3594 3565
+f 3541 3544 3570
+f 3570 3565 3541
+f 3512 3511 3544
+f 3544 3541 3512
+f 3488 3484 3511
+f 3511 3512 3488
+f 3457 3454 3484
+f 3484 3488 3457
+f 3440 3434 3454
+f 3454 3457 3440
+f 3423 3412 3434
+f 3434 3440 3423
+f 3621 3631 3635
+f 3635 3627 3621
+f 3608 3615 3631
+f 3631 3621 3608
+f 3583 3594 3615
+f 3615 3608 3583
+f 3559 3565 3594
+f 3594 3583 3559
+f 3534 3541 3565
+f 3565 3559 3534
+f 3509 3512 3541
+f 3541 3534 3509
+f 3486 3488 3512
+f 3512 3509 3486
+f 3460 3457 3488
+f 3488 3486 3460
+f 3442 3440 3457
+f 3457 3460 3442
+f 3430 3423 3440
+f 3440 3442 3430
+f 3606 3621 3627
+f 3627 3610 3606
+f 3589 3608 3621
+f 3621 3606 3589
+f 3572 3583 3608
+f 3608 3589 3572
+f 3548 3559 3583
+f 3583 3572 3548
+f 3527 3534 3559
+f 3559 3548 3527
+f 3503 3509 3534
+f 3534 3527 3503
+f 3480 3486 3509
+f 3509 3503 3480
+f 3456 3460 3486
+f 3486 3480 3456
+f 3438 3442 3460
+f 3460 3456 3438
+f 3428 3430 3442
+f 3442 3438 3428
+f 3581 3606 3610
+f 3610 3586 3581
+f 3576 3589 3606
+f 3606 3581 3576
+f 3555 3572 3589
+f 3589 3576 3555
+f 3535 3548 3572
+f 3572 3555 3535
+f 3516 3527 3548
+f 3548 3535 3516
+f 3491 3503 3527
+f 3527 3516 3491
+f 3471 3480 3503
+f 3503 3491 3471
+f 3446 3456 3480
+f 3480 3471 3446
+f 3420 3438 3456
+f 3456 3446 3420
+f 3407 3428 3438
+f 3438 3420 3407
+f 3561 3581 3586
+f 3586 3564 3561
+f 3550 3576 3581
+f 3581 3561 3550
+f 3538 3555 3576
+f 3576 3550 3538
+f 3519 3535 3555
+f 3555 3538 3519
+f 3498 3516 3535
+f 3535 3519 3498
+f 3476 3491 3516
+f 3516 3498 3476
+f 3452 3471 3491
+f 3491 3476 3452
+f 3432 3446 3471
+f 3471 3452 3432
+f 3402 3420 3446
+f 3446 3432 3402
+f 3397 3407 3420
+f 3420 3402 3397
+f 1888 2110 2104
+f 1888 2104 2096
+f 1888 2096 2076
+f 1888 2076 2048
+f 1888 2048 2030
+f 1888 2030 2006
+f 1888 2006 1982
+f 1888 1982 1960
+f 1888 1960 1936
+f 1888 1936 1732
+f 2257 2104 2110
+f 2110 2261 2257
+f 2249 2096 2104
+f 2104 2257 2249
+f 2226 2076 2096
+f 2096 2249 2226
+f 2200 2048 2076
+f 2076 2226 2200
+f 2142 2030 2048
+f 2048 2200 2142
+f 2094 2006 2030
+f 2030 2142 2094
+f 2036 1982 2006
+f 2006 2094 2036
+f 1988 1960 1982
+f 1982 2036 1988
+f 1948 1936 1960
+f 1960 1988 1948
+f 1728 1732 1936
+f 1936 1948 1728
+f 2310 2257 2261
+f 2261 2315 2310
+f 2300 2249 2257
+f 2257 2310 2300
+f 2279 2226 2249
+f 2249 2300 2279
+f 2243 2200 2226
+f 2226 2279 2243
+f 2204 2142 2200
+f 2200 2243 2204
+f 2132 2094 2142
+f 2142 2204 2132
+f 2067 2036 2094
+f 2094 2132 2067
+f 2000 1988 2036
+f 2036 2067 2000
+f 1956 1948 1988
+f 1988 2000 1956
+f 1734 1728 1948
+f 1948 1956 1734
+f 2312 2310 2315
+f 2315 2316 2312
+f 2302 2300 2310
+f 2310 2312 2302
+f 2281 2279 2300
+f 2300 2302 2281
+f 2245 2243 2279
+f 2279 2281 2245
+f 2206 2204 2243
+f 2243 2245 2206
+f 2134 2132 2204
+f 2204 2206 2134
+f 2068 2067 2132
+f 2132 2134 2068
+f 2002 2000 2067
+f 2067 2068 2002
+f 1958 1956 2000
+f 2000 2002 1958
+f 1878 1734 1956
+f 1956 1958 1878
+f 2285 2312 2316
+f 2316 2289 2285
+f 2259 2302 2312
+f 2312 2285 2259
+f 2241 2281 2302
+f 2302 2259 2241
+f 2214 2245 2281
+f 2281 2241 2214
+f 2168 2206 2245
+f 2245 2214 2168
+f 2106 2134 2206
+f 2206 2168 2106
+f 2042 2068 2134
+f 2134 2106 2042
+f 1994 2002 2068
+f 2068 2042 1994
+f 1952 1958 2002
+f 2002 1994 1952
+f 1731 1878 1958
+f 1958 1952 1731
+f 2220 2285 2289
+f 2289 2225 2220
+f 2210 2259 2285
+f 2285 2220 2210
+f 2186 2241 2259
+f 2259 2210 2186
+f 2146 2214 2241
+f 2241 2186 2146
+f 2108 2168 2214
+f 2214 2146 2108
+f 2060 2106 2168
+f 2168 2108 2060
+f 2018 2042 2106
+f 2106 2060 2018
+f 1978 1994 2042
+f 2042 2018 1978
+f 1944 1952 1994
+f 1994 1978 1944
+f 1727 1731 1952
+f 1952 1944 1727
+f 2141 2220 2225
+f 2225 2145 2141
+f 2127 2210 2220
+f 2220 2141 2127
+f 2112 2186 2210
+f 2210 2127 2112
+f 2084 2146 2186
+f 2186 2112 2084
+f 2044 2108 2146
+f 2146 2084 2044
+f 2024 2060 2108
+f 2108 2044 2024
+f 1992 2018 2060
+f 2060 2024 1992
+f 1970 1978 2018
+f 2018 1992 1970
+f 1942 1944 1978
+f 1978 1970 1942
+f 1721 1727 1944
+f 1944 1942 1721
+f 2079 2141 2145
+f 2145 2087 2079
+f 2075 2127 2141
+f 2141 2079 2075
+f 2055 2112 2127
+f 2127 2075 2055
+f 2039 2084 2112
+f 2112 2055 2039
+f 2021 2044 2084
+f 2084 2039 2021
+f 1996 2024 2044
+f 2044 2021 1996
+f 1974 1992 2024
+f 2024 1996 1974
+f 1954 1970 1992
+f 1992 1974 1954
+f 1934 1942 1970
+f 1970 1954 1934
+f 1720 1721 1942
+f 1942 1934 1720
+f 2063 2079 2087
+f 2087 2071 2063
+f 2051 2075 2079
+f 2079 2063 2051
+f 2041 2055 2075
+f 2075 2051 2041
+f 2029 2039 2055
+f 2055 2041 2029
+f 2013 2021 2039
+f 2039 2029 2013
+f 1991 1996 2021
+f 2021 2013 1991
+f 1972 1974 1996
+f 1996 1991 1972
+f 1950 1954 1974
+f 1974 1972 1950
+f 1932 1934 1954
+f 1954 1950 1932
+f 1701 1720 1934
+f 1934 1932 1701
+f 2115 2063 2071
+f 2071 2123 2115
+f 2101 2051 2063
+f 2063 2115 2101
+f 2081 2041 2051
+f 2051 2101 2081
+f 2057 2029 2041
+f 2041 2081 2057
+f 2033 2013 2029
+f 2029 2057 2033
+f 2009 1991 2013
+f 2013 2033 2009
+f 1984 1972 1991
+f 1991 2009 1984
+f 1964 1950 1972
+f 1972 1984 1964
+f 1938 1932 1950
+f 1950 1964 1938
+f 1698 1701 1932
+f 1932 1938 1698
+f 1888 1886 1686
+f 1888 1686 1662
+f 1888 1662 1640
+f 1888 1640 1616
+f 1888 1616 1592
+f 1888 1592 1574
+f 1888 1574 1546
+f 1888 1546 1526
+f 1888 1526 1518
+f 1888 1518 1512
+f 1674 1686 1886
+f 1886 1884 1674
+f 1634 1662 1686
+f 1686 1674 1634
+f 1586 1640 1662
+f 1662 1634 1586
+f 1528 1616 1640
+f 1640 1586 1528
+f 1480 1592 1616
+f 1616 1528 1480
+f 1422 1574 1592
+f 1592 1480 1422
+f 1396 1546 1574
+f 1574 1422 1396
+f 1373 1526 1546
+f 1546 1396 1373
+f 1365 1518 1526
+f 1526 1373 1365
+f 1361 1512 1518
+f 1518 1365 1361
+f 1666 1674 1884
+f 1884 1882 1666
+f 1622 1634 1674
+f 1674 1666 1622
+f 1557 1586 1634
+f 1634 1622 1557
+f 1490 1528 1586
+f 1586 1557 1490
+f 1418 1480 1528
+f 1528 1490 1418
+f 1379 1422 1480
+f 1480 1418 1379
+f 1343 1396 1422
+f 1422 1379 1343
+f 1322 1373 1396
+f 1396 1343 1322
+f 1312 1365 1373
+f 1373 1322 1312
+f 1309 1361 1365
+f 1365 1312 1309
+f 1664 1666 1882
+f 1882 1879 1664
+f 1620 1622 1666
+f 1666 1664 1620
+f 1554 1557 1622
+f 1622 1620 1554
+f 1488 1490 1557
+f 1557 1554 1488
+f 1416 1418 1490
+f 1490 1488 1416
+f 1377 1379 1418
+f 1418 1416 1377
+f 1341 1343 1379
+f 1379 1377 1341
+f 1320 1322 1343
+f 1343 1341 1320
+f 1310 1312 1322
+f 1322 1320 1310
+f 1306 1309 1312
+f 1312 1310 1306
+f 1670 1664 1879
+f 1879 1876 1670
+f 1628 1620 1664
+f 1664 1670 1628
+f 1580 1554 1620
+f 1620 1628 1580
+f 1516 1488 1554
+f 1554 1580 1516
+f 1454 1416 1488
+f 1488 1516 1454
+f 1408 1377 1416
+f 1416 1454 1408
+f 1381 1341 1377
+f 1377 1408 1381
+f 1363 1320 1341
+f 1341 1381 1363
+f 1337 1310 1320
+f 1320 1363 1337
+f 1333 1306 1310
+f 1310 1337 1333
+f 1678 1670 1876
+f 1876 1874 1678
+f 1644 1628 1670
+f 1670 1678 1644
+f 1604 1580 1628
+f 1628 1644 1604
+f 1562 1516 1580
+f 1580 1604 1562
+f 1514 1454 1516
+f 1516 1562 1514
+f 1476 1408 1454
+f 1454 1514 1476
+f 1436 1381 1408
+f 1408 1476 1436
+f 1412 1363 1381
+f 1381 1436 1412
+f 1402 1337 1363
+f 1363 1412 1402
+f 1399 1333 1337
+f 1337 1402 1399
+f 1680 1678 1874
+f 1874 1872 1680
+f 1652 1644 1678
+f 1678 1680 1652
+f 1630 1604 1644
+f 1644 1652 1630
+f 1598 1562 1604
+f 1604 1630 1598
+f 1578 1514 1562
+f 1562 1598 1578
+f 1538 1476 1514
+f 1514 1578 1538
+f 1510 1436 1476
+f 1476 1538 1510
+f 1497 1412 1436
+f 1436 1510 1497
+f 1483 1402 1412
+f 1412 1497 1483
+f 1479 1399 1402
+f 1402 1483 1479
+f 1688 1680 1872
+f 1872 1870 1688
+f 1668 1652 1680
+f 1680 1688 1668
+f 1648 1630 1652
+f 1652 1668 1648
+f 1626 1598 1630
+f 1630 1648 1626
+f 1603 1578 1598
+f 1598 1626 1603
+f 1585 1538 1578
+f 1578 1603 1585
+f 1569 1510 1538
+f 1538 1585 1569
+f 1549 1497 1510
+f 1510 1569 1549
+f 1545 1483 1497
+f 1497 1549 1545
+f 1537 1479 1483
+f 1483 1545 1537
+f 1690 1688 1870
+f 1870 1868 1690
+f 1672 1668 1688
+f 1688 1690 1672
+f 1650 1648 1668
+f 1668 1672 1650
+f 1633 1626 1648
+f 1648 1650 1633
+f 1611 1603 1626
+f 1626 1633 1611
+f 1595 1585 1603
+f 1603 1611 1595
+f 1583 1569 1585
+f 1585 1595 1583
+f 1573 1549 1569
+f 1569 1583 1573
+f 1561 1545 1549
+f 1549 1573 1561
+f 1553 1537 1545
+f 1545 1561 1553
+f 1684 1690 1868
+f 1868 1865 1684
+f 1658 1672 1690
+f 1690 1684 1658
+f 1638 1650 1672
+f 1672 1658 1638
+f 1615 1633 1650
+f 1650 1638 1615
+f 1591 1611 1633
+f 1633 1615 1591
+f 1567 1595 1611
+f 1611 1591 1567
+f 1543 1583 1595
+f 1595 1567 1543
+f 1523 1573 1583
+f 1583 1543 1523
+f 1509 1561 1573
+f 1573 1523 1509
+f 1501 1553 1561
+f 1561 1509 1501
+f 1888 1513 1519
+f 1888 1519 1527
+f 1888 1527 1547
+f 1888 1547 1575
+f 1888 1575 1593
+f 1888 1593 1617
+f 1888 1617 1641
+f 1888 1641 1663
+f 1888 1663 1687
+f 1888 1687 1894
+f 1366 1519 1513
+f 1513 1362 1366
+f 1374 1527 1519
+f 1519 1366 1374
+f 1397 1547 1527
+f 1527 1374 1397
+f 1423 1575 1547
+f 1547 1397 1423
+f 1481 1593 1575
+f 1575 1423 1481
+f 1529 1617 1593
+f 1593 1481 1529
+f 1587 1641 1617
+f 1617 1529 1587
+f 1635 1663 1641
+f 1641 1587 1635
+f 1675 1687 1663
+f 1663 1635 1675
+f 1895 1894 1687
+f 1687 1675 1895
+f 1313 1366 1362
+f 1362 1308 1313
+f 1323 1374 1366
+f 1366 1313 1323
+f 1344 1397 1374
+f 1374 1323 1344
+f 1380 1423 1397
+f 1397 1344 1380
+f 1419 1481 1423
+f 1423 1380 1419
+f 1491 1529 1481
+f 1481 1419 1491
+f 1556 1587 1529
+f 1529 1491 1556
+f 1623 1635 1587
+f 1587 1556 1623
+f 1667 1675 1635
+f 1635 1623 1667
+f 1890 1895 1675
+f 1675 1667 1890
+f 1311 1313 1308
+f 1308 1307 1311
+f 1321 1323 1313
+f 1313 1311 1321
+f 1342 1344 1323
+f 1323 1321 1342
+f 1378 1380 1344
+f 1344 1342 1378
+f 1417 1419 1380
+f 1380 1378 1417
+f 1489 1491 1419
+f 1419 1417 1489
+f 1555 1556 1491
+f 1491 1489 1555
+f 1621 1623 1556
+f 1556 1555 1621
+f 1665 1667 1623
+f 1623 1621 1665
+f 1881 1890 1667
+f 1667 1665 1881
+f 1338 1311 1307
+f 1307 1334 1338
+f 1364 1321 1311
+f 1311 1338 1364
+f 1382 1342 1321
+f 1321 1364 1382
+f 1409 1378 1342
+f 1342 1382 1409
+f 1455 1417 1378
+f 1378 1409 1455
+f 1517 1489 1417
+f 1417 1455 1517
+f 1581 1555 1489
+f 1489 1517 1581
+f 1629 1621 1555
+f 1555 1581 1629
+f 1671 1665 1621
+f 1621 1629 1671
+f 1893 1881 1665
+f 1665 1671 1893
+f 1403 1338 1334
+f 1334 1398 1403
+f 1413 1364 1338
+f 1338 1403 1413
+f 1437 1382 1364
+f 1364 1413 1437
+f 1477 1409 1382
+f 1382 1437 1477
+f 1515 1455 1409
+f 1409 1477 1515
+f 1563 1517 1455
+f 1455 1515 1563
+f 1605 1581 1517
+f 1517 1563 1605
+f 1645 1629 1581
+f 1581 1605 1645
+f 1679 1671 1629
+f 1629 1645 1679
+f 1900 1893 1671
+f 1671 1679 1900
+f 1482 1403 1398
+f 1398 1478 1482
+f 1496 1413 1403
+f 1403 1482 1496
+f 1511 1437 1413
+f 1413 1496 1511
+f 1539 1477 1437
+f 1437 1511 1539
+f 1579 1515 1477
+f 1477 1539 1579
+f 1599 1563 1515
+f 1515 1579 1599
+f 1631 1605 1563
+f 1563 1599 1631
+f 1653 1645 1605
+f 1605 1631 1653
+f 1681 1679 1645
+f 1645 1653 1681
+f 1902 1900 1679
+f 1679 1681 1902
+f 1544 1482 1478
+f 1478 1536 1544
+f 1548 1496 1482
+f 1482 1544 1548
+f 1568 1511 1496
+f 1496 1548 1568
+f 1584 1539 1511
+f 1511 1568 1584
+f 1602 1579 1539
+f 1539 1584 1602
+f 1627 1599 1579
+f 1579 1602 1627
+f 1649 1631 1599
+f 1599 1627 1649
+f 1669 1653 1631
+f 1631 1649 1669
+f 1689 1681 1653
+f 1653 1669 1689
+f 1921 1902 1681
+f 1681 1689 1921
+f 1560 1544 1536
+f 1536 1552 1560
+f 1572 1548 1544
+f 1544 1560 1572
+f 1582 1568 1548
+f 1548 1572 1582
+f 1594 1584 1568
+f 1568 1582 1594
+f 1610 1602 1584
+f 1584 1594 1610
+f 1632 1627 1602
+f 1602 1610 1632
+f 1651 1649 1627
+f 1627 1632 1651
+f 1673 1669 1649
+f 1649 1651 1673
+f 1691 1689 1669
+f 1669 1673 1691
+f 1922 1921 1689
+f 1689 1691 1922
+f 1508 1560 1552
+f 1552 1500 1508
+f 1522 1572 1560
+f 1560 1508 1522
+f 1542 1582 1572
+f 1572 1522 1542
+f 1566 1594 1582
+f 1582 1542 1566
+f 1590 1610 1594
+f 1594 1566 1590
+f 1614 1632 1610
+f 1610 1590 1614
+f 1639 1651 1632
+f 1632 1614 1639
+f 1659 1673 1651
+f 1651 1639 1659
+f 1685 1691 1673
+f 1673 1659 1685
+f 1928 1922 1691
+f 1691 1685 1928
+f 1888 1887 1937
+f 1888 1937 1961
+f 1888 1961 1983
+f 1888 1983 2007
+f 1888 2007 2031
+f 1888 2031 2049
+f 1888 2049 2077
+f 1888 2077 2097
+f 1888 2097 2105
+f 1888 2105 2111
+f 1949 1937 1887
+f 1887 1885 1949
+f 1989 1961 1937
+f 1937 1949 1989
+f 2037 1983 1961
+f 1961 1989 2037
+f 2095 2007 1983
+f 1983 2037 2095
+f 2143 2031 2007
+f 2007 2095 2143
+f 2201 2049 2031
+f 2031 2143 2201
+f 2227 2077 2049
+f 2049 2201 2227
+f 2250 2097 2077
+f 2077 2227 2250
+f 2258 2105 2097
+f 2097 2250 2258
+f 2262 2111 2105
+f 2105 2258 2262
+f 1957 1949 1885
+f 1885 1883 1957
+f 2001 1989 1949
+f 1949 1957 2001
+f 2066 2037 1989
+f 1989 2001 2066
+f 2133 2095 2037
+f 2037 2066 2133
+f 2205 2143 2095
+f 2095 2133 2205
+f 2244 2201 2143
+f 2143 2205 2244
+f 2280 2227 2201
+f 2201 2244 2280
+f 2301 2250 2227
+f 2227 2280 2301
+f 2311 2258 2250
+f 2250 2301 2311
+f 2314 2262 2258
+f 2258 2311 2314
+f 1959 1957 1883
+f 1883 1880 1959
+f 2003 2001 1957
+f 1957 1959 2003
+f 2069 2066 2001
+f 2001 2003 2069
+f 2135 2133 2066
+f 2066 2069 2135
+f 2207 2205 2133
+f 2133 2135 2207
+f 2246 2244 2205
+f 2205 2207 2246
+f 2282 2280 2244
+f 2244 2246 2282
+f 2303 2301 2280
+f 2280 2282 2303
+f 2313 2311 2301
+f 2301 2303 2313
+f 2317 2314 2311
+f 2311 2313 2317
+f 1953 1959 1880
+f 1880 1877 1953
+f 1995 2003 1959
+f 1959 1953 1995
+f 2043 2069 2003
+f 2003 1995 2043
+f 2107 2135 2069
+f 2069 2043 2107
+f 2169 2207 2135
+f 2135 2107 2169
+f 2215 2246 2207
+f 2207 2169 2215
+f 2242 2282 2246
+f 2246 2215 2242
+f 2260 2303 2282
+f 2282 2242 2260
+f 2286 2313 2303
+f 2303 2260 2286
+f 2290 2317 2313
+f 2313 2286 2290
+f 1945 1953 1877
+f 1877 1875 1945
+f 1979 1995 1953
+f 1953 1945 1979
+f 2019 2043 1995
+f 1995 1979 2019
+f 2061 2107 2043
+f 2043 2019 2061
+f 2109 2169 2107
+f 2107 2061 2109
+f 2147 2215 2169
+f 2169 2109 2147
+f 2187 2242 2215
+f 2215 2147 2187
+f 2211 2260 2242
+f 2242 2187 2211
+f 2221 2286 2260
+f 2260 2211 2221
+f 2224 2290 2286
+f 2286 2221 2224
+f 1943 1945 1875
+f 1875 1873 1943
+f 1971 1979 1945
+f 1945 1943 1971
+f 1993 2019 1979
+f 1979 1971 1993
+f 2025 2061 2019
+f 2019 1993 2025
+f 2045 2109 2061
+f 2061 2025 2045
+f 2085 2147 2109
+f 2109 2045 2085
+f 2113 2187 2147
+f 2147 2085 2113
+f 2126 2211 2187
+f 2187 2113 2126
+f 2140 2221 2211
+f 2211 2126 2140
+f 2144 2224 2221
+f 2221 2140 2144
+f 1935 1943 1873
+f 1873 1871 1935
+f 1955 1971 1943
+f 1943 1935 1955
+f 1975 1993 1971
+f 1971 1955 1975
+f 1997 2025 1993
+f 1993 1975 1997
+f 2020 2045 2025
+f 2025 1997 2020
+f 2038 2085 2045
+f 2045 2020 2038
+f 2054 2113 2085
+f 2085 2038 2054
+f 2074 2126 2113
+f 2113 2054 2074
+f 2078 2140 2126
+f 2126 2074 2078
+f 2086 2144 2140
+f 2140 2078 2086
+f 1933 1935 1871
+f 1871 1869 1933
+f 1951 1955 1935
+f 1935 1933 1951
+f 1973 1975 1955
+f 1955 1951 1973
+f 1990 1997 1975
+f 1975 1973 1990
+f 2012 2020 1997
+f 1997 1990 2012
+f 2028 2038 2020
+f 2020 2012 2028
+f 2040 2054 2038
+f 2038 2028 2040
+f 2050 2074 2054
+f 2054 2040 2050
+f 2062 2078 2074
+f 2074 2050 2062
+f 2070 2086 2078
+f 2078 2062 2070
+f 1939 1933 1869
+f 1869 1866 1939
+f 1965 1951 1933
+f 1933 1939 1965
+f 1985 1973 1951
+f 1951 1965 1985
+f 2008 1990 1973
+f 1973 1985 2008
+f 2032 2012 1990
+f 1990 2008 2032
+f 2056 2028 2012
+f 2012 2032 2056
+f 2080 2040 2028
+f 2028 2056 2080
+f 2100 2050 2040
+f 2040 2080 2100
+f 2114 2062 2050
+f 2050 2100 2114
+f 2122 2070 2062
+f 2062 2114 2122
+f 2232 2116 2124
+f 2124 2236 2232
+f 2218 2102 2116
+f 2116 2232 2218
+f 2199 2082 2102
+f 2102 2218 2199
+f 2150 2058 2082
+f 2082 2199 2150
+f 2120 2034 2058
+f 2058 2150 2120
+f 2064 2010 2034
+f 2034 2120 2064
+f 2023 1986 2010
+f 2010 2064 2023
+f 1980 1966 1986
+f 1986 2023 1980
+f 1946 1940 1966
+f 1966 1980 1946
+f 1862 1730 1940
+f 1940 1946 1862
+f 2332 2232 2236
+f 2236 2336 2332
+f 2322 2218 2232
+f 2232 2332 2322
+f 2306 2199 2218
+f 2218 2322 2306
+f 2275 2150 2199
+f 2199 2306 2275
+f 2234 2120 2150
+f 2150 2275 2234
+f 2170 2064 2120
+f 2120 2234 2170
+f 2093 2023 2064
+f 2064 2170 2093
+f 2016 1980 2023
+f 2023 2093 2016
+f 1968 1946 1980
+f 1980 2016 1968
+f 1858 1862 1946
+f 1946 1968 1858
+f 2409 2332 2336
+f 2336 2413 2409
+f 2400 2322 2332
+f 2332 2409 2400
+f 2376 2306 2322
+f 2322 2400 2376
+f 2349 2275 2306
+f 2306 2376 2349
+f 2324 2234 2275
+f 2275 2349 2324
+f 2271 2170 2234
+f 2234 2324 2271
+f 2185 2093 2170
+f 2170 2271 2185
+f 2072 2016 2093
+f 2093 2185 2072
+f 1976 1968 2016
+f 2016 2072 1976
+f 1729 1858 1968
+f 1968 1976 1729
+f 2488 2409 2413
+f 2413 2498 2488
+f 2470 2400 2409
+f 2409 2488 2470
+f 2444 2376 2400
+f 2400 2470 2444
+f 2418 2349 2376
+f 2376 2444 2418
+f 2384 2324 2349
+f 2349 2418 2384
+f 2338 2271 2324
+f 2324 2384 2338
+f 2269 2185 2271
+f 2271 2338 2269
+f 2138 2072 2185
+f 2185 2269 2138
+f 1998 1976 2072
+f 2072 2138 1998
+f 1722 1729 1976
+f 1976 1998 1722
+f 2559 2488 2498
+f 2498 2569 2559
+f 2549 2470 2488
+f 2488 2559 2549
+f 2531 2444 2470
+f 2470 2549 2531
+f 2492 2418 2444
+f 2444 2531 2492
+f 2436 2384 2418
+f 2418 2492 2436
+f 2394 2338 2384
+f 2384 2436 2394
+f 2326 2269 2338
+f 2338 2394 2326
+f 2212 2138 2269
+f 2269 2326 2212
+f 2026 1998 2138
+f 2138 2212 2026
+f 1850 1722 1998
+f 1998 2026 1850
+f 2653 2559 2569
+f 2569 2655 2653
+f 2631 2549 2559
+f 2559 2653 2631
+f 2593 2531 2549
+f 2549 2631 2593
+f 2551 2492 2531
+f 2531 2593 2551
+f 2510 2436 2492
+f 2492 2551 2510
+f 2432 2394 2436
+f 2436 2510 2432
+f 2366 2326 2394
+f 2394 2432 2366
+f 2263 2212 2326
+f 2326 2366 2263
+f 2052 2026 2212
+f 2212 2263 2052
+f 1726 1850 2026
+f 2026 2052 1726
+f 2720 2653 2655
+f 2655 2726 2720
+f 2697 2631 2653
+f 2653 2720 2697
+f 2662 2593 2631
+f 2631 2697 2662
+f 2607 2551 2593
+f 2593 2662 2607
+f 2547 2510 2551
+f 2551 2607 2547
+f 2484 2432 2510
+f 2510 2547 2484
+f 2405 2366 2432
+f 2432 2484 2405
+f 2308 2263 2366
+f 2366 2405 2308
+f 2090 2052 2263
+f 2263 2308 2090
+f 1719 1726 2052
+f 2052 2090 1719
+f 2787 2720 2726
+f 2726 2795 2787
+f 2759 2697 2720
+f 2720 2787 2759
+f 2713 2662 2697
+f 2697 2759 2713
+f 2657 2607 2662
+f 2662 2713 2657
+f 2589 2547 2607
+f 2607 2657 2589
+f 2525 2484 2547
+f 2547 2589 2525
+f 2422 2405 2484
+f 2484 2525 2422
+f 2330 2308 2405
+f 2405 2422 2330
+f 2118 2090 2308
+f 2308 2330 2118
+f 1700 1719 2090
+f 2090 2118 1700
+f 2834 2787 2795
+f 2795 2844 2834
+f 2798 2759 2787
+f 2787 2834 2798
+f 2750 2713 2759
+f 2759 2798 2750
+f 2690 2657 2713
+f 2713 2750 2690
+f 2624 2589 2657
+f 2657 2690 2624
+f 2536 2525 2589
+f 2589 2624 2536
+f 2441 2422 2525
+f 2525 2536 2441
+f 2340 2330 2422
+f 2422 2441 2340
+f 2128 2118 2330
+f 2330 2340 2128
+f 1825 1700 2118
+f 2118 2128 1825
+f 2847 2834 2844
+f 2844 2857 2847
+f 2821 2798 2834
+f 2834 2847 2821
+f 2765 2750 2798
+f 2798 2821 2765
+f 2703 2690 2750
+f 2750 2765 2703
+f 2637 2624 2690
+f 2690 2703 2637
+f 2543 2536 2624
+f 2624 2637 2543
+f 2446 2441 2536
+f 2536 2543 2446
+f 2344 2340 2441
+f 2441 2446 2344
+f 2136 2128 2340
+f 2340 2344 2136
+f 1713 1825 2128
+f 2128 2136 1713
+f 1676 1682 1864
+f 1864 1862 1676
+f 1642 1656 1682
+f 1682 1676 1642
+f 1601 1636 1656
+f 1656 1642 1601
+f 1558 1612 1636
+f 1636 1601 1558
+f 1502 1588 1612
+f 1612 1558 1502
+f 1472 1564 1588
+f 1588 1502 1472
+f 1425 1540 1564
+f 1564 1472 1425
+f 1404 1520 1540
+f 1540 1425 1404
+f 1390 1506 1520
+f 1520 1404 1390
+f 1387 1498 1506
+f 1506 1390 1387
+f 1654 1676 1862
+f 1862 1859 1654
+f 1606 1642 1676
+f 1676 1654 1606
+f 1531 1601 1642
+f 1642 1606 1531
+f 1452 1558 1601
+f 1601 1531 1452
+f 1388 1502 1558
+f 1558 1452 1388
+f 1347 1472 1502
+f 1502 1388 1347
+f 1316 1425 1472
+f 1472 1347 1316
+f 1300 1404 1425
+f 1425 1316 1300
+f 1290 1390 1404
+f 1404 1300 1290
+f 1286 1387 1390
+f 1390 1290 1286
+f 1646 1654 1859
+f 1859 1856 1646
+f 1550 1606 1654
+f 1654 1646 1550
+f 1439 1531 1606
+f 1606 1550 1439
+f 1351 1452 1531
+f 1531 1439 1351
+f 1298 1388 1452
+f 1452 1351 1298
+f 1275 1347 1388
+f 1388 1298 1275
+f 1246 1316 1347
+f 1347 1275 1246
+f 1222 1300 1316
+f 1316 1246 1222
+f 1215 1290 1300
+f 1300 1222 1215
+f 1211 1286 1290
+f 1290 1215 1211
+f 1624 1646 1856
+f 1856 1854 1624
+f 1484 1550 1646
+f 1646 1624 1484
+f 1353 1439 1550
+f 1550 1484 1353
+f 1284 1351 1439
+f 1439 1353 1284
+f 1238 1298 1351
+f 1351 1284 1238
+f 1204 1275 1298
+f 1298 1238 1204
+f 1178 1246 1275
+f 1275 1204 1178
+f 1152 1222 1246
+f 1246 1178 1152
+f 1134 1215 1222
+f 1222 1152 1134
+f 1124 1211 1215
+f 1215 1134 1124
+f 1596 1624 1854
+f 1854 1851 1596
+f 1410 1484 1624
+f 1624 1596 1410
+f 1296 1353 1484
+f 1484 1410 1296
+f 1228 1284 1353
+f 1353 1296 1228
+f 1186 1238 1284
+f 1284 1228 1186
+f 1130 1204 1238
+f 1238 1186 1130
+f 1091 1178 1204
+f 1204 1130 1091
+f 1073 1152 1178
+f 1178 1091 1073
+f 1063 1134 1152
+f 1152 1073 1063
+f 1053 1124 1134
+f 1134 1063 1053
+f 1570 1596 1851
+f 1851 1848 1570
+f 1359 1410 1596
+f 1596 1570 1359
+f 1256 1296 1410
+f 1410 1359 1256
+f 1190 1228 1296
+f 1296 1256 1190
+f 1112 1186 1228
+f 1228 1190 1112
+f 1071 1130 1186
+f 1186 1112 1071
+f 1029 1091 1130
+f 1130 1071 1029
+f 991 1073 1091
+f 1091 1029 991
+f 969 1063 1073
+f 1073 991 969
+f 967 1053 1063
+f 1063 969 967
+f 1532 1570 1848
+f 1848 1846 1532
+f 1314 1359 1570
+f 1570 1532 1314
+f 1219 1256 1359
+f 1359 1314 1219
+f 1138 1190 1256
+f 1256 1219 1138
+f 1075 1112 1190
+f 1190 1138 1075
+f 1015 1071 1112
+f 1112 1075 1015
+f 962 1029 1071
+f 1071 1015 962
+f 925 991 1029
+f 1029 962 925
+f 904 969 991
+f 991 925 904
+f 898 967 969
+f 969 904 898
+f 1504 1532 1846
+f 1846 1832 1504
+f 1292 1314 1532
+f 1532 1504 1292
+f 1200 1219 1314
+f 1314 1292 1200
+f 1097 1138 1219
+f 1219 1200 1097
+f 1033 1075 1138
+f 1138 1097 1033
+f 965 1015 1075
+f 1075 1033 965
+f 909 962 1015
+f 1015 965 909
+f 863 925 962
+f 962 909 863
+f 835 904 925
+f 925 863 835
+f 827 898 904
+f 904 835 827
+f 1494 1504 1832
+f 1832 1824 1494
+f 1282 1292 1504
+f 1504 1494 1282
+f 1183 1200 1292
+f 1292 1282 1183
+f 1088 1097 1200
+f 1200 1183 1088
+f 1000 1033 1097
+f 1097 1088 1000
+f 934 965 1033
+f 1033 1000 934
+f 874 909 965
+f 965 934 874
+f 826 863 909
+f 909 874 826
+f 790 835 863
+f 863 826 790
+f 780 827 835
+f 835 790 780
+f 1486 1494 1824
+f 1824 1814 1486
+f 1278 1282 1494
+f 1494 1486 1278
+f 1176 1183 1282
+f 1282 1278 1176
+f 1079 1088 1183
+f 1183 1176 1079
+f 985 1000 1088
+f 1088 1079 985
+f 919 934 1000
+f 1000 985 919
+f 857 874 934
+f 934 919 857
+f 801 826 874
+f 874 857 801
+f 775 790 826
+f 826 801 775
+f 765 780 790
+f 790 775 765
+f 1391 1507 1499
+f 1499 1387 1391
+f 1405 1521 1507
+f 1507 1391 1405
+f 1424 1541 1521
+f 1521 1405 1424
+f 1473 1565 1541
+f 1541 1424 1473
+f 1503 1589 1565
+f 1565 1473 1503
+f 1559 1613 1589
+f 1589 1503 1559
+f 1600 1637 1613
+f 1613 1559 1600
+f 1643 1657 1637
+f 1637 1600 1643
+f 1677 1683 1657
+f 1657 1643 1677
+f 1863 1892 1683
+f 1683 1677 1863
+f 1291 1391 1387
+f 1387 1287 1291
+f 1301 1405 1391
+f 1391 1291 1301
+f 1317 1424 1405
+f 1405 1301 1317
+f 1348 1473 1424
+f 1424 1317 1348
+f 1389 1503 1473
+f 1473 1348 1389
+f 1453 1559 1503
+f 1503 1389 1453
+f 1530 1600 1559
+f 1559 1453 1530
+f 1607 1643 1600
+f 1600 1530 1607
+f 1655 1677 1643
+f 1643 1607 1655
+f 1861 1863 1677
+f 1677 1655 1861
+f 1214 1291 1287
+f 1287 1210 1214
+f 1223 1301 1291
+f 1291 1214 1223
+f 1247 1317 1301
+f 1301 1223 1247
+f 1274 1348 1317
+f 1317 1247 1274
+f 1299 1389 1348
+f 1348 1274 1299
+f 1352 1453 1389
+f 1389 1299 1352
+f 1438 1530 1453
+f 1453 1352 1438
+f 1551 1607 1530
+f 1530 1438 1551
+f 1647 1655 1607
+f 1607 1551 1647
+f 1891 1861 1655
+f 1655 1647 1891
+f 1135 1214 1210
+f 1210 1125 1135
+f 1153 1223 1214
+f 1214 1135 1153
+f 1179 1247 1223
+f 1223 1153 1179
+f 1205 1274 1247
+f 1247 1179 1205
+f 1239 1299 1274
+f 1274 1205 1239
+f 1285 1352 1299
+f 1299 1239 1285
+f 1354 1438 1352
+f 1352 1285 1354
+f 1485 1551 1438
+f 1438 1354 1485
+f 1625 1647 1551
+f 1551 1485 1625
+f 1901 1891 1647
+f 1647 1625 1901
+f 1064 1135 1125
+f 1125 1054 1064
+f 1074 1153 1135
+f 1135 1064 1074
+f 1092 1179 1153
+f 1153 1074 1092
+f 1131 1205 1179
+f 1179 1092 1131
+f 1187 1239 1205
+f 1205 1131 1187
+f 1229 1285 1239
+f 1239 1187 1229
+f 1297 1354 1285
+f 1285 1229 1297
+f 1411 1485 1354
+f 1354 1297 1411
+f 1597 1625 1485
+f 1485 1411 1597
+f 1853 1901 1625
+f 1625 1597 1853
+f 970 1064 1054
+f 1054 968 970
+f 992 1074 1064
+f 1064 970 992
+f 1030 1092 1074
+f 1074 992 1030
+f 1072 1131 1092
+f 1092 1030 1072
+f 1113 1187 1131
+f 1131 1072 1113
+f 1191 1229 1187
+f 1187 1113 1191
+f 1257 1297 1229
+f 1229 1191 1257
+f 1360 1411 1297
+f 1297 1257 1360
+f 1571 1597 1411
+f 1411 1360 1571
+f 1899 1853 1597
+f 1597 1571 1899
+f 903 970 968
+f 968 897 903
+f 926 992 970
+f 970 903 926
+f 961 1030 992
+f 992 926 961
+f 1016 1072 1030
+f 1030 961 1016
+f 1076 1113 1072
+f 1072 1016 1076
+f 1139 1191 1113
+f 1113 1076 1139
+f 1218 1257 1191
+f 1191 1139 1218
+f 1315 1360 1257
+f 1257 1218 1315
+f 1533 1571 1360
+f 1360 1315 1533
+f 1920 1899 1571
+f 1571 1533 1920
+f 836 903 897
+f 897 828 836
+f 864 926 903
+f 903 836 864
+f 910 961 926
+f 926 864 910
+f 966 1016 961
+f 961 910 966
+f 1034 1076 1016
+f 1016 966 1034
+f 1098 1139 1076
+f 1076 1034 1098
+f 1201 1218 1139
+f 1139 1098 1201
+f 1293 1315 1218
+f 1218 1201 1293
+f 1505 1533 1315
+f 1315 1293 1505
+f 1924 1920 1533
+f 1533 1505 1924
+f 789 836 828
+f 828 779 789
+f 825 864 836
+f 836 789 825
+f 873 910 864
+f 864 825 873
+f 933 966 910
+f 910 873 933
+f 999 1034 966
+f 966 933 999
+f 1087 1098 1034
+f 1034 999 1087
+f 1182 1201 1098
+f 1098 1087 1182
+f 1283 1293 1201
+f 1201 1182 1283
+f 1495 1505 1293
+f 1293 1283 1495
+f 1826 1924 1505
+f 1505 1495 1826
+f 776 789 779
+f 779 766 776
+f 802 825 789
+f 789 776 802
+f 858 873 825
+f 825 802 858
+f 920 933 873
+f 873 858 920
+f 986 999 933
+f 933 920 986
+f 1080 1087 999
+f 999 986 1080
+f 1177 1182 1087
+f 1087 1080 1177
+f 1279 1283 1182
+f 1182 1177 1279
+f 1487 1495 1283
+f 1283 1279 1487
+f 1914 1826 1495
+f 1495 1487 1914
+f 1947 1941 1867
+f 1867 1863 1947
+f 1981 1967 1941
+f 1941 1947 1981
+f 2022 1987 1967
+f 1967 1981 2022
+f 2065 2011 1987
+f 1987 2022 2065
+f 2121 2035 2011
+f 2011 2065 2121
+f 2151 2059 2035
+f 2035 2121 2151
+f 2198 2083 2059
+f 2059 2151 2198
+f 2219 2103 2083
+f 2083 2198 2219
+f 2233 2117 2103
+f 2103 2219 2233
+f 2236 2125 2117
+f 2117 2233 2236
+f 1969 1947 1863
+f 1863 1860 1969
+f 2017 1981 1947
+f 1947 1969 2017
+f 2092 2022 1981
+f 1981 2017 2092
+f 2171 2065 2022
+f 2022 2092 2171
+f 2235 2121 2065
+f 2065 2171 2235
+f 2276 2151 2121
+f 2121 2235 2276
+f 2307 2198 2151
+f 2151 2276 2307
+f 2323 2219 2198
+f 2198 2307 2323
+f 2333 2233 2219
+f 2219 2323 2333
+f 2337 2236 2233
+f 2233 2333 2337
+f 1977 1969 1860
+f 1860 1857 1977
+f 2073 2017 1969
+f 1969 1977 2073
+f 2184 2092 2017
+f 2017 2073 2184
+f 2272 2171 2092
+f 2092 2184 2272
+f 2325 2235 2171
+f 2171 2272 2325
+f 2348 2276 2235
+f 2235 2325 2348
+f 2377 2307 2276
+f 2276 2348 2377
+f 2401 2323 2307
+f 2307 2377 2401
+f 2408 2333 2323
+f 2323 2401 2408
+f 2412 2337 2333
+f 2333 2408 2412
+f 1999 1977 1857
+f 1857 1855 1999
+f 2139 2073 1977
+f 1977 1999 2139
+f 2270 2184 2073
+f 2073 2139 2270
+f 2339 2272 2184
+f 2184 2270 2339
+f 2385 2325 2272
+f 2272 2339 2385
+f 2419 2348 2325
+f 2325 2385 2419
+f 2445 2377 2348
+f 2348 2419 2445
+f 2471 2401 2377
+f 2377 2445 2471
+f 2489 2408 2401
+f 2401 2471 2489
+f 2499 2412 2408
+f 2408 2489 2499
+f 2027 1999 1855
+f 1855 1852 2027
+f 2213 2139 1999
+f 1999 2027 2213
+f 2327 2270 2139
+f 2139 2213 2327
+f 2395 2339 2270
+f 2270 2327 2395
+f 2437 2385 2339
+f 2339 2395 2437
+f 2493 2419 2385
+f 2385 2437 2493
+f 2532 2445 2419
+f 2419 2493 2532
+f 2550 2471 2445
+f 2445 2532 2550
+f 2560 2489 2471
+f 2471 2550 2560
+f 2570 2499 2489
+f 2489 2560 2570
+f 2053 2027 1852
+f 1852 1849 2053
+f 2264 2213 2027
+f 2027 2053 2264
+f 2367 2327 2213
+f 2213 2264 2367
+f 2433 2395 2327
+f 2327 2367 2433
+f 2511 2437 2395
+f 2395 2433 2511
+f 2552 2493 2437
+f 2437 2511 2552
+f 2594 2532 2493
+f 2493 2552 2594
+f 2632 2550 2532
+f 2532 2594 2632
+f 2654 2560 2550
+f 2550 2632 2654
+f 2656 2570 2560
+f 2560 2654 2656
+f 2091 2053 1849
+f 1849 1847 2091
+f 2309 2264 2053
+f 2053 2091 2309
+f 2404 2367 2264
+f 2264 2309 2404
+f 2485 2433 2367
+f 2367 2404 2485
+f 2548 2511 2433
+f 2433 2485 2548
+f 2608 2552 2511
+f 2511 2548 2608
+f 2661 2594 2552
+f 2552 2608 2661
+f 2698 2632 2594
+f 2594 2661 2698
+f 2719 2654 2632
+f 2632 2698 2719
+f 2725 2656 2654
+f 2654 2719 2725
+f 2119 2091 1847
+f 1847 1833 2119
+f 2331 2309 2091
+f 2091 2119 2331
+f 2423 2404 2309
+f 2309 2331 2423
+f 2526 2485 2404
+f 2404 2423 2526
+f 2590 2548 2485
+f 2485 2526 2590
+f 2658 2608 2548
+f 2548 2590 2658
+f 2714 2661 2608
+f 2608 2658 2714
+f 2760 2698 2661
+f 2661 2714 2760
+f 2788 2719 2698
+f 2698 2760 2788
+f 2796 2725 2719
+f 2719 2788 2796
+f 2129 2119 1833
+f 1833 1827 2129
+f 2341 2331 2119
+f 2119 2129 2341
+f 2440 2423 2331
+f 2331 2341 2440
+f 2535 2526 2423
+f 2423 2440 2535
+f 2623 2590 2526
+f 2526 2535 2623
+f 2689 2658 2590
+f 2590 2623 2689
+f 2749 2714 2658
+f 2658 2689 2749
+f 2797 2760 2714
+f 2714 2749 2797
+f 2833 2788 2760
+f 2760 2797 2833
+f 2843 2796 2788
+f 2788 2833 2843
+f 2137 2129 1827
+f 1827 1815 2137
+f 2345 2341 2129
+f 2129 2137 2345
+f 2447 2440 2341
+f 2341 2345 2447
+f 2544 2535 2440
+f 2440 2447 2544
+f 2638 2623 2535
+f 2535 2544 2638
+f 2704 2689 2623
+f 2623 2638 2704
+f 2766 2749 2689
+f 2689 2704 2766
+f 2822 2797 2749
+f 2749 2766 2822
+f 2848 2833 2797
+f 2797 2822 2848
+f 2858 2843 2833
+f 2833 2848 2858
+f 1735 2334 2329
+f 1735 2329 2321
+f 1735 2321 2305
+f 1735 2305 2274
+f 1735 2274 2231
+f 1735 2231 2167
+f 1735 2167 2089
+f 1735 2089 2014
+f 1735 2014 1962
+f 1735 1962 1733
+f 2515 2329 2334
+f 2334 2524 2515
+f 2495 2321 2329
+f 2329 2515 2495
+f 2456 2305 2321
+f 2321 2495 2456
+f 2429 2274 2305
+f 2305 2456 2429
+f 2399 2231 2274
+f 2274 2429 2399
+f 2347 2167 2231
+f 2231 2399 2347
+f 2292 2089 2167
+f 2167 2347 2292
+f 2148 2014 2089
+f 2089 2292 2148
+f 2004 1962 2014
+f 2014 2148 2004
+f 1739 1733 1962
+f 1962 2004 1739
+f 2647 2515 2524
+f 2524 2649 2647
+f 2621 2495 2515
+f 2515 2647 2621
+f 2584 2456 2495
+f 2495 2621 2584
+f 2541 2429 2456
+f 2456 2584 2541
+f 2502 2399 2429
+f 2429 2541 2502
+f 2426 2347 2399
+f 2399 2502 2426
+f 2352 2292 2347
+f 2347 2426 2352
+f 2255 2148 2292
+f 2292 2352 2255
+f 2046 2004 2148
+f 2148 2255 2046
+f 1702 1739 2004
+f 2004 2046 1702
+f 2746 2647 2649
+f 2649 2757 2746
+f 2721 2621 2647
+f 2647 2746 2721
+f 2681 2584 2621
+f 2621 2721 2681
+f 2639 2541 2584
+f 2584 2681 2639
+f 2557 2502 2541
+f 2541 2639 2557
+f 2505 2426 2502
+f 2502 2557 2505
+f 2415 2352 2426
+f 2426 2505 2415
+f 2318 2255 2352
+f 2352 2415 2318
+f 2098 2046 2255
+f 2255 2318 2098
+f 1745 1702 2046
+f 2046 2098 1745
+f 2840 2746 2757
+f 2757 2849 2840
+f 2808 2721 2746
+f 2746 2840 2808
+f 2756 2681 2721
+f 2721 2808 2756
+f 2696 2639 2681
+f 2681 2756 2696
+f 2626 2557 2639
+f 2639 2696 2626
+f 2538 2505 2557
+f 2557 2626 2538
+f 2443 2415 2505
+f 2505 2538 2443
+f 2342 2318 2415
+f 2415 2443 2342
+f 2131 2098 2318
+f 2318 2342 2131
+f 1904 1745 2098
+f 2098 2131 1904
+f 2906 2840 2849
+f 2849 2925 2906
+f 2867 2808 2840
+f 2840 2906 2867
+f 2818 2756 2808
+f 2808 2867 2818
+f 2736 2696 2756
+f 2756 2818 2736
+f 2667 2626 2696
+f 2696 2736 2667
+f 2565 2538 2626
+f 2626 2667 2565
+f 2475 2443 2538
+f 2538 2565 2475
+f 2356 2342 2443
+f 2443 2475 2356
+f 2156 2131 2342
+f 2342 2356 2156
+f 1704 1904 2131
+f 2131 2156 1704
+f 2976 2906 2925
+f 2925 2987 2976
+f 2914 2867 2906
+f 2906 2976 2914
+f 2852 2818 2867
+f 2867 2914 2852
+f 2772 2736 2818
+f 2818 2852 2772
+f 2688 2667 2736
+f 2736 2772 2688
+f 2592 2565 2667
+f 2667 2688 2592
+f 2497 2475 2565
+f 2565 2592 2497
+f 2372 2356 2475
+f 2475 2497 2372
+f 2176 2156 2356
+f 2356 2372 2176
+f 1752 1704 2156
+f 2156 2176 1752
+f 2993 2976 2987
+f 2987 3011 2993
+f 2952 2914 2976
+f 2976 2993 2952
+f 2874 2852 2914
+f 2914 2952 2874
+f 2794 2772 2852
+f 2852 2874 2794
+f 2702 2688 2772
+f 2772 2794 2702
+f 2604 2592 2688
+f 2688 2702 2604
+f 2509 2497 2592
+f 2592 2604 2509
+f 2380 2372 2497
+f 2497 2509 2380
+f 2182 2176 2372
+f 2372 2380 2182
+f 1723 1752 2176
+f 2176 2182 1723
+f 3000 2993 3011
+f 3011 3020 3000
+f 2967 2952 2993
+f 2993 3000 2967
+f 2879 2874 2952
+f 2952 2967 2879
+f 2799 2794 2874
+f 2874 2879 2799
+f 2707 2702 2794
+f 2794 2799 2707
+f 2605 2604 2702
+f 2702 2707 2605
+f 2512 2509 2604
+f 2604 2605 2512
+f 2382 2380 2509
+f 2509 2512 2382
+f 2188 2182 2380
+f 2380 2382 2188
+f 1699 1723 2182
+f 2182 2188 1699
+f 3006 3000 3020
+f 3020 3022 3006
+f 2972 2967 3000
+f 3000 3006 2972
+f 2888 2879 2967
+f 2967 2972 2888
+f 2804 2799 2879
+f 2879 2888 2804
+f 2710 2707 2799
+f 2799 2804 2710
+f 2613 2605 2707
+f 2707 2710 2613
+f 2520 2512 2605
+f 2605 2613 2520
+f 2388 2382 2512
+f 2512 2520 2388
+f 2192 2188 2382
+f 2382 2388 2192
+f 1760 1699 2188
+f 2188 2192 1760
+f 1735 1737 1660
+f 1735 1660 1608
+f 1735 1608 1535
+f 1735 1535 1457
+f 1735 1457 1393
+f 1735 1393 1350
+f 1735 1350 1319
+f 1735 1319 1303
+f 1735 1303 1295
+f 1735 1295 1288
+f 1618 1660 1737
+f 1737 1739 1618
+f 1474 1608 1660
+f 1660 1618 1474
+f 1332 1535 1608
+f 1608 1474 1332
+f 1277 1457 1535
+f 1535 1332 1277
+f 1225 1393 1457
+f 1457 1277 1225
+f 1195 1350 1393
+f 1393 1225 1195
+f 1166 1319 1350
+f 1350 1195 1166
+f 1129 1303 1319
+f 1319 1166 1129
+f 1109 1295 1303
+f 1303 1129 1109
+f 1099 1288 1295
+f 1295 1109 1099
+f 1576 1618 1739
+f 1739 1741 1576
+f 1367 1474 1618
+f 1618 1576 1367
+f 1270 1332 1474
+f 1474 1367 1270
+f 1196 1277 1332
+f 1332 1270 1196
+f 1120 1225 1277
+f 1277 1196 1120
+f 1081 1195 1225
+f 1225 1120 1081
+f 1040 1166 1195
+f 1195 1081 1040
+f 1001 1129 1166
+f 1166 1040 1001
+f 975 1109 1129
+f 1129 1001 975
+f 973 1099 1109
+f 1109 975 973
+f 1524 1576 1741
+f 1741 1744 1524
+f 1304 1367 1576
+f 1576 1524 1304
+f 1209 1270 1367
+f 1367 1304 1209
+f 1119 1196 1270
+f 1270 1209 1119
+f 1065 1120 1196
+f 1196 1119 1065
+f 983 1081 1120
+f 1120 1065 983
+f 941 1040 1081
+f 1081 983 941
+f 901 1001 1040
+f 1040 941 901
+f 878 975 1001
+f 1001 901 878
+f 865 973 975
+f 975 878 865
+f 1493 1524 1744
+f 1744 1747 1493
+f 1280 1304 1524
+f 1524 1493 1280
+f 1181 1209 1304
+f 1304 1280 1181
+f 1086 1119 1209
+f 1209 1181 1086
+f 998 1065 1119
+f 1119 1086 998
+f 928 983 1065
+f 1065 998 928
+f 868 941 983
+f 983 928 868
+f 816 901 941
+f 941 868 816
+f 784 878 901
+f 901 816 784
+f 773 865 878
+f 878 784 773
+f 1466 1493 1747
+f 1747 1749 1466
+f 1266 1280 1493
+f 1493 1466 1266
+f 1149 1181 1280
+f 1280 1266 1149
+f 1057 1086 1181
+f 1181 1149 1057
+f 955 998 1086
+f 1086 1057 955
+f 888 928 998
+f 998 955 888
+f 806 868 928
+f 928 888 806
+f 755 816 868
+f 868 806 755
+f 718 784 816
+f 816 755 718
+f 697 773 784
+f 784 718 697
+f 1446 1466 1749
+f 1749 1753 1446
+f 1250 1266 1466
+f 1466 1446 1250
+f 1127 1149 1266
+f 1266 1250 1127
+f 1032 1057 1149
+f 1149 1127 1032
+f 936 955 1057
+f 1057 1032 936
+f 852 888 955
+f 955 936 852
+f 772 806 888
+f 888 852 772
+f 710 755 806
+f 806 772 710
+f 648 718 755
+f 755 710 648
+f 637 697 718
+f 718 648 637
+f 1440 1446 1753
+f 1753 1755 1440
+f 1242 1250 1446
+f 1446 1440 1242
+f 1115 1127 1250
+f 1250 1242 1115
+f 1020 1032 1127
+f 1127 1115 1020
+f 922 936 1032
+f 1032 1020 922
+f 830 852 936
+f 936 922 830
+f 750 772 852
+f 852 830 750
+f 672 710 772
+f 772 750 672
+f 631 648 710
+f 710 672 631
+f 613 637 648
+f 648 631 613
+f 1434 1440 1755
+f 1755 1757 1434
+f 1240 1242 1440
+f 1440 1434 1240
+f 1110 1115 1242
+f 1242 1240 1110
+f 1017 1020 1115
+f 1115 1110 1017
+f 915 922 1020
+f 1020 1017 915
+f 823 830 922
+f 922 915 823
+f 743 750 830
+f 830 823 743
+f 655 672 750
+f 750 743 655
+f 622 631 672
+f 672 655 622
+f 602 613 631
+f 631 622 602
+f 1428 1434 1757
+f 1757 1760 1428
+f 1232 1240 1434
+f 1434 1428 1232
+f 1105 1110 1240
+f 1240 1232 1105
+f 1010 1017 1110
+f 1110 1105 1010
+f 913 915 1017
+f 1017 1010 913
+f 821 823 915
+f 915 913 821
+f 736 743 823
+f 823 821 736
+f 652 655 743
+f 743 736 652
+f 619 622 655
+f 655 652 619
+f 601 602 622
+f 622 619 601
+f 1735 1289 1294
+f 1735 1294 1302
+f 1735 1302 1318
+f 1735 1318 1349
+f 1735 1349 1392
+f 1735 1392 1456
+f 1735 1456 1534
+f 1735 1534 1609
+f 1735 1609 1661
+f 1735 1661 1889
+f 1108 1294 1289
+f 1289 1099 1108
+f 1128 1302 1294
+f 1294 1108 1128
+f 1167 1318 1302
+f 1302 1128 1167
+f 1194 1349 1318
+f 1318 1167 1194
+f 1224 1392 1349
+f 1349 1194 1224
+f 1276 1456 1392
+f 1392 1224 1276
+f 1331 1534 1456
+f 1456 1276 1331
+f 1475 1609 1534
+f 1534 1331 1475
+f 1619 1661 1609
+f 1609 1475 1619
+f 1738 1889 1661
+f 1661 1619 1738
+f 976 1108 1099
+f 1099 974 976
+f 1002 1128 1108
+f 1108 976 1002
+f 1039 1167 1128
+f 1128 1002 1039
+f 1082 1194 1167
+f 1167 1039 1082
+f 1121 1224 1194
+f 1194 1082 1121
+f 1197 1276 1224
+f 1224 1121 1197
+f 1271 1331 1276
+f 1276 1197 1271
+f 1368 1475 1331
+f 1331 1271 1368
+f 1577 1619 1475
+f 1475 1368 1577
+f 1903 1738 1619
+f 1619 1577 1903
+f 877 976 974
+f 974 866 877
+f 902 1002 976
+f 976 877 902
+f 942 1039 1002
+f 1002 902 942
+f 984 1082 1039
+f 1039 942 984
+f 1066 1121 1082
+f 1082 984 1066
+f 1118 1197 1121
+f 1121 1066 1118
+f 1208 1271 1197
+f 1197 1118 1208
+f 1305 1368 1271
+f 1271 1208 1305
+f 1525 1577 1368
+f 1368 1305 1525
+f 1742 1903 1577
+f 1577 1525 1742
+f 783 877 866
+f 866 774 783
+f 815 902 877
+f 877 783 815
+f 867 942 902
+f 902 815 867
+f 927 984 942
+f 942 867 927
+f 997 1066 984
+f 984 927 997
+f 1085 1118 1066
+f 1066 997 1085
+f 1180 1208 1118
+f 1118 1085 1180
+f 1281 1305 1208
+f 1208 1180 1281
+f 1492 1525 1305
+f 1305 1281 1492
+f 1703 1742 1525
+f 1525 1492 1703
+f 717 783 774
+f 774 698 717
+f 756 815 783
+f 783 717 756
+f 805 867 815
+f 815 756 805
+f 887 927 867
+f 867 805 887
+f 956 997 927
+f 927 887 956
+f 1058 1085 997
+f 997 956 1058
+f 1148 1180 1085
+f 1085 1058 1148
+f 1267 1281 1180
+f 1180 1148 1267
+f 1467 1492 1281
+f 1281 1267 1467
+f 1905 1703 1492
+f 1492 1467 1905
+f 647 717 698
+f 698 636 647
+f 709 756 717
+f 717 647 709
+f 771 805 756
+f 756 709 771
+f 851 887 805
+f 805 771 851
+f 935 956 887
+f 887 851 935
+f 1031 1058 956
+f 956 935 1031
+f 1126 1148 1058
+f 1058 1031 1126
+f 1251 1267 1148
+f 1148 1126 1251
+f 1447 1467 1267
+f 1267 1251 1447
+f 1751 1905 1467
+f 1467 1447 1751
+f 630 647 636
+f 636 612 630
+f 671 709 647
+f 647 630 671
+f 749 771 709
+f 709 671 749
+f 829 851 771
+f 771 749 829
+f 921 935 851
+f 851 829 921
+f 1019 1031 935
+f 935 921 1019
+f 1114 1126 1031
+f 1031 1019 1114
+f 1243 1251 1126
+f 1126 1114 1243
+f 1441 1447 1251
+f 1251 1243 1441
+f 1896 1751 1447
+f 1447 1441 1896
+f 623 630 612
+f 612 603 623
+f 656 671 630
+f 630 623 656
+f 744 749 671
+f 671 656 744
+f 824 829 749
+f 749 744 824
+f 916 921 829
+f 829 824 916
+f 1018 1019 921
+f 921 916 1018
+f 1111 1114 1019
+f 1019 1018 1111
+f 1241 1243 1114
+f 1114 1111 1241
+f 1435 1441 1243
+f 1243 1241 1435
+f 1923 1896 1441
+f 1441 1435 1923
+f 617 623 603
+f 603 601 617
+f 650 656 623
+f 623 617 650
+f 734 744 656
+f 656 650 734
+f 818 824 744
+f 744 734 818
+f 912 916 824
+f 824 818 912
+f 1009 1018 916
+f 916 912 1009
+f 1102 1111 1018
+f 1018 1009 1102
+f 1235 1241 1111
+f 1111 1102 1235
+f 1431 1435 1241
+f 1241 1235 1431
+f 1759 1923 1435
+f 1435 1431 1759
+f 1735 1736 1963
+f 1735 1963 2015
+f 1735 2015 2088
+f 1735 2088 2166
+f 1735 2166 2230
+f 1735 2230 2273
+f 1735 2273 2304
+f 1735 2304 2320
+f 1735 2320 2328
+f 1735 2328 2335
+f 2005 1963 1736
+f 1736 1738 2005
+f 2149 2015 1963
+f 1963 2005 2149
+f 2291 2088 2015
+f 2015 2149 2291
+f 2346 2166 2088
+f 2088 2291 2346
+f 2398 2230 2166
+f 2166 2346 2398
+f 2428 2273 2230
+f 2230 2398 2428
+f 2457 2304 2273
+f 2273 2428 2457
+f 2494 2320 2304
+f 2304 2457 2494
+f 2514 2328 2320
+f 2320 2494 2514
+f 2524 2335 2328
+f 2328 2514 2524
+f 2047 2005 1738
+f 1738 1740 2047
+f 2256 2149 2005
+f 2005 2047 2256
+f 2353 2291 2149
+f 2149 2256 2353
+f 2427 2346 2291
+f 2291 2353 2427
+f 2503 2398 2346
+f 2346 2427 2503
+f 2542 2428 2398
+f 2398 2503 2542
+f 2583 2457 2428
+f 2428 2542 2583
+f 2622 2494 2457
+f 2457 2583 2622
+f 2648 2514 2494
+f 2494 2622 2648
+f 2650 2524 2514
+f 2514 2648 2650
+f 2099 2047 1740
+f 1740 1743 2099
+f 2319 2256 2047
+f 2047 2099 2319
+f 2414 2353 2256
+f 2256 2319 2414
+f 2504 2427 2353
+f 2353 2414 2504
+f 2558 2503 2427
+f 2427 2504 2558
+f 2640 2542 2503
+f 2503 2558 2640
+f 2682 2583 2542
+f 2542 2640 2682
+f 2722 2622 2583
+f 2583 2682 2722
+f 2745 2648 2622
+f 2622 2722 2745
+f 2758 2650 2648
+f 2648 2745 2758
+f 2130 2099 1743
+f 1743 1746 2130
+f 2343 2319 2099
+f 2099 2130 2343
+f 2442 2414 2319
+f 2319 2343 2442
+f 2537 2504 2414
+f 2414 2442 2537
+f 2625 2558 2504
+f 2504 2537 2625
+f 2695 2640 2558
+f 2558 2625 2695
+f 2755 2682 2640
+f 2640 2695 2755
+f 2807 2722 2682
+f 2682 2755 2807
+f 2839 2745 2722
+f 2722 2807 2839
+f 2850 2758 2745
+f 2745 2839 2850
+f 2157 2130 1746
+f 1746 1748 2157
+f 2357 2343 2130
+f 2130 2157 2357
+f 2474 2442 2343
+f 2343 2357 2474
+f 2566 2537 2442
+f 2442 2474 2566
+f 2668 2625 2537
+f 2537 2566 2668
+f 2735 2695 2625
+f 2625 2668 2735
+f 2817 2755 2695
+f 2695 2735 2817
+f 2868 2807 2755
+f 2755 2817 2868
+f 2905 2839 2807
+f 2807 2868 2905
+f 2926 2850 2839
+f 2839 2905 2926
+f 2177 2157 1748
+f 1748 1750 2177
+f 2373 2357 2157
+f 2157 2177 2373
+f 2496 2474 2357
+f 2357 2373 2496
+f 2591 2566 2474
+f 2474 2496 2591
+f 2687 2668 2566
+f 2566 2591 2687
+f 2771 2735 2668
+f 2668 2687 2771
+f 2851 2817 2735
+f 2735 2771 2851
+f 2913 2868 2817
+f 2817 2851 2913
+f 2975 2905 2868
+f 2868 2913 2975
+f 2986 2926 2905
+f 2905 2975 2986
+f 2183 2177 1750
+f 1750 1754 2183
+f 2381 2373 2177
+f 2177 2183 2381
+f 2508 2496 2373
+f 2373 2381 2508
+f 2603 2591 2496
+f 2496 2508 2603
+f 2701 2687 2591
+f 2591 2603 2701
+f 2793 2771 2687
+f 2687 2701 2793
+f 2873 2851 2771
+f 2771 2793 2873
+f 2951 2913 2851
+f 2851 2873 2951
+f 2992 2975 2913
+f 2913 2951 2992
+f 3010 2986 2975
+f 2975 2992 3010
+f 2189 2183 1754
+f 1754 1756 2189
+f 2383 2381 2183
+f 2183 2189 2383
+f 2513 2508 2381
+f 2381 2383 2513
+f 2606 2603 2508
+f 2508 2513 2606
+f 2708 2701 2603
+f 2603 2606 2708
+f 2800 2793 2701
+f 2701 2708 2800
+f 2880 2873 2793
+f 2793 2800 2880
+f 2968 2951 2873
+f 2873 2880 2968
+f 3001 2992 2951
+f 2951 2968 3001
+f 3021 3010 2992
+f 2992 3001 3021
+f 2195 2189 1756
+f 1756 1759 2195
+f 2390 2383 2189
+f 2189 2195 2390
+f 2517 2513 2383
+f 2383 2390 2517
+f 2612 2606 2513
+f 2513 2517 2612
+f 2709 2708 2606
+f 2606 2612 2709
+f 2801 2800 2708
+f 2708 2709 2801
+f 2886 2880 2800
+f 2800 2801 2886
+f 2970 2968 2880
+f 2880 2886 2970
+f 3004 3001 2968
+f 2968 2970 3004
+f 3022 3021 3001
+f 3001 3004 3022
diff --git a/test/data/rgc-france-ign.xyz b/test/data/rgc-france-ign.xyz
new file mode 100644
index 0000000..1e1f110
--- /dev/null
+++ b/test/data/rgc-france-ign.xyz
@@ -0,0 +1,36568 @@
+847200 6589700 187.5
+841100 6572900 189.5
+910400 6569400 741
+878700 6562800 372.5
+886800 6583700 551.5
+885600 6538700 519.5
+845100 6580700 188
+899100 6551700 930.5
+925700 6569800 956
+850600 6556400 258.5
+858900 6568500 224
+882400 6539200 466.5
+895900 6562000 661
+864800 6535800 280.5
+913800 6532100 820
+834600 6539900 182.5
+901300 6529100 673
+880600 6552500 273
+901100 6564800 776
+853000 6594200 196.5
+854600 6564500 240.5
+912400 6526900 305
+908400 6547800 987
+883800 6534500 448
+909200 6545100 921
+911200 6538000 971.5
+880400 6541800 286
+872300 6532700 223.5
+874800 6535000 231.5
+897400 6524000 670
+915800 6531500 828
+861100 6593700 201
+873700 6585000 217
+867200 6587900 207
+882400 6577300 451
+905800 6509600 484.5
+876500 6579000 236
+901200 6545400 847.5
+846700 6554400 259.5
+893700 6564700 691.5
+893400 6543200 780.5
+885900 6556800 390
+869600 6542900 285.5
+898200 6568400 716.5
+888400 6537100 683.5
+906000 6543700 882.5
+884800 6568600 379.5
+879800 6558400 401
+932700 6576000 460.5
+890800 6568900 467
+859000 6576200 208
+911300 6540400 952.5
+856600 6567000 231
+889000 6530500 577.5
+893000 6560900 721
+840200 6565800 195
+879800 6565100 379.5
+867500 6534600 256
+860500 6564200 250
+876700 6588300 214.5
+868000 6546300 299.5
+861600 6549200 276.5
+862900 6544400 288.5
+876200 6566000 255.5
+907900 6535900 410
+851300 6538200 292.5
+862500 6531900 248.5
+869900 6566700 250
+903900 6518200 397.5
+850300 6541600 296
+858500 6590500 198
+841900 6569000 191.5
+863700 6584100 206
+891600 6535500 686
+890300 6561300 570
+839900 6561400 203
+839000 6565200 173
+839600 6549500 230
+883300 6556400 334.5
+857000 6525800 178.5
+886300 6551800 437.5
+891500 6542900 553.5
+837700 6553000 201
+862900 6528200 205.5
+881100 6540400 303.5
+859100 6534800 261.5
+874500 6530000 221
+902700 6517400 665.5
+860200 6527300 186
+894800 6568200 644
+902200 6520000 635
+870400 6527000 213
+920900 6573100 1063.5
+887000 6531200 428
+907300 6508100 335
+906000 6551600 941.5
+871300 6596800 205
+907700 6531300 345.5
+859700 6597600 201
+890000 6550800 614.5
+878400 6544100 237.5
+906100 6512800 520
+892800 6535900 697
+870300 6550500 294.5
+899900 6523600 1014.5
+846700 6591400 187
+891100 6523300 390
+841300 6538800 230
+896700 6576700 525
+882600 6571400 407.5
+916100 6564300 807
+863800 6574300 215.5
+937600 6587800 1036
+841900 6536000 226
+851900 6577000 199
+889100 6564400 454.5
+891200 6547800 636.5
+896800 6572200 599.5
+866100 6552900 295.5
+837500 6558000 200.5
+845600 6567300 223.5
+874700 6559300 275
+837900 6541200 218.5
+888300 6555100 443.5
+866800 6539300 272
+856500 6554100 260.5
+872200 6529100 217.5
+843000 6546300 262
+914900 6518200 426.5
+901400 6513900 489.5
+883700 6546000 364.5
+839800 6554300 223.5
+904600 6583300 529
+903400 6522700 647.5
+851600 6526800 241
+918700 6562200 978
+933600 6583300 1086
+847500 6574900 194.5
+915200 6556800 819
+887600 6548100 519
+842100 6548500 258.5
+857100 6546800 279
+901600 6535900 914.5
+853700 6592300 192
+887600 6533600 742
+875800 6568100 251.5
+845800 6537400 268
+893000 6540200 559.5
+911400 6533200 403
+858000 6541300 284
+850700 6568800 218
+929600 6575000 1052
+845500 6573800 191.5
+914500 6523400 389.5
+912100 6524200 420
+856900 6558200 265.5
+896500 6554000 831
+861900 6600100 201.5
+902200 6542600 1003.5
+839200 6543000 228
+874100 6592700 207.5
+909600 6516800 283
+881600 6568800 450
+941600 6588900 955.5
+923000 6559500 918.5
+915100 6558100 856.5
+862200 6591200 200
+899600 6515800 601
+860300 6570700 222.5
+880800 6585600 353
+865600 6564200 245.5
+847400 6570000 205.5
+939600 6585900 605
+936200 6584500 539.5
+897000 6529600 860.5
+855300 6599200 200.5
+881200 6574400 346
+901600 6576300 660.5
+911600 6529800 335
+897200 6568700 585
+898700 6530700 597
+852400 6573700 196
+878500 6585500 229
+879200 6570700 418
+891200 6574500 465
+880000 6563200 387.5
+851900 6601900 191
+907000 6568300 813
+906100 6517800 358
+891000 6564800 552.5
+845800 6540900 285
+837300 6545100 225
+894400 6538700 670
+849700 6581400 198
+835900 6555000 197.5
+882200 6584000 431.5
+846900 6558500 239.5
+882100 6536500 417.5
+866300 6578600 216
+848000 6579800 197.5
+848800 6594300 186.5
+882600 6542600 495
+840200 6560200 214
+931900 6580100 1071.5
+919200 6543800 291
+855300 6528700 248
+938300 6582700 472.5
+841600 6580000 170.5
+908800 6534100 301
+863600 6568600 234.5
+913100 6519800 431.5
+905700 6528100 323.5
+905800 6531200 650
+867200 6567800 240.5
+844700 6542400 269
+842500 6574400 190.5
+887400 6569500 530.5
+896800 6555100 875
+891600 6524600 457
+907500 6537400 582.5
+847300 6546100 283.5
+858000 6529000 249
+841500 6536700 227.5
+858600 6580600 208.5
+865100 6597800 207
+841100 6545200 253.5
+917700 6538600 881
+893300 6550900 738.5
+939400 6577600 427.5
+876200 6542400 223.5
+874100 6544300 272
+857100 6582100 205
+905500 6514700 539.5
+911000 6516700 412.5
+899400 6533700 832
+838000 6559300 200
+847400 6594200 184.5
+924100 6564000 975
+911200 6567900 762.5
+904000 6508900 331.5
+862900 6578000 211
+911300 6525600 406
+903300 6563600 814
+851400 6566000 240
+875700 6582500 222
+916700 6554000 804
+915500 6548900 722
+851100 6559700 244.5
+924100 6567200 943.5
+889500 6558000 505
+860800 6576900 213
+870700 6575000 231.5
+913900 6576300 948.5
+848500 6580500 197.5
+849600 6548400 291
+854700 6577800 203
+876200 6593600 212.5
+886900 6576600 538
+877200 6547400 282
+908400 6512100 446.5
+909500 6565200 869
+931100 6577000 1065.5
+897000 6563100 800.5
+853300 6527600 243.5
+867200 6561500 256.5
+907600 6527900 354.5
+863000 6587800 200.5
+915300 6527100 272
+849800 6588600 192
+912900 6525900 352.5
+865200 6530300 242.5
+910900 6542400 1002.5
+892100 6528400 654.5
+884800 6550400 371
+835500 6546200 204
+904500 6576300 761
+849600 6534600 294
+888400 6581900 540
+880300 6589700 387
+886300 6572300 470
+848200 6563100 239
+864900 6591900 202.5
+938100 6579800 457.5
+853000 6583900 201.5
+895700 6525700 690
+883000 6540900 425
+900600 6531000 742
+845400 6583500 188
+910900 6534700 872.5
+929500 6568900 423
+911500 6527600 366.5
+911300 6523200 343.5
+901300 6573300 723.5
+847000 6562200 231
+859600 6530100 252
+908000 6564000 875.5
+896500 6536700 883
+916100 6566500 732.5
+876700 6534800 233
+842300 6570500 194
+894500 6573500 601.5
+857700 6572600 206
+902800 6575000 749.5
+853900 6540700 285
+908900 6521300 306
+918500 6544800 810
+850000 6525700 238.5
+864400 6557700 263
+883500 6583100 447.5
+908300 6526100 323
+858900 6594700 195.5
+860200 6553800 272.5
+906200 6525100 299.5
+886500 6565100 404
+845700 6577000 191.5
+879100 6553800 287.5
+870400 6554700 288
+868900 6536100 254
+869600 6540200 276.5
+913800 6573300 992.5
+890500 6556400 639
+844900 6571100 203.5
+926400 6582400 1211.5
+914900 6550700 777.5
+936500 6582100 493
+902400 6528600 717.5
+877800 6528600 209.5
+911300 6571500 796
+860600 6538800 282
+901100 6571000 732
+879200 6566900 412.5
+862800 6570300 223.5
+853400 6570800 218
+864500 6569900 235.5
+850500 6595700 192
+899400 6559900 884
+854100 6548900 282.5
+904100 6526300 742
+900900 6549700 990.5
+898300 6566000 725.5
+916800 6551000 385
+917200 6569900 1010
+843600 6586000 171.5
+893400 6526000 499.5
+879100 6551600 287.5
+906900 6551700 994.5
+836000 6544400 208
+844700 6588800 171
+897000 6559700 663
+896900 6519500 610.5
+856200 6559700 253.5
+862000 6534300 255.5
+874800 6561700 260
+906100 6547300 900
+870100 6536200 258
+888800 6541700 545
+882600 6547800 495
+888500 6570100 402
+859000 6555500 268.5
+875600 6545700 276.5
+860500 6530100 237
+853400 6588800 195
+880300 6587500 382
+896900 6566800 555.5
+891800 6557800 736
+939600 6584200 482.5
+838800 6556800 212
+901400 6554600 983.5
+840200 6543100 245.5
+937400 6577500 452.5
+869500 6560100 268
+859300 6584400 205.5
+846700 6586200 188.5
+837500 6539500 211.5
+918200 6560300 936
+871800 6569600 246.5
+917800 6565000 998
+869000 6569000 225.5
+915100 6520900 357
+844100 6562500 222
+884600 6562500 409.5
+933800 6580200 518.5
+836300 6548200 210
+849100 6592500 188
+844500 6558700 248
+895400 6556600 821.5
+841600 6541700 250.5
+850600 6598500 191.5
+865100 6582700 206.5
+898400 6576300 509.5
+866600 6581000 212
+836400 6551400 197
+927600 6564300 394.5
+853100 6553500 263
+845400 6575500 175.5
+930200 6589500 1240
+927500 6572300 1021.5
+860500 6559600 266.5
+843100 6556900 244.5
+862600 6542300 285
+852500 6532600 287.5
+849900 6570400 201.5
+895300 6551800 835.5
+906400 6534600 677.5
+906300 6580800 767.5
+905900 6542500 829.5
+890600 6526100 410.5
+894100 6548000 721
+896000 6542700 652
+865500 6599500 202.5
+871200 6521800 194.5
+935200 6586000 1073
+861200 6597600 206.5
+857300 6587300 199
+853000 6544500 286
+904800 6570900 850
+872200 6538100 265
+877800 6538500 271
+868000 6583900 213
+762500 6968700 148.5
+724200 6911100 119
+727400 6986500 139.5
+720000 6889000 122.5
+753200 6977900 142
+747400 6943800 81.5
+787000 6966300 229
+777700 6962800 182
+725500 6970100 104
+712800 6958000 110.5
+785200 6964100 229.5
+709700 6931000 113
+742200 6957600 89.5
+776000 6937300 101
+760900 6948600 92
+727100 6944100 130
+711600 6951200 117.5
+713500 6964300 82
+770700 6929800 121
+726800 6878000 129.5
+726700 6927600 117.5
+728600 6908700 130
+774800 6924500 71
+746000 6924200 102
+770300 6923400 78
+760100 6937700 135
+749700 6924800 121.5
+722500 6875000 118.5
+732900 6926400 127.5
+770100 6926600 96.5
+728600 6921300 100
+716000 6908100 114.5
+710800 6912000 116
+778900 6952700 156.5
+721700 6899400 129.5
+742300 6936700 68
+741400 6922900 104.5
+740500 6870000 175.5
+748000 6991600 149
+723100 6927600 117.5
+735500 6865000 162
+754800 6929800 145.5
+769900 6973800 174
+722200 6959600 82.5
+787200 6970600 208.5
+758800 6953800 97.5
+747400 6984200 135
+721500 6984200 130.5
+770700 6981100 178.5
+752100 6923800 114
+772000 6956600 144.5
+722600 6904700 152
+709600 6954300 109.5
+725100 6904400 167.5
+720700 6985500 123
+744900 6876500 162.5
+708600 6949700 126.5
+771500 6924700 67
+730300 6966000 90
+723400 6920200 84
+710400 6963600 78.5
+746400 6969500 117
+786700 6971500 213.5
+726900 6924900 102.5
+727300 6958000 82.5
+724500 6977600 111
+715300 6964600 83
+765500 6923100 70.5
+740600 6947000 91.5
+773200 6930000 108
+712800 6948100 106
+736100 6964500 104
+721100 6898700 125
+752100 6977800 135
+716000 6967500 84.5
+743700 6951100 87.5
+707000 6961600 74
+753500 6921700 111
+717800 6944100 77.5
+761400 6919700 117.5
+715900 6891100 119.5
+745000 6958700 109
+707500 6890200 103
+735700 6893700 178.5
+751000 6923700 118
+742000 6884000 151.5
+737500 6923400 117
+751500 6932900 133
+710200 6923000 88
+747700 6914200 131
+735000 6868800 205
+711600 6946800 75
+756500 6931600 149.5
+740600 6872700 165
+739500 6918600 117
+722300 6965600 99
+712400 6916900 107.5
+735200 6971000 103
+735800 6910700 116
+748500 6986700 150
+748900 6915600 131
+712900 6984900 126.5
+738900 6898100 164.5
+775400 6976600 184
+723100 6891400 155
+760500 6974500 164.5
+722700 6915000 103
+756800 6973600 175
+717500 6989300 97.5
+756000 6944900 82
+759200 6978000 151.5
+713700 6934300 101.5
+774500 6967400 181.5
+734600 6897600 172
+711400 6906500 141
+740200 6912000 95
+742100 6944700 95
+778700 6958500 171
+715900 6946300 69
+708400 6960100 68.5
+744700 6931800 140
+726900 6876500 138.5
+754100 6925800 132
+732600 6934200 109
+753300 6919900 108.5
+734100 6945900 119
+730900 6911300 121.5
+740400 6932600 114.5
+717900 6906400 131.5
+753500 6994100 177
+741100 6878400 148
+711200 6904900 139.5
+721400 6893200 154
+716600 6979000 107.5
+710000 6902200 115
+739000 6905400 109.5
+740400 6909100 106.5
+776300 6975500 177
+746500 6880500 183
+713000 6928200 103
+739000 6887700 136.5
+752600 6930100 138
+733700 6991100 150.5
+754600 6936100 148.5
+748700 6980200 146.5
+772300 6964800 164.5
+734200 6978700 122
+761500 6932400 115.5
+755400 6980200 152.5
+730300 6909500 113.5
+747800 6977100 128.5
+745100 6940600 123
+777300 6964600 176.5
+749500 6956300 101.5
+731200 6954500 80.5
+749100 6920000 93.5
+746400 6953300 98
+743200 6933700 117.5
+730800 6948200 85
+753900 6973800 151.5
+730800 6976300 109.5
+744700 6907200 149.5
+705500 6914700 113
+726200 6992200 133
+732700 6909400 116
+750700 6930000 127.5
+716100 6972700 107
+716500 6878700 138
+755600 6960400 107.5
+755000 6971300 160.5
+743700 6896600 179.5
+757100 6927000 125.5
+739600 6886100 143
+719600 6921500 86
+733800 6883200 140
+770800 6972500 185.5
+741500 6876400 152
+726000 6931100 106.5
+721200 6914700 119.5
+749800 6917300 121.5
+722000 6902000 149.5
+729200 6913300 121
+762100 6964800 133.5
+713200 6968200 90.5
+743900 6894000 188
+758400 6964900 127
+713300 6891600 117
+744900 6918600 123
+730700 6881700 136
+710100 6969300 87
+750100 6990600 164.5
+726400 6951500 63.5
+781400 6980500 225
+717100 6967300 85.5
+739100 6956000 83.5
+730200 6903900 147
+767800 6952400 124
+720300 6948100 57.5
+758300 6968200 135.5
+733800 6906000 138
+764700 6965100 141
+728300 6894700 160.5
+711400 6949000 122.5
+759800 6971500 150.5
+737400 6942700 141.5
+733500 6959500 101
+740600 6921600 108
+751000 6983600 153.5
+723200 6922900 97
+714900 6951000 86.5
+709800 6979100 100.5
+712100 6973100 103.5
+754600 6964700 130.5
+726100 6893500 168.5
+741600 6915500 114
+748600 6962800 111.5
+739400 6900800 155
+753200 6951200 82
+730800 6895800 154.5
+756700 6978700 145.5
+716700 6896200 130.5
+717300 6926000 101.5
+720500 6959800 92.5
+715600 6978400 112
+744300 6886500 148
+771700 6951800 132
+722000 6945700 95.5
+727300 6950300 73.5
+733500 6873600 191.5
+760700 6950900 85
+723700 6873900 139.5
+740200 6910300 102.5
+760800 6935400 141.5
+739000 6911100 105
+740200 6936800 113
+744600 6981600 121.5
+737500 6926300 125.5
+733700 6937100 126
+722100 6925100 108
+715500 6887300 124
+738000 6884600 141
+763400 6922600 70.5
+727400 6935200 105.5
+741600 6898200 169.5
+753600 6955900 87.5
+709400 6910900 152
+783600 6973100 194.5
+737300 6883300 147.5
+739900 6977900 115.5
+716600 6884600 150
+707100 6967800 77
+732400 6936100 126.5
+765300 6959400 138.5
+735000 6901700 136.5
+763200 6953000 113
+774200 6920600 73
+756800 6948400 79.5
+719200 6896500 126.5
+720800 6950800 67
+709000 6897600 109
+727600 6936400 140
+712200 6980700 104.5
+741400 6925700 129.5
+730900 6967300 94.5
+724400 6925800 120.5
+725800 6896600 152
+717200 6919900 94
+747100 6988600 137.5
+741000 6908000 130
+762100 6992800 197.5
+737900 6913900 112
+757300 6965800 121.5
+713500 6913400 115.5
+738700 6994000 135.5
+729800 6899200 108
+715200 6933600 105.5
+748300 6932200 149.5
+738800 6880300 150.5
+742100 6935800 63
+712800 6902700 122
+773800 6954600 136.5
+725400 6957500 80.5
+720900 6938100 100.5
+732600 6954000 67.5
+729300 6911900 119
+732600 6915600 120
+730100 6916300 103.5
+722700 6938100 115.5
+745000 6912100 113
+757500 6937100 139.5
+725700 6908100 141
+735300 6917200 100.5
+750600 6917000 124.5
+715400 6906100 116
+716000 6987800 116.5
+725700 6898500 118.5
+731300 6894300 159.5
+732300 6899000 130
+713900 6957200 110.5
+747400 6930700 125.5
+762000 6959500 129.5
+718200 6915300 112
+733600 6961400 97.5
+775200 6964100 174
+705400 6969800 89
+735200 6930200 126
+711300 6915500 106.5
+732500 6889700 173.5
+726000 6920000 65.5
+727100 6962900 83
+709200 6912600 108.5
+780700 6960800 185.5
+739500 6929500 127
+708300 6968100 81
+752500 6966100 135
+721400 6887100 142.5
+743700 6914500 111.5
+739300 6939000 124.5
+732700 6919400 102.5
+747100 6948400 80
+710400 6941300 55.5
+723600 6962400 98
+740200 6959900 93.5
+723700 6984500 135.5
+718800 6887900 141
+735900 6974600 108
+763800 6983300 179.5
+753100 6943100 85.5
+738200 6982900 149
+739700 6976400 115
+766000 6989900 201.5
+724800 6946900 70
+773300 6922200 66.5
+716400 6922500 76
+748700 6950400 76.5
+727800 6956200 83.5
+743000 6990700 149
+747200 6949500 84.5
+757600 6980100 159
+749400 6941800 75.5
+765100 6982900 184
+771100 6935600 105.5
+712300 6941400 53.5
+749100 6952700 91.5
+746500 6974700 135
+772500 6981700 183
+781800 6974000 192.5
+723700 6942200 119.5
+725400 6889900 158.5
+713000 6944100 51
+737600 6975600 113
+722000 6962300 94.5
+710900 6953000 111
+743600 6984500 136.5
+765500 6971100 164
+749100 6986500 155
+758800 6967300 137
+724400 6908800 152.5
+759300 6969300 144
+742500 6910600 109
+746600 6909400 140.5
+731400 6882200 139
+713200 6916400 108
+752700 6968700 138
+765500 6954700 127.5
+747500 6922100 107
+743500 6880200 164.5
+746400 6900300 171.5
+730000 6938000 149.5
+757100 6935900 156
+725600 6934400 109.5
+770700 6987300 195.5
+723900 6981200 123
+768800 6957900 135.5
+759200 6919500 130.5
+728300 6990600 138.5
+716700 6960700 79
+740100 6890500 149
+732900 6929200 127
+735800 6886300 142
+783600 6960800 203.5
+731600 6921800 111
+719000 6992300 122
+731500 6871600 173
+788300 6963400 219
+714400 6923100 89
+723500 6932100 104
+723200 6975300 103
+729000 6928200 117
+741600 6921500 110.5
+716300 6897900 113.5
+713900 6983800 122
+766600 6931900 91.5
+726600 6980400 121
+778200 6959700 169.5
+732600 6982300 126
+770400 6992100 194
+748200 6954400 90
+781400 6957200 181.5
+752300 6979000 139.5
+717500 6980400 103
+748500 6927300 134
+777300 6953300 155.5
+777300 6958300 168.5
+774200 6981800 171.5
+729900 6889900 173
+765800 6978700 173.5
+727500 6963700 83
+756900 6962700 117.5
+761400 6973600 172
+737500 6981800 137
+726100 6922600 102.5
+777900 6980900 212.5
+720200 6928700 110.5
+756800 6956400 106.5
+734200 6862800 145.5
+734000 6922200 106.5
+710900 6935200 106
+740000 6880500 154
+740000 6986100 148.5
+778300 6956400 163.5
+718000 6917400 109.5
+703000 6906700 142.5
+767500 6984000 190
+753000 6937400 130.5
+758200 6945900 77.5
+719200 6913200 131
+728100 6925700 105
+722400 6975500 98.5
+720900 6872600 131.5
+731600 6920900 97
+711100 6956500 100.5
+751500 6936700 129
+778600 6966500 193
+728700 6978300 106.5
+709300 6961300 74.5
+738700 6934800 109.5
+726600 6934400 110
+764600 6941600 101
+780000 6952200 159.5
+733000 6966400 101.5
+751100 6969700 127.5
+740300 6929000 131
+742900 6930500 127
+752700 6935100 150
+711700 6889100 111.5
+703100 6912400 151.5
+719400 6935500 97
+730000 6983300 126.5
+714400 6925500 100.5
+719700 6981700 118
+717800 6924200 98.5
+738300 6936000 130
+747400 6935600 131.5
+718600 6960000 85
+745700 6921900 96
+719200 6968300 89.5
+719000 6927500 113.5
+729100 6972500 101
+738700 6915900 108.5
+751000 6934500 145
+711000 6944600 50.5
+760000 6960200 124
+723100 6971600 92
+722900 6972900 97
+724600 6875200 132.5
+709700 6966300 86.5
+743900 6916900 126.5
+730800 6950500 77.5
+707200 6919100 99.5
+761200 6965200 131
+757200 6950800 80.5
+781900 6963100 209
+731300 6883300 137.5
+757300 6933500 152
+750900 6925300 130.5
+733400 6955500 84.5
+744400 6963600 104
+783300 6956800 181.5
+714400 6893900 118
+741700 6884800 145.5
+712400 6988200 124
+755900 6921000 103
+751000 6966400 121
+727800 6917500 108
+724400 6917800 103.5
+759500 6923400 83.5
+773900 6948300 127
+717600 6875600 127.5
+722700 6916200 106
+715500 6942300 54
+707500 6971100 85
+719200 6893100 147
+736800 6920100 101.5
+724800 6887300 176.5
+713700 6962900 77.5
+717500 6954300 82.5
+751700 6976100 132.5
+731200 6943800 128.5
+717600 6976700 104.5
+733000 6882000 146
+746600 6910600 109
+720100 6919600 98.5
+741200 6961800 98.5
+722200 6988700 124.5
+712100 6919100 103
+730700 6923300 117.5
+741600 6981300 117
+720800 6910100 120.5
+709200 6946900 117.5
+776300 6941600 109.5
+732800 6863500 155.5
+725300 6912700 107.5
+776000 6967700 192
+738800 6881400 150
+720300 6887600 128.5
+723900 6937200 118.5
+761700 6952500 108.5
+714200 6896400 139.5
+724000 6898900 129.5
+736000 6971700 107
+752900 6925000 125.5
+713500 6977200 97
+758400 6963600 120
+745900 6987300 146
+726200 6925500 111.5
+745300 6920200 112
+760800 6917800 136.5
+739900 6987500 155
+707600 6974000 82
+726800 6900600 132.5
+745100 6978100 124
+718300 6938000 59
+765600 6947000 100
+740800 6978100 115.5
+713400 6920200 95.5
+742000 6994000 153
+711100 6962100 77.5
+726800 6939500 146
+739200 6936700 126
+734700 6972900 101
+759500 6933400 147.5
+755400 6967500 135
+780800 6971600 205
+720100 6980200 112.5
+727400 6960600 83
+773300 6968200 179
+713900 6970200 102.5
+748700 6973000 129.5
+733600 6918200 106
+754300 6981000 157
+715200 6914200 118.5
+711600 6970000 103
+718100 6900700 131.5
+743700 6968800 115
+710700 6899700 111
+718300 6983900 122.5
+739900 6913700 94.5
+708400 6963800 85.5
+751600 6946900 87
+780000 6963100 191.5
+730900 6970300 95
+706700 6964500 80.5
+738000 6934900 113
+750400 6898100 189.5
+769700 6945800 108
+740600 6894200 177
+728000 6903900 158.5
+769000 6924900 68.5
+741800 6879300 149.5
+735900 6940000 127.5
+736900 6877200 154.5
+731000 6886000 153
+764300 6979200 165
+767600 6969400 161.5
+773200 6924900 91.5
+725500 6878700 129.5
+737300 6949400 75.5
+737800 6931200 126
+713400 6888300 117
+777800 6950600 142
+727400 6941300 152.5
+774900 6926400 87.5
+768300 6946800 109.5
+741500 6930900 126.5
+719600 6877000 135
+751900 6917500 132
+716700 6957900 76
+728900 6980300 116
+728100 6947600 89
+778600 6975900 194
+744900 6911300 112
+775400 6974100 191
+761500 6933400 136
+746400 6930900 131
+731200 6880000 152.5
+765800 6986900 202.5
+758800 6932600 124
+710800 6975500 92
+721800 6889300 143
+763600 6958500 121
+735000 6923100 106.5
+775600 6927600 90.5
+735300 6883300 147.5
+754300 6918500 125.5
+757500 6921600 62.5
+720800 6957900 82
+740100 6937700 124.5
+720900 6875300 134
+729500 6883000 140.5
+753400 6940000 135
+720400 6923800 105
+749300 6962400 115.5
+707500 6911200 147
+703200 6903800 121
+725800 6914200 111.5
+733700 6970400 100
+729400 6879700 142.5
+727600 6871800 201.5
+757300 6920000 125.5
+785500 6959700 194.5
+773200 6977800 179.5
+728100 6954900 75.5
+723500 6977600 107.5
+721000 6954700 72
+704500 6908700 159
+719700 6955000 71
+722500 6981000 124.5
+710400 6959400 70
+751300 6973500 148.5
+721400 6917700 101.5
+740100 6991500 142
+750900 6918800 107
+786200 6978800 246
+742000 6982300 120
+712400 6899300 103.5
+735000 6955900 87
+719100 6907100 139
+759900 6985500 197.5
+719300 6890400 142
+724300 6914800 108
+712600 6960700 75.5
+724900 6950300 53
+745400 6934400 126.5
+735500 6952500 85.5
+773400 6955600 142.5
+729100 6866400 159
+714700 6898100 112
+761500 6978700 159
+726100 6961600 82.5
+787800 6976500 231.5
+753600 6987500 171.5
+716400 6935500 100
+718100 6974400 106.5
+770700 6966800 164
+724800 6967600 97.5
+734900 6944700 135
+721300 6960700 89
+722600 6895000 150
+715300 6973300 113
+759100 6943000 90
+739300 6965300 111.5
+708300 6922900 89.5
+771400 6960400 158.5
+716700 6928800 109.5
+769100 6964900 154.5
+700700 6913600 155
+748600 6993900 164.5
+759700 6929500 99
+711000 6967200 91.5
+720600 6933100 102
+739500 6874100 155.5
+717500 6929200 111
+776400 6958100 157.5
+757100 6961300 117
+746900 6959300 116
+775600 6960700 172.5
+726000 6954400 69.5
+736900 6912000 114
+744900 6955500 95
+772200 6941700 100.5
+724000 6969700 103
+722600 6884900 161
+782900 6971600 211
+756300 6991300 191.5
+751500 6959200 102
+717600 6948100 74.5
+734900 6935000 114
+746500 6903600 154.5
+733800 6939100 139
+726100 6948000 71.5
+739100 6940300 89
+761700 6925700 75
+754700 6932800 154.5
+709700 6924900 98
+763700 6966400 145
+737200 6945100 123
+748100 6936300 133
+710700 6947700 115
+729600 6931100 106.5
+736900 6886200 141.5
+753100 6960200 99
+741300 6938500 72.5
+748700 6896500 182.5
+729100 6926200 115
+740800 6886800 146.5
+732400 6932200 106
+730300 6935100 121
+711100 6929800 107.5
+720000 6964200 97
+749600 6935300 140
+726300 6977900 106.5
+740500 6904700 138
+720600 6972200 96.5
+714900 6990200 113
+716600 6966000 84
+716000 6894300 137
+720300 6879600 152.5
+711900 6937700 65
+746200 6915900 123.5
+738300 6992600 136
+754000 6932400 141.5
+716900 6889900 125.5
+735500 6915500 111
+776000 6978700 181
+743900 6946100 90.5
+742000 6894500 183
+750300 6922600 113.5
+749300 6932500 137
+742400 6921000 112.5
+723400 6935700 97
+717400 6969200 94
+728200 6898200 119
+728800 6965000 88
+750600 6993000 165.5
+760600 6957400 111.5
+714300 6880200 139.5
+755300 6917800 129.5
+726000 6915100 109
+738000 6965900 111.5
+716900 6984700 121.5
+715600 6901900 123
+755300 6984700 175
+732300 6977900 114.5
+750900 6896000 165
+737700 6900100 165.5
+733100 6903400 160
+726300 6972400 103.5
+714000 6945800 68
+718300 6989300 118.5
+710800 6921000 93.5
+765200 6950100 105.5
+744300 6933900 122.5
+733400 6869300 205.5
+784900 6958500 188
+731500 6950500 69
+740300 6954500 73
+736800 6991800 145
+764900 6973100 169
+769100 6981200 174.5
+725200 6985400 136
+759600 6979700 161.5
+763500 6991700 208.5
+734400 6984100 147
+744900 6986100 142.5
+750000 6978300 132.5
+751200 6954400 84.5
+787100 6960400 200.5
+730300 6964000 86
+736600 6935400 120.5
+732900 6865100 185
+726800 6949300 76.5
+710500 6981000 109.5
+730700 6873700 164
+706600 6905900 145.5
+743300 6923100 116
+709700 6936200 107
+747400 6918000 119
+767200 6979900 172.5
+732600 6987600 142.5
+771700 6982200 187
+775800 6985500 191
+748300 6930700 125.5
+756700 6967500 134
+767200 6965900 149
+782400 6965600 211
+715600 6900700 119.5
+728300 6951800 71
+719400 6969500 93
+730900 6927800 125.5
+742500 6953800 73
+744400 6930400 119.5
+756700 6952600 86
+725500 6901600 136.5
+711500 6938300 60
+755700 6939500 110
+764700 6927800 76.5
+706900 6973200 79.5
+752700 6958600 101
+729200 6907200 144.5
+755900 6926000 123.5
+748400 6925500 129.5
+744100 6927000 129.5
+734200 6926100 129
+737600 6953400 70
+718100 6941400 61
+739700 6942200 84.5
+721500 6922500 93.5
+717400 6942900 55
+750000 6921400 97.5
+714700 6937000 58
+720400 6884100 173
+719900 6881300 170
+737300 6915500 103.5
+727400 6881100 137
+728500 6918500 63.5
+698500 6627400 212
+757700 6573100 436
+704000 6619600 270
+727300 6562700 305
+718900 6578600 291.5
+670700 6583900 288.5
+761800 6574900 370.5
+735900 6551900 314
+750700 6615100 222
+744000 6551100 463.5
+709500 6568700 315.5
+756600 6566200 410
+740600 6619100 229
+646300 6593500 376
+713700 6575800 350.5
+669200 6579000 267.5
+720700 6572100 263.5
+745200 6575500 302.5
+710200 6597000 358
+659800 6586000 314
+702900 6586700 437
+693200 6583300 349
+672200 6574200 353
+768100 6583200 292
+671300 6559900 503.5
+684200 6620900 254.5
+664200 6584600 286.5
+710600 6566800 336.5
+712300 6609300 245.5
+655700 6586000 448
+757500 6596700 267
+717700 6577000 296.5
+714700 6603900 290.5
+678100 6595700 283.5
+686900 6576100 459
+696900 6596500 315
+751500 6611500 233
+705800 6564100 410
+684400 6581800 320
+670000 6604100 223.5
+670500 6611000 234.5
+704300 6609200 268
+673900 6576500 335.5
+753900 6542200 958
+757800 6588600 293.5
+707100 6600800 333
+756100 6562100 565
+737900 6579900 278
+662400 6573400 335
+727200 6607400 247.5
+715300 6555600 429.5
+759000 6576800 443
+699300 6558500 447
+726100 6588600 226.5
+725000 6558600 321
+722200 6606900 231.5
+694400 6587500 363
+689500 6609400 319
+732300 6619600 233.5
+669400 6582300 279
+673900 6612400 253
+712300 6594000 386.5
+710400 6605400 281
+652400 6595800 336.5
+663600 6598200 270
+771900 6590400 268
+720300 6596700 287
+650800 6592800 374
+750200 6547500 688.5
+704200 6589900 454.5
+740400 6585400 280
+676500 6617800 234.5
+676500 6623500 218
+673200 6618600 238.5
+748400 6594200 265.5
+686000 6623600 244.5
+730200 6564900 286
+719300 6612500 230.5
+675200 6569500 468
+693100 6579200 397
+677100 6581500 336
+684100 6574800 440.5
+746700 6617500 228.5
+716500 6564400 318
+678400 6607900 290.5
+751500 6552600 647.5
+691100 6575700 473
+744200 6589600 271
+733000 6590200 262
+724300 6603500 247.5
+734300 6581700 273
+729100 6583500 258.5
+715000 6571300 291
+769100 6578800 300.5
+704200 6600300 338.5
+669900 6588400 279.5
+733100 6596100 260
+744400 6563200 388
+739600 6595800 277
+718600 6563300 294.5
+654900 6591200 342
+723300 6586800 264
+683200 6578000 362.5
+719400 6583000 295
+743500 6580900 298
+731200 6557500 292
+742800 6572500 316
+755100 6577000 396
+750200 6570400 332.5
+698200 6576600 415
+773200 6585300 267
+750100 6618800 203
+656700 6596900 323.5
+716900 6559500 359
+714700 6567500 326
+760100 6567200 501.5
+671700 6563100 441
+726500 6569500 284.5
+714700 6558400 375.5
+677000 6572500 452
+719800 6558100 325
+712900 6552400 454
+731300 6615200 245.5
+739600 6551500 436.5
+673000 6595500 282
+694900 6565000 577.5
+748900 6589000 293
+719500 6552900 373
+689000 6588500 289
+728400 6553100 326
+659300 6581900 450.5
+750800 6565000 400
+722300 6578700 266
+696600 6582200 422.5
+732900 6558700 280
+698300 6574300 398.5
+745500 6586800 273
+755400 6570400 393
+735800 6556700 391.5
+677900 6601000 252
+711300 6571700 322.5
+719600 6605700 245
+743100 6557000 410
+730600 6586800 263.5
+775500 6582000 273
+748400 6580900 319
+703000 6628400 211.5
+669500 6599300 222
+668600 6613900 218
+683300 6586500 317
+706200 6566700 420
+734500 6554400 278.5
+649300 6583400 465
+709500 6597700 366
+715700 6617500 227
+739900 6589700 277.5
+717700 6580900 327.5
+710300 6583900 398.5
+761000 6583700 365.5
+737500 6603300 262.5
+688800 6577000 408.5
+736600 6572900 308
+680100 6576600 397
+724000 6556500 338
+736400 6567100 304.5
+717300 6553100 339.5
+670700 6591800 263.5
+744200 6554800 458.5
+747000 6562700 429.5
+656400 6599900 296.5
+753100 6583900 347.5
+690500 6600100 263
+699800 6603100 289
+762700 6592600 267.5
+754400 6580800 386
+737100 6569800 329
+676700 6584200 324
+727700 6555500 326.5
+719000 6568700 272
+713400 6589400 392
+712900 6583300 360.5
+721100 6553000 365
+662300 6580900 389
+695700 6605800 290.5
+720500 6560400 305
+681900 6597400 251.5
+669100 6591900 212.5
+734700 6577200 273.5
+696500 6579700 446
+664300 6579400 321.5
+740100 6598800 262
+656300 6578200 452
+757500 6543200 856.5
+710700 6560700 351
+668300 6617400 197.5
+749300 6555600 471.5
+719000 6617800 225.5
+674600 6588600 308.5
+650900 6598800 328.5
+746600 6625800 216.5
+666100 6595400 238
+697500 6562100 564
+771800 6596600 253.5
+766000 6587900 285.5
+724000 6589700 257.5
+752800 6589400 340.5
+695300 6625500 239.5
+718100 6587700 318
+745200 6584000 289
+693200 6589200 303.5
+702200 6629500 206.5
+688100 6581000 323
+676900 6567300 510.5
+704700 6576600 387
+717000 6574100 291.5
+664500 6569400 377
+700300 6623200 221
+707900 6620300 245
+701500 6599400 342.5
+673300 6597700 252.5
+762800 6577900 352
+667000 6566100 407.5
+666100 6571500 346.5
+700800 6568700 525
+712100 6611800 235
+707100 6560800 369.5
+740000 6564500 348
+734300 6555500 342.5
+733100 6570800 305
+754500 6551600 686
+741200 6564200 380
+697500 6613600 263
+724100 6598700 241
+670400 6595800 230
+738800 6568200 320
+749100 6572400 364.5
+648600 6587600 405.5
+744100 6568000 320
+687100 6597300 264.5
+702700 6571500 402.5
+723500 6609800 230.5
+704800 6580900 413
+748800 6597500 252.5
+757100 6604100 241.5
+721100 6565400 292
+662000 6591200 288.5
+736300 6574300 301
+733400 6567500 302
+712400 6565000 358.5
+704900 6561400 432.5
+704400 6562800 434
+708400 6563900 364.5
+712700 6620200 222
+700100 6561900 572
+720200 6580600 278
+752700 6557300 651.5
+679800 6589800 327
+670300 6567200 459.5
+722900 6620800 238.5
+709200 6617600 235.5
+735200 6559500 369
+708700 6572900 351.5
+739400 6573200 313.5
+668300 6560700 432.5
+723400 6614400 230.5
+684500 6606800 339
+737600 6609900 248.5
+700700 6580100 420
+732600 6573600 288.5
+695900 6590400 340.5
+716000 6609100 245.5
+745600 6581200 290
+683400 6569900 517.5
+723000 6562700 315
+765900 6598700 247
+701200 6590100 401
+733800 6562500 323.5
+739300 6577300 302.5
+692900 6619100 262
+725500 6607200 221
+706700 6557300 423
+768700 6590700 272
+712000 6558700 405
+758200 6547200 777
+760500 6551400 871
+711800 6570900 303.5
+775200 6593600 251.5
+727800 6593600 240
+687800 6603900 320
+726700 6574400 262
+727500 6602000 245
+738400 6546900 398
+735800 6612400 246
+744600 6602800 257
+705200 6591400 424.5
+715100 6562300 361.5
+702400 6591500 407.5
+719100 6593600 296
+749400 6542700 799.5
+686200 6593900 251
+686300 6613100 312.5
+750800 6585300 330
+723400 6583700 264
+716000 6578200 334
+728100 6576800 247
+686300 6580000 341.5
+679800 6605700 312
+730900 6579300 260
+734700 6564800 323
+702800 6615200 263
+752200 6602700 239
+717000 6568800 319.5
+730300 6562500 277
+742200 6612500 238.5
+762600 6601000 239.5
+668700 6573900 332.5
+689100 6594700 268.5
+698300 6569600 453.5
+666600 6575700 300
+730500 6570600 260.5
+957200 6346500 1266.5
+952300 6372000 1283.5
+932900 6362000 610
+973700 6305800 1234
+970900 6313900 1376
+930500 6343000 1074.5
+950700 6322000 769
+945000 6293900 468.5
+938600 6330100 586
+982400 6326400 1505
+912800 6345600 1055
+930000 6314700 456.5
+938100 6333900 627.5
+1012400 6320600 1071
+936100 6358800 757.5
+961700 6332900 1054
+967500 6367000 1899.5
+962200 6342000 957.5
+989800 6349100 1960
+918000 6344100 1123.5
+923100 6321700 650.5
+911800 6318200 682
+948500 6318000 646.5
+947500 6334200 745
+1005800 6324000 977.5
+923600 6315000 510
+1015100 6320400 908
+942300 6324100 685
+1003200 6330500 1359.5
+996700 6327700 1119.5
+946200 6371300 1280
+924300 6315600 561.5
+943800 6354300 1171
+939200 6320000 513.5
+994400 6370000 1963
+951600 6333300 703.5
+935500 6368100 891
+919800 6312200 550
+952400 6331600 715
+904100 6334800 1099
+912700 6334500 1146.5
+971200 6330800 1238
+987600 6314400 1341
+984400 6372400 1975.5
+922800 6331400 1187
+919100 6329200 918.5
+949200 6302700 523.5
+969000 6303600 1195.5
+968400 6377500 1635
+932100 6318400 426
+927300 6321500 500
+971300 6335900 1582
+1005700 6320200 1093
+939300 6347600 949.5
+915200 6318300 630
+1002100 6382500 2249.5
+980300 6338700 1690
+909200 6327200 766.5
+947200 6296500 487.5
+942100 6302700 505.5
+916700 6307800 539.5
+918100 6316100 576.5
+993300 6313300 1412.5
+1006000 6379900 2385.5
+921200 6305200 463
+953800 6300600 556
+928400 6312900 549
+998100 6386600 2350.5
+935900 6362200 713.5
+949700 6348100 1308
+930500 6346600 727
+937500 6341200 881
+944600 6362900 1142
+942000 6336400 744.5
+940800 6337300 572.5
+966800 6341400 1371.5
+970800 6324700 1113.5
+940700 6357400 910.5
+916100 6335700 1205.5
+917100 6310400 601.5
+927800 6319300 478.5
+970600 6358800 1897.5
+950400 6331900 569.5
+908000 6318400 571.5
+973100 6376000 1635.5
+970300 6323000 1153
+944700 6358100 1290.5
+927200 6333300 1153.5
+996900 6375800 2111
+922200 6319400 627
+939400 6297800 446
+905600 6323500 784.5
+965800 6372000 1791
+954500 6321100 927.5
+986100 6309900 1335.5
+951400 6312100 674
+952900 6374000 1157
+941400 6365200 1085
+911800 6309100 553.5
+948800 6307000 576.5
+951000 6319000 633.5
+922600 6302400 395
+909600 6337400 1120
+989700 6355700 2189.5
+978500 6324200 1260
+959000 6310700 1101.5
+915400 6336100 863
+928200 6356200 612
+935700 6329900 560.5
+966800 6357200 1632
+996900 6319100 1329
+962100 6378500 1120
+951800 6344000 1159.5
+998900 6325800 958.5
+958500 6326600 1069
+936100 6355900 908.5
+942800 6332100 751
+931800 6323200 480.5
+964600 6360600 1548
+936100 6337200 969
+932100 6334000 1002.5
+972700 6326600 1164
+985600 6322400 1328.5
+940900 6358200 850
+926600 6327600 675
+913700 6312500 596
+988400 6326400 1471.5
+982400 6311600 1200
+933800 6327600 543
+941200 6339300 838.5
+927900 6331600 649.5
+934400 6317500 484
+981400 6325000 1332
+988100 6319300 1399
+927800 6326100 579
+965700 6325600 1120
+960800 6357000 1549
+951500 6373900 1196
+966900 6384000 1545.5
+919000 6324400 685.5
+979600 6373200 1920
+917300 6332400 1189.5
+949600 6353700 1497.5
+975000 6352800 1875.5
+956300 6327100 754
+988900 6369100 2066.5
+990900 6371900 1897.5
+992900 6372900 2070.5
+940000 6308900 470.5
+938500 6344300 616.5
+921600 6299600 393.5
+964600 6345800 1122
+943800 6368100 1151
+935500 6347800 796.5
+967900 6347400 1469
+926100 6345100 1174.5
+975800 6333700 1496.5
+997900 6380300 2143
+957000 6316300 1172.5
+910600 6330100 816.5
+946600 6376600 1078.5
+1001800 6328900 1537
+923800 6307700 504.5
+969400 6350700 1503.5
+987200 6344800 1805
+992000 6329500 1360
+963800 6369100 1437
+973600 6318600 1234
+957700 6329200 1040
+937100 6301200 447.5
+951700 6307900 664
+948800 6377500 1085
+943500 6314900 529.5
+938300 6366300 1088
+984300 6319000 1314.5
+967400 6342900 1520
+924000 6327300 703.5
+952400 6347400 1324
+919200 6345100 1154
+953200 6338000 863.5
+908000 6309700 647
+991100 6331600 1525
+942700 6320100 625.5
+959000 6337900 1127.5
+936500 6342000 859.5
+984600 6339500 1826.5
+993000 6308600 1406.5
+914400 6322900 691.5
+932200 6299700 419.5
+959400 6370500 1251
+952200 6365000 1430
+910200 6315700 583.5
+949200 6338900 915.5
+988900 6372600 1988
+941800 6374500 1051.5
+988100 6347400 1903
+908500 6344900 1120.5
+994300 6325300 1118.5
+964100 6318200 1330
+941200 6343400 952.5
+916000 6353000 1087
+988500 6401100 1722.5
+924300 6385700 1293
+934400 6369600 951.5
+951900 6379300 1005
+967000 6389800 1489
+928200 6389900 1764.5
+938500 6392500 1650
+934700 6389300 1797
+932300 6375000 1125.5
+953700 6390400 1622
+993500 6432700 2242
+935400 6386500 1432
+993900 6425900 2334.5
+939400 6374100 800.5
+975400 6422300 2386.5
+984100 6426400 2041
+933000 6403600 1893
+950400 6393400 1205
+957300 6388700 1096
+984500 6431700 1953
+914900 6394500 1606
+939600 6413700 1771.5
+921300 6379300 1037.5
+990000 6434400 2049.5
+904200 6367300 938.5
+958200 6407700 2306
+956500 6379400 1183.5
+985600 6407400 1899.5
+946600 6398700 1172.5
+941400 6403800 1489
+917500 6369100 1078
+951400 6398900 1187.5
+902300 6375700 1141.5
+909600 6360900 997
+1012800 6416100 2432.5
+995700 6414500 2021.5
+964700 6388100 1580
+952500 6418200 2344.5
+940200 6383000 762.5
+963400 6403900 2145.5
+975300 6425000 2639
+944400 6404600 1490.5
+1006300 6407600 2465.5
+919700 6364100 900
+943700 6402800 1646
+977500 6391300 1789
+987900 6404100 1775.5
+982700 6409000 2028
+970000 6391200 1740
+979300 6396800 1965.5
+975700 6387700 1837
+948600 6397700 1323
+922200 6373200 1215.5
+979800 6420100 1889
+945000 6406600 1800
+923000 6382400 1170
+947200 6383300 948
+984500 6402600 1978.5
+918300 6368500 713.5
+908600 6388500 1341.5
+939700 6407600 1035.5
+953100 6385800 1173.5
+944400 6389100 1492.5
+970500 6386600 1517.5
+943400 6379100 775.5
+918500 6384300 1395
+999300 6403600 2302.5
+948600 6419000 2036.5
+989200 6402400 1780.5
+976500 6436900 2528
+940100 6409800 1909.5
+903400 6371500 1142
+940800 6413200 1798
+914200 6376500 1153
+899900 6377500 1088
+900300 6367400 885
+953600 6399000 1767.5
+948800 6387800 1026.5
+975500 6420600 2229
+920400 6354800 1045
+979600 6388700 1605.5
+983300 6412100 1859
+928200 6403600 1855.5
+960200 6444000 2555.5
+999900 6413600 2254.5
+929200 6361800 625.5
+935700 6415900 1759.5
+983900 6442000 2326
+921000 6364700 888
+981600 6433700 2100.5
+923900 6355900 963
+1004200 6410900 2392.5
+912900 6391500 1287
+981400 6416900 2094
+909400 6387200 1213
+924500 6379100 1302
+936000 6410500 1672
+942900 6408400 2089
+925000 6357800 933
+953500 6380400 1183.5
+983200 6422100 1960
+925800 6397400 1855
+954600 6374900 1142.5
+983600 6400800 1847
+918200 6355300 1073.5
+939100 6386300 1036
+931100 6359100 569
+896900 6377100 935
+935200 6372500 1000
+913000 6357600 1037.5
+915800 6365400 979.5
+947900 6400500 1417.5
+926200 6365100 943
+977600 6388200 1818.5
+925000 6361400 892
+943400 6402100 1515.5
+936600 6379900 1319.5
+927600 6383300 1438.5
+916100 6373700 1032
+985500 6428100 1887.5
+899400 6369900 1063.5
+938900 6377700 840
+907500 6365800 1031
+928200 6386400 1239
+918900 6371900 967.5
+913500 6372100 1113
+982100 6385800 2056
+938100 6410700 953.5
+926300 6381500 1225.5
+951300 6383200 982.5
+914600 6360800 971
+916800 6380800 1037
+955800 6401700 1845.5
+979900 6412400 2086
+942600 6380800 786
+920500 6368400 1006.5
+911200 6378700 1260
+930900 6377000 1312.5
+908300 6372100 1272.5
+944700 6416400 1849.5
+937200 6375100 1015
+1005900 6416700 2239
+980400 6393700 1865
+921300 6363900 918.5
+939700 6384300 1376.5
+950900 6403100 1982.5
+914400 6383800 1148.5
+960200 6388300 1641.5
+1010500 6418400 2409
+919200 6361200 981
+963500 6381000 1035
+931500 6367800 962.5
+957200 6379400 1075
+915600 6349600 1186
+986400 6425900 2031.5
+917500 6389100 1421.5
+918700 6376800 1051
+951100 6388900 975
+938600 6404500 1701
+896700 6368900 1047.5
+948600 6381600 1009
+952700 6378100 998
+942900 6378300 845.5
+929300 6408200 1852.5
+928100 6352100 972
+911600 6365300 1107.5
+949300 6400300 1183
+962700 6443700 2701
+954300 6396800 1969.5
+986900 6428500 1853.5
+944400 6400600 1567
+987100 6403300 966.5
+972700 6390300 1652
+967000 6394200 1995
+986400 6389800 2079
+992800 6395300 2350.5
+1037600 6312200 354
+1031000 6328900 1041.5
+1041500 6307400 477.5
+1039900 6305200 229.5
+1040500 6308300 474.5
+1034600 6300200 186.5
+1031400 6300200 536.5
+1036200 6304500 499
+1016600 6292200 570.5
+1011300 6290900 497
+1022900 6301900 761.5
+1010100 6317000 967
+1039500 6315900 767.5
+1021500 6324700 661.5
+1006900 6329800 1095
+1029100 6313900 729
+1032800 6318000 913.5
+1027100 6299200 646.5
+1045100 6316600 863.5
+1037100 6311500 245.5
+1012700 6290300 177.5
+1056200 6303600 330.5
+1042100 6319700 847
+1013400 6328800 1306
+1007200 6317600 1049
+1012700 6343100 1793.5
+1026700 6293500 191
+1008400 6361500 2080.5
+1041000 6322400 1103
+1051100 6310300 384.5
+1030500 6289600 108.5
+1047400 6298900 287.5
+1035800 6325300 1047.5
+1044100 6307900 502.5
+1047200 6330700 1293.5
+1023400 6290700 188.5
+1012400 6325100 894.5
+1000900 6345300 1855
+1007000 6339500 1641
+1027300 6284000 142.5
+1014200 6327200 1137.5
+999500 6350300 1990
+1028600 6340200 1570
+1032200 6297300 197
+1065000 6333300 1426
+1057400 6318700 997
+1069600 6340100 1604.5
+1047900 6304600 297.5
+1054100 6325700 1298
+1021800 6316100 927
+1019600 6320400 763
+1015800 6285800 157
+1034000 6317900 831
+1054400 6303900 402
+1002000 6314600 1170
+1047000 6310900 382.5
+1059600 6314000 782
+1050900 6315100 727
+998500 6306800 1336
+1004800 6299700 1022
+1028000 6316900 871
+1020600 6288200 180.5
+1004800 6304400 1280
+1046300 6333500 1827.5
+1045300 6302800 213
+1031400 6323200 811
+1019200 6340900 1927.5
+1033000 6284400 81.5
+1051300 6301800 350
+1020000 6329400 1120
+1024900 6280900 130
+1032400 6293000 106.5
+1033600 6302900 486.5
+1021500 6297300 706
+1021100 6293600 257.5
+1017600 6285400 244.5
+1023800 6351300 1824.5
+1017000 6322300 978
+1006500 6344000 1846.5
+1010100 6296400 1001
+1033100 6325200 737.5
+1022500 6286100 150.5
+1065000 6331400 1499.5
+1045600 6310400 567.5
+1030700 6338100 1524.5
+1024600 6283500 148.5
+1013900 6317100 908
+1022100 6330100 1146
+1025400 6307700 1170
+1010300 6317500 887
+1054100 6310200 729
+1036900 6308200 504
+1034700 6314400 458
+1023300 6328200 1067
+1047400 6303000 373.5
+1023000 6294300 329
+1032600 6330500 1173
+1012400 6291800 501
+1034500 6293700 93.5
+1017300 6307600 1135
+1010700 6328600 1119
+1010300 6290000 315
+1036700 6316000 480
+1024200 6340900 1664
+1044900 6313600 670
+1045200 6333000 1272.5
+1029500 6309500 950
+1005700 6314700 1144.5
+1018600 6275500 220
+1062100 6307600 387
+999600 6312500 1294
+1037800 6295000 107
+1052700 6307400 417.5
+1057700 6308700 502.5
+1019500 6283700 88
+1047600 6305400 435
+1010200 6312500 1064.5
+1044000 6298500 260
+1000300 6304900 1383
+1020500 6294300 429.5
+998000 6304200 1365
+1040800 6339100 1917.5
+1028500 6334400 1171.5
+1061700 6310800 741
+1050300 6319000 983.5
+1045900 6328800 1167.5
+1014600 6314300 957
+1005300 6332300 1546
+1049400 6297200 71.5
+1014100 6301300 1176.5
+1067700 6342800 1736
+1025500 6313300 860
+1018600 6316100 717.5
+1035400 6310000 557.5
+1022200 6321700 1024.5
+1008500 6339900 1630.5
+1040600 6337400 1424.5
+1031600 6311500 709.5
+1027200 6340800 1419.5
+1044600 6303800 342
+1030400 6319900 852
+1003700 6343000 1657.5
+1021800 6316500 655
+1062300 6325700 1115.5
+1060200 6305600 400
+1049000 6299300 70
+1028800 6323900 1021
+1023300 6334100 1333
+1054900 6301300 270
+1023000 6318000 714
+1040800 6311700 448
+1050300 6313600 637
+1006000 6290700 433
+1018300 6306200 920
+1030800 6296100 180.5
+1058900 6310300 657
+1013200 6358700 1988
+1034000 6339100 1639.5
+1018200 6279800 243
+1048100 6313000 526.5
+1031300 6334600 1215
+1020500 6299300 746
+1031000 6324500 987.5
+814800 6439600 826
+841200 6461700 242
+836600 6472300 269.5
+810700 6392900 326.5
+804200 6394100 496.5
+776800 6412100 1135.5
+796800 6398200 744.5
+792700 6382800 603.5
+833000 6433300 628.5
+810500 6386800 266
+797000 6358100 291.5
+827200 6373400 242
+839600 6415400 320.5
+845500 6429400 379.5
+778600 6375900 627.5
+826900 6421500 575
+834400 6426000 623.5
+787700 6385700 802
+823600 6405100 440.5
+788100 6373800 549.5
+836400 6428700 504
+832500 6406800 476.5
+830000 6413100 491
+845300 6434800 275
+800000 6401400 711
+772100 6401100 1140
+822600 6452900 912.5
+819300 6385300 351
+839500 6459600 271.5
+840400 6436100 360.5
+833500 6442200 348
+809500 6421700 838.5
+836400 6455700 272
+832500 6420700 553.5
+832400 6438800 432.5
+792500 6379100 551
+821800 6389200 417
+822200 6407400 630.5
+842900 6419600 312.5
+792100 6363800 307
+830400 6436400 568
+812500 6417400 846.5
+819300 6395400 608.5
+806000 6408000 962
+787800 6371200 347.5
+794100 6413100 1345
+825700 6425800 663
+799200 6409400 1038
+829800 6425800 752
+825100 6379200 328.5
+797900 6422900 1277
+815600 6401300 703
+802700 6381900 245.5
+802700 6367700 323
+800000 6356400 283
+802600 6417400 1106.5
+799400 6386000 758
+835000 6403700 252
+810400 6403100 847
+842500 6415700 328
+821400 6382100 393
+808000 6427400 760
+822500 6403100 648.5
+828600 6455600 775
+821700 6459500 915.5
+824900 6414800 473.5
+800400 6398900 589
+836600 6464600 351.5
+826800 6451400 829
+821600 6393800 580.5
+833600 6384300 257.5
+791600 6409200 1278.5
+838100 6466400 321
+800900 6392400 590
+790800 6403400 987.5
+822300 6364200 225
+791800 6377000 493.5
+810000 6390000 286.5
+806600 6431500 828.5
+832400 6415800 453
+844000 6439300 272.5
+841600 6453500 264.5
+789600 6388200 950.5
+818300 6421700 570
+811000 6368500 247
+826600 6405800 511.5
+804100 6426800 905.5
+792000 6360800 323.5
+812800 6373100 398
+807400 6432400 871
+830600 6472000 494
+788300 6396900 1016
+828900 6360000 197
+837600 6474000 265
+795600 6364700 181
+833900 6463200 405
+828900 6399100 521.5
+827300 6446200 780.5
+820700 6448000 986
+824600 6433100 601
+819200 6420900 662
+831100 6415100 385
+804900 6423200 845.5
+836700 6430500 499
+818400 6428200 755.5
+823900 6429800 645.5
+786200 6403800 1160
+790300 6375800 555
+829900 6423200 654.5
+776300 6385600 890
+801700 6384500 361
+840100 6468700 257.5
+828700 6395800 495.5
+830800 6453300 450.5
+797400 6379500 315.5
+825500 6419000 473
+796000 6378100 428.5
+832700 6398900 433
+805400 6380900 232.5
+808300 6397200 596.5
+780600 6391100 1128
+815200 6385000 306.5
+785300 6372400 617
+789000 6411100 1255
+834300 6377400 227.5
+807100 6388100 362
+824100 6396000 677.5
+812300 6384500 241
+819600 6367100 351.5
+829300 6372500 228
+831500 6471500 558
+830700 6450700 666.5
+781400 6416600 1058
+818800 6443400 861.5
+774900 6400600 1259.5
+815100 6447900 992.5
+809900 6367100 301
+814300 6357400 264
+816700 6410300 817
+806900 6418000 892.5
+830700 6464900 636.5
+806500 6389700 401
+839800 6462400 271.5
+808200 6377200 213
+811200 6381200 210.5
+799300 6382600 483
+832500 6455800 317.5
+803200 6416200 1053.5
+820200 6456600 1002.5
+788400 6417300 1281
+835500 6397200 356.5
+833400 6411900 504
+785400 6382000 787.5
+831800 6465700 556
+811200 6382300 222.5
+817600 6437300 738
+847900 6427900 256.5
+810400 6425500 710
+799800 6429000 1005
+826600 6405300 475
+800000 6376800 290
+798500 6405300 929
+795000 6393000 978.5
+792700 6397200 962.5
+802800 6383500 283.5
+822500 6372800 426
+785500 6361400 558.5
+838800 6447100 297.5
+817300 6427100 719.5
+824300 6421100 563
+806900 6370400 266.5
+783800 6414100 1098
+835400 6470100 432.5
+800700 6419500 1103.5
+817900 6379100 332
+831600 6402400 377.5
+844200 6442600 311.5
+811000 6400200 545
+842700 6444100 263.5
+798400 6376400 221.5
+838300 6407600 233.5
+841200 6465300 248
+799600 6393900 769.5
+829800 6459900 598.5
+803100 6403700 979.5
+828000 6444300 721
+812700 6428000 801
+806800 6373600 166
+817600 6414100 701.5
+781200 6400300 1145
+809100 6379800 246
+818900 6391100 447.5
+817500 6394200 687
+775800 6395200 1227
+809300 6441900 940.5
+771000 6393000 1169.5
+830000 6438800 646.5
+788900 6381800 597.5
+819500 6434000 775
+800100 6389500 784.5
+810000 6435500 886.5
+824600 6459600 646
+797900 6424900 1256.5
+823500 6423900 647.5
+807700 6421100 791.5
+803400 6402100 731
+791800 6373400 403.5
+808300 6386000 313.5
+796600 6374600 305.5
+836400 6408400 297.5
+835200 6389100 368.5
+792500 6388400 901.5
+789900 6369300 265
+814200 6395800 460.5
+839800 6396900 276
+796600 6385600 738.5
+835500 6400700 341.5
+829300 6379300 236.5
+802200 6397100 421
+834300 6407600 397.5
+790100 6368000 537
+823200 6443300 840
+828300 6405200 488.5
+836700 6391500 373
+812300 6390800 249.5
+802000 6399400 644.5
+841200 6455800 261.5
+811800 6405200 920.5
+826600 6416900 428.5
+775400 6405500 1232.5
+796900 6410900 1303.5
+780000 6407800 1246.5
+812200 6393200 293
+831100 6461500 508
+819200 6406500 734.5
+824900 6357300 125.5
+825100 6389500 448.5
+842100 6447300 280.5
+828200 6413100 378.5
+828600 6430800 714
+814100 6380900 299.5
+779900 6381000 792
+811800 6362200 224
+832600 6467800 593
+804000 6373100 182
+807700 6393400 396
+824700 6409400 520.5
+786900 6369800 557
+827500 6466500 635.5
+831000 6365200 231.5
+803700 6389200 559.5
+842000 6450800 252.5
+805300 6383000 304.5
+841600 6432700 425
+836600 6419300 473
+795600 6402200 947
+835700 6446100 370.5
+826700 6437400 669
+811900 6396300 353
+802000 6413200 1251.5
+814200 6408700 879.5
+807500 6403000 858
+831000 6394500 410.5
+811000 6447900 946
+821800 6412600 622.5
+814500 6443000 872
+803400 6370500 173
+814700 6404600 791
+837700 6448800 457.5
+844800 6436900 288.5
+835700 6462900 357
+786400 6406900 1191.5
+837500 6441000 334.5
+826900 6385300 344.5
+827600 6392100 497.5
+814200 6425900 678.5
+804900 6395200 372.5
+818100 6454000 978.5
+835500 6466700 463.5
+812300 6423900 665.5
+819000 6425500 607
+802600 6379700 261
+834100 6436000 519.5
+815300 6423600 646
+821900 6457000 816.5
+820300 6417600 632.5
+843400 6423700 390.5
+803800 6361500 328.5
+838400 6452500 401.5
+802000 6387300 520.5
+806900 6413000 1081
+829100 6402900 492.5
+838100 6470300 253
+793400 6369800 225.5
+834100 6451100 452.5
+809000 6361700 350.5
+840000 6463400 259
+813500 6400600 562.5
+802300 6395400 443
+805000 6428500 857.5
+807700 6399300 578.5
+812900 6414600 839.5
+813800 6419800 875.5
+840700 6412700 245
+839700 6403000 266.5
+804200 6391400 581
+771100 6403900 1132.5
+815400 6387300 283.5
+805200 6402600 810
+838300 6461200 298.5
+833200 6471200 535
+816800 6391400 415.5
+818200 6407500 730.5
+830000 6440900 542.5
+810600 6413900 1008
+846100 6422800 192
+780700 6413100 1050.5
+837800 6433800 466
+839200 6449400 309.5
+779400 6403700 1253
+804100 6436700 948.5
+822200 6399300 632.5
+783300 6389500 1152
+845000 6420000 164.5
+803000 6384400 398
+808600 6394900 373
+834500 6458900 304.5
+808100 6376000 236.5
+810300 6392200 295.5
+829700 6389000 412
+777000 6390200 1001
+799800 6368000 173.5
+798300 6363200 289.5
+828500 6357500 76.5
+821600 6437800 766
+831500 6446000 560.5
+794500 6372200 266
+771400 6398200 1067
+845700 6431100 295
+826800 6959500 176.5
+848700 6928700 245.5
+845600 6923700 243
+807700 6973200 265.5
+832200 6954200 221.5
+822400 6938100 171
+799000 6933800 107
+844100 6952100 227.5
+795800 6972000 242.5
+792600 6981900 287
+816000 6962300 227.5
+820400 6982700 236
+803100 6967500 252.5
+832700 6937900 218
+830100 7003600 169
+803200 6932600 107
+836400 6910000 162.5
+827500 7002900 225
+805600 6935100 87
+816400 6966500 218.5
+845400 6929300 268.5
+843400 6913600 190.5
+824200 6935300 161
+800700 6965200 232
+870000 6948700 248.5
+835300 6956900 277.5
+823600 6940500 209.5
+842200 6911000 187.5
+807600 6966500 228
+816700 6953500 220.5
+797700 6974600 265.5
+816400 6923600 139.5
+823100 6929500 145.5
+836800 6942500 210.5
+826700 6972400 229.5
+835300 6951000 232
+845900 6912400 201.5
+794000 6948500 130
+791100 6925200 104
+854000 6947400 255
+840400 6922200 171.5
+843000 6950100 234
+829100 6963000 226.5
+793300 6920600 126.5
+812300 6921900 148
+794500 6973000 228.5
+824000 6992600 246.5
+807400 6977500 310
+830000 6976400 319.5
+822300 6911300 151
+826200 7002000 229.5
+841900 6941500 228.5
+832600 6929000 202.5
+789400 6946200 147
+864700 6952600 291.5
+825600 6921200 144.5
+850400 6955300 196
+818000 6919200 142.5
+813300 6948600 219.5
+804600 6938700 95
+803300 6948700 192
+825600 6965400 204.5
+820700 6931400 138
+826500 6908600 148
+814500 6937600 130.5
+845300 6962100 338
+811300 6933400 92
+846800 6949100 224
+804700 6963400 249.5
+836300 6930500 194.5
+819000 6909500 154.5
+842700 6954900 195
+790100 6950700 167
+814100 6952800 235
+833700 6927300 202
+820200 6969200 237
+830500 6956000 221.5
+810700 6969800 198
+804400 6943000 122
+810300 6965800 225
+844400 6933300 253
+817800 6965400 180
+822400 6934200 143
+811200 6938700 116.5
+832500 6911700 140.5
+816600 6946800 232.5
+835300 6912700 142.5
+860800 6948500 218
+814200 6943300 181.5
+802800 6983100 330.5
+813500 6942100 147.5
+821000 6939800 194
+817700 6941000 168.5
+836000 6953400 244.5
+781600 6942000 121
+787500 6936700 103.5
+808700 6936400 87.5
+791400 6974300 230.5
+834400 6932400 204
+838100 6945900 248
+816200 6925500 138
+826900 6913700 114.5
+781700 6925700 86
+793900 6963500 230.5
+809200 6928900 122
+838500 6949300 253
+797600 6923500 112
+821300 6953000 253.5
+839900 6918600 159
+808800 6963500 258
+821100 6920500 110
+808600 6948900 198.5
+823500 6999700 206.5
+829700 6952700 224.5
+784900 6932700 101
+790300 6931400 114.5
+807400 6931100 122
+850100 6953600 206.5
+840100 6955700 233.5
+821200 6908200 151.5
+817900 6967600 195.5
+784000 6952500 172
+818500 6951200 235
+786900 6946400 144.5
+864100 6950300 260.5
+797600 6943500 127.5
+833700 6909200 139
+832300 6935500 192.5
+809000 6918300 142.5
+827800 6936400 185
+822400 6991400 299
+812700 6935900 99
+802500 6956300 208.5
+808600 6913300 161
+837100 6938500 246
+805000 6922800 121.5
+829600 6957100 197.5
+858900 6944500 260.5
+784200 6934100 98.5
+841800 6913100 184
+803600 6934900 112.5
+832400 6949600 226.5
+818600 6939000 164.5
+805700 6912100 132.5
+830500 7005900 159.5
+820800 6945200 232.5
+812200 6962800 234.5
+808300 6958800 243
+807600 6932900 110.5
+806100 6972000 242.5
+797700 6940400 109.5
+838900 6961600 283.5
+831400 6963200 220.5
+784200 6931900 93
+803400 6923100 120
+846000 6956400 215
+840100 6915100 179.5
+790200 6937400 103
+847400 6954400 201.5
+841900 6926900 228.5
+800900 6969800 250.5
+827700 6964200 215.5
+801400 6938300 115.5
+843400 6959700 289
+778700 6934800 100.5
+827400 7004600 179.5
+815100 6967400 158.5
+799400 6953100 167.5
+839600 6935600 226
+819800 6916400 151
+856200 6952900 194
+828200 6928700 172
+806200 6967800 233.5
+797300 6967600 245
+799100 6962100 240.5
+776400 6926500 77.5
+819500 6957000 228
+802900 6971000 256
+840400 6952000 234.5
+800400 6922900 117.5
+833600 6955000 223
+838200 6958500 177
+815300 6961600 244
+798100 6949000 131
+815300 6972400 268.5
+794800 6967300 228
+820700 6967900 250.5
+824600 7002100 171.5
+780000 6925400 79
+793200 6950700 142.5
+829900 6922600 179
+816100 6924300 139
+867600 6946900 238.5
+820600 6960400 212
+785600 6955300 187
+827400 6958400 177
+844400 6916100 195
+801200 6947100 134.5
+819300 6954800 232
+824500 6977700 307
+861000 6946100 195.5
+838100 6916500 165
+811500 6944800 177.5
+825700 6969900 246.5
+824200 6958100 192
+858400 6949100 221
+790100 6955300 194.5
+833400 6952000 208
+816900 6950900 237
+835200 6946200 233.5
+791200 6936500 101
+825200 6945600 235.5
+823400 6943200 222
+800000 6977300 303.5
+835200 6963400 278
+834200 6944100 179
+841800 6948800 238.5
+828500 6992600 329.5
+787800 6941100 118.5
+823700 6960300 203
+840000 6927800 213
+796800 6959700 213.5
+795100 6936600 104
+845900 6942600 233
+810800 6978000 290.5
+814600 6927300 136
+792300 6943300 126.5
+824200 6909000 144
+818400 6925300 103.5
+817300 6971400 266.5
+838000 6920500 197
+818200 6958000 242
+820800 6956200 202
+831700 6970700 286
+828500 6976400 248.5
+794700 6924300 112
+832500 6977700 329
+849000 6939600 229
+849000 6949700 248
+782000 6934800 102.5
+830200 6924100 181.5
+809800 6922800 137
+828400 6915100 140.5
+797200 6934400 107
+839300 6959800 214.5
+829300 6969400 276.5
+823900 6965000 228
+788400 6981000 271
+816200 6969200 197
+847600 6931800 242.5
+778200 6945500 128
+863000 6953400 285.5
+820200 6933300 122
+791200 6968500 217
+820400 6918900 143.5
+820500 6942700 216
+810800 6972400 238
+794300 6959200 215.5
+803900 6912200 135.5
+857100 6954800 232.5
+807000 6938100 101
+802800 6975300 298
+861200 6952400 242.5
+836100 6928000 191.5
+843400 6921100 194.5
+825500 6919200 123.5
+800500 6932700 108.5
+815100 6934900 113
+822500 6989700 289
+796100 6917500 132
+831100 7000600 238.5
+859200 6954100 266.5
+803900 6973000 251.5
+836400 6924500 208
+809300 6981800 256
+809200 6946400 186
+795000 6954100 162
+832600 6915300 162.5
+817700 6983900 293
+840400 6933600 236
+821800 6963100 184
+778100 6943300 111
+806400 6954000 231.5
+799100 6935400 106.5
+813100 6943100 173.5
+833900 6961400 200
+847900 6957800 306
+841500 6961400 312
+823400 6995900 217
+833100 7004300 205
+853300 6957100 253.5
+781600 6951600 148.5
+828000 6957000 187.5
+813400 6963800 224.5
+815600 6957900 247
+826800 6953000 236.5
+821700 6980600 257.5
+831000 7002500 222
+822700 6977100 264
+790000 6924600 99
+853200 6949800 242
+856700 6950300 226
+863900 6942100 267.5
+846700 6947800 233
+862800 6946500 222
+822900 6950500 248
+818900 6970800 256
+792500 6960800 212
+780000 6929200 84
+778900 6938300 99.5
+809500 6970900 269.5
+854100 6954200 192
+818500 6921800 142.5
+828700 6961000 197.5
+784100 6933100 76.5
+827100 6974400 264
+817000 6977800 264
+786300 6954700 185
+828300 6907600 144
+826600 6955300 217
+808300 6942900 134.5
+841500 6946600 248.5
+792800 6924900 110
+823900 6999700 237.5
+831000 6964700 235
+835000 6907400 145.5
+818500 6933200 104.5
+782300 6945700 129
+800000 6917300 136.5
+816600 6928700 107.5
+826000 6931500 171
+821100 6964700 172
+823500 6923400 137.5
+825200 6954000 249.5
+827700 6955300 212.5
+829100 6917800 158.5
+796400 6951700 143.5
+824800 6949800 239.5
+843800 6957800 227.5
+788600 6970200 211
+797600 6970900 247.5
+808300 6924500 131
+820200 6944000 223.5
+787900 6924900 99
+850100 6947200 243.5
+819400 6974600 319
+793300 6939100 106.5
+841500 6956200 195
+866800 6954500 291
+865600 6949100 228.5
+816700 6934400 128.5
+812400 6952700 243.5
+818400 6936400 142.5
+814400 6932100 105
+794200 6935500 106
+807600 6922100 116.5
+843800 6934400 233.5
+806800 6982300 348
+850700 6940300 221
+814600 6946700 207.5
+812500 6971900 283
+851100 6928200 261
+827300 6966200 229.5
+778600 6929100 93.5
+803500 6965100 235.5
+846100 6918900 214
+810800 6948700 221
+841000 6916800 159.5
+803000 6945500 130
+829700 6913700 144.5
+840800 6927700 235.5
+853900 6952300 189.5
+864700 6946000 209.5
+811100 6951500 228.5
+808500 6938600 103.5
+840500 6962700 310
+829700 6912600 122.5
+804600 6970400 251.5
+833700 6914100 157.5
+796700 6964300 237.5
+800000 6972700 259
+855500 6955600 250.5
+793600 6927500 115.5
+801200 6950400 183
+839900 6953200 247
+848000 6952000 222
+846600 6959500 312.5
+816900 6943100 180
+823100 6916600 124
+791800 6946400 141
+820700 6913300 154.5
+801900 6912400 131
+795800 6945100 129
+812800 6969100 190.5
+819200 6923200 112.5
+788500 6929100 109
+807400 6971500 224.5
+791000 6976600 239
+840000 6957600 225
+795400 6975000 281.5
+819000 6960600 212.5
+814300 6969700 200
+829700 6946400 230
+826200 6961500 182
+833200 6957500 194.5
+796100 6955600 171.5
+822400 6956400 233
+820700 6948800 243.5
+830300 6930400 181
+826900 6927000 156
+823800 6927400 146.5
+798000 6928600 122
+798100 6938600 111.5
+835900 6917300 180
+863500 6945100 258
+829400 7002100 223
+840000 6924700 190.5
+792000 6979100 280
+862200 6944000 242.5
+816000 6964200 230
+821800 6926500 113.5
+806100 6964500 241.5
+804800 6927600 136
+819800 6954500 232
+825900 6940600 210.5
+839500 6940700 264.5
+794100 6943500 113
+844700 6909500 192
+806900 6917500 145.5
+790500 6971800 209.5
+815000 6916900 156
+843600 6956200 198.5
+869200 6947300 258.5
+866500 6944600 279
+785400 6925700 94.5
+784300 6925800 92.5
+815300 6930300 98
+798200 6950100 135.5
+810100 6985300 337.5
+795100 6940700 105.5
+839000 6937600 258.5
+793200 6975400 246.5
+832100 6961100 203
+789100 6965000 224
+851000 6958400 280.5
+857300 6948000 252.5
+814600 6951400 229
+835800 6934200 208.5
+788700 6937200 111
+835500 6936700 221.5
+824300 6913800 145.5
+808100 6940200 106.5
+812900 6928200 129.5
+828500 6975000 262.5
+829400 6966000 251.5
+818000 6960900 235.5
+836000 6938900 241
+829800 6941000 210
+805400 6932200 119
+837800 6930000 204
+803000 6926300 133
+829000 6926600 172.5
+781100 6930500 89
+582600 6198100 986.5
+554400 6219500 540
+575100 6188200 1474
+596400 6212700 570
+556900 6233300 276
+583100 6219900 519
+547200 6223300 453
+586700 6218600 497.5
+605200 6220600 379.5
+601200 6209900 511.5
+586300 6210700 541.5
+596200 6187000 863.5
+570500 6231800 292
+571800 6225600 337.5
+574100 6206500 1151
+569700 6226800 356
+604600 6197600 1497.5
+612800 6213200 418
+567400 6209800 964
+596500 6186400 1260.5
+550000 6209500 821
+593200 6216100 527.5
+602000 6215000 475.5
+586800 6220800 388
+595300 6187100 1018.5
+581400 6217300 542
+535800 6219500 379.5
+603000 6205400 679
+590400 6223700 319
+569500 6211600 565.5
+531000 6206300 1024.5
+599400 6209200 548.5
+541500 6207200 784
+575300 6218600 478
+584000 6228700 319
+552800 6220500 452
+587100 6193400 827
+602900 6209300 599
+597700 6187100 1500.5
+588400 6204900 667.5
+547200 6216600 482.5
+555600 6203200 940.5
+545700 6225100 424
+540200 6207600 860
+579500 6241400 261
+604900 6182000 1281
+568700 6223600 387.5
+611600 6226100 394
+565700 6243300 256
+572900 6216300 533.5
+544400 6211000 641.5
+543700 6221700 451.5
+623800 6181700 1305.5
+595600 6221900 319.5
+571000 6220800 428
+582000 6222700 487
+587900 6201900 958
+578500 6218200 518.5
+577400 6235900 313.5
+590000 6208400 677.5
+564700 6226800 366.5
+610200 6202600 688.5
+549800 6213100 535
+592700 6202800 781.5
+529700 6206300 1101
+604800 6180700 1554
+562700 6231100 321
+604500 6173800 1884.5
+589300 6190000 1013
+594900 6215600 544.5
+600600 6186100 1287.5
+545500 6222800 460
+534900 6200400 1253.5
+613100 6217300 429.5
+613600 6224300 370
+575300 6211200 801.5
+568800 6235900 290.5
+540300 6213400 807
+606900 6210700 534
+551600 6208400 633.5
+564900 6200200 1269.5
+574900 6223600 417
+592600 6240100 275.5
+596200 6188700 1456
+598400 6204800 751.5
+555300 6208000 938.5
+538500 6205300 724
+528000 6205600 1431.5
+588000 6189900 1091.5
+602000 6219600 370
+562600 6232900 329.5
+586300 6215400 510.5
+554000 6198900 987
+606900 6206000 614.5
+541200 6200800 1738
+587500 6204100 901
+576600 6220000 468.5
+553000 6206400 818
+592000 6213100 544.5
+539900 6201700 1341.5
+563300 6214700 457.5
+584300 6191900 884
+586300 6232800 305.5
+592400 6187900 1131
+577900 6233200 314.5
+603000 6181900 1727
+579000 6229400 331.5
+581600 6196200 1372
+608200 6221700 369
+575500 6186400 1930
+566700 6201900 1140.5
+583100 6190100 1253.5
+608800 6178700 1801.5
+585500 6230600 325
+560500 6233700 324.5
+606700 6216000 396.5
+615700 6214200 454
+601400 6200300 1445.5
+571700 6213800 523
+566700 6216600 499.5
+547900 6220300 503.5
+601600 6166400 2047.5
+567200 6224200 382
+588000 6198800 1017.5
+573100 6223800 399.5
+534300 6199600 1711
+572600 6235100 300.5
+580800 6186700 1851
+555800 6212900 615
+597000 6216300 474.5
+609400 6198500 815.5
+594500 6189700 1393.5
+598500 6202800 744.5
+542100 6227400 448
+591500 6189000 740.5
+580500 6206300 1071
+589200 6210400 610.5
+584100 6238300 291.5
+551000 6199100 1448
+590500 6202500 1099
+575800 6207300 895
+574500 6235400 308.5
+606800 6201500 748.5
+560200 6223800 442
+614200 6221500 363
+598400 6207700 656.5
+596800 6231500 304
+606000 6209700 504.5
+599500 6221300 348
+609100 6217800 405
+608100 6188100 1499.5
+577600 6213600 651.5
+551500 6189200 1712
+610200 6215500 398.5
+583200 6192600 1129
+598300 6186700 1360
+546200 6216100 462.5
+606700 6180800 1619.5
+613100 6219700 382.5
+580700 6240600 284
+596900 6220700 326.5
+588100 6217200 450.5
+585800 6213200 462
+590300 6187500 1263
+599000 6222600 322.5
+587000 6205800 723
+580300 6214100 524
+605800 6181800 1381.5
+563900 6189400 1708.5
+612900 6201100 778.5
+596200 6205800 725
+584700 6191500 915.5
+548700 6211300 793.5
+586300 6208300 645.5
+548000 6213200 473
+572000 6211600 547.5
+605900 6204400 646
+581800 6229700 346
+542900 6213100 763.5
+562300 6201400 965
+586600 6213700 522
+562200 6228600 300
+532700 6199400 1798.5
+560300 6222200 559
+623700 6180200 1768.5
+603200 6223100 372
+564900 6233100 318.5
+536700 6217700 392
+595200 6228000 282
+608500 6214900 454
+578100 6227400 372
+535100 6206400 837.5
+600800 6219000 383.5
+595100 6189000 1415.5
+589900 6221200 337.5
+626200 6180300 1049.5
+579000 6208900 762.5
+573000 6227500 338
+610500 6204100 600.5
+591800 6217200 465
+580200 6231700 337.5
+586900 6197100 675
+552800 6197800 1666.5
+608200 6211500 506
+580400 6188600 1212.5
+586900 6225100 364.5
+592500 6188200 550
+598100 6226600 329.5
+592600 6189200 987
+598100 6187900 1536
+597700 6186000 992
+538900 6207000 719.5
+559600 6231200 312.5
+607900 6208500 571.5
+538000 6223500 393.5
+568500 6209300 1053.5
+600500 6183400 1430.5
+582400 6207900 502.5
+552800 6222600 436.5
+602000 6183200 1125.5
+622600 6181700 1789
+539800 6205500 793.5
+588200 6221800 306.5
+581900 6226100 342.5
+595300 6225200 293
+589400 6195800 908.5
+584200 6189500 746
+566900 6198000 1431
+578600 6186500 1433.5
+591400 6194300 1357.5
+592700 6209000 685.5
+564700 6212700 646
+603700 6210800 499.5
+580400 6198700 1281
+604100 6220200 379
+593800 6227700 288.5
+611000 6210500 460
+589200 6215900 490
+569200 6229200 323.5
+533800 6206300 1138
+551300 6226900 395.5
+580100 6207300 687.5
+579000 6224100 380
+537400 6204400 640
+533600 6206900 985.5
+588000 6192100 981.5
+557800 6190400 1681.5
+555600 6221600 540
+605700 6213800 501
+609100 6210600 463.5
+544300 6217500 469
+626900 6179800 1143
+550900 6206900 821.5
+590400 6189700 985.5
+603600 6201600 712
+616500 6209100 466
+599600 6185400 879
+546600 6214000 386
+558200 6200800 800.5
+564900 6214800 478.5
+577600 6231300 320
+575400 6212900 478.5
+598300 6228200 327
+589700 6233000 268
+597000 6218800 384.5
+583700 6220800 395
+566400 6221500 427.5
+577400 6185100 1656
+600500 6222200 343
+543200 6217600 436
+583100 6186200 1784.5
+583200 6209800 580
+602100 6205100 663
+536600 6200800 1000
+553800 6200900 791.5
+552900 6215500 560
+609800 6188200 1493.5
+539200 6204400 919
+610900 6206900 574.5
+614000 6220000 393.5
+595700 6229500 265.5
+582600 6206300 1013
+626100 6178100 1690.5
+598700 6185700 1420.5
+593700 6187300 1209
+607600 6203500 624.5
+585300 6189000 1251.5
+579100 6242300 273
+531400 6206000 1100
+539000 6201800 1693
+538400 6216400 523
+544100 6208800 1010
+598800 6217700 432.5
+591300 6187000 1733
+537100 6203200 1114
+550900 6220600 468
+579500 6235200 309
+595400 6201900 1279
+583400 6196600 766.5
+591800 6187900 647.5
+600700 6207200 583.5
+596000 6224400 293.5
+534600 6206200 1106.5
+624600 6180000 1707
+577000 6186700 1118.5
+585900 6195200 825
+531800 6200200 1522.5
+585500 6197800 919
+611800 6207000 584.5
+570200 6209700 927.5
+568800 6239000 273.5
+548400 6202700 1213.5
+536600 6216700 463
+592300 6219100 396.5
+561500 6217000 457.5
+559900 6212200 722.5
+529800 6205800 1176
+560000 6195900 1239.5
+577700 6188100 1399.5
+593300 6205800 745.5
+543800 6216500 433
+589100 6229300 278
+581200 6211300 699
+536000 6205600 1096
+579900 6194900 1416.5
+585000 6195100 757.5
+601200 6183700 1080
+602100 6186200 1340
+582500 6186100 1758.5
+607000 6179500 1640.5
+578400 6243000 249.5
+557400 6231300 327.5
+815500 6821800 147
+772100 6761700 184
+778000 6764000 215
+784900 6801800 135.5
+763400 6791900 200
+784400 6762500 253
+819900 6810200 146.5
+827400 6791700 256.5
+777400 6792100 130
+805700 6786500 216.5
+752600 6798800 201.5
+782000 6836500 132
+778500 6773700 141.5
+775800 6782800 173.5
+796800 6766600 259.5
+781400 6797300 116
+807300 6813900 132
+759800 6796800 182
+767200 6814100 117.5
+778000 6786300 147.5
+816500 6783900 284
+782800 6815000 151
+774200 6765800 177.5
+800900 6828700 150
+799600 6786800 155.5
+826600 6801500 250
+783100 6808300 169
+774200 6807500 152
+775500 6827900 94.5
+804800 6812100 131.5
+780000 6793500 122
+834200 6793000 247.5
+811400 6791300 208.5
+801100 6782000 191
+779900 6782200 144
+762700 6822800 92
+769700 6828500 96.5
+792900 6774300 208.5
+786400 6826500 116
+771600 6814100 142.5
+773600 6828000 99
+806400 6813300 124
+813200 6809400 135
+746100 6792800 150
+822600 6791000 277.5
+819800 6779000 303
+792200 6830800 144.5
+784500 6769600 210.5
+783700 6816600 155.5
+791400 6777100 199.5
+802200 6785700 199.5
+747200 6824200 98
+811200 6812600 138.5
+777400 6801800 131
+818000 6811900 141.5
+762500 6774900 215
+761600 6810100 148.5
+820200 6786900 266
+831900 6790200 248
+777800 6799900 128
+790900 6790600 135
+786800 6828300 124.5
+796900 6784000 171.5
+752900 6792900 179
+829500 6805000 191
+805200 6772200 239
+800900 6819900 132
+779100 6829500 102
+748200 6816000 122.5
+776900 6829700 107.5
+775700 6786100 218
+742600 6828800 112
+752000 6806600 149.5
+786200 6784900 149.5
+793500 6805800 150.5
+737100 6821600 86.5
+800900 6812700 142
+782600 6785300 145.5
+807000 6789400 194.5
+788300 6822500 140
+744600 6811600 151
+778700 6787400 136
+756700 6800400 165.5
+783400 6787800 130
+775900 6762100 223.5
+833900 6780900 274
+750500 6815800 118
+811400 6778300 272
+736900 6812600 103
+817400 6816400 135
+737600 6818400 96
+783500 6804200 162.5
+823400 6796900 233
+771100 6801000 206.5
+781300 6795700 120
+761500 6801600 179.5
+797100 6783000 172.5
+804000 6773600 236
+811700 6765100 265
+789700 6825900 126
+765200 6774400 154.5
+813300 6819100 115.5
+760000 6783000 237.5
+806500 6770800 251
+768400 6778600 208
+764500 6766700 132
+741300 6819700 120
+765700 6823700 87
+762900 6772500 147.5
+762700 6779100 229
+812100 6774700 258
+796700 6822300 138.5
+756300 6811800 144.5
+802100 6817600 121.5
+802200 6775500 217.5
+800200 6823100 130
+734500 6825700 113
+799300 6826200 146.5
+757900 6795300 181
+777100 6781700 163
+803600 6807200 132
+772400 6809500 113.5
+741300 6823700 80
+774400 6810000 143.5
+793600 6818000 152
+817600 6813900 140
+816900 6772300 265.5
+778600 6805500 154.5
+745300 6816900 130.5
+812900 6811200 139.5
+775900 6823000 114
+828400 6809600 161.5
+781900 6822800 118
+767300 6796500 200.5
+790500 6783200 162.5
+824800 6796000 226
+748500 6797000 203
+743900 6824500 135.5
+788200 6826400 117
+822200 6796700 218.5
+836200 6784900 258
+776600 6795800 182.5
+819800 6776900 293.5
+826500 6804900 178.5
+743200 6830900 92
+789900 6800500 154
+765200 6821100 95
+800000 6788000 160.5
+741100 6832500 129
+757900 6789200 193
+781600 6802800 111.5
+791200 6824800 136
+801700 6771000 235
+804900 6797900 164.5
+790500 6805100 161.5
+772200 6780200 208
+802100 6815900 117.5
+766400 6790200 223
+813700 6820200 142.5
+814300 6783300 273.5
+776500 6804700 139.5
+775900 6770200 176.5
+808500 6781500 238.5
+788700 6795400 119.5
+758400 6823800 83.5
+827900 6789400 274
+786900 6812700 165.5
+813900 6815600 121
+791200 6837300 154
+817000 6800700 184
+787300 6799500 134.5
+771800 6785500 236.5
+796500 6776900 208.5
+754600 6811600 141.5
+799700 6817700 126
+808800 6821400 135.5
+805400 6817000 131.5
+782200 6811400 181.5
+798900 6820000 128
+742200 6813800 140.5
+733700 6817100 90
+809000 6794100 188.5
+815700 6803000 153
+738300 6830400 133
+803100 6794100 155.5
+809700 6775600 242.5
+770500 6778500 201.5
+795100 6817200 150.5
+798700 6807800 142
+743400 6811600 141.5
+753700 6824200 89.5
+803600 6778200 215
+788900 6841500 160
+789300 6765700 264
+730600 6818300 72.5
+778200 6798200 117.5
+807800 6769800 241
+825900 6793700 236
+802800 6774200 224.5
+812400 6800400 172.5
+832300 6806700 213
+780100 6842700 145
+793100 6809400 166
+809900 6826700 131
+790800 6833500 132.5
+779700 6762500 236.5
+821600 6794300 239.5
+778600 6827300 95.5
+802600 6789600 180
+785400 6796400 116.5
+800300 6817200 124.5
+777200 6800700 107.5
+759400 6786100 212.5
+782500 6793500 122
+792600 6843300 174
+754600 6804100 188
+834300 6802000 251
+807900 6825000 137.5
+782700 6775700 154.5
+822900 6786900 288.5
+767900 6771600 150.5
+749600 6820600 108.5
+835300 6795000 276
+807600 6817300 137.5
+769500 6819900 105.5
+817600 6818500 120.5
+807700 6810900 125.5
+764000 6824600 87.5
+794200 6823400 149
+792200 6824400 142.5
+794100 6783900 161
+766100 6780200 218.5
+816300 6824300 148
+795100 6772900 229
+809500 6808900 129.5
+731800 6816500 86.5
+779500 6796100 121
+808400 6811400 134.5
+778900 6783700 148.5
+813200 6797200 198.5
+746900 6816900 129.5
+789300 6772500 218
+816900 6817400 131
+746200 6827900 100.5
+777900 6782700 172.5
+832600 6797500 269
+788700 6762700 298
+774100 6789800 203.5
+828100 6786100 287
+810100 6766700 251
+768300 6822000 99
+814300 6819600 115.5
+807600 6779500 243
+831200 6794800 245.5
+817400 6820800 119.5
+800700 6790800 156
+808700 6816400 114
+749800 6793100 172
+788300 6787100 128
+823900 6788600 291.5
+806100 6824500 145.5
+789300 6770900 243
+782900 6800500 117.5
+777700 6769800 160
+768600 6761400 155.5
+818200 6807900 149
+784800 6773700 183.5
+813600 6806700 153
+770100 6794400 216
+788800 6807100 174.5
+813300 6788500 244
+836000 6799100 291
+770800 6772700 137.5
+822500 6797700 209
+782800 6764700 234
+826700 6793900 252
+787500 6801900 140
+799300 6795300 151.5
+822600 6814400 140.5
+748400 6810100 150
+757200 6818700 106.5
+780800 6789300 131.5
+804500 6794000 158.5
+777900 6784600 168
+781900 6837900 138
+763400 6785200 232.5
+757000 6807800 152
+816900 6779000 287
+814100 6794700 223
+811000 6781600 256
+781900 6832200 127
+782600 6776900 163
+773300 6811400 139.5
+786900 6768300 228.5
+815400 6806100 151.5
+829800 6803000 232.5
+754500 6791700 185
+747100 6805400 189.5
+796100 6792400 137.5
+791300 6787100 150.5
+820600 6790400 248.5
+790700 6835200 153.5
+781300 6785100 126
+774000 6838200 125.5
+784100 6826600 104.5
+754100 6820900 87.5
+810700 6824000 132
+788500 6809800 179
+764300 6769700 132
+795400 6825100 128.5
+784500 6786000 137.5
+787800 6797600 121.5
+774200 6835700 121
+781400 6791000 125.5
+818800 6799200 197
+773300 6793000 200
+819100 6825900 130.5
+810100 6816900 122
+763300 6776900 201
+770800 6816400 126
+795200 6815300 154.5
+766600 6808100 163.5
+768400 6816400 106
+817900 6828100 132.5
+775600 6799100 122
+781200 6826600 103
+761200 6816300 115.5
+745200 6828000 90
+783000 6818000 143
+732300 6809900 129.5
+814500 6804100 155.5
+830300 6798000 268.5
+743500 6806700 140
+772400 6797700 187
+770400 6812300 113.5
+743700 6800900 196
+764100 6795800 192
+790400 6786400 127.5
+791400 6826700 117.5
+774300 6788900 216.5
+748300 6824200 111.5
+768700 6791800 231
+767900 6799500 195.5
+790100 6775400 187
+766700 6819200 104.5
+737000 6827000 126.5
+802000 6766600 252
+777100 6773200 148.5
+749300 6786500 189.5
+775100 6819000 127.5
+743900 6805000 168.5
+811200 6818800 141.5
+754000 6795400 176
+794900 6811400 158.5
+764700 6798000 189.5
+739800 6808200 126
+788400 6790500 141
+732600 6812800 110
+793700 6760800 282
+817600 6806600 156.5
+792700 6803000 159
+761300 6803400 181.5
+819100 6821600 124
+819000 6796000 215
+824600 6783300 299
+783500 6790800 124
+767400 6828700 89.5
+785200 6793100 124.5
+780000 6800400 113
+815300 6790900 243.5
+814300 6774100 256
+833300 6796500 276.5
+822900 6808200 157
+794000 6795700 129.5
+820000 6797500 196.5
+833200 6781600 257.5
+791900 6797100 122.5
+804200 6776100 232.5
+764800 6807100 176.5
+824300 6772500 287.5
+821200 6801900 203
+832600 6800300 288.5
+813600 6780500 282.5
+779100 6766700 194
+776900 6815600 166
+784800 6790100 119
+767500 6831300 89.5
+816400 6794600 227
+732500 6822900 121.5
+798200 6823400 123.5
+780900 6823700 112
+749000 6812400 139.5
+750400 6802100 209
+824500 6803000 207.5
+774500 6785100 241.5
+811400 6807600 146
+754600 6815200 133
+737700 6812000 117
+802400 6780200 220
+804600 6815100 116
+774400 6772100 147
+817600 6801300 178.5
+809000 6788100 231
+782300 6828500 112.5
+792600 6785800 155
+775900 6781600 167
+825100 6813200 144
+812900 6782100 259.5
+822100 6826000 126
+802500 6823300 148
+776200 6808200 160
+829300 6797300 257
+794400 6763900 270.5
+768200 6769700 137.5
+782200 6769200 178.5
+796900 6770300 247
+779900 6788000 131.5
+780500 6803300 123.5
+778100 6789300 137.5
+798100 6801800 133
+771400 6830400 104
+793400 6825800 136.5
+820300 6793200 235
+803900 6820100 136
+810200 6820900 137
+746900 6790000 168.5
+732300 6819400 74.5
+797100 6779500 188.5
+798700 6789300 167
+774200 6780600 209.5
+782500 6820900 128.5
+797000 6793100 141
+764300 6829200 85.5
+611900 6252900 183
+657100 6219700 473
+647800 6248100 319
+642800 6205400 369
+612300 6250800 174.5
+608300 6259200 256
+658500 6231700 226.5
+644900 6218600 399
+672600 6217000 364.5
+664400 6246000 224.5
+636600 6181700 1550.5
+656200 6251700 609
+620400 6245000 163
+642800 6217400 317
+623600 6220200 415
+637500 6215200 328
+617600 6216200 482
+652900 6216400 521.5
+684800 6204500 423.5
+638500 6200000 488.5
+616400 6188100 1453.5
+609100 6257000 227.5
+627700 6231600 214.5
+623700 6252300 405.5
+625400 6231500 249.5
+653400 6201100 679
+629100 6245700 189.5
+658500 6220300 433.5
+598400 6234000 299.5
+689400 6229500 145
+675200 6236100 126.5
+622500 6244400 168
+621400 6232500 275
+675600 6220700 210
+645200 6230100 214.5
+687100 6241500 71.5
+639800 6203400 420
+631500 6216200 294
+625900 6188700 896.5
+648300 6252600 615.5
+639300 6211100 450
+647300 6235400 165.5
+677100 6198800 528
+693700 6238300 20
+633100 6197600 691.5
+699900 6238500 24
+659700 6219800 431
+628900 6223500 247
+644100 6248700 371.5
+659500 6222800 378
+685800 6243100 166.5
+707200 6223100 100
+674000 6244300 75
+628900 6229600 247.5
+706000 6233800 72.5
+667800 6206800 478.5
+670000 6203200 585.5
+661400 6206800 552
+638300 6196800 605
+610400 6253900 193
+645000 6225400 216.5
+647200 6223100 399.5
+631700 6242400 173.5
+621900 6236200 228.5
+635700 6233700 275
+623000 6256500 490
+610000 6250300 184.5
+608800 6246700 244
+695600 6240000 27
+605400 6246600 258.5
+677400 6239400 86
+655900 6224800 437
+613200 6235400 353
+636600 6192300 690.5
+640300 6239700 128.5
+604900 6229600 342.5
+611600 6228100 395
+613400 6237200 334.5
+620600 6209800 575.5
+620800 6189600 1341
+672400 6206500 442.5
+631500 6225400 285
+661200 6211900 442
+627600 6218500 300.5
+667100 6203300 479
+664900 6243700 163
+630800 6199400 565.5
+624400 6195000 969.5
+634200 6190900 813.5
+695400 6202600 162.5
+618400 6189700 1372.5
+681400 6222700 220
+643300 6182800 1240
+674300 6233300 137
+618300 6205500 735.5
+636500 6199400 453.5
+608100 6252300 208
+637300 6183700 1136
+615100 6247100 180
+654300 6249800 478.5
+605400 6242800 269
+690300 6236600 22
+615100 6254500 244.5
+659400 6197800 644.5
+603000 6241800 293.5
+682600 6230800 89.5
+652300 6240000 119
+605900 6244800 268.5
+607500 6231200 360
+648200 6249400 427.5
+606800 6250400 209
+691600 6242900 36.5
+663600 6218400 261
+625400 6192300 805.5
+672600 6220300 214.5
+673600 6236900 80
+619000 6219300 420
+595600 6239400 288.5
+615600 6206500 576.5
+656300 6246300 463
+681700 6208700 263.5
+631200 6196900 653.5
+622100 6202800 731
+656100 6228700 295
+615200 6186200 1564
+596400 6243100 275
+622100 6227900 317.5
+639500 6236600 140
+636300 6217800 448
+650500 6213700 635.5
+696200 6210200 275
+605700 6238500 311.5
+692700 6203600 404.5
+665900 6230200 314
+635800 6223300 229
+634800 6214700 416.5
+646000 6209800 623.5
+631600 6219700 270.5
+632500 6218600 240
+664300 6211300 440
+658900 6209500 527
+644700 6185000 950
+634600 6195200 664.5
+634600 6210900 447
+665100 6202200 671
+619900 6191800 916.5
+621800 6190300 917
+669700 6212000 446
+642100 6227700 231.5
+680900 6238200 73.5
+651100 6250100 534
+601200 6249700 236
+621800 6248500 272
+618600 6226000 345
+626300 6225500 281.5
+663600 6239300 75.5
+620200 6223800 402.5
+636700 6206500 423.5
+626300 6237000 165
+644800 6205500 528
+618000 6222500 387
+688600 6238800 59
+644300 6202400 538
+654500 6243200 205.5
+672300 6242200 79.5
+669300 6201300 580
+698100 6203500 111
+669900 6233800 72
+641000 6204900 391.5
+640800 6229800 266
+617200 6229600 352
+660300 6231900 284
+614700 6218100 423.5
+601800 6240800 305.5
+622000 6216100 480.5
+660500 6227500 340
+642900 6219700 259.5
+598600 6241300 288.5
+640100 6198100 713.5
+615400 6240000 244.5
+641900 6252700 622.5
+614900 6256800 281.5
+638200 6232000 290
+648200 6231700 174
+669500 6236100 77
+596600 6246000 260.5
+700300 6231700 142.5
+630200 6204700 433
+609500 6237100 317
+620400 6218400 455.5
+628400 6248500 227.5
+637900 6255700 745.5
+686800 6231300 95
+651000 6253700 642
+630100 6233800 280
+661000 6241500 151.5
+676900 6232200 129.5
+628500 6196300 1025
+633800 6220600 236
+698200 6214300 63
+639200 6205100 390.5
+678300 6211900 361
+646200 6215600 537.5
+604200 6252400 243.5
+666500 6242600 117.5
+654300 6230500 268.5
+655800 6220600 439
+677300 6241000 42.5
+614000 6229500 348
+644600 6238700 147.5
+654500 6239400 147
+643600 6228700 188
+692100 6234800 96
+663500 6198000 540
+610300 6232100 355
+601400 6244600 270
+616500 6220100 422
+662500 6256100 730.5
+603300 6231200 320.5
+602700 6237900 311.5
+633600 6224700 224.5
+606300 6255600 247
+649600 6225100 342.5
+667800 6217800 326.5
+699300 6224900 95
+637500 6220400 267
+682900 6227600 150.5
+647000 6253900 580.5
+639400 6249500 411.5
+634200 6209100 491
+607000 6241500 299.5
+622100 6223800 315
+709700 6237700 44.5
+692700 6245800 123
+636800 6251500 462.5
+629300 6210200 513
+657200 6235300 125.5
+640300 6232100 187.5
+623800 6218200 428.5
+621000 6206500 577
+651400 6248500 362
+637400 6242600 201
+631900 6210000 435
+601400 6247300 251.5
+617200 6239200 187
+686900 6206500 228
+622500 6184900 1350
+710900 6236700 81.5
+634500 6182400 1095
+605300 6232600 303
+664500 6196100 599.5
+616100 6222700 389
+622100 6192300 806
+638800 6226500 281
+653700 6195700 836
+615600 6251900 190
+620700 6225200 291
+618200 6234200 309.5
+643100 6190300 909.5
+635200 6202200 399.5
+687900 6212900 208
+623500 6213600 586
+609100 6191000 1117.5
+698200 6199300 159
+631800 6187700 930
+662800 6253100 594.5
+630900 6191800 851
+635400 6189600 819
+658500 6203700 631.5
+640900 6247600 353.5
+606500 6233200 313.5
+686000 6245000 152
+664200 6231700 260
+688700 6235100 27.5
+621700 6241500 145
+689600 6241000 72.5
+629700 6216900 313.5
+667500 6194700 520
+685100 6232500 38
+671800 6239300 75
+642000 6216000 500
+693600 6236300 51.5
+633100 6216700 285.5
+654200 6241500 166
+655400 6209800 699
+628100 6238600 142
+703500 6213500 66.5
+638400 6205400 369
+627600 6204500 521
+674700 6229900 125.5
+636300 6245900 265
+694000 6232500 102
+641900 6241100 193.5
+612400 6243700 260
+661700 6247600 502.5
+656100 6242400 180.5
+662100 6237000 82
+605900 6235900 319.5
+658100 6256600 783.5
+668600 6210000 463
+616700 6237200 304.5
+627200 6215300 450.5
+633100 6239800 175
+633200 6207900 438.5
+635900 6239000 121.5
+629700 6214700 408
+696000 6236900 65
+642900 6225700 209.5
+614200 6241700 242.5
+632600 6251700 454
+660900 6221200 248
+630200 6208700 541.5
+669100 6221400 334
+667200 6234000 71
+626000 6222900 344
+626800 6247100 205
+643800 6221800 364
+632800 6192600 820
+648400 6239400 132
+628200 6220200 295.5
+642300 6223800 241.5
+618100 6252500 250
+661800 6220400 307
+682700 6216600 244.5
+677900 6215700 278.5
+686300 6239000 95
+654500 6237100 120
+634000 6204600 416.5
+652300 6235400 112
+702400 6201100 35
+683700 6238700 70.5
+649100 6209400 761
+637400 6189700 862
+655600 6232100 134.5
+648800 6211800 684.5
+655100 6256800 863.5
+620900 6229100 343.5
+643800 6257700 801.5
+658800 6207200 511.5
+625100 6230300 281.5
+644100 6253500 658
+617700 6191700 1007
+613100 6253700 202.5
+664400 6206400 604.5
+664000 6225700 343.5
+680300 6233500 103
+644300 6244300 241
+627700 6200100 815
+624400 6227000 269.5
+644300 6194400 763
+643300 6209800 544.5
+653100 6225800 372
+652300 6214800 593
+625800 6242900 163
+632800 6222500 226
+650000 6230600 290
+653000 6237000 110.5
+639000 6252600 620.5
+647600 6241300 156
+640400 6206900 389
+630500 6244300 218
+604500 6248600 246.5
+629700 6227900 270.5
+599200 6248100 245.5
+644900 6227700 232.5
+677100 6195400 335
+639900 6260700 837.5
+667200 6231900 320
+697700 6243300 32.5
+671700 6225500 328
+689500 6246600 178.5
+684600 6222600 147.5
+661300 6217600 448
+649400 6220100 429.5
+688600 6207000 378.5
+629400 6225600 235.5
+693600 6217200 153
+651400 6241400 193.5
+644300 6207000 522
+625900 6228600 254.5
+660100 6235600 110.5
+707900 6232000 99
+691400 6238300 38
+626300 6233200 195.5
+655900 6195900 626.5
+647200 6200400 591.5
+654600 6234700 114
+643200 6187000 989
+626200 6217600 409.5
+670300 6223200 187
+699400 6208400 100.5
+679100 6216500 236
+637500 6237900 132
+658000 6213100 560.5
+627300 6211700 510.5
+618900 6209900 501.5
+657700 6210500 562
+627900 6251400 430.5
+680300 6209500 310
+675300 6226300 164
+696600 6220900 142.5
+704800 6237000 7
+687600 6236600 27.5
+662800 6233800 85
+646100 6253700 579
+685100 6210700 222.5
+649700 6252900 641
+611200 6189400 1449
+672000 6196500 534
+628200 6182600 1461
+686700 6223800 169.5
+677800 6227600 147.5
+619400 6255200 411.5
+632300 6214000 424.5
+614600 6191300 1121
+649600 6248500 273
+636300 6204300 354.5
+671500 6235700 85
+614600 6233800 347.5
+657400 6205400 597
+631400 6183000 1677
+623800 6189200 1174.5
+624800 6185900 1130
+628400 6188100 962
+676400 6207400 413.5
+610200 6233500 323.5
+649000 6206100 591.5
+671700 6231300 327.5
+604800 6239500 293
+664800 6215800 320
+614200 6226100 384.5
+635400 6227000 330.5
+638500 6223100 255
+617800 6212100 457
+626500 6227100 231.5
+652900 6247400 313.5
+646900 6197700 783.5
+649600 6250500 396.5
+681000 6295700 743
+688000 6407000 1126.5
+640500 6373100 512
+665400 6382300 475
+701400 6369400 738.5
+631700 6377800 364.5
+617600 6377400 273.5
+636300 6347100 424
+696200 6353300 934
+647200 6365700 549
+671600 6318800 445
+615400 6371500 307
+638700 6345100 406
+649900 6348400 533.5
+673300 6416000 803
+674400 6362000 694
+714300 6311500 691.5
+702500 6359600 776.5
+678400 6380800 489.5
+682300 6330100 622.5
+618400 6347300 332.5
+680500 6357400 790.5
+673300 6390500 554
+688300 6344600 933
+662900 6357300 627
+696700 6345400 867.5
+665400 6348100 606.5
+662700 6326000 438.5
+641100 6376300 418.5
+696000 6296600 748
+694700 6336800 761.5
+654800 6337900 479
+620800 6379600 298
+637000 6388300 317.5
+655800 6367300 490
+616000 6379500 242.5
+694100 6366800 715
+697200 6323700 615
+704600 6344700 691
+680100 6316300 421.5
+685900 6364700 746
+623500 6348500 363
+668900 6306600 557.5
+645500 6347100 507.5
+666400 6338700 752
+716700 6343300 637
+667700 6401400 506.5
+661300 6370800 451.5
+623500 6367100 388
+691700 6327700 482.5
+661100 6390500 447
+653100 6370000 526.5
+668100 6367200 589
+685000 6393500 766.5
+666000 6311100 500.5
+634400 6382400 382
+702400 6297900 686
+677600 6319600 427
+695600 6310500 556
+683000 6342600 815.5
+705700 6358100 772.5
+618200 6356400 329.5
+708100 6340200 613.5
+676400 6332200 622
+723900 6342900 719.5
+617500 6362700 376.5
+640600 6390100 323
+661700 6346300 522
+682400 6366200 729.5
+644200 6373800 502
+649100 6392500 404.5
+646600 6378900 446
+663400 6384900 536
+687900 6362600 779.5
+693700 6387900 982.5
+681900 6309900 498.5
+626600 6375100 316
+669400 6315600 470.5
+680900 6421900 834.5
+612800 6356800 356
+624100 6355300 382
+633500 6386500 349.5
+624400 6379900 289
+665700 6394200 483
+661100 6350100 614
+665700 6320000 436
+645700 6392100 386
+661800 6316300 387.5
+670300 6376900 463
+643200 6380900 372
+702000 6374700 806.5
+690200 6368000 660
+676600 6366100 712
+694500 6305300 560
+671200 6408700 552
+628300 6354000 489.5
+666400 6360500 583.5
+650400 6342700 466
+638000 6394700 389.5
+670800 6392400 516.5
+628000 6380600 334.5
+673000 6398900 618.5
+627200 6371500 392
+687900 6398400 1105
+649300 6352000 592.5
+670600 6367500 608.5
+671600 6349600 702
+697900 6374000 694
+659200 6336900 507.5
+680400 6348500 791.5
+700400 6314300 628.5
+698700 6309500 560
+620000 6352400 348.5
+690300 6302600 662
+681100 6401700 805.5
+713900 6303600 631
+667500 6385600 536.5
+639200 6388300 320.5
+632100 6383300 356.5
+708800 6371900 740.5
+636200 6373000 495
+635900 6364600 507
+667600 6363000 577.5
+706900 6368700 726
+654600 6380300 360
+700200 6356600 885.5
+637800 6369700 530.5
+696700 6303900 589.5
+666100 6361300 572
+683300 6397500 869
+701000 6371500 649.5
+655200 6332400 437.5
+682800 6351600 876.5
+617800 6370200 376.5
+663600 6314300 438
+662800 6334900 535
+672900 6343600 767.5
+647500 6374700 466
+642700 6340400 379
+649500 6353700 638
+728900 6324900 915.5
+710400 6342100 620
+683600 6372500 670.5
+715700 6319400 780
+668600 6354500 678.5
+645200 6382600 425.5
+720700 6339300 689.5
+690000 6297000 843.5
+690900 6317700 499.5
+659300 6327400 474.5
+695100 6381600 895
+678700 6383800 577.5
+673900 6384100 530.5
+685500 6403000 976.5
+618300 6381000 265
+671700 6414500 616
+655300 6360600 601.5
+637700 6384500 309
+639100 6356800 597
+696900 6331600 520.5
+697200 6370200 660
+631100 6365800 432
+668800 6399000 469.5
+681200 6380400 547
+647400 6344600 446.5
+688500 6371800 667
+710500 6343300 626
+631000 6360600 496.5
+671700 6301000 630.5
+694300 6361800 779.5
+680400 6327900 544
+669400 6334600 730.5
+701400 6293400 810.5
+633100 6369900 496.5
+725400 6312700 770
+710900 6320300 722.5
+626100 6343700 350
+692400 6333700 713.5
+638700 6375600 424
+634800 6355400 621
+672800 6380700 442
+660800 6395000 500.5
+666500 6406300 516.5
+649300 6365700 567
+631800 6348400 416.5
+620400 6365200 364.5
+706200 6333200 614
+643300 6353500 590
+634700 6378500 366
+668100 6324600 443
+623000 6362000 390.5
+680900 6411400 622
+627000 6386300 288.5
+661400 6379900 438.5
+672700 6329000 559
+654400 6373100 459.5
+675100 6414600 622.5
+644500 6343100 401.5
+702400 6308200 579
+662400 6341200 542
+675800 6297500 710
+705200 6332000 574
+649800 6371700 528
+657600 6350800 626
+708800 6310900 674.5
+698900 6329500 561
+686800 6354900 860.5
+688200 6298700 695.5
+668100 6309500 475
+660500 6381400 483.5
+699100 6319700 626
+700600 6378600 980.5
+686600 6308900 505.5
+709900 6308600 633
+678500 6404300 623
+678300 6353600 726.5
+685700 6406200 1021
+717800 6336200 647
+673700 6304800 622.5
+689400 6394900 1019.5
+707900 6339700 618
+698000 6316900 555.5
+665200 6305000 714.5
+640900 6384700 308.5
+667000 6389600 461.5
+653200 6374800 427
+629200 6383600 321.5
+697700 6363800 753.5
+640100 6381200 355.5
+629200 6348900 411
+617300 6374700 352.5
+652700 6340700 462.5
+703700 6322500 661
+674400 6309600 533
+686900 6410700 980
+650400 6385400 452.5
+670200 6359900 658.5
+704500 6317500 799.5
+611900 6378100 256
+659100 6389800 426
+635300 6368500 515.5
+666300 6377300 465.5
+708300 6339300 606
+687500 6366200 636.5
+625200 6358800 435.5
+655500 6347900 562.5
+643400 6368000 537
+682500 6407400 880
+659600 6360700 529
+671400 6401200 528.5
+647200 6360900 570.5
+652100 6389100 437
+683500 6387600 677.5
+608400 6375800 265.5
+646900 6339700 399
+622900 6371400 400
+641200 6349300 488.5
+638600 6364200 539
+643900 6388800 368
+654700 6353300 641.5
+675600 6322900 490.5
+632100 6352800 480
+614200 6364800 342
+714700 6344900 669
+690200 6330300 675
+701600 6318900 673
+729500 6319700 960.5
+686900 6316200 514.5
+724100 6324800 673.5
+674700 6337000 845
+680300 6302000 624
+649300 6336400 462.5
+657400 6375100 404.5
+696600 6340700 805.5
+675500 6312400 463
+712800 6323300 828
+690900 6381900 654.5
+628500 6366900 417.5
+638100 6378100 364.5
+695800 6300500 584
+669900 6322100 442.5
+686500 6328000 475.5
+689300 6389400 952.5
+701100 6304400 638
+640200 6341500 363
+666400 6317300 463.5
+665700 6342600 681.5
+697500 6360200 824.5
+630700 6374100 399.5
+623300 6343900 293.5
+684100 6357600 830.5
+690700 6408100 1132.5
+695900 6371600 605
+685300 6379600 590
+653300 6383300 437
+677800 6374700 533
+664400 6360900 564.5
+689200 6376400 611.5
+707800 6321900 676.5
+685200 6415200 835.5
+694600 6291900 753
+695700 6373900 638
+698900 6346300 743.5
+684100 6324300 495
+886200 6293400 306
+906300 6238500 192.5
+913900 6264500 355.5
+856900 6291800 232.5
+856800 6308800 53.5
+867400 6296200 179
+881000 6293700 255.5
+840400 6312700 89.5
+864100 6301300 180
+906500 6258500 477
+847400 6300700 199.5
+856900 6302700 56
+890200 6277200 222
+860900 6270400 60
+852800 6310500 68.5
+845000 6313000 20.5
+897700 6272900 287
+912200 6268300 338
+901400 6251700 418.5
+877400 6275000 125
+885500 6283000 275
+836100 6308500 87.5
+895500 6264700 241.5
+909000 6257500 409
+903000 6260400 525.5
+910300 6258600 439.5
+907900 6269000 345
+909700 6262000 373.5
+904000 6275300 420.5
+910500 6242100 362.5
+880900 6260500 67.5
+908900 6272200 646
+869300 6284600 189
+868200 6291400 210
+913800 6238500 279
+892900 6247100 320
+889300 6287900 330.5
+848100 6306400 55
+846300 6255900 1.5
+843300 6305400 12
+896600 6288000 328
+849100 6311000 62.5
+875600 6294800 162
+875700 6283600 145.5
+892700 6263100 192.5
+864500 6274500 95.5
+854300 6306400 48
+845400 6293100 171
+863100 6263800 70.5
+880600 6268000 135.5
+844600 6295500 181
+899800 6252900 332
+861000 6303400 111.5
+916500 6273200 623
+831400 6287800 28.5
+900500 6280800 348
+874300 6291800 224.5
+908700 6246900 387.5
+865900 6258400 93.5
+861100 6258200 34
+875100 6289800 279
+842600 6307400 75.5
+881200 6257500 69.5
+882000 6264900 127.5
+833500 6302100 101.5
+905700 6262400 330.5
+908600 6286400 491.5
+891700 6258400 360
+904100 6285100 370
+874100 6287500 235
+871500 6250400 88
+861700 6277900 62.5
+905800 6271300 429.5
+907400 6264800 280
+838900 6299500 118
+911300 6253500 433
+903100 6272400 250
+918300 6291300 374.5
+857600 6261600 24.5
+832600 6308000 13.5
+901900 6268400 242
+910400 6276400 681
+887100 6259500 171.5
+873600 6283700 182.5
+912200 6234300 194
+904300 6245600 237
+857000 6297700 212.5
+904800 6259700 539
+841400 6300500 37
+844100 6293000 81
+856400 6306000 57
+917500 6264600 513.5
+913300 6247700 572.5
+850900 6289600 140.5
+837700 6293500 122.5
+815600 6262500 3
+874600 6250500 89
+846300 6284000 224.5
+878800 6253200 119
+879400 6260100 50
+897000 6262100 451.5
+866600 6281000 74
+871900 6279400 119.5
+867400 6275900 105.5
+882500 6286500 296.5
+912800 6285500 495.5
+908300 6243100 280
+893100 6290400 284.5
+863800 6290600 279.5
+919300 6245700 603
+911300 6256500 270.5
+885400 6273800 172.5
+882300 6271900 148.5
+900500 6264800 278.5
+875500 6266500 73
+913300 6255800 554
+881700 6275800 158.5
+882500 6254800 131.5
+875400 6256200 101.5
+464100 6874900 186.5
+477700 6911700 78.5
+500100 6916000 89.5
+413100 6926800 21
+426600 6912500 54.5
+487600 6885100 109.5
+460200 6899300 27.5
+502400 6914200 92.5
+472200 6888600 48
+498400 6884800 132
+447700 6888200 75
+425200 6917300 48.5
+484900 6880800 147.5
+446900 6871900 155
+463700 6892500 66.5
+433100 6873800 177
+424100 6875600 207
+511500 6878900 164.5
+426200 6869900 196
+437900 6920900 29
+417300 6862500 231
+458800 6914400 31
+422300 6918900 34.5
+490700 6919200 67.5
+489500 6910600 112.5
+497400 6925100 69.5
+479700 6916100 68
+485700 6916500 52
+445800 6897600 68
+407200 6915300 34
+418000 6902400 99.5
+470400 6877800 89
+457400 6893400 80
+406500 6918000 22.5
+438500 6892200 122.5
+471600 6884200 59.5
+487200 6889500 51
+428200 6916000 43
+438500 6887200 193
+477300 6878900 58.5
+418700 6887100 210.5
+499300 6885800 135
+468000 6882900 94.5
+426900 6911100 56
+438000 6874700 184.5
+434700 6889600 137
+401800 6920900 18.5
+491700 6882300 118
+495500 6920100 91.5
+463500 6884200 130.5
+464500 6910200 28.5
+442400 6915100 34
+413300 6920900 24
+403400 6922000 15.5
+418200 6866000 238.5
+406400 6919600 21.5
+416400 6926400 31
+413200 6915400 34
+503700 6924900 59
+419100 6913000 36.5
+484800 6914600 89.5
+434700 6905200 69
+436500 6918500 37
+457100 6900000 25
+481600 6912900 86.5
+452000 6888400 85.5
+431100 6911700 61
+465100 6902700 31
+476200 6915600 62
+467900 6902700 31.5
+467800 6908100 34
+444000 6907000 59.5
+451400 6904200 68
+482300 6882900 106.5
+497600 6901500 86
+464200 6876200 157.5
+478000 6903000 73
+463500 6878100 168
+427800 6899400 114
+479200 6909100 67
+484000 6884000 99.5
+476200 6888300 28
+480400 6905300 85
+441700 6905300 83
+489000 6877900 145
+451800 6909900 66.5
+451700 6872300 171.5
+447800 6909300 46.5
+417200 6867000 183.5
+442200 6869100 132.5
+469700 6902900 23.5
+491100 6898500 125
+444200 6894600 90
+459400 6889000 95.5
+492300 6918500 68
+461700 6885500 100
+506300 6877300 198
+430200 6901500 103
+499700 6880300 150.5
+449400 6871600 119.5
+411000 6877000 134
+441900 6888600 159.5
+406400 6922700 20
+494600 6886200 123
+404200 6917300 30.5
+451600 6892000 52
+420500 6914600 48
+448100 6908800 52.5
+491700 6916800 59
+490400 6881500 122
+448500 6912000 41.5
+424500 6900700 139
+502200 6916000 84.5
+504600 6898200 129.5
+448600 6914100 32.5
+479000 6872300 105.5
+440700 6916000 38.5
+420700 6874000 159
+429200 6912900 54.5
+442500 6898900 82.5
+484400 6902300 79
+457900 6873600 194
+507900 6890400 145.5
+459800 6893700 81
+460600 6884100 138
+455200 6893400 54.5
+485800 6878200 138.5
+469000 6884200 74
+413300 6881200 174.5
+404700 6923800 25.5
+453500 6874800 234
+453100 6896300 28
+434200 6876400 189
+470500 6914000 11
+427400 6864700 197
+414000 6925800 30.5
+502000 6922300 84.5
+421800 6900300 135.5
+429800 6911800 61
+468900 6896500 38
+471900 6904500 23.5
+452200 6906900 65.5
+425700 6901900 111
+437000 6896500 137
+433000 6892800 156
+489500 6889800 101.5
+419500 6889600 155.5
+460500 6891800 91
+448200 6877600 159
+436900 6870200 171.5
+441500 6878100 152
+488600 6891800 100
+426200 6878000 219
+475200 6868800 81
+405300 6878100 119
+459700 6908300 18
+478200 6868900 79.5
+462900 6913700 16
+463100 6866000 185.5
+447100 6879300 105.5
+413000 6870900 140
+469000 6895300 47.5
+448900 6904000 59.5
+473300 6891500 45
+432200 6903500 99
+452200 6883600 179
+481500 6894500 20.5
+502900 6879700 190
+418300 6894900 140
+449800 6878000 203.5
+415400 6925300 24.5
+438200 6911700 62.5
+456000 6918000 18.5
+454500 6911400 44.5
+452700 6912700 56.5
+435700 6887600 131.5
+439200 6912200 52.5
+413800 6910900 55
+432000 6908600 68
+429400 6895800 110
+499900 6878700 157.5
+474300 6909600 53.5
+440700 6870400 169
+496500 6896900 107
+414600 6866900 155
+444600 6916100 29
+403000 6867700 247
+453700 6899300 34
+397100 6866700 173.5
+454700 6884100 135
+437400 6914800 42
+465700 6896400 39.5
+423400 6912100 57.5
+459900 6913300 30.5
+474400 6906400 14.5
+434700 6916500 49.5
+463700 6907300 26.5
+418000 6911700 68.5
+420400 6907600 83.5
+431600 6915300 53.5
+472300 6899700 19.5
+479200 6887900 38
+478200 6894200 31
+438000 6893900 115.5
+414900 6873000 108
+430400 6892200 142
+459100 6870000 215.5
+498300 6887600 125.5
+445200 6878600 85.5
+415300 6901800 115.5
+500000 6919900 118
+427600 6871000 194
+453600 6919600 16
+474200 6894900 31.5
+441900 6918700 50
+420100 6901900 101.5
+492700 6912000 64
+404500 6870000 140.5
+427200 6914800 42
+475700 6890300 40.5
+488600 6907900 115.5
+442800 6911400 43
+438200 6907000 71
+421100 6869800 181
+463300 6897900 28
+430600 6871700 197.5
+469900 6893600 43
+431300 6907000 81
+465300 6885800 82
+417400 6892400 110.5
+464300 6881300 116
+453700 6890100 64
+461500 6887900 94
+445700 6888600 85.5
+443400 6898900 73.5
+452900 6881600 160.5
+410500 6913900 38.5
+484600 6919900 56.5
+421800 6889300 196
+490500 6883700 118
+442700 6889800 123
+431500 6890400 148
+446400 6915800 27.5
+483300 6905600 90.5
+478800 6886000 35.5
+488600 6888200 83.5
+492900 6875200 158
+505600 6888200 120
+426200 6872800 194
+439200 6917400 60
+454800 6918900 18.5
+493200 6877100 138.5
+448000 6899600 65
+404400 6878200 146
+497100 6879400 166
+407300 6868800 171.5
+455400 6867100 138
+477000 6874600 82.5
+506400 6911600 102.5
+495600 6883500 138
+455400 6898400 40
+398800 6866000 212.5
+440400 6873800 176
+494200 6909700 82
+490700 6896700 145.5
+498000 6906600 83
+418700 6899100 124
+409700 6927200 19.5
+425100 6909600 55
+458100 6897200 47
+442900 6902000 90.5
+408500 6877500 127.5
+495100 6913200 62.5
+440100 6876600 146.5
+425400 6882100 257.5
+495000 6926700 69.5
+436400 6914100 49.5
+460400 6866600 181.5
+450400 6887800 136
+439600 6867000 122.5
+463500 6880200 143.5
+459600 6877000 162
+435000 6899700 91
+464100 6867900 197.5
+468800 6909400 13.5
+439200 6890700 134
+455800 6881500 143.5
+419500 6860200 249.5
+491600 6926200 72
+435600 6867900 142
+488500 6901600 103.5
+482300 6891600 44
+484400 6893900 38
+400700 6862800 274.5
+453100 6892200 44.5
+423300 6907000 85.5
+486200 6890400 85.5
+489300 6904300 119.5
+450300 6897600 55
+454300 6868200 170
+459700 6905500 25.5
+411800 6917300 21
+454300 6877700 185.5
+401800 6915700 28.5
+508700 6893300 140
+409900 6871000 122
+491300 6909400 93.5
+479200 6886300 45
+415300 6882000 159
+427700 6889600 175
+418800 6877600 173
+449700 6880600 133
+456400 6869600 187.5
+435300 6908900 62.5
+499900 6923900 81.5
+496600 6917200 83.5
+487500 6921700 41.5
+437600 6900200 96
+497200 6914800 76.5
+428700 6906100 81
+495300 6915400 76.5
+475800 6910700 64
+428500 6921800 38.5
+465200 6909400 37
+412200 6879500 158
+435100 6910800 56.5
+495300 6877100 148
+470300 6880600 77.5
+451300 6920100 27.5
+490400 6913800 62.5
+449800 6886700 100.5
+486100 6903700 95
+489800 6885100 112.5
+457700 6909100 29.5
+483800 6897500 84.5
+448800 6910000 50
+449300 6873000 205.5
+442100 6907200 66
+452600 6877000 210.5
+497600 6897500 92
+475800 6893300 39
+436500 6901900 85.5
+415600 6873000 122
+508900 6881000 159.5
+484000 6894600 57.5
+418000 6918200 36
+450200 6915500 37.5
+499000 6900300 93.5
+467800 6911600 16.5
+453700 6894200 42.5
+444900 6892100 83
+492500 6894100 130
+484700 6898700 98
+408100 6865700 219
+477000 6876100 68
+485700 6912200 108
+455500 6879500 148.5
+409200 6913300 42.5
+464900 6888800 62
+501500 6916500 99
+413700 6875600 134
+481400 6914400 105.5
+420100 6880500 164.5
+460700 6903000 21
+507100 6880400 180
+411000 6928300 21
+438400 6877900 173.5
+422200 6894500 186
+427400 6919300 36.5
+446400 6892200 63.5
+435200 6907300 61.5
+500600 6910200 98
+443500 6896700 79.5
+428200 6917500 38
+510300 6883300 141.5
+413500 6862700 238
+439300 6900700 100.5
+473300 6887800 42
+492800 6926300 72.5
+443400 6876800 121
+491100 6894200 140
+474700 6873800 73.5
+437600 6881200 228.5
+479600 6870700 149.5
+488400 6918800 51
+444800 6918300 44.5
+405400 6869100 147
+442800 6896000 83.5
+439700 6897300 139
+425800 6905200 87
+418300 6924600 39.5
+452800 6866700 117.5
+420800 6923300 39.5
+419200 6921100 42
+425100 6896400 166
+454000 6896300 58
+418200 6874500 121.5
+423500 6883300 258
+484200 6919500 57
+444700 6886100 98.5
+458600 6883200 133.5
+504700 6906700 127
+482100 6895000 78.5
+435900 6912800 47
+486400 6875100 153.5
+478800 6913300 77
+467100 6873200 118
+451300 6896200 41
+504400 6918600 85.5
+445700 6874100 148
+496900 6893800 106
+468000 6876600 119
+492400 6878500 125.5
+419300 6914700 41.5
+467900 6879000 125.5
+448200 6900500 52.5
+417800 6916200 39.5
+485200 6900900 91.5
+496300 6910100 73.5
+422300 6880500 192.5
+407000 6908300 44.5
+504600 6878400 186
+446200 6912400 39
+424100 6868200 214
+458000 6867900 173
+477000 6909000 65
+443500 6920400 28
+473300 6914300 7.5
+451000 6914300 40
+424400 6881300 238.5
+440300 6907300 67
+412700 6912900 43.5
+489700 6912600 87.5
+465900 6870500 138.5
+462100 6903800 24
+462800 6908400 25
+406000 6912100 32
+480000 6884500 48
+430500 6915100 49.5
+423400 6923100 39
+480000 6900100 67
+417800 6915100 40
+443100 6916100 33
+456700 6911700 38
+439000 6902600 82.5
+451100 6902100 38.5
+484800 6904600 86
+498000 6908300 71.5
+427600 6910500 57
+420600 6897300 132
+501500 6884100 148.5
+454200 6915700 37.5
+457900 6902200 20
+426200 6911100 56.5
+504000 6888600 116.5
+457600 6905500 35.5
+440800 6897200 83.5
+491700 6903600 114
+503700 6891400 119
+479900 6911100 88.5
+435900 6875100 176
+451700 6912600 43.5
+480500 6898200 10
+453100 6911000 55.5
+483500 6902400 68
+445600 6886900 89.5
+436500 6910400 57
+446600 6895900 81
+444800 6903500 75
+446400 6918100 27.5
+461200 6909600 25.5
+485900 6909900 106.5
+459600 6897800 40
+502700 6891100 117
+447400 6894600 77.5
+435000 6882800 255
+440500 6909400 55.5
+442500 6891800 110
+449300 6895200 68.5
+501900 6900100 109
+427800 6885500 209
+504300 6883400 172.5
+501500 6894800 107
+465200 6901300 13.5
+436500 6893900 143
+444500 6899100 62.5
+496800 6903500 84
+412200 6923800 27.5
+468300 6868900 178
+420200 6904700 90
+462300 6879500 165.5
+455700 6914100 44
+422700 6870700 187
+479900 6875700 93.5
+474600 6870500 65
+498300 6913700 79
+471500 6887100 54.5
+417400 6876900 139.5
+454300 6903300 37.5
+486600 6917800 51
+467500 6886200 82.5
+440800 6920100 32.5
+502500 6887100 141
+432400 6876800 213.5
+440600 6883400 169.5
+464500 6873500 175.5
+450000 6906100 66.5
+410500 6921800 19.5
+450000 6869100 146.5
+454500 6907700 42.5
+430500 6883700 265
+415200 6921800 27.5
+402700 6926100 16
+462300 6898900 22.5
+467500 6890200 56.5
+486900 6913200 90
+434400 6886100 202.5
+447600 6919900 24.5
+455100 6865800 124
+472000 6868700 112
+474400 6914000 67.5
+442700 6884400 121.5
+410500 6918000 16.5
+424000 6920200 40
+450400 6883300 138
+507200 6886000 135
+433600 6918000 51.5
+430800 6917800 38.5
+502000 6904400 127.5
+435700 6921000 37
+465000 6911900 20
+446600 6906500 56.5
+444100 6913400 36.5
+499100 6889600 112
+436900 6888700 142.5
+472100 6892200 32.5
+494000 6902100 110.5
+488700 6895500 99
+427100 6922600 37
+458700 6895200 71
+508300 6900200 137
+448900 6892700 58
+453500 6908900 56.5
+474600 6879200 48
+510800 6883000 154
+428700 6897900 134.5
+452600 6900700 25
+480500 6898200 57.5
+441400 6889600 145
+510800 6896600 150.5
+417200 6889500 139
+481400 6917600 69.5
+435500 6871800 152
+454700 6871600 188
+410700 6879600 134.5
+473700 6895800 34.5
+491000 6886500 101.5
+439600 6921200 11
+463200 6868300 189
+450000 6890300 55.5
+487100 6904500 105
+460700 6911900 30
+408100 6911900 36.5
+498900 6903500 92
+508300 6896400 131.5
+423000 6914200 52.5
+471200 6870500 108.5
+483100 6909700 91.5
+474100 6866700 116.5
+474500 6899600 22.5
+412300 6922800 25
+447000 6875100 198
+456000 6915000 38
+488900 6898100 130
+466900 6913400 21
+487600 6881700 152
+428700 6893100 142.5
+490100 6880100 127
+501100 6902600 117.5
+471600 6897100 34
+457000 6887900 84
+494800 6889700 117.5
+493700 6905700 120
+416800 6903900 100.5
+462100 6870900 191.5
+431100 6879000 237.5
+432300 6894800 109
+442200 6879900 153.5
+475000 6881200 55.5
+437900 6885000 198.5
+435800 6879500 280.5
+484500 6885900 78.5
+474700 6876400 48.5
+499200 6927900 58.5
+443800 6909500 46
+491200 6877900 131
+478300 6907800 73.5
+483400 6912200 98.5
+467800 6901300 23
+503600 6906500 102.5
+505300 6899700 118.5
+456500 6874200 187
+461600 6876100 186
+416100 6919100 23
+466800 6892600 40.5
+499100 6921000 99.5
+494100 6891800 118
+430900 6888200 221
+426400 6886300 245
+493000 6915700 64
+407800 6870400 127
+408000 6873300 112.5
+465200 6894800 44.5
+420100 6874500 142.5
+499200 6895700 93.5
+468400 6872300 106
+465000 6903700 38.5
+421000 6893000 163.5
+459300 6896300 56.5
+504200 6890100 120
+448700 6920300 26
+505900 6904600 129.5
+434100 6894500 142.5
+432800 6913800 64
+405700 6862300 260.5
+438200 6888300 171
+478200 6884100 48.5
+440700 6911600 59
+439200 6908600 64
+476500 6906300 71
+417600 6882600 149
+481000 6903400 69.5
+502000 6892800 114
+472300 6866100 130.5
+489400 6919800 75.5
+400700 6869300 162.5
+440700 6895200 90.5
+424700 6891700 182.5
+434400 6921400 36
+484700 6889100 54.5
+499200 6892000 115
+435500 6892300 142.5
+501500 6908400 100
+435600 6903400 83
+458500 6886800 94.5
+412300 6872700 129.5
+464100 6906000 27.5
+439100 6905300 86
+436800 6921600 27.5
+453600 6879900 168.5
+479400 6907100 74
+422500 6876100 189.5
+424000 6914700 57
+475100 6897300 20.5
+419700 6859300 269.5
+437000 6908900 59.5
+444800 6874100 146
+418800 6885900 211.5
+438500 6915300 38
+504900 6886600 134.5
+425000 6888200 217
+464800 6899400 13
+471900 6872900 105.5
+448000 6883000 99
+501900 6926500 54
+469500 6900500 22.5
+477200 6900600 18.5
+445900 6899900 61
+409000 6923300 19.5
+407000 6872700 129.5
+470100 6870900 92
+487100 6883200 128
+459700 6879800 155.5
+461700 6902800 21
+430600 6874600 206.5
+445800 6881600 87
+482300 6908800 80.5
+406600 6928400 17
+421300 6866700 220.5
+473800 6877900 85.5
+464500 6891500 61.5
+495800 6924600 71
+486400 6893300 94.5
+504400 6895100 119
+422400 6921500 42.5
+433900 6900900 97.5
+471100 6901100 23
+493900 6879000 144
+497700 6910500 80.5
+448100 6916900 28
+450100 6899200 45
+425700 6863600 211
+430300 6867700 181.5
+466600 6896000 15.5
+488000 6922600 74
+426300 6915900 48.5
+451300 6878200 198.5
+416700 6922200 39.5
+458900 6885700 101
+458600 6916400 15
+431400 6921400 38.5
+507300 6902700 143
+442700 6887400 153.5
+440600 6914500 36.5
+409700 6879100 155.5
+421600 6909900 70.5
+700300 6417300 958.5
+654200 6429000 710.5
+688600 6431600 1215.5
+692000 6415600 878.5
+653000 6473200 509
+641800 6425100 573
+653800 6394200 424
+696400 6446200 937.5
+685600 6421200 803.5
+661000 6446200 955
+673100 6459700 1218
+665100 6469400 727.5
+683400 6464500 972.5
+662000 6449000 1165.5
+703700 6446100 931
+656000 6456300 923.5
+665600 6477500 707.5
+697600 6452600 1019.5
+651600 6436000 716.5
+704700 6451500 906.5
+687200 6424700 922.5
+676000 6461100 988
+655800 6425300 720
+657000 6451400 1035
+662800 6443000 1228
+657500 6475700 490
+715900 6441300 1060
+706900 6457500 876.5
+684400 6424900 1020.5
+714700 6451700 832
+645800 6413100 615
+691900 6445400 992
+680900 6471300 969
+635600 6396900 318.5
+694100 6463400 1222
+652300 6444500 667.5
+645900 6427400 600
+639300 6417600 610
+631200 6428800 523
+654800 6446600 786
+702300 6455900 916.5
+650600 6462900 545
+664400 6471500 698
+643900 6434800 546
+655900 6443700 787.5
+694700 6431600 979.5
+700400 6449200 923.5
+701900 6411900 1122.5
+647400 6452900 661.5
+632100 6436300 482.5
+648800 6444300 664
+650800 6446700 694
+719100 6453200 841.5
+721800 6431900 1153
+677700 6456700 1202
+703600 6419300 844
+638800 6427900 528
+673000 6441100 1308.5
+663200 6456100 919.5
+682600 6425500 933
+666400 6422900 811.5
+651000 6470400 498
+642700 6397700 447.5
+646100 6440500 578.5
+639600 6440200 515.5
+659200 6439600 877
+635300 6422800 640.5
+689400 6463900 1182.5
+688800 6447200 1180
+654400 6440100 770.5
+711500 6426900 899.5
+699500 6463000 1121.5
+662100 6421700 738.5
+683300 6451100 1288
+663000 6408900 553.5
+691400 6458500 1107
+707300 6437200 898.5
+652300 6454800 697
+632900 6439800 503.5
+643300 6453400 541.5
+648200 6464400 588.5
+651900 6417700 682
+694900 6458900 1039.5
+666600 6436000 1022.5
+647000 6431900 623
+674500 6474900 762
+692500 6434100 1238
+698100 6447700 880
+704600 6453700 905.5
+717600 6433700 1047.5
+722200 6441200 1122.5
+661700 6426000 791
+655400 6409200 706.5
+701100 6433200 978.5
+678200 6426100 1080
+657100 6422900 705
+721800 6445100 1022.5
+690600 6426400 1072
+706800 6429200 872
+657300 6410200 747
+684800 6429900 1299
+669200 6419300 655.5
+675100 6428000 1219.5
+634600 6414800 626.5
+699900 6435900 1016
+689700 6445700 1015.5
+640300 6431900 552.5
+678400 6464900 972.5
+712100 6431300 808
+659200 6470700 611
+639400 6415000 570
+695300 6405500 1172.5
+654500 6432200 741.5
+703100 6462600 972.5
+686800 6442000 1363.5
+654400 6430700 724.5
+708500 6442000 1003.5
+644100 6456300 487
+706800 6419000 898
+647700 6458000 555.5
+709900 6459000 773
+704800 6440200 939.5
+656100 6404800 668.5
+636700 6417800 670
+635600 6405700 440.5
+660800 6466600 787.5
+651200 6399200 434
+662900 6435800 898.5
+648800 6409400 627.5
+685400 6475600 1012.5
+646900 6399300 478.5
+668900 6463200 905
+663600 6482300 663
+655300 6461900 598
+703100 6430800 886.5
+685700 6458500 1124.5
+666700 6428100 903.5
+649200 6458800 625.5
+638200 6428200 567
+659200 6433900 799
+667100 6436600 1126.5
+663800 6417600 658.5
+637500 6408600 426
+681200 6465400 959
+652100 6476700 522
+673600 6426600 875
+712700 6454200 830.5
+668900 6471600 740.5
+641800 6449600 646
+694700 6450600 1039
+695400 6419200 842
+665800 6421200 693
+703500 6415200 997
+689800 6471700 1231
+637800 6394900 360
+632100 6419100 667.5
+661900 6484200 639.5
+676800 6458300 1107.5
+708100 6448300 951.5
+673300 6430600 1171
+670400 6431300 957
+691000 6419800 837.5
+686400 6467500 1104.5
+647600 6405900 593.5
+712400 6456500 783.5
+696900 6412100 997.5
+712000 6447500 1005.5
+673600 6435100 1119
+661100 6406300 557
+670400 6424500 850
+700300 6399700 1235.5
+641000 6409500 482.5
+656300 6468600 565
+699000 6443800 961.5
+645100 6443900 578.5
+663800 6403400 503.5
+703000 6439300 910.5
+716500 6446000 1064
+718000 6428600 865
+639200 6448700 514.5
+659800 6429500 843
+710100 6435500 870.5
+657600 6413600 731
+659200 6437800 1007
+660400 6401000 545.5
+653500 6400600 536.5
+690700 6450500 1168.5
+672900 6422300 767
+680800 6430500 1303.5
+636700 6392600 326.5
+653400 6469200 515
+637500 6421800 594
+721500 6443300 979
+646200 6453000 640.5
+641500 6437000 567.5
+721600 6428800 1050.5
+673300 6464800 838.5
+706800 6422400 808
+640900 6460400 475.5
+707900 6464100 924.5
+666000 6454500 1110
+663800 6461600 944.5
+693000 6447300 1039.5
+684800 6446300 1352.5
+698700 6425400 845
+694900 6442400 1022.5
+702400 6408500 1116.5
+716600 6426200 861
+655900 6472100 527.5
+663100 6425600 792.5
+667400 6466500 779.5
+676800 6451200 1387
+683900 6461800 1145.5
+639100 6398700 387.5
+657500 6462900 674
+694800 6424400 889.5
+636300 6430200 561
+676100 6471500 824.5
+639900 6421200 586.5
+720800 6449600 1020.5
+691300 6442500 1214.5
+637400 6410800 471.5
+664800 6433600 933
+651800 6452100 677
+726500 6445000 896
+705100 6433300 920
+645200 6417900 644.5
+658500 6460000 776
+715100 6422500 939.5
+644600 6404800 463.5
+710900 6441200 981
+670300 6450700 1296.5
+703300 6426200 851
+712500 6440200 971
+649100 6402300 597
+633800 6433300 538
+657300 6404900 646
+705600 6468200 860.5
+679000 6474700 845.5
+716500 6421300 977.5
+660200 6448900 1018.5
+715500 6461400 758
+647300 6467600 504
+709900 6462800 774.5
+694800 6439300 1192
+656700 6401700 529
+648700 6429000 656.5
+716300 6437300 978.5
+637200 6402200 401
+649700 6423800 591
+649200 6430300 665.5
+677200 6439200 1327.5
+667300 6444800 1221.5
+679900 6448800 1413.5
+662400 6471200 576
+636500 6401600 394
+642800 6420100 620
+648500 6420700 635
+667200 6412300 567.5
+663900 6413800 611.5
+489800 6536300 92.5
+508600 6507800 186
+486200 6532600 91
+449300 6513300 30.5
+470100 6531000 78
+471700 6489200 133
+472400 6532400 73.5
+466900 6520700 96
+472200 6509800 53.5
+519600 6534500 191.5
+438900 6516900 38
+480200 6543900 100.5
+466100 6484200 120.5
+485600 6546200 102.5
+460500 6539300 110
+455300 6510000 49.5
+505300 6524900 185
+481200 6534600 85
+481700 6508400 111
+476400 6536600 75
+478200 6502500 101
+434800 6516500 39
+458900 6494700 78.5
+512000 6535700 200
+481600 6469000 89
+468800 6531800 91.5
+483100 6536600 90
+473800 6464200 87.5
+483700 6532900 86.5
+477600 6481300 130.5
+489400 6527200 96
+453800 6499500 93.5
+472900 6519900 89
+480300 6505500 100
+443400 6517900 27
+517700 6522700 252
+462000 6504500 57.5
+534300 6541500 268.5
+482800 6499800 124
+509900 6522800 261.5
+483400 6551500 114
+449100 6498200 57
+528900 6560300 208.5
+461700 6490800 88.5
+498000 6514100 108.5
+485300 6492700 163
+442000 6513500 30
+476500 6522100 94
+470700 6508800 57
+503800 6497800 155.5
+436600 6510500 31.5
+511500 6531000 210.5
+468000 6477300 124
+478100 6479400 126
+480400 6537000 71
+447600 6518000 21
+472900 6541400 110
+453100 6474300 118
+458300 6530200 122.5
+477500 6526100 90
+491100 6505400 131
+464700 6523300 118.5
+498100 6491400 152.5
+448400 6519700 24
+474100 6484000 150
+522100 6543200 188.5
+528200 6553600 192
+474200 6530100 88.5
+476600 6548600 117.5
+517900 6546400 180.5
+468200 6537100 95.5
+468100 6490700 111
+461000 6529400 124
+466500 6462500 64.5
+501600 6519900 212
+478700 6533300 84.5
+503000 6504000 151.5
+476400 6464100 84
+474000 6505000 84
+469700 6537200 105.5
+459100 6509600 55.5
+482500 6474600 126.5
+469700 6479000 126.5
+497400 6527800 104.5
+472200 6471000 93.5
+458000 6491200 77
+453700 6516600 32.5
+434700 6518400 54.5
+503000 6551900 162
+487700 6543800 104.5
+528300 6548000 222.5
+474700 6557500 139
+497700 6535700 135
+498400 6497000 163.5
+482300 6490300 153
+454700 6483500 112.5
+448700 6480800 112
+449200 6507100 80
+467900 6468100 82.5
+466100 6479500 129.5
+466900 6470500 87
+486800 6506600 110.5
+458700 6478300 133.5
+484600 6475900 124
+484100 6556800 144
+466500 6487400 121
+497300 6553200 163
+464000 6485700 112
+476800 6543200 97
+463800 6471300 110.5
+492000 6541300 127
+460100 6470700 105.5
+506200 6534100 173
+473400 6543700 107.5
+493900 6503800 155.5
+499600 6546800 154.5
+467000 6506200 53.5
+503500 6536000 164.5
+469300 6499400 99
+509500 6526400 219
+492700 6537300 118.5
+455200 6502300 106
+475200 6494400 129.5
+474600 6508800 43.5
+480300 6539100 91.5
+521000 6553000 167.5
+483700 6483900 130
+490000 6531700 97
+456700 6527500 114.5
+463500 6511400 62.5
+464800 6506600 42
+460600 6532200 100
+476500 6492500 139.5
+470900 6473800 109
+451100 6485300 103
+460400 6515700 62
+498700 6523200 121.5
+466800 6543700 96.5
+467300 6495300 109.5
+466800 6516900 83
+496800 6519000 105.5
+517000 6540900 181.5
+460600 6495300 85
+492900 6548100 150
+485400 6548300 120.5
+469000 6526500 100.5
+468700 6494100 119
+444100 6499600 53.5
+461500 6509500 41.5
+473800 6554300 143.5
+493900 6496400 163
+487000 6524300 116.5
+480900 6531800 99.5
+512800 6519100 287.5
+464500 6476400 130.5
+463900 6496600 103
+480000 6545700 106
+488700 6545100 100.5
+479300 6468200 86
+474500 6480900 115.5
+533600 6547100 269.5
+480600 6526600 109.5
+514900 6516500 214
+486700 6555200 123
+439400 6521500 39
+492900 6523000 102
+472000 6551200 120
+490700 6489200 122
+478700 6540700 86
+475000 6533300 78.5
+461100 6500300 90
+459200 6536100 107
+448700 6500500 64
+489500 6531300 85.5
+493800 6511300 105.5
+451600 6509700 33.5
+449700 6492900 80.5
+502200 6543900 168.5
+456900 6472900 110.5
+475300 6529300 99
+485900 6537900 90
+465400 6493200 102
+484900 6511100 99
+494900 6533200 135.5
+455200 6478300 123
+470400 6468400 99.5
+526600 6530500 206
+469000 6521100 94
+497900 6548900 169
+503200 6532200 155.5
+457000 6517500 69
+459000 6484200 95
+454500 6520200 55.5
+486200 6536100 83
+485500 6504300 124
+485500 6519100 117
+520900 6522800 257.5
+504900 6513200 217.5
+476400 6512500 65
+460500 6510200 34
+486100 6541800 94
+452900 6514100 24
+464000 6480100 142
+440300 6525200 17.5
+515300 6533700 204.5
+445300 6502100 59.5
+465500 6472900 106
+469100 6488800 127.5
+472200 6545500 104.5
+458100 6511800 25
+480100 6492400 146
+462000 6524200 137.5
+491200 6535800 107.5
+497500 6501800 166
+445800 6504100 78.5
+448300 6522200 21
+462300 6484800 114.5
+457300 6522100 92.5
+502000 6528100 132.5
+483100 6523200 99.5
+473800 6511500 68.5
+502100 6541000 157.5
+476600 6524500 64.5
+478800 6488000 141
+499800 6540300 143.5
+486600 6484800 134.5
+481900 6525900 115
+446300 6490100 78.5
+437200 6523400 57
+524800 6539500 220.5
+495000 6520500 110.5
+504900 6541100 168
+524800 6527600 222.5
+458500 6500100 96
+464400 6468400 97.5
+440300 6507500 49
+452900 6523700 47.5
+500200 6518300 143.5
+458400 6466600 90
+448000 6486900 87
+514800 6525700 268
+502400 6510900 132.5
+438700 6513900 17.5
+522700 6558500 177
+503800 6521500 206
+469000 6465100 80.5
+479400 6511700 60.5
+450400 6522900 29.5
+517200 6519300 255.5
+466300 6508900 59
+476300 6554000 127
+523800 6550600 183
+481600 6553500 123
+466900 6512100 82
+465000 6538600 92.5
+506500 6531100 166
+460200 6518100 70.5
+448700 6515900 29.5
+475600 6481800 126.5
+474100 6550100 123
+484800 6471900 89.5
+478100 6467600 75
+459700 6520600 113.5
+528400 6541400 228
+476400 6468100 111
+513800 6553600 194
+446700 6527100 23
+500400 6513700 165.5
+489200 6551600 123
+485300 6539500 95
+489700 6540300 107
+491400 6526000 90.5
+466900 6549100 102
+509700 6545300 189.5
+463900 6491400 100
+475600 6499100 106
+503400 6547100 165
+442300 6502900 40.5
+449900 6495300 49
+471900 6481400 124.5
+483600 6512500 101
+443100 6506200 50
+510700 6512300 195.5
+455100 6495000 59.5
+500800 6504600 143
+493400 6491100 156
+507800 6550400 183.5
+460500 6508100 57.5
+451800 6500500 91.5
+491300 6503300 151
+486600 6541200 93
+469900 6511100 73
+464300 6507600 57.5
+463600 6518300 99.5
+461600 6474800 129.5
+452800 6504600 93
+485200 6490100 142
+494800 6518900 114
+463800 6482300 123.5
+454800 6512800 25.5
+480400 6541700 112.5
+480100 6555300 127.5
+486600 6510500 101.5
+453500 6490800 81.5
+499200 6512400 112
+505500 6502300 142
+471000 6554300 135.5
+462500 6544800 98
+471500 6524800 92.5
+484700 6536800 88.5
+484200 6527900 123
+497400 6529300 129
+437600 6509600 33.5
+479300 6550700 126.5
+478000 6546900 114
+470100 6466300 86.5
+447300 6497400 47.5
+474300 6471200 88.5
+441000 6516100 29
+461800 6542700 107
+487500 6490700 150.5
+480000 6473400 109
+449900 6474900 106
+467700 6552300 116.5
+497000 6542700 137.5
+482800 6547400 126
+495000 6508700 115
+527800 6535200 217
+471000 6496200 144
+477500 6558300 131
+460100 6476500 124
+477300 6516300 66
+466000 6530100 105
+478800 6557700 134
+445000 6515100 30
+472300 6493100 139
+509800 6515000 249.5
+441900 6508500 58
+484300 6531000 92
+483600 6479800 128
+455400 6488400 73.5
+470000 6541800 93.5
+456000 6524200 89
+449900 6488200 104
+469800 6502500 80.5
+518300 6537600 198
+455600 6504900 93
+509600 6554500 169
+456700 6514800 30.5
+470400 6516600 85.5
+459600 6481800 120
+478800 6553700 121.5
+471200 6467500 107.5
+476100 6517500 78
+537200 6544700 295.5
+466200 6534300 97.5
+494000 6514700 104
+472900 6528200 89.5
+520400 6554700 177
+478800 6509500 77.5
+446800 6481200 99.5
+456500 6496100 66
+449200 6482400 108
+505400 6510600 189.5
+446700 6510900 28.5
+450900 6517500 37.5
+464900 6465300 81.5
+476800 6529900 92
+489600 6494700 160.5
+519900 6548600 174.5
+476800 6487500 142.5
+497300 6539400 124.5
+458400 6538400 114
+516500 6526300 244.5
+492600 6542500 125
+458900 6502200 70.5
+482700 6516700 97
+506600 6557600 158.5
+482000 6510700 79
+468500 6463400 73
+463500 6532300 96
+508300 6519400 280
+487700 6512700 119.5
+511400 6529200 190.5
+471100 6549300 100.5
+519200 6529200 216
+473000 6535800 86.5
+516700 6530500 223.5
+523100 6533100 199
+445000 6474500 108
+498600 6542200 158.5
+478200 6475700 110.5
+475900 6539900 85.5
+487800 6498900 164.5
+499000 6505900 137.5
+458600 6496600 93
+491900 6529500 102
+470300 6507200 47.5
+486200 6539100 84
+482300 6495900 147
+462900 6497200 95.5
+469800 6484400 125.5
+485600 6550900 109
+461700 6487800 94
+366600 6547300 7.5
+427100 6516500 26.5
+454400 6548600 124
+398300 6523600 30.5
+397900 6538900 12.5
+454700 6535100 105
+384800 6518400 17
+450200 6537400 92
+440200 6486100 73
+430200 6553600 61.5
+414300 6516000 46.5
+418500 6514300 38
+421600 6518800 16
+407000 6584800 6.5
+428900 6524500 63
+427600 6521500 43.5
+444500 6552500 115.5
+430700 6494100 47
+389400 6544100 11
+389200 6567800 29
+448000 6452900 64.5
+410300 6563300 45
+433300 6479100 77.5
+384000 6569600 19
+391200 6512500 19.5
+425700 6488500 46.5
+402400 6570100 21
+437600 6483200 64.5
+396200 6558100 20
+419400 6555300 28.5
+399200 6558400 15.5
+449500 6546700 117.5
+451100 6548600 130.5
+352000 6577500 7.5
+441300 6496000 77
+433500 6556000 44
+381500 6523000 14
+435500 6532000 26
+442100 6471900 92
+399200 6563500 22.5
+417500 6522700 41.5
+426600 6492700 31.5
+434800 6541600 50.5
+449900 6528900 53
+383800 6575400 19
+394200 6573700 21.5
+397800 6520700 21.5
+353600 6582100 7.5
+423400 6504100 35.5
+463500 6455400 65.5
+386900 6561300 11
+399400 6534800 18.5
+407400 6520100 32.5
+399100 6499100 23.5
+385500 6543400 5
+411000 6510800 40
+429700 6543100 39
+392900 6586500 6.5
+408100 6528300 42.5
+407200 6493300 34.5
+377200 6574500 14.5
+413200 6575600 17
+408000 6537200 15.5
+413400 6560800 49.5
+420900 6541500 50
+433700 6553600 37.5
+453600 6543600 111.5
+418700 6519300 11
+424900 6478800 73
+387800 6515900 19
+426800 6482100 73.5
+382700 6564300 8.5
+409500 6518600 35.5
+383900 6513200 13.5
+426100 6505800 54.5
+401400 6498100 31
+440100 6535900 49.5
+405200 6561700 26.5
+395900 6551300 13.5
+406400 6490400 15.5
+415600 6514200 37
+461000 6451700 53.5
+450100 6534700 82.5
+431700 6536700 39.5
+436600 6532800 24.5
+398700 6572700 16
+438900 6532400 26.5
+383700 6522800 14
+412100 6481000 35.5
+446100 6531900 40.5
+447200 6468200 97
+442200 6488000 78
+361500 6557500 7.5
+433300 6473900 77.5
+448800 6531400 64.5
+379100 6575900 17
+396500 6512100 11.5
+418900 6486200 66
+454600 6459500 79
+436200 6557600 57
+410900 6531100 36.5
+402600 6577000 28
+446600 6472300 108.5
+425100 6558900 57
+444500 6477500 81.5
+389600 6570900 34.5
+379200 6524100 12.5
+435600 6505200 49.5
+406800 6582600 18.5
+418900 6482200 51
+428400 6491600 33.5
+420900 6508800 37
+420200 6558000 43.5
+419600 6511200 38.5
+377500 6521500 20
+452000 6553700 144.5
+441300 6478500 77
+363400 6576300 8.5
+361300 6574600 9
+437900 6470400 94.5
+420100 6501500 35.5
+420800 6512400 27
+426300 6508900 30
+423400 6519400 38
+399300 6532700 23.5
+405600 6548400 32
+394300 6515600 10
+410900 6521200 47.5
+423800 6498900 33.5
+440500 6467400 96
+434600 6482800 66.5
+389900 6580500 12
+402800 6565900 27
+417300 6532800 32.5
+393700 6550400 12
+452500 6451400 42.5
+435700 6559400 65
+430200 6508600 47
+420600 6484000 69
+395500 6568200 23.5
+433100 6550200 37
+442900 6531200 27
+423500 6511100 31.5
+418800 6483800 73
+379800 6570600 14
+429600 6489300 56.5
+387300 6550400 11.5
+417800 6506900 40
+412100 6537300 6.5
+397900 6526500 25.5
+395100 6507600 21
+413800 6555100 27
+405900 6574300 31.5
+442300 6496700 82
+390500 6566600 27
+427500 6523100 55.5
+415400 6487000 57.5
+366500 6574400 8.5
+364700 6551300 15
+397500 6561300 31.5
+437300 6554800 53.5
+390700 6519700 5.5
+428300 6517400 36
+434700 6496600 47
+426400 6565100 56
+382500 6567600 11
+437700 6503600 40
+395600 6575600 10
+405900 6540100 28.5
+435600 6462700 62
+421600 6550000 41
+424900 6524000 53.5
+428400 6482100 62
+398900 6567600 21
+407300 6560200 19.5
+399000 6502200 27.5
+442900 6470200 109
+427200 6495600 38.5
+415500 6510200 46
+437000 6479000 49
+446000 6551200 120.5
+414800 6556900 42
+433100 6528000 59
+386500 6511100 17.5
+429900 6505300 68
+410800 6506400 35
+438500 6526800 18.5
+412000 6508300 41.5
+428700 6497300 55
+437400 6498000 72.5
+432600 6517400 48.5
+358900 6575700 8.5
+369900 6543500 10
+417800 6527200 31
+401200 6530100 26
+437400 6543400 70
+381000 6517000 22.5
+453500 6550300 130
+439700 6502500 50.5
+423900 6484900 54
+429900 6559100 50.5
+413100 6547600 24
+392700 6577700 9.5
+426200 6534000 58.5
+443100 6537500 64
+427300 6477800 74
+389800 6538300 9
+439700 6543700 66
+422200 6564700 52.5
+450600 6540200 83.5
+426400 6500900 46.5
+434100 6525000 61
+448700 6542100 78
+459100 6460000 72
+406800 6567900 27
+421300 6493400 35.5
+401300 6505400 34.5
+438500 6478400 75
+440600 6470400 96
+405000 6585900 4.5
+419500 6533500 32.5
+416000 6497100 42.5
+438300 6488200 70
+390700 6564400 34
+420600 6481200 58.5
+363700 6555500 5.5
+440700 6457200 76.5
+435900 6475100 83.5
+435600 6486200 61.5
+405000 6515100 35.5
+418100 6548700 33
+423200 6545100 20
+410000 6501400 31.5
+416200 6543400 33
+386600 6573400 19.5
+400500 6575800 18.5
+456100 6547500 117
+441500 6545800 69
+427300 6544300 42
+452800 6536300 103.5
+401900 6523000 28
+378300 6536000 9
+401700 6581700 19.5
+431000 6480600 69
+426700 6485800 50
+436000 6536200 41
+411800 6567000 46
+393200 6530000 20.5
+419000 6494000 44
+455900 6468400 97
+422300 6499100 28
+405200 6509700 22
+432900 6470800 82
+429400 6561400 67.5
+393400 6521700 16
+414400 6533000 30.5
+386700 6520200 6.5
+443500 6542500 80
+433600 6513800 12
+431800 6490400 63
+414600 6527100 41.5
+381400 6533000 10.5
+400700 6517500 25
+406400 6578600 22
+427500 6549000 67.5
+407300 6554000 31.5
+431500 6499400 72
+442500 6535200 45.5
+441700 6502000 33.5
+421000 6525500 41.5
+384000 6585400 5.5
+416900 6500200 40.5
+407500 6521800 35.5
+425000 6495700 28
+412600 6534400 15
+413800 6496900 38
+385900 6569400 21
+440500 6477300 75.5
+410000 6524700 43.5
+457900 6544600 112
+412700 6552200 35
+414600 6537600 34
+419400 6539900 44.5
+393700 6532000 17
+440100 6483600 72
+410000 6515600 37.5
+419500 6550800 25
+417100 6502600 39
+462400 6462300 79
+410500 6488200 32
+455900 6534200 112
+384200 6546800 9
+432600 6547400 44.5
+427000 6538300 52
+416500 6482800 55.5
+421200 6491500 46
+405500 6542600 18
+428500 6474200 55
+397300 6546200 16.5
+396300 6564900 25
+414700 6481700 45
+434900 6555800 41.5
+434900 6501200 59
+445000 6550100 74.5
+423800 6489700 38
+427800 6530800 68.5
+371400 6537700 12
+422900 6530800 46.5
+391700 6503000 19.5
+407800 6495300 33
+386100 6545400 10.5
+419100 6497200 34
+393700 6540800 9
+406000 6566400 26.5
+428800 6502700 48
+419700 6552800 36.5
+410200 6579200 16
+411200 6551500 33
+370200 6571100 8
+392800 6538000 13
+431600 6472500 55
+436200 6528200 21
+418100 6530100 29.5
+409000 6557600 24
+381700 6513100 25
+419200 6545700 32.5
+422800 6474500 63.5
+432400 6540600 47.5
+383200 6580500 9.5
+404800 6537300 14
+367400 6570200 8.5
+428700 6558800 46
+392800 6545800 14.5
+423700 6533300 46
+404400 6494100 32
+394600 6558500 23.5
+390700 6569500 36
+428500 6555700 66.5
+423700 6552100 73.5
+377200 6554300 7.5
+443500 6495100 82
+431100 6545200 41.5
+379800 6573900 17
+398100 6543200 14
+439100 6473200 89.5
+386500 6530500 9
+439500 6491100 56
+403400 6512700 24
+423700 6555400 55.5
+433200 6506900 39
+413800 6487100 44
+428400 6515600 14.5
+407900 6506900 33
+406800 6496400 35
+432300 6545500 42.5
+435600 6481900 65.5
+434300 6547300 51
+426900 6475800 57
+430600 6513800 19.5
+419600 6499000 33
+433200 6495000 41.5
+432400 6476900 78.5
+386900 6564100 16
+444700 6465800 99.5
+373500 6535600 17.5
+397200 6577000 14.5
+389200 6524500 4.5
+416700 6566600 46.5
+441200 6552300 69.5
+388400 6508500 22.5
+437500 6492100 50
+413500 6503300 32.5
+450400 6527300 59.5
+438800 6481000 68
+374800 6540400 5
+406200 6531700 30.5
+400700 6507800 32.5
+450100 6465600 96.5
+387300 6557000 9
+447700 6529600 47
+451300 6544200 101
+405900 6526800 37.5
+443300 6556700 90.5
+411600 6483300 50.5
+390700 6573000 22.5
+403400 6500800 30
+402300 6572500 12
+411700 6524900 47
+434200 6492500 52
+445700 6544400 85
+385600 6566800 14.5
+432700 6558100 54
+429900 6530700 60
+447200 6535000 70.5
+403900 6555500 14
+411700 6490800 34
+434300 6551800 41.5
+441800 6474000 84
+418100 6504500 37
+408400 6510800 29
+420800 6545500 24
+452200 6530600 91
+383300 6551300 10.5
+399800 6510800 19
+390700 6560500 24
+378300 6527300 28
+431700 6488900 56.5
+384200 6560800 10.5
+437400 6475000 81.5
+396700 6533200 20.5
+432500 6548400 53.5
+410400 6575200 16
+412900 6543500 24.5
+413500 6479400 43.5
+382600 6573400 21
+405900 6518400 33.5
+429900 6483300 58.5
+387200 6541900 7.5
+446700 6539500 76.5
+395100 6500400 12
+421200 6538600 61
+439200 6537700 56
+423800 6540500 58
+413400 6556900 22.5
+441900 6474700 78
+436500 6492100 64.5
+442000 6491400 81
+425800 6555200 68.5
+423100 6535300 39.5
+452000 6456800 62.5
+357900 6578900 5
+386800 6579300 10
+439500 6531100 27
+429800 6476500 72.5
+403700 6523400 29.5
+454300 6527500 101.5
+391400 6547900 9
+420300 6537200 49
+402400 6536200 22.5
+393800 6569800 24
+383900 6535900 13
+434000 6466700 70.5
+408200 6546300 23
+427200 6511400 29
+437400 6548900 58.5
+409300 6491400 36
+445100 6468500 112
+454100 6540600 103
+447800 6463600 70.5
+404100 6547300 14.5
+449900 6462500 75.5
+443400 6485200 84.5
+446500 6458700 71.5
+426400 6494300 43
+440300 6530100 22.5
+421900 6560700 63.5
+423500 6527800 71.5
+415600 6569700 40
+390900 6526500 15.5
+389100 6577500 12.5
+455700 6454400 70.5
+409400 6546000 14.5
+381200 6578400 15.5
+446200 6464200 85
+430600 6532100 43
+437300 6506200 26
+350300 6579800 9
+431000 6534200 52.5
+424000 6546500 39.5
+401600 6559500 17
+402200 6539700 17
+401200 6543500 14
+667300 6638800 170
+644900 6618500 201.5
+668100 6710000 223.5
+669600 6682400 313.5
+651000 6616600 225
+651200 6667400 143
+677600 6648000 186.5
+669100 6694800 320.5
+662200 6624900 230
+659000 6634800 165.5
+637100 6628300 177.5
+648500 6632100 167
+659900 6615500 205.5
+670800 6676200 205.5
+629500 6680600 138
+650100 6605500 276
+684400 6689900 283.5
+677300 6686500 328
+651900 6690600 232
+637600 6666400 124.5
+646100 6644400 151
+663400 6664900 152
+655800 6678400 226.5
+646300 6609100 272.5
+662600 6620900 181
+694600 6666600 182.5
+679200 6673600 212.5
+691000 6698400 199.5
+699100 6674600 169
+659300 6649600 169
+661100 6681400 243
+663700 6621600 201.5
+663500 6676400 174.5
+653400 6636200 155
+690400 6671700 200
+683800 6681700 205.5
+693500 6660600 194
+690000 6709200 185
+697500 6653000 192.5
+681200 6638300 241
+673300 6633800 177.5
+654900 6652600 161
+681800 6627400 211.5
+700400 6670700 174
+650200 6673100 184
+685400 6648700 232
+656600 6619700 198.5
+680400 6669000 215
+686000 6637800 226
+657600 6646000 173
+669100 6621400 200
+655000 6647400 170
+646100 6668000 137.5
+658500 6655500 152.5
+650400 6608700 252.5
+648800 6662700 143.5
+652400 6639400 167
+628100 6674100 115.5
+641200 6684700 154
+636100 6670700 119.5
+685500 6694100 261.5
+626000 6678900 119.5
+685200 6663300 195
+647200 6624600 201
+687600 6660200 213.5
+672000 6680200 236
+683100 6669400 222
+627700 6669300 132.5
+673800 6638900 199.5
+612600 6672000 130.5
+641400 6610900 235.5
+670300 6702900 276.5
+672000 6709800 238.5
+661300 6694000 273
+686800 6668600 195
+681700 6684100 263
+686200 6699300 238.5
+680800 6655600 201.5
+648800 6680900 213
+647800 6601000 299.5
+619900 6676000 139
+652100 6642700 169
+632500 6636700 162
+661200 6672100 154.5
+663400 6616900 198
+619500 6681200 121
+673400 6663700 162.5
+639200 6664900 126.5
+687100 6685400 205.5
+694100 6673000 173.5
+685300 6696400 254.5
+615600 6677400 137.5
+673700 6706400 230.5
+679300 6664600 179.5
+691300 6687200 198
+684900 6651900 209.5
+661400 6611100 220
+640600 6672000 122
+665700 6618700 182.5
+696000 6650100 198.5
+636500 6675500 112
+654200 6628900 182
+631500 6659200 132.5
+651200 6656900 153.5
+677900 6691900 307.5
+664700 6714800 211.5
+657200 6650200 167.5
+656800 6625800 184
+686700 6638900 220
+668300 6652600 166.5
+693800 6636900 212.5
+688100 6631600 226.5
+669000 6626500 226
+644500 6648600 147
+653500 6703500 223.5
+649800 6650000 159.5
+676400 6689200 330
+683400 6633300 221.5
+695200 6642000 206
+688800 6711800 182
+632400 6664200 138
+679600 6643900 213
+660400 6625200 173
+681500 6703100 285
+675900 6682200 272
+692300 6646400 203.5
+664900 6622400 181.5
+659400 6676400 196.5
+680900 6644400 212.5
+648800 6710200 158
+701000 6663000 177.5
+645800 6631000 173
+646300 6652300 146.5
+656100 6681500 237
+674400 6683800 327.5
+691400 6661000 217.5
+637200 6619500 213.5
+685600 6704500 237
+636900 6625400 213.5
+636000 6642700 152
+673800 6648300 180
+704000 6651200 188
+637300 6678300 139
+636800 6594700 419.5
+688300 6651800 226
+628500 6670100 120.5
+677900 6675900 210
+667600 6677600 187
+666600 6660500 154.5
+676100 6652400 188.5
+691500 6665200 186.5
+637800 6633000 172.5
+703600 6645100 197
+641500 6601100 362
+657200 6696000 233
+682300 6660600 200.5
+642100 6635200 166.5
+669800 6635300 174.5
+697400 6658000 187.5
+661200 6658600 154.5
+639200 6694700 137.5
+664900 6648900 163
+661100 6641000 167.5
+702400 6658300 185.5
+642000 6623300 205.5
+690000 6689400 218.5
+664100 6689300 303.5
+638800 6607200 300
+651900 6622100 209
+663500 6708300 255
+619200 6684600 122.5
+651600 6698800 187.5
+667400 6666600 156.5
+675900 6698300 291
+632800 6655100 140.5
+689200 6681100 183.5
+668400 6680300 223
+668200 6656800 160.5
+646400 6657000 153
+633100 6648300 145.5
+631300 6668500 130
+668100 6606600 211.5
+663800 6663800 152
+695000 6669700 187
+656700 6671800 150.5
+660700 6666700 150
+641400 6674200 133
+681600 6694600 309.5
+612100 6672100 124
+699100 6660600 183.5
+623500 6683400 125.5
+646700 6647200 150
+658100 6674500 178.5
+647700 6637900 159.5
+645700 6667000 131
+634000 6675600 117
+664600 6651200 160.5
+644000 6718500 140
+647900 6639900 153
+690400 6707700 165
+640000 6615800 214.5
+645100 6659900 140.5
+696100 6645200 202.5
+700300 6669100 176
+682800 6710900 221.5
+686300 6655300 214
+674400 6702800 254.5
+685500 6653600 219.5
+688900 6693400 208.5
+653100 6617100 218.5
+645200 6616000 231
+647900 6718900 151
+672900 6654000 178
+690400 6702600 169
+651700 6609300 259.5
+702200 6635400 200.5
+673700 6659300 171.5
+685100 6670200 207.5
+656300 6676800 177
+671200 6669400 189
+642800 6592800 393.5
+616200 6671300 139.5
+639600 6637900 159
+643100 6655300 140.5
+666500 6631500 235.5
+635800 6657500 141.5
+683600 6647800 214.5
+667400 6642800 169.5
+660200 6620900 185
+678200 6633500 214.5
+656300 6604500 293
+686000 6629500 229.5
+674300 6645200 183.5
+673700 6635700 200.5
+652000 6633700 182
+647900 6705500 157
+664300 6605300 230.5
+694600 6686300 148
+696500 6679600 167.5
+643600 6690800 185.5
+623700 6673100 131.5
+684700 6658900 199
+665800 6681500 260.5
+690800 6642200 213.5
+687800 6692300 256
+681500 6700400 276.5
+686500 6676200 183
+689100 6690800 197
+671200 6644900 180.5
+686900 6687200 242
+639800 6612000 224.5
+653700 6673200 176.5
+632900 6652600 142
+650400 6646900 162
+656100 6624400 201.5
+677600 6640000 207
+654100 6665000 144.5
+657800 6710000 197
+658000 6680600 223.5
+676100 6699500 284
+641000 6659000 136
+680700 6689500 292.5
+675300 6666300 191.5
+658300 6686600 264
+678200 6629500 196
+628700 6663900 130
+702800 6640500 198
+662700 6654900 160
+690200 6661000 206.5
+667400 6616200 189.5
+640100 6647900 153
+665900 6670800 160.5
+637200 6652200 143.5
+662200 6631300 220
+679500 6650500 200
+657800 6630000 198
+637600 6636500 164
+639800 6623900 203.5
+659900 6622900 176
+668600 6706800 253.5
+647400 6634900 159.5
+639600 6680800 148.5
+656700 6630000 177
+693700 6672800 190
+677700 6707200 268
+685600 6678800 187.5
+658100 6717500 177
+700600 6665800 174.5
+651000 6634900 155
+672700 6625600 210
+588400 6440400 274
+660600 6477900 595.5
+575100 6475900 323.5
+637700 6469600 470.5
+579500 6444900 224.5
+593200 6468800 381.5
+643000 6476000 509.5
+613900 6452000 393.5
+573800 6470300 265.5
+588800 6494000 445.5
+570000 6469900 259
+630000 6477700 539.5
+621800 6457800 403
+575300 6446100 208.5
+629200 6487700 755
+593000 6438500 231.5
+603700 6491700 552.5
+633400 6502100 839.5
+608400 6462500 349.5
+652600 6488000 658.5
+651600 6480500 528.5
+593400 6473500 410
+625000 6473700 604.5
+569100 6459500 241
+588800 6459900 282
+570700 6462600 223
+596300 6463500 401.5
+597500 6451900 428.5
+648100 6473700 503
+630500 6481100 567
+588600 6467500 354.5
+597400 6442900 330
+573300 6461100 220
+627300 6435800 470
+594100 6441100 318.5
+603300 6468900 363.5
+613400 6459600 433
+614100 6443100 327.5
+578300 6456100 176
+654400 6489500 690
+602800 6430400 238.5
+616800 6506000 733
+600600 6453400 494.5
+646200 6488400 615.5
+592500 6453000 246.5
+644700 6486800 666
+637700 6474000 519.5
+572600 6457900 232.5
+613300 6458400 421.5
+629200 6449200 557
+616700 6475800 565.5
+591300 6442500 331.5
+620400 6432000 391.5
+647700 6501800 747.5
+603700 6463700 322.5
+637400 6464300 411
+600700 6485700 443
+619400 6464900 557
+578200 6442500 277.5
+625000 6486900 777.5
+606400 6431300 290
+627200 6466700 589.5
+594800 6466000 398
+575200 6463900 176.5
+629500 6505100 878
+628100 6453300 507
+573300 6478700 377
+638800 6497800 749
+571900 6472400 298
+573400 6476700 376.5
+657800 6490600 700
+605700 6468200 352.5
+640000 6489600 680.5
+603500 6457100 386
+602700 6441100 334.5
+619000 6455600 401.5
+593000 6464700 374
+621400 6443100 370
+587700 6481600 355.5
+614100 6435700 343
+616400 6444300 303.5
+612100 6491300 706
+617600 6438300 371
+627900 6483300 692
+582100 6440100 284.5
+600900 6434300 243.5
+598100 6438500 196.5
+605100 6445300 494
+586700 6443500 268
+578000 6477700 345
+642100 6497500 713
+600700 6442000 370
+603500 6478000 416.5
+607800 6428700 217
+593400 6485400 374
+625300 6479000 666.5
+660700 6493900 653
+584600 6495100 452.5
+578000 6471500 288.5
+601700 6496000 429
+599500 6432800 155.5
+598400 6490000 386.5
+597000 6472200 450
+599700 6444100 373
+586300 6465900 314
+604400 6437200 251
+651900 6502000 765
+612000 6475400 469.5
+564900 6465500 249
+598700 6482200 421
+568800 6462200 251
+620200 6461200 494
+582900 6455900 198
+570400 6474200 308
+661000 6506800 694
+609900 6467300 413
+638100 6501900 747.5
+593900 6458100 283.5
+616900 6479600 649.5
+636900 6452300 458.5
+565100 6460200 229.5
+597300 6457700 315
+620400 6452800 371.5
+591800 6456100 290.5
+584400 6484300 383.5
+606300 6454900 407.5
+590100 6486300 383
+639700 6505300 734.5
+609100 6490600 729
+621900 6439100 411.5
+594600 6496500 478.5
+594800 6436400 158.5
+607400 6463500 342
+648700 6505600 773
+568600 6470100 282
+620500 6499000 825.5
+651100 6494300 733
+658000 6505400 681.5
+566500 6484500 315
+613200 6448000 333.5
+647900 6479800 521.5
+608500 6505300 676.5
+606300 6481000 460
+633100 6456400 468
+629100 6442600 438
+643300 6506500 749
+565900 6479700 344.5
+613700 6494100 767
+567500 6482500 333.5
+626200 6440500 405.5
+599300 6475000 432
+608700 6436900 285.5
+659100 6510100 720.5
+607200 6472400 400
+569600 6455800 217.5
+624300 6469600 593
+606700 6506200 635.5
+600200 6499000 551.5
+623000 6468100 561
+594600 6448700 300.5
+614800 6490300 753
+567000 6467500 204
+576900 6492300 399
+577500 6467100 253.5
+586600 6470700 365
+601000 6438100 201.5
+626400 6512000 812.5
+595500 6453600 324
+590200 6480500 382
+611700 6453500 391
+625200 6504100 832.5
+633100 6486200 620
+610100 6459400 437.5
+633400 6493300 783
+596100 6449700 331.5
+585900 6490500 413.5
+580500 6482800 409
+578800 6437700 304.5
+655400 6479600 693.5
+657300 6507000 806.5
+639500 6466500 463.5
+653300 6479800 620.5
+617300 6471200 581
+661100 6488300 653
+575400 6448100 211.5
+617800 6450800 371
+608100 6443500 392
+608400 6431700 256
+572200 6468100 189
+611200 6451300 331
+573800 6464800 170.5
+645200 6501800 704.5
+577900 6450300 155
+632300 6511100 825
+605000 6439700 304.5
+608500 6449400 438.5
+580400 6463300 245
+618000 6509500 705.5
+609100 6481200 626
+610200 6478600 621.5
+599600 6448100 385
+650800 6490900 652.5
+637200 6507800 809
+578900 6482500 394.5
+598400 6435500 183
+646100 6494500 684.5
+619600 6484700 705
+584000 6476600 339.5
+626400 6443100 403
+635100 6475100 496.5
+648800 6483200 591
+569400 6486100 323.5
+606200 6426400 204.5
+580600 6492300 406
+634400 6486600 619
+593900 6478400 417.5
+606100 6474200 398
+647700 6507100 821
+612900 6469200 549
+608800 6460000 371.5
+620000 6473200 580.5
+653000 6508000 831
+605500 6486900 647
+628000 6462400 430.5
+609000 6431500 319
+581300 6469600 302
+573000 6453400 165.5
+622400 6475800 695.5
+606000 6493800 570
+606100 6436500 301.5
+645700 6483800 618
+631500 6470500 516
+584200 6467800 359
+632100 6463400 410
+637900 6480200 608.5
+592100 6450600 243
+604400 6461100 313
+611600 6463700 458.5
+661600 6511900 712.5
+631100 6492300 793
+623900 6464100 444.5
+578500 6458800 142.5
+619900 6458400 448
+648400 6481500 527.5
+634600 6466400 431.5
+575300 6484100 363
+599700 6439900 251
+617600 6454600 396
+584200 6459700 250
+566100 6463200 256
+629400 6503200 891.5
+612600 6484700 717.5
+587200 6453400 213.5
+588800 6449300 257.5
+657900 6496700 674
+584700 6452100 208.5
+583800 6445900 233
+597400 6492700 427.5
+617100 6435600 381
+651600 6485200 625
+643600 6500900 691.5
+632300 6448200 509
+623300 6448400 392
+594300 6481300 382.5
+595600 6440500 282
+597800 6460300 315.5
+616400 6500400 755.5
+609100 6501900 646.5
+613000 6501700 741
+571700 6463600 172
+619300 6447300 347
+600700 6432200 242.5
+591300 6440100 235
+627500 6438600 451
+615500 6488400 702
+608000 6446500 415.5
+574700 6469100 246
+603300 6427900 205
+627100 6457300 440.5
+579000 6446100 231.5
+653100 6484000 606
+609600 6436200 331
+620700 6493000 790.5
+566800 6451100 207
+608700 6440100 345.5
+609300 6456800 387.5
+820800 6767600 275.5
+882800 6716400 253
+838400 6719000 420.5
+821800 6695500 466
+842200 6672900 371.5
+863100 6655800 183
+847800 6709400 466.5
+807200 6742700 277.5
+840900 6695200 438
+834400 6738500 367
+831300 6698400 483
+808700 6716700 325.5
+872300 6674600 193
+846300 6700800 441
+814000 6724600 385.5
+865900 6683400 209
+840600 6681100 479
+796300 6718500 325
+865000 6707400 262.5
+795700 6703400 339.5
+803300 6739200 304
+840500 6691800 430.5
+823400 6738700 336
+823900 6697400 460
+826800 6675500 434.5
+877000 6700000 211
+799500 6754400 242.5
+797700 6714700 311.5
+819800 6677100 419
+820400 6707800 397
+850000 6676600 230
+820500 6705300 407.5
+824600 6676600 438
+875900 6700700 209.5
+831700 6660700 435.5
+882900 6718300 255.5
+858100 6681500 211.5
+826900 6667000 438
+823400 6734300 343
+876700 6721400 275.5
+838100 6734600 395
+798300 6717900 325
+828500 6673200 437
+856600 6702900 304
+833400 6651000 317.5
+832900 6693900 477.5
+851900 6717400 386
+812900 6761500 273.5
+847900 6678000 341.5
+842400 6684700 454.5
+849500 6669700 218
+817300 6739000 339.5
+845200 6666600 260
+787000 6671200 557
+853200 6714200 405.5
+835800 6649200 205
+879000 6668200 194
+833100 6748000 324.5
+859100 6692600 231
+815000 6757300 251
+804000 6709500 315.5
+824900 6765200 268
+878300 6695600 196.5
+789000 6698500 423
+802700 6725500 285
+859900 6684400 210.5
+832600 6712000 456
+877500 6685700 215.5
+840500 6656200 206
+831800 6691700 442.5
+845400 6717300 417
+866300 6703700 260
+845300 6707300 460.5
+826900 6699600 464.5
+849800 6686400 394.5
+800600 6692400 404.5
+843800 6654800 199
+809400 6738100 314
+795100 6724200 291
+844200 6682900 455.5
+850200 6653700 185.5
+800400 6725600 284
+844100 6725800 435
+851100 6656400 191
+819400 6681200 399.5
+854800 6679500 216
+816500 6755700 259
+825000 6675100 458
+847800 6672600 370
+865600 6689100 205.5
+854700 6705300 380
+838000 6693700 444
+819400 6673100 430
+827800 6748100 334.5
+819800 6660800 416.5
+819300 6701000 446.5
+810000 6708100 379.5
+799700 6738200 272
+884300 6674500 196.5
+879400 6683800 207
+785400 6698300 442
+848700 6677000 254
+873500 6659500 184
+837900 6653700 206.5
+792400 6704700 327.5
+811800 6739900 314.5
+813100 6701200 405.5
+847100 6725300 400
+826800 6691500 507.5
+873400 6692400 214.5
+809300 6692500 446
+878000 6709800 237
+824700 6685400 450.5
+880300 6688200 210
+842000 6743100 372
+885700 6687200 194.5
+823300 6703500 414.5
+871200 6694600 216.5
+825500 6750800 302
+849200 6684700 397.5
+801300 6760300 267
+833200 6688600 418.5
+798800 6697400 405.5
+827600 6695700 509
+871400 6680700 191.5
+843900 6692900 420
+811900 6692500 421
+885400 6695100 188
+820100 6675100 429.5
+877200 6696800 195
+864100 6667600 196
+826600 6688200 487
+832700 6762900 286.5
+851700 6689800 315
+840400 6666100 336.5
+824500 6668400 442
+832200 6666000 483
+818400 6670300 426
+843300 6673800 377
+795100 6672500 452
+838000 6664200 403
+834500 6662800 428.5
+872400 6690700 215.5
+871200 6660600 187
+813500 6759100 267
+825600 6752800 296.5
+816100 6691200 449.5
+852200 6667900 213
+831500 6650000 309.5
+865000 6670100 195.5
+844300 6656500 199.5
+832100 6681200 508
+832700 6766700 284.5
+843500 6678000 423
+800300 6674300 421.5
+859900 6662100 192
+839300 6750000 358.5
+826300 6679200 429.5
+833300 6649100 219
+806800 6710400 363.5
+851200 6726200 404
+817200 6698100 416
+825900 6663600 465
+856100 6699800 296.5
+791100 6721000 288
+848900 6682600 361
+871700 6656800 188
+797700 6675500 476
+860000 6719700 348
+872900 6687000 219
+830200 6730900 376.5
+812500 6677800 382
+872800 6713600 264
+825000 6654200 467
+842300 6656700 202.5
+798400 6724300 294
+827800 6749600 309
+822300 6711900 375.5
+801000 6702900 344.5
+801800 6758200 242
+807600 6710000 365.5
+866700 6663100 185
+818900 6726400 384
+841100 6682700 454.5
+832900 6707800 484.5
+790700 6709900 317.5
+820300 6738300 321.5
+799000 6699300 342
+803600 6702100 320.5
+871700 6699800 228.5
+793400 6730500 262
+882200 6692400 204
+842800 6702500 441
+802200 6672400 436.5
+833700 6660700 366.5
+862600 6698000 227
+806000 6718700 305
+881700 6700900 211
+801100 6720600 313.5
+835500 6693300 407.5
+839900 6672600 448
+805200 6705100 332
+860300 6688100 218.5
+863600 6675000 196
+862000 6709000 281.5
+881300 6690700 194.5
+790200 6716100 302.5
+810900 6755200 277.5
+854000 6677500 217.5
+849100 6683900 387
+794500 6696600 429
+877500 6670600 190.5
+823000 6678100 421.5
+851300 6661600 197
+857500 6679100 211
+831300 6689400 447.5
+871600 6668900 183.5
+856100 6678000 217
+868300 6680700 209.5
+815600 6692800 436.5
+862700 6679800 198
+861900 6676600 198
+820100 6726700 381.5
+870600 6683600 200.5
+827500 6697600 472.5
+815900 6728800 376.5
+847900 6717400 391
+882400 6725900 284.5
+782900 6700600 403
+863100 6657600 184
+800200 6704700 335.5
+844500 6671700 348.5
+804400 6699800 331
+801700 6670700 445
+829500 6737700 367.5
+861600 6702300 249
+823400 6709400 397
+882300 6675800 194
+813500 6708100 369
+881000 6674600 194.5
+835300 6657200 301
+841100 6664500 289
+832900 6697200 505
+880700 6685000 195
+835700 6676200 578.5
+846600 6702600 422.5
+880500 6701700 217.5
+839700 6659800 300
+826800 6677400 406
+850500 6698100 389.5
+863600 6715300 302.5
+885200 6684000 197
+824100 6690700 473
+820400 6734600 338
+857700 6676700 213
+881400 6703100 218.5
+871200 6689300 216.5
+828600 6704500 444.5
+801300 6742900 262
+828700 6697700 493.5
+861100 6729100 397
+827700 6758300 286.5
+843400 6675000 389
+884900 6693000 194.5
+807600 6699500 402.5
+831400 6756600 313.5
+863300 6702600 246
+878400 6704900 217.5
+879500 6697400 204.5
+835800 6695500 478
+856100 6729000 385.5
+835800 6688900 408
+873500 6679200 195.5
+867800 6717200 285
+829000 6720900 405
+867000 6680600 215.5
+863200 6662600 179.5
+813400 6673300 386
+878100 6678300 192.5
+848000 6675100 308.5
+845700 6668600 282
+839200 6751900 355
+840100 6651500 197
+805000 6722400 294.5
+823300 6673100 470.5
+873300 6706700 225
+841100 6757400 313
+834600 6671700 482.5
+861900 6705500 275.5
+809900 6704000 415.5
+825700 6705600 430.5
+854200 6693400 315
+873100 6670700 183
+814500 6666100 389
+788300 6712500 277
+818200 6668000 431.5
+832900 6655500 363.5
+840400 6668900 452
+847800 6656400 191
+808300 6697300 344.5
+825300 6707500 421
+807000 6746900 256.5
+829400 6687100 475
+817700 6752000 254.5
+793600 6675400 480.5
+824800 6694900 465
+852800 6674900 214.5
+809600 6673600 380
+817600 6674300 424
+846700 6669800 288.5
+834600 6654600 328.5
+862000 6725600 387
+807700 6735100 332.5
+850200 6671600 223
+794300 6723800 278
+807400 6704400 405.5
+803800 6690600 454.5
+830200 6672200 495.5
+811100 6698000 389
+838100 6725100 447.5
+837500 6683800 454.5
+834500 6762000 289
+878100 6681600 193.5
+824200 6660100 471.5
+818100 6717900 349.5
+819300 6757600 271
+824300 6651500 419.5
+822400 6667700 404.5
+793400 6682500 518
+839200 6670300 498.5
+800700 6715000 328.5
+798300 6752100 268.5
+845900 6724100 429.5
+804600 6666800 371.5
+851700 6687000 244
+822900 6734700 351.5
+859100 6689900 228.5
+813500 6669500 390.5
+808900 6677600 439
+866000 6727800 386.5
+795300 6708800 325.5
+826400 6728300 363.5
+864200 6688500 210.5
+824600 6661400 495.5
+814000 6755700 219.5
+861400 6681600 203
+797700 6688900 418.5
+805900 6689000 466
+814100 6720400 340.5
+825100 6760700 265
+868000 6672900 190.5
+831200 6706300 518.5
+830300 6681000 437.5
+827600 6739400 349
+844900 6688300 459
+810200 6662900 375.5
+829200 6647200 366.5
+823800 6657400 479.5
+852400 6695600 293.5
+805100 6720500 298.5
+861900 6684200 208
+838700 6655700 212
+814300 6677000 378
+798100 6702900 346.5
+785300 6704000 328
+843200 6664600 278.5
+837500 6754800 316.5
+827400 6733400 386
+871000 6697700 224
+830000 6651400 362.5
+860400 6715400 300
+790100 6713700 285
+845200 6751700 350.5
+823900 6723500 383
+828000 6732400 357.5
+806400 6694800 437.5
+874500 6723900 287.5
+865500 6695900 225
+855900 6710500 409
+824200 6758600 275
+820600 6692300 455
+836600 6732300 402
+862200 6686100 217
+863200 6716400 308.5
+859000 6657400 192.5
+855500 6715400 355
+827700 6652200 442.5
+848300 6731000 423
+881000 6722600 264.5
+848600 6679100 347
+807400 6702000 398
+863800 6676900 193
+802500 6698000 394
+797100 6700000 350
+839700 6738300 379.5
+810000 6722300 346
+870700 6720200 287.5
+878700 6713900 245
+834100 6691500 370
+879700 6671600 193.5
+808200 6714400 332
+794300 6719100 306.5
+805400 6710900 360.5
+849400 6716400 372
+788400 6706200 301
+842000 6739300 392.5
+855800 6684500 226.5
+815700 6660400 396
+842200 6676900 401
+819400 6736500 344.5
+842400 6669000 348
+834600 6705200 488
+840400 6679500 485.5
+801100 6752900 240.5
+824200 6681100 442
+822300 6655400 450.5
+841800 6675200 384.5
+810500 6712900 343
+829900 6677500 441
+874800 6702400 221.5
+818400 6768700 268.5
+865200 6700500 234
+824200 6753600 272.5
+808800 6709400 361
+792000 6711000 289
+851400 6694800 324
+870000 6700200 234
+840500 6697900 487
+866800 6693200 220
+797500 6727100 273.5
+850900 6696500 383
+824300 6691900 498.5
+859300 6688700 222
+803700 6713300 350
+867900 6689100 215
+826700 6701300 449.5
+871600 6682900 209.5
+854300 6700300 313
+854900 6673100 211.5
+805100 6723900 287.5
+851000 6672700 223.5
+794100 6715400 239
+808700 6754600 272
+857900 6706500 297
+817800 6759500 286
+818300 6679700 414.5
+815200 6753500 244.5
+822700 6715600 390.5
+849800 6721200 404.5
+875200 6699500 207.5
+855100 6707300 393
+817800 6741900 314
+824800 6700900 439
+793100 6700100 380.5
+850300 6687500 357.5
+815900 6662900 384.5
+803100 6681200 445.5
+840100 6686200 437
+840800 6670500 373.5
+807300 6754700 262.5
+832100 6683000 429.5
+787300 6708200 294.5
+825100 6730500 353.5
+850000 6675800 301.5
+812600 6671200 370
+830000 6656900 419
+827300 6723300 382.5
+823400 6761800 270
+848900 6695100 345.5
+817600 6685900 464.5
+832700 6685100 443.5
+857000 6698300 262
+856200 6682200 222
+825500 6719300 400
+843100 6676100 405
+819000 6712300 371
+818300 6665000 398.5
+812200 6686800 436.5
+817200 6758200 257.5
+878400 6710900 240
+856300 6724000 375
+791400 6694500 462
+807100 6728900 318
+856900 6686600 225
+879300 6711700 239
+880200 6707800 224.5
+815200 6713500 360.5
+868100 6706200 249
+805500 6713200 348.5
+883300 6721200 272
+862300 6694800 220
+821100 6717100 367
+821800 6689100 484
+822300 6727100 385.5
+868200 6684700 199
+812700 6682800 454.5
+832200 6676100 479
+873200 6681000 196.5
+811800 6752800 243.5
+822300 6681200 411
+860000 6666400 202
+829700 6758900 296
+820600 6665800 420
+815000 6709200 379
+828300 6654300 439.5
+803600 6716900 317.5
+863400 6656500 184
+880400 6675800 183
+844600 6747000 384
+813400 6690300 425
+866500 6712400 274.5
+815100 6674700 401
+829300 6714600 454.5
+801800 6685500 433.5
+783200 6703300 354.5
+822100 6664600 440
+785400 6708300 290.5
+866300 6720400 303.5
+843200 6699000 420.5
+842300 6716100 424.5
+880800 6679800 196
+823100 6666200 428.5
+803200 6676600 384
+865000 6672500 195
+797100 6670300 475.5
+871700 6669400 180.5
+841800 6662600 222
+825000 6652700 441
+834200 6656200 318.5
+870100 6658700 187.5
+845700 6734200 443
+819900 6684200 460
+840800 6731600 433.5
+840500 6677100 477.5
+836500 6760900 275
+823500 6686600 461
+802000 6750100 245
+856000 6681200 215
+843800 6745900 401.5
+869800 6678500 206
+850500 6729900 404.5
+811600 6763300 272
+845400 6729900 440.5
+872800 6684000 202
+852200 6722500 407.5
+815300 6684100 407.5
+795700 6722700 297.5
+800900 6758100 245
+878500 6706900 227
+815100 6760000 266.5
+803600 6704600 323
+835700 6698200 517
+798000 6707000 342
+870200 6673600 193.5
+791700 6718600 277
+803800 6724000 286
+884100 6697800 215
+851500 6658400 193.5
+815000 6703100 393
+888500 6690500 197.5
+870600 6681500 193
+848600 6712000 436
+797100 6679300 483.5
+809100 6667800 377
+842200 6668000 338
+871500 6670100 182
+821200 6670900 418
+814500 6732400 354
+878300 6716500 251
+810200 6701400 421.5
+834800 6706000 499.5
+815500 6744500 292.5
+859900 6702500 280
+859200 6715500 335
+832500 6700400 488.5
+857400 6694500 246.5
+796300 6696300 401.5
+839300 6743800 361
+796700 6695200 431.5
+832300 6728200 403
+870100 6686500 213
+864900 6692100 211
+846500 6690000 430.5
+807800 6720200 308
+810700 6690300 440
+812800 6706200 379.5
+866300 6678200 196.5
+815500 6679400 404
+806300 6684500 445.5
+831900 6662400 466.5
+874700 6669500 185.5
+810900 6761800 269.5
+872800 6664000 186
+852600 6698500 327
+867500 6657200 189
+826900 6711200 438.5
+846100 6740900 396.5
+849200 6657100 190
+859300 6655000 188.5
+840000 6674800 480.5
+834100 6747500 338.5
+819100 6697600 435
+852100 6702600 413.5
+865000 6664800 180.5
+807900 6693900 454.5
+802400 6694900 453
+818400 6732700 361
+835900 6708900 478
+859500 6664600 201
+789300 6692800 518.5
+871600 6703500 232
+829000 6691100 495.5
+844100 6749100 373.5
+815600 6699200 420
+855800 6670300 208.5
+806000 6737600 300
+820700 6658300 417
+857500 6664200 202.5
+817500 6704800 440.5
+871000 6710000 253
+885300 6688200 193.5
+860800 6659700 190.5
+802500 6678900 428.5
+818500 6720300 393
+825300 6686800 463
+841800 6707800 453.5
+844200 6679700 444
+812100 6716200 322
+874400 6678200 194.5
+784400 6711800 246.5
+852700 6665100 207.5
+810100 6680800 454.5
+852000 6731900 401
+818700 6695000 441.5
+862900 6667000 201.5
+816900 6748100 278
+816900 6688100 461
+861300 6691200 220
+836500 6651800 208
+875000 6693900 207
+878600 6693200 201
+802200 6708700 303
+808100 6724000 306.5
+859100 6720200 358
+812800 6695700 422.5
+877300 6673400 188.5
+795700 6728500 272
+812900 6718500 319
+843300 6660600 203.5
+828500 6717700 428.5
+810600 6718600 312.5
+819700 6713700 361
+800300 6710900 330
+838500 6716400 432
+874100 6696300 197
+875400 6677700 192.5
+791500 6715300 296.5
+807700 6682300 464
+816200 6759000 272
+826000 6703700 425.5
+805000 6752300 239.5
+795200 6721200 316.5
+868000 6668400 187
+833600 6686300 432.5
+829500 6702100 464.5
+838200 6687700 416
+818400 6740100 315
+845400 6659400 201
+882200 6698100 199.5
+786500 6686900 588.5
+865200 6681300 199
+816300 6700900 408.5
+806600 6750800 237.5
+823200 6670500 417.5
+883300 6695500 209.5
+792900 6687400 495
+798900 6733700 290.5
+858600 6701900 260
+856000 6689500 233
+821700 6758800 282.5
+833700 6740700 352.5
+863300 6659900 184
+852200 6680300 224
+860800 6696700 227
+799700 6672500 472
+819000 6680200 391
+814100 6707200 402.5
+870500 6682600 195.5
+856800 6660800 201
+864200 6723100 371
+801300 6717900 339
+795600 6736100 262.5
+836400 6658100 313
+840300 6676000 468
+825100 6740200 335
+862700 6664500 179.5
+842400 6755200 321
+826600 6668700 443
+818300 6723000 388.5
+827300 6735500 374.5
+835600 6721100 438
+847500 6731100 435
+814600 6746600 272.5
+860900 6710800 292
+834200 6713200 433.5
+818900 6662900 404.5
+244700 6867100 45.5
+252400 6835100 171
+241500 6809800 168.5
+244600 6859400 55.5
+232300 6871300 82.5
+317900 6811200 89.5
+317500 6823600 99.5
+254800 6854800 61.5
+272100 6836700 105.5
+245900 6811100 188.5
+232500 6869700 67
+261500 6862400 66
+244900 6872000 42
+242600 6804100 204
+235500 6865800 60.5
+304900 6849900 41
+324200 6830300 89.5
+294500 6830400 73.5
+242000 6873300 38
+298000 6801800 136.5
+251100 6861900 50
+311600 6821200 79.5
+306700 6847600 33.5
+227400 6876300 48
+331100 6839900 45.5
+218000 6816000 145
+227200 6843200 171
+232500 6804700 212
+308800 6833100 47.5
+228500 6846300 171.5
+269100 6838000 97
+255000 6841000 206
+224800 6830900 203.5
+288000 6796800 129.5
+225500 6810600 220.5
+265800 6840000 163
+284500 6801000 161.5
+215900 6843500 239
+243000 6853700 113
+307200 6834300 57
+217300 6862600 53.5
+240200 6867800 31
+222200 6877100 35.5
+259400 6853400 67.5
+270300 6852100 41
+321600 6835700 93
+291900 6842900 67
+239700 6842300 202.5
+290400 6828600 85.5
+306200 6837100 65.5
+270900 6849400 43
+257600 6847500 94.5
+311600 6833700 63
+299400 6837700 75
+256300 6830400 240.5
+306400 6843000 50.5
+324300 6822400 72.5
+334500 6834900 31.5
+238300 6817100 212.5
+256100 6870100 43
+311300 6838600 41
+265500 6849400 60.5
+243300 6861600 63.5
+282400 6788000 93.5
+288600 6830600 69.5
+288900 6835600 77
+240600 6828100 265
+251800 6830300 218
+223900 6817500 178.5
+317500 6808900 91.5
+272700 6802000 159
+217600 6827400 161
+255500 6860700 51.5
+274900 6839200 67
+218600 6858000 80.5
+316800 6817900 91.5
+247800 6844800 134.5
+292400 6800100 162.5
+327100 6838000 63.5
+280000 6793200 99.5
+283400 6812100 216
+246600 6846800 94
+307300 6801900 111
+320600 6846500 23.5
+302000 6849800 49.5
+271200 6845800 71.5
+257600 6843100 165
+256800 6850500 75
+299500 6829500 85
+262200 6850000 99.5
+312400 6819200 74
+248200 6873400 48
+289100 6803200 207.5
+317800 6842400 27.5
+243500 6842000 159.5
+250100 6815300 228.5
+273800 6820700 208.5
+328900 6811900 99
+217500 6811700 196
+325400 6824900 62.5
+297700 6850700 58
+249200 6826300 242.5
+270300 6832800 142.5
+244100 6864200 48
+317100 6829500 71.5
+237200 6871600 61.5
+248800 6869300 38
+270900 6854900 37
+223400 6854200 137
+276200 6797200 122.5
+302500 6796300 95
+287800 6825900 104
+240100 6823300 220.5
+263000 6827800 187
+225700 6867400 53.5
+220400 6829200 188.5
+231200 6856800 94
+318700 6827700 85
+233600 6867800 51
+263600 6809700 198.5
+235900 6825200 251
+244300 6848700 125
+243100 6837100 209.5
+242500 6858000 73
+254100 6856500 58
+260300 6802800 129.5
+217100 6859000 54
+242500 6828700 259.5
+247100 6861900 42
+262700 6853600 80.5
+280800 6835600 76
+283100 6821400 140
+255700 6805700 179.5
+217800 6872200 52
+236800 6860300 65.5
+235200 6842500 230.5
+260100 6877400 17
+265800 6826100 191.5
+328100 6824100 47
+299300 6844200 77
+325400 6822100 68.5
+228200 6852600 112.5
+321700 6827000 99
+268100 6856500 43.5
+251400 6819100 207
+238100 6851300 202
+268000 6813300 200
+246100 6852300 89
+300500 6824900 84
+313800 6837600 46
+317500 6845600 21.5
+247800 6833900 181.5
+223800 6826200 176.5
+265000 6817400 197.5
+304600 6817000 91
+221500 6872300 53
+216000 6807600 214
+299100 6840600 77.5
+314200 6827600 94.5
+327800 6816100 32.5
+239200 6807700 198
+320700 6822400 80
+236200 6802800 219.5
+322600 6824800 82.5
+259700 6857200 65.5
+234400 6829000 262.5
+218800 6855300 129.5
+252800 6847800 103
+246200 6826100 239
+262800 6813800 212.5
+300300 6820800 123
+333300 6818500 39
+262300 6822300 234.5
+246500 6876400 35
+259700 6843500 114
+256900 6810400 210.5
+258900 6817400 244
+291000 6814400 234
+328500 6829100 47
+310100 6845900 38
+320700 6818700 83.5
+269900 6806100 171.5
+296300 6807000 214.5
+306400 6825400 66.5
+314300 6840100 30.5
+259500 6807300 175.5
+273600 6815400 193.5
+317100 6827600 93.5
+288500 6840400 63.5
+248000 6821700 222.5
+212200 6860100 63.5
+256200 6846400 138
+243400 6819300 215
+236000 6811700 183.5
+303500 6810500 135
+311400 6807800 103.5
+213100 6854000 90
+231300 6863800 69.5
+305700 6822600 60.5
+330800 6837000 49.5
+217300 6864300 60
+283300 6797200 129
+281600 6801900 139.5
+297300 6827600 98.5
+310300 6814900 94
+280200 6812800 172
+226800 6874000 50
+293600 6824900 109
+278000 6836900 54.5
+307600 6852600 40.5
+242900 6855100 82
+329400 6817400 45
+231000 6866700 71.5
+217300 6819800 129.5
+265400 6835000 157
+293500 6817100 192
+232600 6875300 46
+249800 6877700 29.5
+242800 6870800 33.5
+246900 6854000 74
+314300 6822500 94
+238700 6868400 45.5
+310700 6799300 98.5
+279600 6824500 157.5
+248800 6857800 53
+253900 6866500 50.5
+312800 6849500 38
+293700 6812200 223
+310300 6818300 58.5
+251400 6819500 234.5
+266800 6800300 121.5
+279600 6796300 104
+284100 6821200 208.5
+286200 6839300 52.5
+220400 6820600 139.5
+257000 6865400 64.5
+224400 6821500 187
+236500 6862500 75.5
+263500 6839300 163.5
+217900 6849600 176
+247700 6809200 200.5
+244800 6869500 25
+251700 6871300 41
+251900 6807800 214
+326600 6817800 42
+318500 6808600 87.5
+281700 6828400 99
+267500 6832200 143
+260400 6866500 53
+277200 6813200 182.5
+241400 6866100 48
+259400 6851800 77
+240300 6859700 64.5
+229600 6874000 54
+262800 6830700 192.5
+263800 6858100 54.5
+276400 6836600 95
+243800 6814400 158
+244000 6846300 127.5
+326800 6829200 49.5
+258600 6820600 246
+329200 6819700 23.5
+242800 6868500 27.5
+216100 6833000 204.5
+267700 6852800 66
+321100 6843400 39.5
+259900 6836900 200
+234300 6870700 59
+233300 6860100 82
+298600 6812100 172.5
+328500 6833100 41
+232200 6833000 248
+231500 6811600 207
+256200 6826700 247
+226000 6864300 58.5
+329400 6831300 48.5
+302400 6814500 134
+321000 6829600 94
+268100 6844400 99
+249500 6837500 146
+254600 6812000 252.5
+287100 6810900 231
+268400 6819400 232
+324000 6815500 43.5
+332100 6832500 39
+222000 6812400 203
+303500 6842400 54.5
+322400 6811800 91
+258200 6860600 64.5
+265700 6803900 137.5
+291200 6820900 207.5
+315500 6839900 43.5
+268500 6840800 96.5
+266400 6845600 71.5
+301500 6838900 76
+230800 6823500 254
+237400 6846900 211.5
+221200 6834800 231.5
+238200 6875200 46
+233600 6876000 46
+251700 6852700 76.5
+258300 6825400 250
+292500 6833000 84
+243300 6878000 36
+265700 6808100 162
+299900 6808700 148
+301900 6830100 64
+331400 6820700 42
+229600 6860100 58
+242600 6871900 33
+269700 6809200 203.5
+229200 6839500 231
+222000 6866100 51
+269800 6827800 173
+312100 6830400 86
+267000 6813700 177
+247500 6814400 179
+275400 6831600 119.5
+314800 6831200 69.5
+253300 6859700 56.5
+259100 6831000 221.5
+250900 6856200 69.5
+250000 6846200 113
+274800 6808200 187
+293400 6822200 119.5
+276100 6826300 181
+281700 6838700 43
+252300 6877400 26.5
+324000 6814000 62.5
+307400 6807800 112.5
+260600 6818900 231
+284400 6832800 57.5
+260600 6834400 192.5
+320600 6838700 46
+326500 6840700 51
+220200 6862000 66.5
+274300 6841600 71.5
+288500 6808600 223.5
+291200 6846700 58.5
+289500 6824000 111
+227600 6828800 211
+301200 6806200 131.5
+289000 6820500 222.5
+327500 6827600 69.5
+261600 6845000 109.5
+309800 6841700 44.5
+241100 6853500 105
+257800 6856600 62
+255100 6863000 57.5
+270700 6794900 105.5
+247500 6838600 147.5
+257200 6872500 36
+284700 6792800 120
+236000 6822000 230.5
+286500 6836000 57.5
+215900 6854300 103
+232100 6819800 227.5
+318200 6832700 69.5
+236100 6854900 110.5
+247900 6849500 93.5
+256500 6858300 53.5
+237000 6863700 52.5
+279200 6819100 190
+234300 6836400 234.5
+224900 6847900 140
+251400 6831100 193
+225800 6837200 244
+333700 6830500 47
+221400 6844300 211.5
+225100 6853500 109.5
+232800 6848300 200.5
+332500 6824500 52
+218400 6837700 249
+656200 6574700 431.5
+637800 6535500 554
+649200 6565000 402
+601900 6555000 469.5
+655900 6541900 666
+646600 6578200 436
+660400 6535400 720
+598700 6587800 283
+603000 6551500 520.5
+644600 6535600 601.5
+656400 6551900 591.5
+640500 6572600 433.5
+659400 6561500 468.5
+592700 6542400 394.5
+593100 6577500 357
+614300 6584000 312
+665900 6543100 631.5
+591000 6571500 396
+641000 6542300 605
+610300 6556300 576
+643500 6529700 635.5
+606400 6563900 486
+625100 6534500 601
+657900 6541500 667
+649400 6560200 436
+624800 6578700 433
+642000 6544100 589
+650100 6543100 583.5
+616900 6547900 550
+582800 6578900 335
+659500 6538400 676.5
+603500 6532300 577.5
+622500 6584100 336
+641100 6584900 404.5
+604100 6567900 510.5
+640100 6529600 625
+607600 6541000 504.5
+635000 6572600 426.5
+585200 6562000 373
+620000 6591800 404
+622100 6528200 704
+621800 6521000 791
+597700 6583100 288
+631200 6560400 443
+605700 6536700 548
+587600 6584600 340
+655700 6516100 781.5
+609800 6584100 307
+625700 6580300 350.5
+647900 6571600 412.5
+624300 6589800 363
+608400 6558300 484.5
+615500 6527400 684.5
+598800 6554400 471
+645900 6549500 483
+603700 6561100 436
+649300 6554500 502.5
+661400 6550600 549.5
+648100 6531000 669.5
+646400 6510100 829
+661400 6547600 555
+652300 6538400 647.5
+626200 6550400 489
+615700 6591800 411
+659000 6569100 371
+585400 6576500 364
+600100 6582200 293
+621600 6548100 564
+615300 6540400 602
+624800 6563900 446.5
+622300 6537300 562
+627400 6590200 382
+596000 6535800 502
+655700 6546700 629
+656600 6531700 747
+621000 6558900 450.5
+615700 6581500 381.5
+639500 6576400 515.5
+645600 6584900 414
+640500 6533500 614
+652800 6571200 403.5
+634800 6524700 679.5
+587200 6589000 302.5
+611000 6544800 498
+643200 6589200 450.5
+585300 6561600 393
+652500 6531100 693
+645400 6542700 589
+642700 6535300 598.5
+648900 6535700 633.5
+660400 6564000 426
+647500 6551000 516.5
+579100 6569500 361
+605300 6579600 304
+608600 6533800 632.5
+609700 6567400 478
+616700 6589200 362
+591100 6556300 409
+639600 6549000 556
+635300 6520700 735.5
+644600 6546800 549.5
+629600 6552800 433
+588000 6579700 330
+602900 6542600 475
+595900 6534000 520
+631800 6523800 747
+659600 6542500 585
+638600 6544100 524
+634100 6582900 370.5
+633700 6551500 491
+608500 6545100 511
+636300 6557200 520
+634600 6561000 499
+600400 6548500 494.5
+634500 6543500 492.5
+629400 6570500 419
+606100 6591400 353
+609800 6553300 568
+627000 6555100 398
+638700 6542800 559
+664200 6563000 414
+613300 6584900 310
+604100 6553700 500.5
+612500 6574600 347.5
+642500 6554500 482.5
+643900 6521800 752
+632100 6579100 412
+658800 6540600 661.5
+587100 6567900 392
+640800 6561000 401
+590000 6550000 535
+610400 6540500 583
+657800 6539300 698.5
+648100 6515100 844.5
+658400 6544200 617
+640800 6543500 603
+618300 6542900 536
+652000 6519900 781
+639100 6525500 712.5
+613400 6515500 624.5
+621400 6560800 394.5
+608400 6561900 555
+594400 6579200 320
+590100 6568900 405
+626700 6572500 440
+589500 6553400 484.5
+598200 6572000 444
+643700 6519500 788
+616000 6557000 565.5
+612700 6564000 517.5
+603700 6545300 452.5
+626000 6544500 573.5
+650900 6530000 734.5
+609500 6590600 325
+638000 6515300 803.5
+624100 6532000 646
+634000 6549700 496
+606800 6529300 575.5
+629900 6550400 429
+644000 6580300 430
+647800 6530700 658.5
+639100 6568600 406.5
+630800 6570300 398.5
+605800 6584700 279.5
+631900 6537100 604
+640500 6591400 457
+623000 6576400 465.5
+666200 6551200 547.5
+649000 6574500 425
+659300 6556100 533.5
+609800 6578100 340
+603300 6587600 276
+583300 6572000 370
+636700 6573900 510.5
+589800 6562800 409.5
+614100 6556800 580.5
+617900 6559500 468
+613800 6575600 386
+618000 6556100 531
+638600 6559500 465.5
+640600 6581500 422
+628600 6562700 480
+630400 6578300 442.5
+646000 6573600 419.5
+629400 6565000 478.5
+595100 6574800 423
+594100 6558500 473.5
+618900 6588700 347.5
+611500 6550700 567.5
+643600 6557800 439.5
+626500 6547000 494.5
+619900 6563500 390
+590600 6585400 321
+626200 6554500 447.5
+631500 6588000 396
+661400 6556700 482.5
+654300 6557900 470
+594100 6588900 282
+643700 6559900 422.5
+595300 6553900 447.5
+614600 6543200 516.5
+640500 6536900 571.5
+613800 6535700 660
+641300 6566100 421
+646000 6541700 561.5
+655600 6565700 415
+602300 6578500 382
+639600 6583500 365
+634600 6567300 435
+621100 6551100 566.5
+614900 6552100 601
+634500 6529800 635.5
+618100 6573600 414.5
+629100 6584800 351
+653500 6535100 709
+617000 6569800 407
+635500 6539900 512
+612100 6556500 550.5
+594200 6566600 403.5
+648500 6556600 452.5
+614800 6568800 346.5
+652600 6550500 574
+632400 6540300 535.5
+596900 6553200 456.5
+632100 6517100 847
+653100 6576200 486
+597800 6540100 503
+617200 6553500 598
+642800 6526600 695
+647000 6518700 792.5
+642700 6511500 804.5
+617600 6537300 594
+602300 6558700 450
+588900 6539800 377
+653200 6530400 750.5
+649500 6522900 737
+634200 6589300 428
+595400 6563100 420.5
+598200 6529100 474.5
+591300 6577200 344
+619800 6539800 559
+624300 6544500 583
+592300 6545400 472
+617200 6517300 675.5
+597300 6579300 400.5
+628700 6545400 526
+593400 6582600 314.5
+604700 6574000 469.5
+627400 6527900 711
+594900 6531300 502
+620300 6544200 553
+654200 6533400 719
+626700 6539600 610
+582900 6584900 333.5
+632000 6554000 469
+616200 6560400 486
+602600 6561900 425
+603600 6540100 491
+635900 6531900 572
+622800 6568000 436
+480500 6445900 84
+514600 6418600 75
+520200 6414200 107.5
+500100 6477300 160
+482000 6427400 78
+559900 6416200 151.5
+553300 6417400 170.5
+516600 6470300 181
+540800 6475700 182.5
+552500 6451800 222.5
+506100 6414700 80.5
+495800 6412200 104.5
+534600 6457200 160
+567100 6424500 172.5
+525200 6507000 292
+497300 6406000 122
+518500 6434600 162.5
+529300 6403700 168.5
+489200 6453200 108.5
+538000 6432400 152
+531500 6453600 171.5
+558700 6468300 221.5
+504300 6409700 127.5
+491100 6441800 93.5
+502300 6474600 150.5
+544500 6470500 202.5
+510800 6441300 171.5
+507300 6475000 142
+544800 6495700 334
+542700 6473400 212
+502400 6469200 142
+498300 6430200 102
+557000 6406400 182.5
+547700 6465300 205.5
+550100 6412300 179.5
+511400 6454500 136
+499100 6466000 115
+557900 6452400 207.5
+525500 6418500 107.5
+510100 6420300 74.5
+529100 6470100 172.5
+531400 6404300 171.5
+544100 6395400 226
+538200 6492000 266.5
+495400 6459600 147
+490100 6414700 87.5
+567800 6432000 217
+560500 6463600 233
+550100 6442500 183
+514400 6450500 157
+538300 6460300 180
+479600 6459800 87.5
+545300 6417000 152.5
+529300 6450300 183.5
+504800 6473700 136
+521500 6459800 161.5
+539800 6417000 145
+553500 6447000 193
+551400 6417700 162
+564800 6424400 179.5
+525000 6454900 152.5
+545600 6439200 185.5
+465500 6423900 58.5
+535400 6396700 221
+491300 6464400 104.5
+523000 6451600 193
+552900 6485300 310.5
+547700 6446300 206.5
+520800 6501700 247.5
+537300 6478700 204.5
+487100 6461000 106.5
+519900 6489700 209.5
+486700 6445900 86.5
+531900 6429400 182
+494700 6443500 85
+533300 6422900 122.5
+531500 6449500 189
+512300 6428700 125.5
+497200 6469700 137
+546000 6483800 252
+515500 6480200 178.5
+568900 6424500 210
+503700 6438000 131.5
+495400 6482700 144.5
+521600 6445200 197.5
+576400 6421600 189
+516000 6445000 172
+502700 6489800 154
+539800 6427300 134.5
+496900 6446200 107.5
+504500 6423700 97
+486900 6467400 85
+555300 6411600 170
+533100 6400200 183
+510100 6446000 147.5
+535400 6400200 215.5
+545700 6471400 209
+468800 6418600 9
+517200 6405000 125
+526700 6452200 180.5
+547200 6424100 178.5
+520700 6478500 156
+536600 6466000 169.5
+520600 6483700 172.5
+498600 6402400 109
+544600 6462800 192
+570000 6421900 166
+489800 6443200 93
+540900 6415600 119.5
+531600 6485000 225
+537800 6414700 150
+529700 6459400 153
+507800 6467300 146.5
+514200 6404600 145
+475100 6460000 82
+516000 6476600 151
+505200 6407600 152.5
+508600 6461400 161.5
+554300 6478700 270
+515200 6441300 164
+516700 6459000 135.5
+563700 6444500 175.5
+499300 6407400 124.5
+546900 6401100 241.5
+567000 6436100 240
+560600 6449400 162.5
+515100 6503000 223.5
+503800 6449300 124
+542300 6407400 174
+517200 6427800 145
+540700 6409800 168.5
+495100 6410000 104
+523300 6410300 113
+497200 6426900 92.5
+542900 6418400 137
+528300 6456900 160
+508600 6489700 159
+527200 6429900 178
+494100 6447400 100.5
+469500 6424600 63
+497700 6461800 143
+467800 6428900 58.5
+555700 6456700 280
+557400 6447900 169
+518700 6456800 150
+489100 6468900 107
+531200 6459100 152.5
+513900 6446000 152.5
+487100 6472600 101
+528400 6435300 206.5
+517400 6403100 110
+555000 6416700 146
+548900 6473200 238.5
+548900 6457900 227.5
+562900 6455700 228
+513700 6498000 214.5
+516700 6406900 152.5
+555200 6422400 196.5
+524400 6436200 196.5
+495500 6403700 109
+531000 6425300 130
+520400 6434500 168
+553600 6414600 167
+542600 6436300 176.5
+496500 6452600 114
+534800 6418400 145.5
+466500 6434700 61
+524100 6414700 113
+521600 6431400 158
+535900 6491000 241
+489100 6435200 104
+505200 6488400 170
+513600 6412800 119
+526600 6487800 241
+468700 6440500 60.5
+519500 6426700 138
+521300 6417900 109.5
+503500 6435800 136.5
+563900 6430900 222
+539200 6481500 225
+504700 6491400 164.5
+552800 6428900 184
+509400 6421700 95.5
+517400 6483700 184.5
+553300 6404700 222
+471600 6421900 61.5
+492200 6412400 82
+524000 6490700 232
+544700 6408900 180
+497200 6434700 129.5
+507500 6429100 134.5
+485000 6467300 81.5
+479600 6419900 87
+537900 6422300 151
+565300 6414600 171.5
+524000 6477100 163.5
+490900 6428100 86.5
+570700 6419300 157
+566400 6416200 138.5
+468100 6422000 58
+562100 6442000 199
+503200 6457200 164.5
+499700 6459500 165.5
+553200 6470900 237
+527300 6410800 128
+465000 6421300 45.5
+564500 6405000 177.5
+549100 6469000 228.5
+499200 6474200 172.5
+547800 6461500 204.5
+495800 6473700 156
+497600 6408600 121.5
+516600 6417400 65
+542600 6398700 238.5
+564700 6422900 163.5
+500500 6402500 112
+502100 6410500 130.5
+533100 6431800 169.5
+532900 6482800 207.5
+532000 6397900 175.5
+549100 6417900 162
+493800 6435700 115.5
+491400 6403700 106
+526000 6420800 121
+510000 6413400 105.5
+550900 6461200 227.5
+556400 6415800 139
+505500 6480000 163
+529300 6400800 172.5
+542400 6410500 185
+504500 6484400 167.5
+483000 6469200 80.5
+488000 6479700 120.5
+571000 6425000 207
+492900 6470800 124.5
+527200 6419900 99.5
+470400 6459000 87.5
+552300 6458700 268
+547500 6475800 244.5
+515900 6416500 106.5
+514100 6424800 120
+520800 6456500 132
+521900 6401900 143
+541400 6453300 204.5
+492600 6458800 134
+499200 6431600 121
+562200 6406500 171.5
+536400 6426700 146.5
+494600 6480700 138
+526400 6494900 249.5
+477800 6427300 72
+472200 6439500 54
+473500 6425600 70
+548600 6434200 161.5
+572600 6448200 197
+568600 6417700 147.5
+562100 6427700 216
+478000 6431300 72
+559200 6422800 210.5
+492700 6462400 135.5
+541500 6403300 214.5
+535900 6445400 205
+511200 6476300 151
+518700 6416900 84
+547800 6409200 209.5
+526200 6463800 182
+495400 6490500 134
+481300 6431900 83.5
+470500 6431700 71.5
+499200 6438400 129.5
+532500 6408100 176
+511300 6479400 151
+500200 6491700 141.5
+507100 6493300 163.5
+510900 6404000 127
+524600 6438100 188.5
+554400 6482600 301.5
+556200 6471300 256.5
+539400 6477300 191.5
+545500 6420900 147.5
+529200 6475900 184.5
+492600 6443000 99
+565300 6407500 159
+548400 6450500 210.5
+524500 6482600 182.5
+573800 6439000 272
+555000 6460300 259
+547000 6411500 174.5
+516100 6401700 92.5
+494900 6406300 126
+502400 6404200 132.5
+572900 6429700 234
+499400 6463600 135
+518400 6463300 162.5
+532800 6476100 199
+501100 6420100 79
+467700 6439000 42.5
+548800 6490200 314
+562200 6434300 228.5
+525900 6457600 160.5
+493800 6475400 133
+547400 6394300 228
+506300 6438900 161
+555300 6401200 240
+497800 6464400 102.5
+515700 6420900 101.5
+525700 6446800 200.5
+506600 6412000 90.5
+514900 6468100 178
+512700 6415200 115
+527000 6426200 144
+501300 6477100 162.5
+549900 6398400 257.5
+554100 6431300 196
+559100 6429500 224
+513400 6473200 164.5
+517200 6434400 153
+475300 6423600 74.5
+511000 6501400 179.5
+506100 6418800 59
+531600 6420000 119.5
+494900 6420600 65
+554900 6451300 187.5
+542400 6480800 224.5
+529800 6496100 279.5
+484500 6465200 87
+475200 6420200 60
+510800 6488900 193
+495600 6455000 150
+513000 6418000 75
+511900 6410300 106
+498800 6488000 143.5
+531000 6482500 193.5
+542100 6502000 370.5
+566000 6476900 344.5
+488600 6411800 98
+549900 6479200 272.5
+509400 6453000 141
+509800 6482500 171.5
+529200 6439800 217
+515800 6486000 188
+483800 6441400 72
+514600 6437800 164.5
+571500 6446200 234.5
+547200 6472700 196.5
+482300 6451200 94
+545700 6458200 191.5
+484600 6456000 91.5
+493300 6419300 35.5
+485100 6436800 88.5
+543200 6392400 208.5
+567600 6439900 204.5
+542100 6495700 345.5
+490200 6483800 123
+509900 6419000 75
+540800 6440800 210
+480300 6465800 82
+534900 6462800 160
+500800 6407000 148.5
+547700 6416800 153
+516500 6511300 219
+496700 6408400 124.5
+472700 6461800 69.5
+553700 6437200 169
+483500 6458700 81
+476600 6453500 92.5
+560700 6475400 294
+548200 6390000 211
+558800 6413100 181.5
+506600 6425900 111.5
+541600 6449500 227.5
+520000 6408800 130.5
+542800 6458400 179.5
+544500 6405800 207.5
+552300 6467400 213
+488600 6414800 90.5
+493200 6466100 108.5
+492600 6440800 74
+534100 6449400 190.5
+523400 6510600 272.5
+525500 6407200 140.5
+569800 6435000 260
+555300 6442500 173
+525200 6500900 275.5
+507500 6442700 157
+536500 6496600 320.5
+550400 6407300 219
+538800 6466600 170
+544100 6452700 216
+512200 6408300 141
+483500 6462300 92
+536000 6434800 169
+539600 6425200 148.5
+570900 6443800 230
+522500 6427600 164.5
+535800 6437800 198.5
+531200 6394700 184
+495400 6438700 103.5
+517800 6411600 117.5
+504400 6496100 172.5
+504100 6439800 147.5
+498200 6412600 112.5
+546100 6420400 160.5
+539500 6456200 191.5
+542800 6411800 142
+507100 6483200 184
+523200 6417800 105.5
+531900 6442500 199.5
+508500 6407200 117.5
+476200 6438500 76
+507900 6410200 92.5
+485300 6415400 83.5
+558800 6469600 265
+563800 6417100 164.5
+507000 6403600 107
+551400 6472700 263
+517300 6446400 181
+554800 6454000 229
+500900 6447800 119
+520000 6505200 263
+541600 6431000 135
+512700 6461900 164
+487600 6429200 87
+558000 6412800 156
+535400 6408900 182
+517800 6501800 238.5
+547000 6403800 222
+537500 6481900 225
+511300 6492400 178.5
+517500 6494900 230
+513900 6430800 119.5
+501500 6429400 116.5
+541700 6469500 196
+551700 6437700 149.5
+516600 6493500 200.5
+511000 6472100 137
+500900 6486700 156
+467300 6460600 65.5
+512300 6466500 159.5
+504800 6431100 137.5
+569600 6438200 255.5
+491700 6480600 126
+545800 6431900 146.5
+520000 6479700 163.5
+528700 6422000 113.5
+522400 6488400 179
+528000 6414800 135
+556800 6436500 198.5
+543900 6499000 398
+481500 6462300 83.5
+515400 6501500 208
+535700 6455700 175
+558400 6455700 245.5
+502200 6466600 137.5
+499400 6455900 149
+523700 6468400 167
+574400 6447400 205.5
+526200 6471900 174.5
+510100 6424700 105
+503700 6464800 150
+492700 6422300 64
+505800 6452600 140
+532400 6401100 183.5
+543600 6428200 150
+544000 6478600 243
+538400 6451300 208.5
+558600 6460600 256.5
+524000 6471800 182
+541800 6460600 184
+520300 6439000 179
+561100 6451400 201.5
+498200 6400500 88
+503400 6444600 134
+501400 6442300 156.5
+536100 6447900 204
+514200 6434800 177
+495100 6427600 82.5
+532800 6473900 193.5
+543700 6488400 253.5
+510300 6505700 200
+512400 6482700 183
+507500 6502800 178
+559500 6474100 298.5
+473500 6445000 71.5
+571900 6444600 245
+544000 6417300 152.5
+483500 6435500 85.5
+536300 6404800 203
+550800 6435500 168.5
+557200 6467100 209.5
+568300 6418700 152.5
+510600 6406300 130
+489200 6418800 22.5
+483000 6423300 81.5
+522500 6405400 172.5
+465000 6454700 69
+493800 6399900 87
+489500 6473300 123
+516400 6456700 129
+517500 6419800 84
+510800 6455600 117
+559000 6404600 208
+499600 6452000 119.5
+477900 6422400 92.5
+560900 6448000 164
+510400 6434900 171.5
+549400 6436400 161
+488200 6420200 58.5
+574300 6422200 201.5
+520200 6424400 153
+515400 6489600 208
+491300 6431500 107.5
+547100 6405400 227
+547600 6414800 181
+522300 6496200 244
+498800 6416200 35.5
+554800 6464000 208
+541600 6412000 129
+563300 6462400 254
+503700 6412300 113
+533300 6462200 151.5
+527200 6477100 178
+508100 6456900 148.5
+536300 6421400 132.5
+495000 6442200 114.5
+507700 6420400 71.5
+557700 6444100 161.5
+491700 6476600 136
+523200 6442200 195
+525500 6404100 173
+471500 6425700 62
+512000 6431400 142.5
+531100 6408000 159.5
+530700 6401900 183.5
+513500 6508600 208.5
+489600 6409200 133
+489100 6483200 116.5
+560500 6401500 202
+488900 6475300 120.5
+501500 6480300 172.5
+542800 6462300 186
+501700 6413700 117
+528800 6395000 160
+545800 6413700 168
+509800 6499600 163
+528300 6406900 144.5
+560600 6479600 305
+508200 6470600 117.5
+533400 6469800 168
+566500 6449300 190.5
+506500 6445600 137.5
+521500 6455600 162.5
+490000 6447300 103.5
+479800 6439100 68
+506600 6434300 145.5
+471900 6432300 68.5
+468000 6432000 66
+933000 6686100 427
+988500 6717800 349.5
+960500 6694200 539.5
+930700 6667600 413
+976000 6688200 776.5
+923800 6664700 377.5
+981700 6675600 983.5
+913600 6666200 348.5
+947900 6698100 365
+940900 6652900 801.5
+950200 6635700 950
+947200 6630900 1104
+998800 6697700 697.5
+943000 6630800 1085.5
+976200 6687000 626
+917800 6674300 267.5
+949400 6697500 320.5
+945100 6664000 735
+918800 6684400 271.5
+956600 6666900 958
+1005400 6701800 665
+975200 6670800 952
+948200 6632200 961.5
+946100 6695200 422
+975900 6683200 708.5
+968300 6697800 555
+955700 6691500 593
+980100 6703800 574.5
+954700 6641600 980
+955400 6703000 457
+919800 6678900 316.5
+960700 6705600 380
+980700 6717800 389
+953900 6708800 386
+996700 6691600 902
+963100 6700400 483.5
+968000 6682000 736.5
+990800 6723100 375.5
+918700 6664300 424
+968200 6705900 414
+977100 6680600 920
+946300 6707900 265.5
+971900 6711100 360.5
+963300 6692000 694.5
+976300 6724100 436.5
+950100 6672800 686
+973600 6668200 932
+933300 6660400 715
+934000 6676200 534
+944900 6684100 581.5
+959700 6679400 759.5
+967700 6685400 703.5
+990500 6718900 362.5
+987200 6677700 851
+928400 6650100 670
+979100 6720100 395.5
+912100 6682000 263
+957200 6711000 432
+973800 6666400 1018.5
+939500 6703400 331.5
+953100 6634500 957
+936800 6697400 411
+951600 6652400 875.5
+935600 6701600 250.5
+956800 6679700 727.5
+926300 6696900 230.5
+916700 6660800 370
+942900 6690100 478.5
+961800 6659700 921.5
+932100 6683500 428
+981300 6709500 475
+963000 6660500 943.5
+922500 6668600 479
+927900 6657300 563.5
+977900 6697100 620
+934100 6657500 764.5
+949500 6709700 338.5
+987600 6706000 469
+986100 6721800 362.5
+943700 6698900 336
+969500 6714300 379.5
+934600 6698700 367.5
+950400 6708500 348
+928400 6693800 450.5
+958800 6696400 465.5
+945300 6648700 843
+993900 6706100 550.5
+989300 6722300 358.5
+976800 6706000 495.5
+990600 6721500 351
+954600 6636100 1010.5
+979700 6721300 381
+931200 6656300 716.5
+924800 6669000 378.5
+977300 6703600 606
+985600 6699700 503
+940700 6644300 846
+919000 6691200 237
+949600 6707900 352
+919700 6688000 260
+956700 6637600 1129.5
+933500 6689800 396
+977900 6723300 410.5
+977800 6673200 985
+944100 6693600 421.5
+959200 6673100 837.5
+907500 6685100 287
+920100 6666000 400
+962100 6655500 1057
+947100 6634800 1007.5
+953400 6677500 643.5
+979700 6676400 907
+923400 6680500 299
+980600 6723300 409
+954000 6687100 529.5
+958800 6712900 394.5
+917300 6689700 242
+968500 6704600 598
+981800 6686300 781.5
+957400 6684900 609
+917600 6680700 262.5
+939300 6661700 779.5
+946100 6670200 668.5
+942800 6639100 961.5
+955400 6675500 750.5
+975900 6716700 401
+959000 6698700 471
+989600 6704300 662.5
+939300 6682200 545.5
+973300 6700500 680.5
+920000 6665400 438
+932400 6697500 404
+995100 6698400 794
+990600 6693800 875
+956300 6696500 423.5
+913700 6685000 256
+947600 6655500 811
+943600 6676800 491.5
+968500 6715600 382
+954900 6672100 834
+962600 6683600 734.5
+918700 6667300 405
+926600 6659500 483.5
+962100 6657800 994
+924700 6691600 326.5
+970600 6694300 630.5
+933400 6694400 389.5
+958500 6634800 1136
+940600 6687600 478
+975400 6719900 418.5
+922300 6664300 489
+987600 6721100 374.5
+919500 6661000 548
+984200 6715200 360.5
+994100 6692500 849.5
+983500 6701100 535.5
+922000 6688200 285.5
+951800 6690600 484.5
+947800 6690100 435.5
+921500 6686500 276
+939100 6665100 561.5
+913100 6686700 248.5
+944700 6688000 455.5
+937600 6680600 524
+965700 6682800 628.5
+945000 6672600 503
+982200 6697600 640
+946400 6706100 330
+932500 6688900 320
+993100 6722200 368.5
+984500 6698600 508.5
+952600 6714300 325
+976300 6697000 630
+939200 6697100 358.5
+975200 6704900 610
+944200 6695700 404.5
+991300 6698800 613.5
+988600 6713900 378.5
+927200 6681800 403.5
+938100 6694200 378.5
+938600 6678700 585
+960700 6688300 631
+924300 6695700 244
+959600 6683400 646
+935400 6690900 290.5
+913900 6689700 234.5
+976600 6677300 970.5
+913000 6688400 246
+940700 6627900 1106
+970500 6679000 762
+1001400 6701300 653.5
+983900 6701000 490
+916400 6666300 344.5
+952600 6654100 872.5
+923200 6678300 329
+982500 6680300 946.5
+937700 6692100 313.5
+962300 6686300 735
+978900 6686300 700
+983000 6691500 551.5
+973800 6715800 405
+952600 6711600 351.5
+964500 6666600 951.5
+970200 6711400 392.5
+913100 6670200 347.5
+924200 6675300 378.5
+979800 6690500 551
+995200 6710800 519.5
+982100 6689500 771
+987400 6707500 475.5
+992500 6711700 464
+933600 6673500 502
+948900 6662700 719
+944400 6644200 961.5
+971000 6712400 361
+952000 6708700 349
+971000 6664600 1025
+958300 6689700 626
+930600 6658100 686.5
+936800 6645700 836
+984900 6708300 450.5
+957300 6636200 1130
+916700 6694100 225
+983900 6718500 357.5
+974700 6680700 810
+949600 6698900 379.5
+959700 6716800 358.5
+912800 6679500 256
+991000 6709800 467.5
+938100 6623900 1086
+930000 6665300 482.5
+927200 6693600 347
+945300 6692700 423.5
+915800 6678100 285
+982300 6718300 377.5
+968700 6678500 879
+927300 6683000 357
+961600 6708500 391
+973100 6679300 687.5
+971800 6709200 386
+943300 6703500 374
+905400 6687300 259
+962500 6649800 1047
+983600 6700400 518
+946500 6665600 562.5
+983900 6717000 394.5
+956900 6655200 936.5
+943000 6707000 257
+955300 6650500 1065.5
+980100 6713700 388.5
+990600 6713800 406.5
+961900 6703100 414
+952000 6651400 854
+977700 6722300 397
+934500 6647600 840.5
+986600 6712500 452.5
+960200 6709300 406
+955600 6637900 1036
+930600 6653300 687
+963000 6676900 870.5
+951300 6686000 530
+989700 6681200 802.5
+956900 6714000 368
+942500 6646200 845.5
+944900 6645800 961
+918400 6672800 369
+981000 6714900 379.5
+938500 6698000 351.5
+990300 6708100 495
+957400 6704000 465
+968500 6708900 402
+938400 6615600 1190
+959600 6697200 395
+948800 6651200 857
+960300 6676400 748.5
+993000 6709100 475.5
+948100 6708900 324
+966900 6712000 392
+950400 6689000 499.5
+963500 6710800 397
+933200 6701400 240.5
+952900 6705100 424
+979600 6700300 612.5
+953600 6700000 399.5
+948400 6656500 811
+941900 6696900 355
+943000 6663100 781.5
+951000 6698500 423.5
+924300 6682200 360.5
+947600 6677500 579
+948800 6647200 916.5
+944400 6697100 349.5
+940200 6675200 452
+932200 6669700 429
+918100 6685700 263.5
+923200 6669600 400
+986800 6717000 332
+916500 6668000 372.5
+981400 6703800 600.5
+938300 6672000 479
+977900 6712300 386
+932500 6676900 451
+953600 6706800 428.5
+921800 6697300 231
+972100 6697000 588.5
+987900 6697800 560
+985800 6719000 382.5
+942100 6669400 477.5
+957300 6646800 1018
+962600 6662100 873.5
+943000 6667600 531
+924600 6693200 286.5
+958900 6692400 570
+955300 6714300 342
+993800 6714700 490.5
+938400 6663800 580
+918200 6669400 389.5
+982200 6693200 547.5
+949400 6695500 474
+925600 6690000 333
+920400 6687900 266.5
+942000 6626400 1120.5
+996500 6718500 398.5
+995800 6694000 730
+937100 6664400 535.5
+987600 6690400 855
+939600 6627300 1115
+989000 6716200 365.5
+914400 6692500 221.5
+976600 6721200 436.5
+956400 6716100 310
+939600 6684800 434
+985000 6710900 440.5
+927600 6695900 346.5
+981900 6682700 830
+983300 6684400 910
+968500 6690000 755.5
+945600 6630000 1117
+929000 6655100 616
+974600 6711000 391.5
+915200 6688300 248
+952600 6703200 442.5
+929600 6671100 405
+947000 6703000 377
+970200 6719700 421
+954000 6693900 435.5
+944900 6690800 426
+996300 6689400 753.5
+971800 6700600 701
+950700 6641500 931.5
+972000 6716000 378.5
+957400 6699200 418.5
+993300 6707800 475.5
+946300 6700800 393.5
+944700 6697800 344
+998500 6692000 719
+973500 6705700 490.5
+922900 6692900 272.5
+978800 6708900 432
+956300 6688500 565
+963800 6705000 412
+949600 6686500 545.5
+989600 6717800 356.5
+966000 6701000 563
+962400 6670400 910.5
+910200 6685100 266
+951300 6670400 779
+974000 6714200 389.5
+971100 6697500 576.5
+951700 6640100 914
+978100 6718400 388
+965600 6707900 334
+976100 6700100 629.5
+948900 6714200 269
+974800 6698300 561
+947700 6639600 966
+930800 6675900 466
+978000 6720500 364.5
+959300 6701800 383
+952500 6717200 271.5
+955700 6635800 1171
+945800 6674200 567.5
+937100 6655100 790
+955300 6679200 651.5
+978800 6679400 995.5
+939700 6706100 247
+951400 6632500 1125.5
+947800 6707400 338
+985000 6686700 890
+916400 6675300 299
+981700 6714700 376.5
+921300 6685500 280
+988800 6720800 342.5
+960200 6686400 660
+938200 6691700 402
+954700 6685500 584
+928200 6670600 402.5
+972900 6692700 696.5
+979300 6674100 990
+954000 6696900 347.5
+915700 6684700 261
+958800 6702400 410.5
+933200 6671200 431.5
+996100 6701600 647.5
+909800 6689000 257
+965800 6716400 446
+951900 6638400 968.5
+989100 6686300 789
+994500 6701700 584
+951000 6669400 711
+907200 6683200 265.5
+992400 6694000 810
+974100 6682000 640
+967100 6676400 872.5
+948000 6683000 595
+954800 6652800 923.5
+984900 6717900 327.5
+946300 6671400 656.5
+915300 6682400 263.5
+906600 6686100 281.5
+935200 6703100 249
+949300 6675400 620.5
+969900 6720800 409
+975500 6675100 955
+944700 6705400 356.5
+941900 6658400 755
+929000 6682000 425.5
+978500 6668800 955
+978200 6677100 975
+982700 6695600 623.5
+945400 6698400 354
+971600 6717500 408
+980700 6689800 574
+927000 6654800 615.5
+914200 6673300 265
+962300 6689900 704.5
+988000 6692800 740
+953400 6674600 691
+963200 6716800 425.5
+981900 6719900 380
+929300 6673000 456
+962700 6702100 415
+989600 6691100 884.5
+980400 6720800 381
+925000 6680400 383
+918900 6678300 285
+935900 6685100 432.5
+970000 6674000 874
+952700 6664900 844.5
+954700 6660400 907.5
+975000 6712200 363.5
+976500 6691000 722
+981700 6700500 594.5
+978700 6690700 560
+946600 6648000 840.5
+972100 6695700 577.5
+950200 6660600 770
+931200 6697000 408
+955600 6706500 437.5
+964400 6706300 330
+920200 6666600 422
+951200 6696700 429.5
+914400 6663400 343
+942200 6629200 1103.5
+961400 6687400 720
+975300 6694000 700.5
+993500 6689900 901.5
+988300 6719700 357.5
+931900 6685100 367.5
+964800 6678400 760.5
+957300 6681500 688.5
+943500 6700100 422
+985400 6696100 567.5
+910400 6681200 264
+994200 6696500 779.5
+917000 6686200 257
+994500 6691600 887.5
+916900 6682400 271
+966000 6696000 561
+923400 6662400 454.5
+994300 6719100 377.5
+918500 6665400 315
+935400 6700500 332.5
+952400 6707900 383.5
+935800 6677500 487
+970600 6676100 855.5
+936000 6687400 473
+964200 6695900 562.5
+932400 6691400 333
+953100 6671600 813.5
+987400 6686600 864.5
+920800 6690200 264
+977600 6714400 368.5
+912600 6684600 243.5
+924200 6670200 348
+989200 6701200 617.5
+976700 6681400 850.5
+980800 6715700 393.5
+957600 6715900 359.5
+989900 6712000 469
+917100 6666000 276
+921000 6671700 398.5
+924300 6666400 386.5
+972300 6709500 314
+958500 6708400 439
+946600 6698400 365
+948700 6665000 618.5
+945100 6668800 648.5
+911500 6691200 219.5
+990200 6705400 503
+919400 6671500 380.5
+920200 6679900 297
+940500 6705900 254.5
+910900 6662800 259
+930100 6660800 492.5
+940500 6700400 338
+977600 6689300 656
+993900 6721000 362.5
+916500 6672300 372.5
+973800 6707200 449.5
+918600 6671000 390.5
+987200 6701300 625
+917000 6688500 252
+952000 6647400 916.5
+978800 6695400 743
+936200 6669400 501.5
+924000 6673900 378.5
+990000 6696300 700
+933200 6664300 514.5
+954200 6710200 376
+944000 6667700 530
+936600 6696100 404.5
+928500 6686800 422.5
+950600 6702600 407.5
+975100 6686100 683.5
+992200 6704200 680
+931500 6649500 779.5
+950100 6643000 999
+932500 6665700 466.5
+952400 6663400 850
+954000 6644600 943.5
+946800 6692900 469.5
+976900 6693100 756.5
+930300 6697100 408
+949600 6666100 806.5
+921800 6677200 360
+954600 6713100 348.5
+937600 6677700 460
+936500 6692000 289.5
+919500 6681500 259.5
+946000 6704800 359
+951000 6716200 271.5
+968600 6710800 342
+959500 6642700 1070.5
+914000 6677500 285.5
+940900 6703500 281
+984300 6705000 580.5
+941800 6693100 414
+961600 6695400 544
+952300 6641700 922.5
+944600 6706900 265.5
+949100 6657500 785.5
+985600 6691400 700
+961400 6682700 714
+960600 6663800 988.5
+1002600 6699700 731
+936300 6662200 750
+907700 6688400 265
+947900 6630500 1098.5
+960000 6657500 926.5
+919800 6677100 336
+953100 6633500 1176.5
+919300 6695500 227.5
+924000 6688800 315
+955800 6673500 790.5
+957000 6686700 593
+967500 6697800 534.5
+926300 6666900 374
+950800 6706800 381
+918400 6693800 229.5
+943600 6679600 595
+926400 6680300 410
+964200 6661700 978.5
+993200 6715800 410.5
+927200 6666100 399
+917200 6663300 373.5
+942500 6674100 488
+969300 6661000 1036
+953600 6693000 477.5
+964600 6703900 461
+968900 6668100 891.5
+939600 6624500 1182
+943900 6628300 1170
+945100 6660500 811.5
+873000 6355200 524
+868300 6457400 444.5
+880700 6388300 987
+840400 6370100 117.5
+864900 6465600 424
+847300 6377000 336
+875800 6395000 1074.5
+860700 6372900 496.5
+869600 6385900 629
+892000 6391900 994.5
+899300 6346100 1074
+878300 6391400 1056.5
+889200 6379100 970.5
+850100 6388900 188.5
+876100 6382100 1058.5
+866400 6426000 719.5
+895200 6365300 969
+848200 6364100 204.5
+897200 6362400 968.5
+887500 6364200 893
+867800 6443200 170
+875500 6355600 539.5
+889900 6374400 963
+905800 6402100 1381
+848700 6361700 133
+842800 6458400 246
+881500 6355500 699.5
+849600 6458900 302
+877200 6364600 644
+883800 6395900 880
+899700 6356000 1098.5
+867100 6428800 717
+911000 6345300 1132.5
+864700 6436400 238.5
+855200 6444900 234.5
+851000 6444600 223.5
+849200 6447500 255
+853100 6450300 310
+853800 6395600 328
+870600 6364700 587
+861500 6440600 206.5
+878500 6441600 304.5
+853700 6404600 250.5
+882100 6402200 768
+844300 6452800 236
+884300 6441400 615.5
+867300 6460000 470.5
+852700 6419000 175.5
+872300 6423200 1017
+845500 6436400 125
+842600 6454900 247.5
+853800 6384700 319.5
+883200 6369600 864
+868100 6379800 868.5
+854000 6374400 361
+844400 6370900 185
+841400 6396200 233
+851600 6447000 207
+842500 6402100 118.5
+863200 6372200 835.5
+849200 6427700 148.5
+860100 6405300 314.5
+882100 6351500 757
+869500 6400800 675.5
+860400 6357500 275
+873600 6412400 846
+898300 6340500 1109.5
+852400 6436800 174
+881100 6418000 1095
+888400 6376100 846.5
+850900 6412400 146.5
+890600 6367800 847.5
+891800 6429200 1230.5
+896800 6402600 1276
+844900 6381300 265.5
+887600 6408900 1104
+893800 6381500 1016
+845800 6409900 171.5
+852100 6405400 309
+908100 6361000 1103.5
+877300 6371200 592.5
+863500 6396200 927.5
+848000 6465300 268.5
+882100 6363300 700.5
+867400 6359100 498.5
+843400 6371800 236.5
+874700 6357800 614
+843600 6385600 133
+857500 6397600 386.5
+909700 6383000 1256
+904900 6384300 1113
+839000 6385900 134.5
+901400 6361200 1039
+886200 6387300 1160
+864100 6382600 646
+851000 6469600 219.5
+857600 6373600 481.5
+874400 6376200 916
+895100 6374900 1140
+871400 6444400 177
+849600 6457100 273.5
+894900 6377600 955.5
+903200 6389100 1040.5
+865500 6393800 469
+886600 6381700 1056.5
+860100 6467900 342.5
+845000 6443000 197.5
+865100 6428800 308.5
+843300 6390100 197
+880600 6410300 673.5
+862900 6389300 657.5
+887900 6398500 906.5
+872700 6366600 743.5
+849400 6357300 110
+860000 6451800 280
+870900 6400300 738.5
+842700 6360800 188
+908200 6352300 1103
+863900 6431700 308
+859600 6383300 614
+888500 6413900 1062.5
+859700 6421200 401.5
+864300 6361600 352
+865700 6457800 418.5
+842400 6467700 160.5
+870700 6375900 911.5
+892600 6404600 1235.5
+854100 6356000 165.5
+896800 6352300 1110
+892800 6357300 958
+864200 6408900 490.5
+901500 6350100 1073.5
+896200 6357300 928
+894600 6393700 873
+895100 6399200 994
+872600 6386200 758.5
+885400 6360600 700
+903900 6391400 1233
+886000 6394400 960
+851900 6383000 313.5
+846500 6391800 313
+868600 6393500 823
+867200 6367800 731.5
+854100 6379700 444.5
+864100 6421600 742
+870900 6382600 962.5
+880900 6381600 1116
+846600 6445900 247.5
+854900 6390100 237
+882100 6374100 922.5
+844300 6390900 261
+856200 6387200 435.5
+854300 6432100 169
+892400 6438900 1087.5
+869400 6389800 893.5
+884500 6355800 881.5
+869500 6437500 716.5
+893500 6344100 912.5
+856100 6416800 228.5
+883400 6390300 1059.5
+860700 6395200 566.5
+850600 6419400 160
+905300 6351300 1072
+900200 6395400 1064
+881400 6406200 756
+874500 6366900 604
+861400 6413800 620
+843700 6394800 363
+890500 6411800 1239
+846700 6373400 244.5
+882900 6398700 849.5
+884500 6372500 777.5
+842900 6450500 245.5
+892800 6442000 1008.5
+845000 6462400 249.5
+881800 6392500 809
+878700 6412600 674
+878000 6367600 527.5
+845400 6403500 299
+890000 6405900 730
+914400 6399900 1712.5
+871200 6414900 721
+847900 6381400 305.5
+844000 6365200 217.5
+837100 6388400 67
+856500 6413700 286.5
+849900 6368100 199.5
+867600 6445500 267.5
+896900 6382500 1179
+851600 6455300 317.5
+849600 6417100 167
+868800 6448000 308.5
+862600 6458900 411
+883200 6412500 697
+875300 6420700 984.5
+874600 6389400 1005
+847000 6453900 246.5
+849300 6390200 171
+840900 6390700 244.5
+892800 6385100 1101.5
+855900 6449000 293.5
+861400 6388900 611
+841800 6397400 226.5
+871800 6390900 985.5
+888500 6400300 866.5
+851400 6367800 168
+878200 6403900 694.5
+851500 6458500 296
+846800 6384200 203
+844000 6447100 229.5
+875400 6398400 945.5
+858300 6460600 382.5
+883200 6439200 785.5
+858900 6463800 387.5
+902100 6407500 1276
+847100 6435700 128
+896300 6355800 967
+849500 6429400 149.5
+869500 6411100 558
+851700 6409000 172
+846200 6368800 225
+861900 6420900 425
+869700 6407700 537.5
+892800 6364300 964
+850600 6442100 207.5
+880100 6398600 752
+861000 6445800 304.5
+879000 6362300 814.5
+856200 6467600 318.5
+855700 6400000 365
+866400 6446400 257
+891000 6353500 1065.5
+865400 6424500 686
+860200 6428500 228.5
+844200 6407500 223
+841000 6362700 169.5
+899400 6385300 1097.5
+880500 6371000 665.5
+848200 6421100 144.5
+893400 6367600 917
+857500 6390900 287
+839700 6367500 143
+864600 6449100 358.5
+847000 6356000 103
+884300 6379400 1064
+873000 6425900 942.5
+852800 6448300 238.5
+866900 6391400 547.5
+859800 6432700 193.5
+851900 6370800 300.5
+851300 6437500 134
+887100 6358600 883.5
+865000 6455900 412
+873100 6440200 664.5
+853400 6412900 195
+853400 6420000 178
+861300 6377400 757
+890200 6404100 846
+879200 6435800 730
+866200 6402200 580
+877400 6439800 740.5
+846200 6455600 252.5
+876500 6372200 755.5
+845400 6401600 335.5
+884500 6414200 1086
+876400 6377800 1071
+854600 6455500 340.5
+887600 6371100 813
+855800 6459500 336.5
+856300 6471300 246
+858800 6402600 315
+880600 6438100 744
+879000 6432000 1006
+871200 6438900 277
+853500 6461100 307.5
+866700 6412700 750
+854400 6424400 160.5
+862900 6404000 513.5
+845200 6445100 241.5
+889800 6358600 873
+862600 6454900 375.5
+846000 6362700 185
+864000 6444900 240
+854200 6444000 193
+836100 6373100 127
+903500 6397600 1238.5
+902700 6348300 1117.5
+896600 6388800 1022.5
+875200 6370100 759
+836500 6377800 195
+892700 6402100 812.5
+854700 6457200 335
+843700 6459200 250.5
+880700 6366000 773
+900600 6392000 1095.5
+861500 6451400 355.5
+891300 6397900 885.5
+866200 6433000 330.5
+887100 6424600 1341
+907000 6354100 1152.5
+875300 6442000 454
+861300 6415900 619.5
+856500 6394100 348.5
+857400 6408700 282
+890900 6388800 1139.5
+846000 6351700 183.5
+835100 6365700 53.5
+859600 6391200 414.5
+884600 6366000 867
+848100 6385600 170
+861400 6439700 177.5
+904500 6381700 1263
+873600 6362000 643
+864100 6370900 792.5
+879200 6408200 657.5
+876400 6358300 721.5
+857300 6469000 271
+856100 6441100 147.5
+891900 6378000 868
+887800 6439300 758.5
+907100 6358200 1131
+864100 6452900 381
+879300 6415000 777
+858400 6451900 325
+877000 6442500 429
+867200 6408900 484.5
+867800 6386000 712
+862600 6368700 393
+848800 6443600 198.5
+879100 6434500 629.5
+865700 6403500 451
+850000 6381300 305.5
+859700 6387200 578.5
+875000 6351000 629.5
+874800 6406500 711.5
+842100 6379400 269.5
+877000 6400800 727.5
+853600 6392100 193.5
+868800 6430900 855.5
+910700 6351600 1107
+853800 6400000 347.5
+859500 6457200 376
+892600 6395700 911
+885100 6350500 877.5
+911100 6354300 1032
+866800 6451800 378
+856600 6455300 366.5
+848500 6395600 363
+869600 6358200 532
+853000 6467400 306
+887400 6362600 920.5
+859400 6424300 267
+877600 6353700 668.5
+865700 6388800 664.5
+855700 6384500 431.5
+860800 6409700 500.5
+839200 6378000 234
+868900 6453000 394
+874100 6402100 575
+869600 6432700 778.5
+843200 6448400 246
+894000 6350000 921
+893200 6355200 971
+841700 6461900 148.5
+861400 6443400 245.5
+880600 6441500 277
+890500 6432800 1062
+877100 6352100 626.5
+895300 6344900 965
+582300 6928500 111.5
+583700 6892800 84.5
+552500 6888200 144
+545900 6890600 146.5
+524000 6927100 68.5
+577600 6875500 106.5
+531800 6919400 94.5
+540000 6874400 170
+538600 6898600 114
+518000 6874600 188.5
+605100 6906700 70.5
+529800 6902700 106
+553400 6893500 134
+576600 6856800 112
+519300 6909300 148.5
+592000 6909100 106.5
+562600 6874200 146
+607100 6909400 71
+570400 6906300 40
+556600 6863900 151.5
+555200 6884900 142.5
+608100 6920800 116.5
+576200 6880100 105.5
+534900 6870000 165.5
+582400 6892600 75.5
+601900 6905600 114
+577100 6922100 122
+610900 6909700 94.5
+539600 6850200 197
+568100 6872400 145
+543300 6852400 195
+542500 6880200 135.5
+547800 6910900 142.5
+558300 6902500 154.5
+540100 6885500 126
+560000 6870500 136.5
+555200 6904300 144.5
+565900 6869300 146.5
+529200 6900700 123
+573500 6862200 139
+585900 6913500 116
+539300 6846700 193.5
+543500 6885000 131
+575100 6898200 109.5
+602600 6916100 105
+535500 6897000 138.5
+572900 6906500 9
+566300 6903300 80
+515900 6899900 147
+598000 6901900 114
+533800 6859300 199
+598700 6905000 123.5
+579700 6921300 93
+533800 6865200 179
+525400 6912400 107
+605500 6911400 82.5
+538900 6854400 198
+551700 6896700 145
+573500 6906400 35.5
+584400 6879800 106
+508300 6914300 95
+562300 6891500 88
+575800 6901300 73
+536400 6894200 112.5
+527800 6928200 58.5
+549300 6891300 139
+578700 6926300 110.5
+581500 6889600 98
+558900 6892300 103.5
+562300 6885100 120
+562100 6893500 87
+586500 6889600 76.5
+551200 6851100 162
+575900 6884600 79
+573400 6913100 82
+581600 6880800 89.5
+560100 6900100 142
+521200 6920300 70
+520600 6933100 11.5
+511400 6915000 110
+524600 6890300 130
+600600 6923300 133.5
+606700 6923400 134
+539900 6912100 117
+571000 6914800 72.5
+543600 6910900 135.5
+551700 6874200 130.5
+595000 6913400 108
+514600 6882400 177.5
+527000 6919300 97
+561300 6879000 108
+527200 6923900 100
+592800 6903700 109
+573300 6871500 145.5
+556300 6905900 97.5
+548600 6899500 149
+580500 6872900 122
+528800 6861600 217.5
+552300 6866500 167
+557600 6858900 164.5
+545100 6857100 174.5
+584400 6897200 73
+532600 6899200 106
+514300 6879200 175.5
+535200 6891500 90
+543800 6919800 103.5
+597400 6924700 152
+536200 6911800 110.5
+581400 6903200 42.5
+610300 6913200 95.5
+520600 6932000 38
+529000 6874300 182
+510000 6911900 123
+538700 6844900 191
+522100 6915100 71.5
+573400 6909700 11
+580900 6861700 99
+532200 6874600 160.5
+576200 6887500 82.5
+592900 6890500 122
+526600 6895600 145.5
+529200 6887500 132
+602900 6901800 82.5
+551100 6885500 146
+578100 6895500 79.5
+519400 6920000 58.5
+517300 6890100 167.5
+565600 6888200 92
+516700 6892200 179.5
+582600 6887900 127.5
+519700 6892800 163
+589400 6889100 79
+555900 6872800 131.5
+589300 6873000 124.5
+548600 6858300 172
+567300 6877000 138
+553700 6870900 160.5
+581400 6913900 114
+546500 6919500 105
+535500 6922200 116.5
+580500 6882800 86.5
+559200 6904600 100.5
+516400 6883000 183.5
+527800 6903900 126
+580500 6907700 75
+581800 6925100 91
+544100 6862600 179.5
+532500 6923400 101.5
+559200 6912300 65
+522600 6925800 66.5
+565400 6914900 51.5
+513600 6928400 57
+580300 6912000 128.5
+514500 6922700 61
+590900 6910700 123
+508600 6929000 48.5
+544700 6903400 128.5
+560700 6905600 112
+504900 6922700 72.5
+578400 6854100 106.5
+565000 6901300 88.5
+584300 6906300 84
+578000 6900700 67
+562500 6908300 108
+572200 6853100 114
+564500 6893400 85
+570900 6868100 145
+547100 6920600 70.5
+521200 6889800 144.5
+531200 6910300 83
+509500 6907300 111.5
+593300 6908500 114
+515800 6915700 109.5
+520500 6897700 174
+591300 6916300 128.5
+535900 6906400 121
+514900 6872500 199.5
+520500 6903100 161.5
+511000 6911100 116
+575100 6864000 120
+577200 6871400 144
+569100 6888500 98
+571700 6891400 89.5
+534700 6894300 106
+547400 6878500 140.5
+561300 6896800 108.5
+528600 6917100 75.5
+584000 6911100 109.5
+536100 6875100 155
+537800 6911300 109.5
+579100 6882300 81
+540600 6915800 133
+538900 6896500 139.5
+594900 6910100 123
+548300 6865900 179
+565700 6913000 66.5
+587500 6878900 121.5
+574900 6914100 91
+579900 6865000 105
+544900 6859300 179
+573200 6887600 85.5
+552800 6858000 171
+533300 6896700 105.5
+546900 6898000 139.5
+532300 6887500 138.5
+560700 6883200 110.5
+567000 6888800 115.5
+543900 6896800 128.5
+568700 6869800 148.5
+579100 6905000 22
+542800 6905100 146.5
+567300 6905700 68
+542000 6896300 137
+554300 6907000 104.5
+557300 6904100 139.5
+512500 6903100 127
+576600 6861900 130
+529400 6899700 148
+519600 6912300 117
+550400 6900800 150
+595000 6893900 116.5
+540600 6901500 110.5
+509100 6908500 105
+542500 6891900 152
+522800 6876200 186.5
+561100 6887200 116.5
+512400 6917900 90
+522000 6894700 163.5
+543600 6922200 71.5
+540800 6887800 131.5
+585900 6880700 124
+515000 6893600 183.5
+533000 6892400 110.5
+555400 6866500 161
+545300 6899900 139.5
+571500 6883000 102.5
+600100 6918800 118.5
+553800 6895500 127
+555600 6855900 169
+515200 6903100 148
+586700 6917900 105.5
+553100 6905900 119
+597000 6909600 113.5
+565800 6884600 94.5
+555100 6877800 120.5
+559600 6902600 155
+582500 6920300 84
+583100 6895300 72.5
+535100 6871000 162
+524900 6894000 141.5
+584100 6863900 94.5
+540200 6924800 72.5
+541400 6921400 115.5
+576500 6908900 82
+567900 6854100 127
+582000 6878600 83
+512800 6908100 116.5
+589700 6907100 86
+571000 6876300 134.5
+534000 6906000 93.5
+583400 6904100 77
+520300 6879300 168.5
+596900 6904800 113.5
+522200 6884200 149
+584500 6876500 88.5
+579400 6877800 94
+506100 6926300 56
+542100 6908400 152.5
+508400 6925300 68
+526400 6927800 35
+510900 6927500 51.5
+521300 6899500 175.5
+578500 6918100 87
+533800 6901800 96
+588800 6902800 121
+565500 6877900 136
+581300 6917600 125.5
+592800 6924100 138
+592600 6894900 103
+575900 6873600 140.5
+538100 6917100 114.5
+542900 6879500 154.5
+595600 6915400 116
+599000 6912700 104
+530100 6905700 92
+578500 6863800 109
+527800 6907500 117
+550000 6878000 149.5
+548800 6871300 167.5
+529300 6921700 100.5
+598100 6888900 77.5
+558800 6865000 147
+519200 6885700 161
+530400 6872000 176.5
+537600 6889000 123.5
+567200 6898500 78.5
+519100 6895000 170.5
+571600 6900800 79.5
+538700 6910200 121.5
+571900 6877900 123
+569700 6909800 62
+602400 6899000 85.5
+513900 6899100 146.5
+524700 6870300 201
+542500 6915700 117.5
+551000 6878100 123
+551200 6854500 172.5
+552200 6902500 152.5
+509100 6918000 94
+518300 6897200 170
+559700 6854200 147
+569200 6875200 141
+558200 6879200 103
+578300 6890900 123
+568200 6865500 148
+573400 6916000 80
+555800 6876000 120
+567000 6900600 70.5
+571700 6870600 145.5
+538200 6912800 117
+579900 6867500 104
+557200 6894000 104.5
+529900 6895600 141
+565600 6889900 131
+556300 6882400 125.5
+578600 6859800 103
+560200 6880400 106
+586000 6920400 99.5
+556900 6869700 146
+531100 6868800 190
+559100 6886900 141
+545300 6895000 141
+570200 6885000 126
+527200 6880900 165.5
+599300 6908700 93.5
+559100 6853000 149
+564200 6889500 90.5
+575500 6894400 125
+511900 6921500 79.5
+550700 6904200 137
+515600 6921200 64
+539000 6879200 138.5
+607500 6917800 110.5
+585600 6869000 94
+549500 6905800 138
+568100 6882800 126.5
+596600 6888000 73
+549700 6867600 180
+533900 6877700 160.5
+520600 6868300 223
+534700 6916500 93
+585800 6871100 91.5
+573700 6868800 134.5
+604300 6920100 122
+534500 6912600 95.5
+547400 6905000 161.5
+536700 6844500 203
+523300 6899100 169.5
+578600 6883700 78.5
+564000 6871600 148
+590700 6895500 122
+549100 6903500 157.5
+575900 6909800 79
+566200 6891800 116
+591300 6925000 128.5
+559200 6888800 106
+595100 6925400 150
+592500 6887300 74.5
+521900 6910100 125.5
+584500 6919300 86
+565300 6861500 152.5
+553000 6908300 111
+525600 6903700 139.5
+552000 6877800 121.5
+594200 6902800 109
+526800 6906100 115
+513900 6905500 130.5
+562200 6890200 90
+600800 6897300 84.5
+585900 6892000 75.5
+583100 6867500 116
+580000 6880300 87
+573500 6881500 130.5
+518000 6877300 175.5
+528000 6863100 221.5
+546500 6882800 150
+522500 6873200 203.5
+555800 6907800 83
+584800 6874800 91.5
+521700 6926900 64.5
+532200 6881600 157
+537000 6913800 113.5
+515200 6927800 56.5
+558500 6867400 139.5
+536500 6901400 104.5
+519400 6922700 66
+537000 6880600 146.5
+594800 6906100 105.5
+535100 6882800 140
+539500 6905800 137
+525100 6882800 172
+550700 6912400 99
+527400 6878300 171
+525900 6910400 146
+526500 6925800 99.5
+579400 6873700 132.5
+521400 6924100 68
+584100 6917100 101
+596000 6924000 148.5
+567000 6912900 65.5
+525100 6902400 161
+578600 6896900 76
+578900 6868800 120
+586200 6891000 76
+587800 6910300 109
+574300 6907600 64.5
+524700 6868200 208.5
+516600 6916800 84.5
+538900 6920400 122.5
+531900 6906000 81.5
+526700 6915300 72
+515400 6885900 186.5
+522500 6905400 142.5
+583000 6886900 129.5
+546500 6902000 148
+589600 6926300 132
+518100 6897700 174.5
+583400 6875200 89
+552100 6890100 141
+541600 6912900 123.5
+529000 6866100 200
+554900 6898400 143
+556600 6862400 154.5
+542100 6856300 185
+518600 6919500 65
+560600 6876100 137
+545300 6913100 127
+584200 6871400 92
+597200 6906500 119
+524200 6907600 141
+573800 6879800 118
+573200 6899800 119.5
+528700 6883000 155
+531500 6890400 117.5
+556300 6878800 107
+595800 6902000 120
+513100 6870000 214
+578500 6898400 68.5
+567900 6860800 143
+524600 6900700 165
+567200 6854400 124.5
+542300 6897800 123.5
+583600 6926400 114.5
+545800 6919900 92.5
+593400 6916900 135
+514000 6918200 78
+534400 6920100 107
+538600 6900800 105.5
+582100 6926600 94.5
+562700 6894900 86
+529000 6919400 118.5
+520000 6900900 171.5
+543600 6915300 115.5
+516700 6894800 177
+538700 6908400 143.5
+580000 6856000 99.5
+597100 6897700 116
+554100 6905400 123.5
+516100 6898200 163.5
+573200 6890500 85.5
+535000 6925100 101
+542800 6893100 149
+599500 6895000 86.5
+585100 6883400 122.5
+584100 6885800 132.5
+537900 6877600 139.5
+544900 6876300 153.5
+565300 6895900 86
+504700 6924600 56.5
+588100 6900300 102
+583100 6877000 81
+557400 6889800 139
+576100 6876500 108.5
+570200 6888000 96.5
+601000 6909600 83
+517900 6924700 61
+530100 6913200 64.5
+518200 6875500 180.5
+603200 6921500 133.5
+574400 6889900 82
+541400 6919500 119
+568900 6889900 95.5
+597600 6921300 135.5
+587100 6866000 96
+567300 6915000 69.5
+548300 6880900 147.5
+579500 6907000 75.5
+549600 6889400 143.5
+547000 6896300 130.5
+513700 6911900 132.5
+517800 6906300 161
+545600 6880200 153
+578500 6886300 102
+538000 6915800 131
+536300 6847500 207.5
+510400 6886300 150.5
+561900 6901400 139
+569500 6892200 77.5
+543800 6850000 182.5
+527600 6900300 161.5
+552600 6899800 151
+586600 6893600 74
+538700 6892800 152
+523000 6886000 141.5
+527300 6920900 90.5
+526200 6874900 185
+560000 6873800 120
+522800 6902300 166.5
+528000 6926800 83.5
+510300 6899500 148
+541800 6867600 172
+569500 6893600 80
+517100 6867900 208
+518600 6888800 173.5
+594900 6919100 142
+512300 6875300 188.5
+574600 6916400 83.5
+536800 6889900 119.5
+550400 6861200 166
+525100 6917900 71.5
+506900 6919400 97
+513100 6925300 58.5
+588500 6914500 132.5
+549700 6857800 168
+540300 6909300 134.5
+531900 6860500 203.5
+554400 6902100 152.5
+519300 6910300 130.5
+576200 6881900 98.5
+569500 6911000 66.5
+564900 6882000 102
+529000 6913200 87.5
+569700 6880000 123
+570200 6902200 73
+606800 6915100 95.5
+529000 6897500 159.5
+538200 6924300 114
+550900 6905900 131
+604500 6918000 102.5
+530600 6908400 95
+532500 6921400 121
+562200 6899100 83.5
+577800 6913600 112
+523700 6922900 91
+554700 6891600 140
+580100 6871700 131.5
+555300 6888800 143.5
+531900 6884600 139.5
+603800 6905800 97
+575200 6853800 111
+542700 6868800 171
+575200 6886600 81.5
+539500 6866600 179.5
+602700 6922600 136
+572500 6857200 126
+542200 6846900 186.5
+546900 6861600 177
+580500 6887300 89
+552200 6850300 158.5
+537700 6877800 147
+569400 6907800 67.5
+597400 6915100 108.5
+594000 6899200 132.5
+534000 6856700 199.5
+512400 6891600 189.5
+563600 6866200 150
+548100 6909200 132
+528300 6892500 129
+532600 6907300 86.5
+515500 6873900 193
+598100 6899700 116
+517200 6871200 198.5
+578600 6889800 110
+557500 6871800 127
+567800 6894900 80
+570800 6877900 124.5
+514700 6888900 178
+519300 6881600 164.5
+574900 6874600 140
+552300 6882100 134.5
+578100 6923900 115.5
+537100 6908800 127
+588800 6918100 120
+562100 6860700 156
+569300 6914100 62
+522500 6912600 95
+557700 6898800 135.5
+534000 6909900 102
+568800 6883600 113.5
+561600 6913500 63.5
+577100 6883800 81
+581500 6910800 111
+543800 6887900 149.5
+592200 6911000 128.5
+547400 6886600 150.5
+518100 6902400 161.5
+552600 6863000 160
+603800 6903200 84.5
+549000 6912000 134.5
+552000 6910000 130.5
+604900 6910900 81
+571200 6863900 142
+579200 6911100 113.5
+545200 6906000 159
+512800 6914900 114
+522000 6904200 160.5
+575500 6903900 41.5
+589400 6923300 122.5
+530700 6904000 108.5
+547900 6901300 146
+518400 6904500 163
+545600 6909300 144.5
+550300 6883000 138.5
+551900 6907600 125
+530200 6881300 159.5
+547000 6870100 159.5
+585600 6895100 78.5
+510600 6921900 84
+573000 6874400 142
+580500 6919300 75
+552700 6872500 163
+539400 6904600 113.5
+549400 6875400 136.5
+560100 6884800 126.5
+513400 6867900 207.5
+576400 6916800 80.5
+591800 6914000 121
+514300 6896100 174
+557100 6852600 153.5
+572700 6859300 130.5
+563600 6857800 158
+541700 6876800 154
+533300 6861900 189
+536400 6905100 103
+547600 6850700 170
+557400 6896100 111
+511300 6893500 170
+549000 6897000 147
+528800 6884800 159
+518600 6914200 102
+554500 6875200 147
+572300 6913000 10
+581400 6891400 97
+535500 6854300 203
+525000 6886100 140
+600900 6902900 108
+570400 6905000 67.5
+545500 6903700 152.5
+600800 6892100 81
+577500 6897600 95.5
+580300 6899400 67.5
+590900 6898000 111
+510400 6902700 119
+531600 6899700 143
+511400 6897800 156.5
+550000 6909200 141
+526500 6891200 127
+582700 6871700 115.5
+571900 6905000 27.5
+518900 6917500 69
+582300 6902400 76.5
+572100 6897100 113.5
+598300 6896400 96.5
+556400 6901000 148.5
+547700 6893200 137
+598600 6839500 141.5
+613000 6807700 150.5
+575800 6802500 158.5
+587000 6801300 147.5
+592900 6861100 122
+588500 6811800 137
+604400 6798000 135.5
+547900 6834800 252.5
+616700 6797000 134.5
+603800 6809600 145.5
+584000 6791700 137
+580100 6805200 159.5
+621900 6795300 139
+588800 6814500 139
+596100 6828700 125
+589300 6841200 113
+618200 6800100 141
+571200 6814900 175
+584600 6834300 166.5
+600400 6777600 126.5
+594500 6774600 126
+598100 6797700 147.5
+605400 6823100 138
+540800 6798500 196.5
+617000 6789500 133.5
+570200 6795000 156.5
+551800 6819700 196.5
+568100 6822300 201.5
+581100 6817000 159
+604000 6824000 137.5
+554000 6813800 249.5
+564800 6796500 179.5
+573300 6813900 172.5
+605700 6781100 131
+563900 6791600 174
+584400 6829400 186
+538600 6790600 217
+572000 6795800 150.5
+595400 6844000 146
+575300 6795900 143.5
+600900 6785700 129
+587700 6777800 125
+589200 6801900 153
+578600 6814300 153
+561900 6813600 224
+556300 6847600 173.5
+594400 6803000 159.5
+618900 6804000 142
+551200 6787800 195.5
+554500 6849500 159
+554800 6791600 203
+580300 6838700 162.5
+590000 6830400 146.5
+601700 6830400 134
+565600 6791500 159.5
+585300 6855000 105
+618400 6787000 130.5
+552400 6822500 204
+580200 6780900 124.5
+608500 6824800 142
+612700 6790000 133
+578200 6824400 202.5
+578500 6782000 129.5
+555000 6784500 175
+609200 6806700 150
+593700 6796200 146.5
+573800 6846000 145
+553700 6824400 221.5
+604300 6811900 141
+544600 6844800 199
+619900 6808300 142
+572800 6841400 142.5
+598900 6808100 149.5
+568400 6769700 122
+560000 6804400 219.5
+553700 6812100 254
+571500 6840700 147
+593600 6799600 158.5
+543400 6790500 218
+539400 6806100 144
+578800 6811100 155.5
+553600 6840800 182.5
+564000 6853000 141.5
+565900 6833500 187.5
+600200 6800500 143.5
+606000 6819100 140
+593100 6828100 138
+558400 6837600 186.5
+580200 6854200 101.5
+596000 6850300 141
+612300 6814400 147
+608900 6785100 129.5
+590500 6834600 131.5
+546600 6790000 218.5
+610100 6803400 148.5
+551000 6826200 235.5
+555200 6798900 224.5
+588900 6771500 129.5
+554700 6830800 230.5
+566800 6820200 189
+595200 6832900 131.5
+588800 6861000 98
+591100 6842400 112
+544100 6781300 217.5
+538300 6794800 213.5
+587600 6782500 128
+568400 6786600 170.5
+596600 6785100 127
+573500 6842400 136.5
+565100 6828800 220
+615400 6793800 133
+570800 6852700 127
+602300 6835300 137.5
+556300 6801100 214
+567900 6803900 176
+596200 6813100 147
+592300 6855200 130.5
+604800 6815900 140
+542000 6803300 190.5
+607100 6821600 136.5
+609600 6780200 127
+581300 6801200 147.5
+611900 6781500 127.5
+569900 6771100 125
+585700 6784400 139.5
+586800 6842600 110.5
+575700 6780500 132
+607400 6816900 139.5
+565100 6781100 163
+578900 6770700 124
+542900 6787400 207.5
+562200 6808500 226.5
+588400 6850100 133
+622600 6810900 148.5
+572900 6775500 126
+600500 6804200 147.5
+587800 6819800 144.5
+589300 6786700 136
+564100 6821600 223
+587500 6836800 133
+591500 6822300 138.5
+586100 6788200 134
+548600 6797100 231
+544800 6793200 208.5
+586500 6816400 152
+549700 6814000 213.5
+588200 6817300 141
+600900 6812400 147
+601800 6820500 152
+580600 6792400 132.5
+619600 6793200 137
+594300 6833300 127
+614600 6812600 151.5
+557600 6813100 242
+575500 6816400 162
+561600 6776200 144
+576900 6837600 157.5
+545300 6836700 250
+592800 6840200 119.5
+606700 6813200 140.5
+563500 6838200 164
+584000 6780400 129.5
+582100 6848000 109
+592900 6824500 133.5
+598200 6829300 128
+606200 6810500 145.5
+596400 6782800 125.5
+571100 6772000 121.5
+581000 6826500 178.5
+621800 6805500 137
+592400 6793300 142.5
+589300 6778200 124.5
+593200 6779000 125.5
+616100 6783500 131
+582800 6798500 145
+554000 6818500 220.5
+554800 6838500 195
+556500 6804500 234.5
+558300 6790500 194
+575200 6823300 221
+575200 6842500 139
+556500 6824600 226.5
+549800 6784000 196.5
+582500 6839800 138.5
+584000 6850800 106.5
+594800 6852300 128.5
+585300 6809800 146
+565400 6800400 169
+589500 6856200 115
+591200 6813000 146.5
+567200 6853400 134
+583200 6824900 162.5
+581900 6774400 130
+546600 6838100 233
+571700 6798100 152
+568400 6767700 122
+574300 6774300 124
+568200 6848300 148
+546100 6807000 204.5
+552300 6840500 195.5
+620100 6815600 152
+574700 6852500 110
+600400 6826700 132.5
+574200 6799100 149.5
+577700 6846300 119
+596000 6794300 143.5
+569200 6827000 231
+580800 6828200 193
+606200 6776500 128.5
+549700 6810000 219.5
+614000 6805400 145.5
+591500 6790600 139
+588800 6780200 127.5
+545100 6798500 219
+577300 6784300 142.5
+613500 6778300 123.5
+588500 6865800 110
+571300 6806900 175.5
+548000 6840200 204.5
+571000 6831300 214
+594700 6845600 142
+553300 6820900 217.5
+585200 6845600 108
+598100 6830300 122
+585500 6862800 94.5
+586000 6772200 131.5
+589900 6844200 119.5
+572500 6768900 119.5
+579800 6849700 107
+603100 6803800 147
+542700 6840400 219.5
+603300 6825700 132.5
+573900 6811100 172.5
+570700 6784400 160
+567400 6797400 164.5
+603600 6791500 131
+558100 6845100 164.5
+576000 6788400 163
+592300 6863000 116.5
+546500 6808800 202
+561400 6777100 145
+595100 6858600 107.5
+599500 6816700 149
+550300 6844700 188
+576300 6808700 169.5
+597600 6786700 129.5
+621700 6798100 138
+594000 6836600 121
+607300 6796500 134
+575000 6848300 132.5
+581400 6842800 142.5
+567300 6811700 197
+591600 6839700 114.5
+609300 6800400 146
+592700 6867200 137.5
+561700 6819800 212.5
+583300 6863000 91
+573300 6802300 162.5
+579400 6848000 113
+559100 6848500 156
+565800 6846400 164.5
+580200 6808700 157
+567000 6806900 186
+607200 6805100 149
+548400 6797600 228
+571700 6822800 205
+569000 6777700 136
+578300 6793300 137.5
+579000 6819900 198
+602200 6783700 128
+556400 6851200 152
+574100 6849300 133.5
+584200 6848200 107.5
+570300 6832600 203
+558400 6842500 174.5
+587300 6810500 144.5
+600300 6834400 136
+568600 6813200 201.5
+577900 6806500 167.5
+616200 6808100 151
+619600 6809900 150
+576300 6790200 152.5
+612600 6796800 133.5
+578800 6780000 124.5
+551100 6848000 169.5
+586900 6792300 138
+585800 6798800 148
+611900 6792200 132
+579600 6796700 139.5
+594200 6788900 134.5
+576700 6843100 137
+567500 6817800 194.5
+607500 6825100 134.5
+560300 6779500 179
+571900 6765900 111
+576200 6775800 127
+591800 6819700 134
+606100 6788800 129
+604300 6834200 137
+615700 6790400 141
+559600 6835000 196
+583400 6803000 157
+620900 6788700 131
+569500 6845300 157.5
+563100 6800000 196
+553300 6795300 215
+589500 6869400 98.5
+551000 6795900 229
+616000 6779800 124.5
+578700 6776200 126
+599000 6792400 139
+594700 6817300 139
+590400 6853500 135.5
+587100 6861800 93.5
+600800 6822200 145.5
+593800 6853900 112
+596300 6804800 153.5
+579100 6817700 157
+595700 6825000 131.5
+580200 6788000 143.5
+563700 6827800 230
+591300 6850800 141.5
+546500 6802200 238
+562400 6773500 154.5
+582400 6784700 132.5
+611400 6784800 130.5
+575100 6764800 114.5
+565100 6811700 218.5
+586300 6818100 149
+561800 6832500 194.5
+580600 6834600 178.5
+569800 6810800 186
+606100 6828000 146.5
+587100 6845700 111
+587600 6794800 141.5
+592400 6839500 110
+586900 6824200 158
+564900 6773000 134.5
+591100 6869200 124
+595500 6828400 131.5
+569900 6818100 174.5
+589300 6819800 136.5
+609300 6818700 138.5
+592900 6810400 146
+564600 6806300 210.5
+562900 6847800 153
+538600 6804600 155
+559000 6797400 200
+540900 6794600 202
+613200 6809500 149
+587300 6815700 141.5
+617300 6807000 147
+589800 6848700 127
+575300 6820400 197.5
+582100 6811900 148
+595500 6840100 130.5
+583400 6849800 105
+541700 6843200 201.5
+572100 6849000 133
+559300 6847400 161.5
+581800 6766200 120
+550800 6806800 230
+595600 6821600 142.5
+572600 6791200 157
+562000 6816200 223
+581300 6861300 100.5
+558000 6823600 228
+587700 6827300 166
+590100 6808500 142.5
+569300 6838900 152.5
+612000 6810900 148.5
+619400 6806400 146.5
+588400 6805800 150
+553500 6834500 211
+584300 6838700 143
+587300 6813100 141.5
+591400 6844700 126
+611800 6816300 144
+570600 6808900 185
+587800 6863900 109
+621100 6800100 142
+583600 6807700 152
+573100 6834200 168
+597500 6835600 129.5
+586600 6769200 128
+543900 6804700 201
+539500 6801300 154
+570100 6801500 174
+592000 6797700 149
+577600 6811800 157
+571100 6836000 160
+549300 6836300 223
+576100 6825800 206.5
+613000 6800800 142.5
+581500 6822100 179
+541800 6801300 177.5
+577800 6800800 148
+588700 6853200 137.5
+617100 6813400 149
+551300 6803000 239.5
+584100 6846600 107.5
+576500 6766000 114.5
+559800 6792000 189.5
+159800 6833300 81
+147500 6798200 50.5
+163000 6831400 48.5
+136300 6846600 63
+211900 6820200 128
+200900 6865400 47
+169100 6859500 48
+158000 6863500 30.5
+152100 6793900 79
+178400 6810100 89
+155000 6785100 66.5
+172300 6863700 28
+141200 6848000 56.5
+168500 6815100 163
+193300 6832200 286.5
+133500 6796800 29.5
+172800 6834200 103
+153400 6837600 48
+186800 6850400 67
+153800 6783000 25.5
+212400 6775500 50
+183200 6785700 93.5
+150800 6782900 42.5
+159200 6801800 69.5
+141700 6840500 48
+170000 6827100 160
+156500 6851400 53.5
+174300 6856500 78
+204600 6827000 142
+195000 6858000 40.5
+146100 6856300 29
+195600 6799300 171.5
+207800 6811600 183.5
+193300 6850700 75
+141600 6845400 66.5
+141400 6801600 49.5
+165300 6845100 58.5
+213500 6809300 165
+209500 6817700 119.5
+163400 6805100 63
+185400 6840800 132
+157600 6858900 41.5
+158600 6845000 75
+168300 6843400 84
+214000 6844400 188
+179500 6801000 134.5
+176000 6816900 71
+177700 6859900 57.5
+133100 6850900 56.5
+210200 6845800 178.5
+155800 6774000 18.5
+221500 6779000 85
+170200 6836800 99
+199900 6770500 47
+191900 6855900 50.5
+201200 6822800 156.5
+175200 6849300 71.5
+166600 6832300 68.5
+210900 6772800 42.5
+144400 6854400 33.5
+188100 6810400 89
+156400 6776800 28
+160400 6798800 83
+176500 6782900 55
+173100 6830600 181.5
+135200 6800100 48.5
+176900 6835100 221.5
+128100 6835800 29.5
+153600 6792100 82
+206600 6835700 183.5
+168800 6855300 61.5
+175400 6814000 44
+155000 6833500 72.5
+164400 6819100 111.5
+186400 6865500 28.5
+217400 6770800 42.5
+181900 6863900 30.5
+182300 6828400 245.5
+163800 6795700 84.5
+158800 6857500 38.5
+147600 6860200 39.5
+200900 6832900 223.5
+176700 6778000 37
+196000 6772100 51
+185400 6859300 44
+157100 6769800 12.5
+163200 6793000 97.5
+201000 6790800 153.5
+207500 6764500 33
+166800 6820200 83.5
+211200 6864000 39
+189300 6817500 116
+179300 6779600 49
+204900 6845600 163
+190100 6859300 40
+185200 6872200 16.5
+195800 6852500 56.5
+173900 6812100 104
+168400 6823500 77
+200900 6813200 117
+213700 6836300 196
+148800 6801500 50.5
+181500 6854100 77.5
+175000 6800100 103.5
+206600 6861800 58.5
+172300 6847300 69.5
+160700 6776500 18.5
+177800 6820700 163.5
+161300 6865500 12.5
+151400 6787200 46.5
+191500 6863100 37
+219300 6775200 51.5
+181300 6801000 169
+205900 6859600 74
+153400 6840400 65.5
+137100 6842000 61.5
+176300 6842700 102.5
+183400 6775400 53
+153400 6855800 41.5
+186800 6870100 29
+145000 6840800 48
+183400 6867800 20.5
+161900 6780700 35.5
+159600 6839200 55.5
+165000 6799700 149
+148900 6843100 80.5
+139200 6848800 58
+154800 6796700 70.5
+191800 6791300 167
+192800 6844800 120
+170600 6851600 73
+189900 6778300 78
+160600 6855200 46.5
+178600 6846600 79
+162700 6861300 33.5
+142400 6858600 28.5
+199400 6847600 125
+168100 6848200 61
+172600 6840900 107
+206700 6771400 41.5
+164400 6772500 8.5
+198100 6820000 146.5
+164500 6773500 2.5
+188200 6772800 44.5
+202400 6854800 68.5
+144900 6820200 51
+165600 6860400 38.5
+126900 6844700 30
+128100 6847300 35.5
+155400 6769000 8.5
+178200 6857800 61
+152200 6848200 65
+102300 6847900 30.5
+197000 6852600 52
+146400 6848500 61.5
+204300 6775800 76
+154600 6817800 72.5
+165600 6839800 88
+165900 6835600 90
+136700 6836300 51
+159800 6814000 149.5
+146600 6796600 51.5
+164200 6802100 159
+186000 6835300 238
+180900 6796600 113.5
+189800 6800600 156
+139600 6851900 41
+146900 6791200 48.5
+127300 6851300 30.5
+182300 6808300 144.5
+139900 6856500 28
+201100 6828400 179.5
+177600 6863900 39.5
+162700 6859000 44
+192200 6824200 192
+130800 6847600 50.5
+137200 6824300 32.5
+208600 6856400 76.5
+163300 6811300 124.5
+206200 6850700 109
+134900 6835700 53.5
+163000 6808700 48
+190500 6784300 98
+187700 6847100 111.5
+200500 6780300 97
+182900 6858400 57.5
+180400 6844600 105.5
+165600 6778300 31
+162600 6835500 90
+150500 6851400 44.5
+112000 6840400 13
+129300 6839400 70.5
+188800 6807300 133
+141400 6828400 39
+158300 6789800 97.5
+210800 6850000 117
+216800 6779400 66.5
+164800 6847400 89.5
+188600 6831700 303.5
+207600 6841800 202
+154700 6862700 38.5
+147300 6824500 43.5
+160900 6851300 74
+136000 6856400 31.5
+191900 6795400 166
+201500 6809200 180
+185800 6796600 139
+194300 6809100 92
+161700 6863900 32
+138600 6796100 33.5
+176900 6789500 72
+176100 6811300 109
+212900 6850600 157
+164000 6827600 46.5
+173800 6853000 85.5
+180500 6863800 33
+193100 6828400 213.5
+161700 6823900 58
+178300 6840300 119
+154300 6853900 44.5
+192200 6803900 163
+212700 6782300 92.5
+171300 6789900 73
+142700 6797700 37.5
+174500 6779700 39.5
+183100 6814600 95
+151600 6771200 11
+159000 6793700 113
+206200 6782800 94
+176200 6856400 73
+169000 6776800 29.5
+155500 6853500 44.5
+152800 6780000 26.5
+137100 6796400 39.5
+129600 6798400 40
+155000 6802200 43
+131000 6799500 43
+183500 6843700 111
+164600 6853600 52.5
+164700 6841300 88
+162400 6852700 59.5
+186800 6788500 109
+128900 6842800 69.5
+168600 6846200 76
+192300 6768400 24
+158400 6842200 79.5
+172600 6778900 35.5
+204500 6766800 33.5
+165100 6788800 82.5
+198500 6841600 200
+156500 6780900 46
+157700 6819200 95.5
+130400 6853700 26
+209100 6776400 56.5
+205500 6813700 104
+191000 6837700 255.5
+184900 6822700 184.5
+125300 6835000 25.5
+115800 6799700 4.5
+169200 6780700 29
+177800 6851600 94
+129500 6832600 44
+194100 6816500 162.5
+159800 6771700 13.5
+155800 6844500 84.5
+170900 6803400 166
+196200 6806300 164
+142700 6794700 52
+182800 6839400 144
+202100 6865200 64
+174500 6818500 139
+143600 6849600 50.5
+212800 6817600 119
+146600 6836200 51.5
+189200 6822300 140.5
+198000 6859500 53
+159600 6854200 53.5
+166600 6783700 44
+159700 6827200 38.5
+171300 6840400 120
+208400 6825100 143.5
+135600 6854100 43
+169900 6808100 148
+791900 6271600 2.5
+832600 6315900 98.5
+793100 6348400 311.5
+825700 6304500 47
+801500 6314700 110.5
+742600 6319400 570
+788300 6299500 64.5
+738500 6321200 876.5
+810100 6323300 134.5
+798600 6321000 107.5
+782000 6359000 442.5
+752500 6315000 501.5
+818900 6328100 169
+783700 6308800 129
+842500 6329700 98
+809300 6340300 227.5
+835100 6311700 81
+820100 6356600 230.5
+798900 6301400 108.5
+827600 6333700 143.5
+775500 6308600 238
+798300 6293300 15.5
+768300 6327900 415.5
+802700 6328600 246
+764900 6317900 526
+787100 6311900 133.5
+776200 6316400 272.5
+774800 6365300 931
+814300 6313500 123.5
+780300 6312800 266
+792500 6295800 53.5
+801900 6348300 261.5
+832500 6345600 159
+820400 6304800 65
+832200 6302300 78.5
+796400 6274900 1.5
+777800 6367500 927.5
+768700 6318900 341
+799000 6299900 102.5
+807600 6348300 282
+798000 6303900 127
+775500 6335100 415.5
+782200 6363700 668
+750100 6324800 739.5
+810600 6326600 178.5
+766200 6322000 571
+799700 6287100 20.5
+794900 6329600 137
+777000 6344300 565.5
+836300 6325100 157.5
+799300 6298000 65
+786600 6341000 247.5
+780300 6311100 254
+791100 6322200 165
+790400 6315100 176.5
+819600 6327000 182
+828100 6309800 42.5
+820800 6353300 223
+731100 6331100 898
+759000 6326400 700.5
+774700 6325300 331
+827500 6352900 171.5
+791200 6348900 356.5
+829900 6345600 141
+800000 6349000 133.5
+818500 6303300 63.5
+782700 6345900 434
+789500 6306800 164.5
+751800 6317400 475.5
+786600 6325900 132
+841800 6318900 96.5
+756200 6328000 719
+799200 6341200 233
+757900 6335500 700
+770900 6334400 488.5
+796600 6323500 122.5
+728900 6329300 720.5
+797700 6317000 143.5
+802700 6336100 411.5
+818200 6312900 146.5
+808700 6293100 86.5
+799000 6347800 158.5
+783000 6305500 125
+830900 6307300 14
+824700 6313700 83.5
+784400 6313700 156
+831600 6352200 111.5
+816300 6350100 189.5
+730700 6336900 900.5
+805800 6329800 233.5
+823400 6345900 200
+779500 6304100 144.5
+829500 6349000 152
+824800 6320200 105.5
+790100 6357000 337.5
+806200 6324000 148.5
+779000 6328900 280
+822300 6320000 103.5
+735300 6318700 958
+818800 6347700 209
+792600 6351900 309.5
+803600 6297100 58.5
+786700 6353900 387.5
+814300 6318400 116
+782100 6324500 145.5
+796700 6304000 124
+784700 6356300 390.5
+785900 6301800 69.5
+809300 6332700 239.5
+735800 6329600 1030.5
+790300 6339000 207
+796500 6282400 3
+821800 6352400 228.5
+777900 6350800 517.5
+797200 6318800 137.5
+793200 6353100 316.5
+802600 6319900 79.5
+819000 6339400 214.5
+757400 6320500 554
+791900 6342900 335.5
+774300 6322400 266
+793800 6320400 167
+780900 6361700 598
+785800 6322200 131.5
+778000 6356300 573
+788800 6321700 134.5
+828600 6315700 89.5
+829900 6289600 8
+825600 6316800 64
+784600 6348600 425
+786600 6327100 144.5
+835600 6321000 157.5
+776400 6331200 256.5
+793400 6298400 97
+792200 6316000 183.5
+806700 6291900 64.5
+733700 6317200 708
+801500 6303700 132.5
+772900 6316800 234
+842300 6324500 94
+788100 6309800 163.5
+792400 6334200 174.5
+788700 6311900 164
+805700 6296200 40.5
+738200 6335300 1092.5
+796400 6330900 158.5
+806800 6321400 89.5
+813100 6335700 274
+748200 6319300 361
+837900 6331100 100.5
+795100 6322500 159
+822800 6329300 207.5
+793100 6306500 135.5
+769600 6326900 334
+748600 6321600 412
+782300 6346300 396
+797100 6309000 145
+824900 6355600 132.5
+806200 6343900 371
+762300 6322900 630.5
+802200 6296200 58.5
+804700 6350000 221
+818400 6334000 207
+790100 6319200 119
+815400 6287600 58
+820000 6321200 118.5
+823400 6333600 177.5
+843700 6326800 76
+797500 6288000 8
+794600 6333000 182.5
+780500 6354900 475.5
+807500 6357500 238
+825500 6310500 44.5
+826000 6342100 162
+809400 6305200 118
+797600 6311600 122
+777600 6339400 424
+833300 6338300 129.5
+816400 6322700 121
+798300 6294600 42.5
+831400 6317100 140.5
+754200 6319900 443.5
+784200 6331000 279.5
+781400 6369300 608
+796100 6314100 153.5
+829100 6307300 78
+836200 6337800 38.5
+826600 6328200 214.5
+808200 6337900 281
+840500 6332200 45.5
+783700 6301600 137.5
+788800 6349900 377.5
+790300 6302300 107.5
+795700 6340500 193
+762700 6334700 718.5
+796600 6326400 144
+805500 6322500 145
+818600 6318300 116
+816700 6335100 239.5
+811000 6300600 57.5
+781200 6356400 425.5
+787000 6308400 99
+775700 6361600 854.5
+829500 6341700 149
+829300 6332800 157.5
+803200 6340800 379.5
+771100 6322800 386.5
+803500 6349700 233
+818800 6341400 174.5
+826600 6324400 181.5
+771200 6326400 380
+805300 6299900 68.5
+817500 6325300 146
+745800 6321400 833
+803600 6323700 162.5
+794400 6328000 130
+782600 6318000 130
+815100 6335400 230
+751400 6331600 927
+799500 6345300 248
+781700 6328400 262.5
+760900 6336000 537
+746200 6319800 494
+754600 6339900 769.5
+747000 6322500 453
+826400 6332400 174.5
+796000 6312800 159.5
+785900 6357900 327
+817500 6357500 226.5
+787800 6355400 319
+824700 6335000 182
+797500 6350600 174
+815500 6328400 177
+827000 6335500 174
+789200 6325400 127
+820600 6325800 162
+830200 6312500 69.5
+790100 6332000 154.5
+795600 6353900 281.5
+779600 6319800 127.5
+818200 6353600 230
+765900 6325800 657.5
+798800 6331500 217
+779900 6325400 269
+817100 6347400 201
+786900 6318700 119.5
+792900 6325900 130
+831600 6330600 171.5
+834600 6340300 148
+809900 6319200 104.5
+723700 6332100 670.5
+806100 6316000 120
+804000 6328000 153
+784900 6310900 125
+784200 6324300 142
+785500 6304800 68.5
+790400 6297400 55
+747900 6324600 872.5
+796200 6315400 140.5
+747500 6314500 574
+796800 6294200 42.5
+801800 6323300 138.5
+818000 6309800 95
+787500 6304000 93.5
+755300 6318700 339
+741600 6318700 594
+818500 6330300 172.5
+736900 6311300 566.5
+821500 6345000 148.5
+793000 6318500 143.5
+779100 6347300 544.5
+813400 6352300 202.5
+799700 6338400 391
+820600 6333700 180.5
+754000 6325700 540
+827700 6320300 128.5
+804100 6315600 113.5
+836400 6344600 122.5
+779600 6307500 128
+827300 6350000 202.5
+801400 6294300 47.5
+766600 6335000 516
+795600 6352000 301.5
+813800 6324700 161.5
+792600 6342100 194.5
+816100 6307900 119
+780900 6342300 380
+787800 6299000 62.5
+796000 6299200 119
+786500 6337100 236
+802900 6289100 48.5
+778800 6331900 274
+788700 6342300 351.5
+844100 6320200 95.5
+798300 6328800 173
+766500 6330000 727.5
+797400 6321800 106.5
+821200 6314100 139.5
+786900 6316400 153.5
+824100 6315400 98
+741200 6312800 616.5
+786200 6332300 247
+781500 6352900 507
+819800 6310300 97.5
+808600 6327400 182.5
+821800 6336300 183.5
+835500 6327800 177
+803300 6351800 165.5
+808400 6354900 184.5
+795500 6310500 156
+786600 6351000 463
+815000 6297600 75
+794000 6335800 205
+784100 6335900 360
+790700 6323600 152
+746000 6310100 450
+776600 6321700 222
+740400 6321500 890.5
+782600 6304100 139
+795100 6294100 48.5
+794500 6292000 36.5
+781600 6320600 138.5
+798800 6326600 155.5
+791100 6328900 151.5
+790400 6299600 96.5
+796900 6338900 205
+822300 6347100 209
+822000 6296100 51.5
+792200 6356200 357
+825800 6344100 139.5
+815300 6304100 43
+815700 6342200 197.5
+744700 6322500 756.5
+784400 6320800 128
+800400 6324100 142.5
+768800 6310900 337.5
+798000 6335400 218.5
+748800 6317100 423
+779600 6334700 418
+835000 6317300 124.5
+799200 6315500 112
+824100 6357300 222.5
+769300 6330500 526.5
+792100 6330500 150.5
+800600 6301400 106.5
+814800 6301200 55.5
+832700 6335400 150
+784300 6340100 349
+774300 6330000 321
+795700 6346600 171.5
+836200 6329900 150
+784300 6317600 167.5
+790600 6325500 133.5
+512400 6251700 257.5
+553800 6274300 227
+516200 6213900 682
+502400 6230700 486
+498100 6192800 1993.5
+499100 6192800 1677.5
+548100 6237200 297.5
+581600 6282000 187.5
+538700 6230100 476
+598200 6266500 226
+593000 6269000 210
+567200 6289800 128.5
+568700 6269300 156
+543800 6266700 265
+498800 6235600 471.5
+507300 6208200 966.5
+585000 6302600 153
+602000 6261900 223
+533700 6224800 354.5
+519000 6219000 530
+569100 6286500 130
+509800 6217700 719
+494200 6193700 1578.5
+585700 6288100 184.5
+559600 6244600 278
+529900 6226800 347
+514600 6225900 448
+571300 6268000 200
+512100 6203800 839.5
+575400 6268800 215.5
+544400 6236000 288.5
+545400 6272000 241
+505600 6230300 464.5
+561700 6256800 223.5
+610800 6266300 250.5
+567800 6268000 155.5
+571900 6250200 251
+587400 6285800 186.5
+522100 6245300 330.5
+557300 6279400 200.5
+519500 6212200 1187.5
+565600 6280700 168
+535200 6219300 377
+579300 6268000 204.5
+514900 6199800 1272
+529100 6248400 306.5
+540800 6251100 300
+508500 6206700 1074
+536600 6215300 812.5
+511600 6236000 411.5
+540300 6239800 313
+592100 6249200 255.5
+506100 6217700 664.5
+581900 6297900 174.5
+528700 6222900 360
+504300 6191100 1259.5
+584500 6263100 213.5
+564500 6263800 228.5
+534500 6239800 320.5
+588900 6258400 216
+560400 6289800 156
+582700 6302500 103.5
+515600 6217500 584
+552600 6270000 197.5
+593500 6271800 216
+574400 6270700 203.5
+576800 6273100 197.5
+531800 6256400 254
+539400 6257800 279.5
+508200 6211300 588.5
+516000 6239300 373
+522700 6253100 263
+571700 6253600 229
+497300 6197800 1558.5
+535300 6242200 310
+504100 6223200 432.5
+535100 6232800 330
+504500 6238100 404.5
+575800 6240700 283
+534200 6220700 361.5
+583000 6310600 167.5
+578500 6296100 165
+554300 6288200 173.5
+531500 6229300 377
+551200 6282700 217.5
+505200 6203100 1137.5
+509400 6211000 1094
+573600 6292600 158.5
+496700 6193200 1515
+544700 6235500 265.5
+604900 6275000 222.5
+564900 6284800 159
+500600 6226800 483
+576500 6268800 230
+521300 6227100 388.5
+596600 6262100 223.5
+613200 6263300 233
+589500 6280400 203.5
+598100 6262900 224
+546800 6293400 226.5
+599000 6277000 208.5
+552000 6284100 144
+573000 6260500 165.5
+570500 6288100 122
+549900 6271800 260
+582400 6251700 248.5
+586400 6260800 213.5
+578500 6269700 213
+573000 6248500 251.5
+513700 6253600 255
+539500 6253300 291.5
+566200 6277500 168
+516600 6251300 274
+552200 6243200 217
+548800 6244000 233
+576000 6257600 218
+580700 6247100 243.5
+547500 6258900 273
+522700 6247200 316.5
+599500 6270900 234.5
+576800 6294500 155
+595600 6250500 238.5
+560200 6235000 312.5
+509100 6212200 696.5
+549900 6239900 223
+513900 6221300 478
+522700 6234900 397.5
+539000 6232900 440.5
+577900 6288300 178
+531400 6220200 365.5
+506200 6211600 725.5
+601900 6275700 204.5
+591000 6282300 191
+602300 6256800 238
+571100 6270500 188.5
+556000 6260600 213.5
+584400 6266500 188
+531000 6252200 295.5
+580700 6260600 236
+555400 6245900 257.5
+531500 6257500 254
+495300 6198800 1712
+547800 6234000 309.5
+573600 6289500 157.5
+524400 6217500 600.5
+577600 6262700 240
+553500 6241500 269
+503300 6193500 1156.5
+523200 6220800 428
+573100 6265900 210.5
+515700 6219200 523
+547100 6241400 242.5
+503600 6218500 556
+557200 6252300 205
+509900 6212300 788
+563800 6249200 255.5
+554800 6291100 173
+528200 6216800 569
+560300 6276800 181.5
+537100 6253100 289
+601400 6273300 219
+510300 6237100 363
+587900 6262700 204.5
+529600 6231700 385.5
+596100 6256500 212
+561900 6287300 169
+527100 6258300 241.5
+593100 6292700 183
+532500 6254300 275.5
+547900 6287700 212
+550900 6246200 225
+592000 6265700 221.5
+523900 6225600 341
+538500 6240000 316
+510000 6227400 430.5
+499700 6225400 511
+501900 6223700 476
+580200 6258500 225.5
+527400 6215600 865.5
+557900 6240300 286
+516800 6215600 598.5
+584900 6280100 192
+579800 6308500 151.5
+535100 6231600 409
+542300 6297700 237.5
+514600 6233400 399.5
+571600 6299200 176.5
+508600 6204500 1317.5
+557000 6290400 145
+561500 6281300 191
+584300 6268700 195.5
+570000 6283200 136
+604600 6260900 254.5
+542900 6294100 194.5
+583100 6261300 232.5
+508000 6208700 1070.5
+587800 6301200 139.5
+525700 6228500 385.5
+569200 6265900 156.5
+544200 6231700 405
+540700 6295200 203.5
+609900 6261700 259.5
+513900 6246600 317
+559000 6256800 195.5
+574200 6279600 189
+602000 6258100 243.5
+564500 6270000 166.5
+589200 6249800 242.5
+527900 6234800 379
+594600 6260000 211.5
+518500 6231000 404
+533200 6251900 301
+504000 6195200 786.5
+524500 6256000 256.5
+573900 6304600 134
+543300 6264900 263.5
+596000 6279000 204.5
+599100 6259200 229
+580800 6265600 211.5
+542500 6259100 287.5
+580000 6304500 120.5
+546300 6254200 278.5
+573300 6298000 165
+583300 6284200 186.5
+594900 6267600 219
+573600 6295800 154
+519400 6251300 272
+577200 6271000 207
+597600 6250600 237
+561400 6252200 238
+516100 6235700 393.5
+576300 6251300 228.5
+576000 6237700 309.5
+508600 6243000 353.5
+543000 6235600 347.5
+532500 6238900 395.5
+502600 6233100 439.5
+564300 6236600 300.5
+536200 6227000 374
+514200 6210600 1206
+511400 6204400 1118
+552200 6283900 199
+506200 6202100 1125
+591300 6274300 217
+592000 6285200 209.5
+500300 6234800 451.5
+590600 6277900 214
+520200 6210100 1027
+562800 6292900 142
+533300 6215100 809.5
+557300 6289600 155
+529700 6252900 278.5
+588900 6275500 208
+503700 6189800 1302.5
+578400 6265000 233.5
+583500 6282700 193
+547100 6264000 279.5
+583600 6269800 189
+513000 6224500 451
+496600 6232300 497
+505300 6199500 1286
+529700 6210400 1047
+534200 6255100 282
+511200 6206500 1178
+528400 6240600 373
+549800 6287700 204.5
+605100 6270200 226.5
+504200 6192900 1304
+563500 6268000 171
+515500 6242100 309
+584000 6274000 187
+592700 6244700 279
+533100 6242700 315
+577100 6266700 231.5
+510800 6232600 430
+569400 6258300 192
+516200 6242600 317
+591700 6260500 199.5
+519600 6244200 315
+525500 6235300 357
+565500 6302200 162
+544200 6289300 200
+575600 6245600 265.5
+572800 6249800 254.5
+597400 6275200 232.5
+499600 6194900 1509.5
+564500 6288600 145
+597400 6264400 229.5
+504100 6222900 559
+516400 6224200 451
+551300 6236500 274.5
+560500 6259700 186.5
+565900 6270800 163
+543900 6296300 231
+538100 6300100 211
+573900 6260600 214.5
+589000 6287300 197.5
+504500 6226600 461.5
+579400 6286300 178
+512900 6243900 301
+526000 6231300 411.5
+506000 6215400 692
+577300 6289800 177.5
+505900 6223800 400.5
+587100 6278600 203
+522200 6219200 486
+573400 6286800 130
+501100 6231300 475
+589100 6244000 265
+502600 6222900 523
+506100 6203600 1067
+513900 6248900 281.5
+586500 6294000 165
+601800 6252600 225
+541800 6301300 230.5
+552100 6248600 218.5
+577500 6291900 160.5
+557900 6264000 202.5
+595900 6252200 222
+571200 6295700 143.5
+577700 6285300 164
+585900 6270400 200.5
+581000 6283700 177
+525600 6206900 1127
+598400 6265100 244.5
+546900 6296800 215.5
+568700 6295000 115
+567800 6299500 164.5
+601400 6260500 233.5
+504800 6193700 1389.5
+581500 6273600 181.5
+503600 6194800 1217.5
+500700 6192500 1083.5
+593800 6265100 234.5
+557000 6272400 191
+539900 6234100 378
+581100 6271100 171.5
+552800 6228300 423
+544900 6270200 250
+505600 6235900 396
+590300 6293800 180
+569000 6290200 118
+595500 6247700 256.5
+580000 6266900 209.5
+528100 6257000 268
+582500 6264800 194.5
+530200 6245200 322
+551700 6292100 212
+533100 6222400 354
+588100 6268500 210.5
+510400 6239900 363.5
+552100 6254900 233.5
+552000 6259300 228
+595000 6270300 225.5
+560900 6237800 307
+528900 6229300 371
+512500 6239200 357
+566100 6272400 160
+530700 6217400 518
+602500 6263700 240
+513200 6234400 410
+599600 6273600 228
+517300 6222300 454
+508800 6246200 315.5
+519800 6232500 410.5
+593300 6255600 213.5
+573100 6263400 217
+528700 6254700 266.5
+588900 6270300 195
+542600 6263500 280
+508800 6210800 1016.5
+541700 6261100 265.5
+528300 6243800 323
+563900 6299400 106.5
+537000 6225000 357
+613400 6266600 230.5
+523700 6227900 381.5
+609000 6269200 236
+532700 6250800 296
+579100 6255600 237.5
+533300 6230900 379.5
+528600 6252300 281
+583800 6304900 154.5
+525500 6250700 286
+552700 6265600 211
+588300 6251700 241
+513300 6204700 1205
+502800 6217900 447.5
+524200 6230800 424.5
+534200 6249300 299.5
+498700 6196900 1517
+561000 6239900 298
+521800 6243100 333.5
+518800 6255200 254.5
+557800 6281000 202.5
+519700 6225300 358.5
+525100 6223000 410
+600800 6264700 243
+526400 6225500 352.5
+536200 6246500 316.5
+502200 6236500 426.5
+530000 6239500 371.5
+554600 6299700 149
+532500 6240500 318
+540900 6259300 269.5
+502400 6219900 559.5
+570200 6245500 275
+602600 6272200 216
+532800 6246600 318.5
+592100 6252500 223.5
+592800 6258200 168.5
+575400 6271100 211
+587900 6290400 198.5
+563000 6235600 332.5
+497800 6192800 2012
+578800 6280200 176.5
+507900 6221800 557.5
+587600 6272600 196
+558800 6250200 232
+542500 6255500 291
+586700 6283100 194
+500400 6193700 1307
+520600 6215400 819.5
+520400 6239000 354
+550000 6251200 241
+612800 6265000 223
+523700 6258900 219
+511300 6214600 694.5
+543000 6262200 278
+525600 6244000 331
+552600 6233600 341
+546900 6248800 282.5
+532300 6234200 401.5
+519100 6247200 298.5
+542100 6230600 453
+516700 6199100 1587
+548900 6230200 369.5
+495800 6191900 2084.5
+562300 6247100 248.5
+535000 6228100 320
+572200 6289400 127
+507200 6225900 447.5
+575500 6287300 164.5
+527300 6219400 422.5
+562300 6275500 178.5
+514200 6230900 433
+553400 6295400 196
+527800 6232300 381
+499200 6229500 501
+523600 6236000 352.5
+580500 6294100 172
+595100 6266000 230
+503800 6198400 1285
+557900 6266400 183.5
+581000 6286100 194
+517100 6211300 1187
+504400 6200000 1182.5
+568800 6264800 166.5
+495800 6193400 1535
+539600 6225600 354
+531000 6242400 319.5
+567600 6237500 266
+560100 6252100 227.5
+586100 6275300 190.5
+584000 6290900 173
+496900 6197900 1603
+576400 6290600 174
+617500 6259100 399
+580400 6289200 173.5
+580900 6277300 187.5
+515000 6212300 697
+568800 6251600 260.5
+517200 6244100 308
+574300 6257400 203
+525700 6233900 367
+591000 6256800 205.5
+508000 6239000 357
+619400 6262700 280
+539100 6247300 316.5
+596800 6277400 207
+584100 6272500 194
+572000 6293000 145.5
+506800 6212800 694.5
+510300 6222900 541.5
+566100 6237900 290
+557500 6294900 145.5
+570500 6262700 162
+589900 6298700 171
+538200 6235300 362
+531100 6211900 944.5
+505200 6202800 1060
+534900 6222200 368
+602300 6266300 228
+583700 6296200 167.5
+534400 6216200 746
+539300 6227900 460.5
+569900 6291300 122
+554300 6286900 179
+512800 6211400 1148
+534600 6237200 407.5
+514700 6240200 328.5
+507800 6222800 480
+532000 6225800 348
+502900 6190900 1674
+580300 6263100 229.5
+501600 6191900 1116
+495100 6193600 1577.5
+507100 6221100 565.5
+513400 6201500 801.5
+517500 6221300 419
+494200 6194200 1666.5
+521000 6212300 1037
+512300 6201800 1337
+499800 6193700 1302.5
+539500 6255100 296.5
+505200 6195400 1460.5
+505300 6198100 1436.5
+494400 6191600 1745
+505100 6201900 1145.5
+497500 6193400 1413.5
+547000 6231600 363
+536800 6244500 311.5
+506600 6224800 451
+549900 6267800 253.5
+558900 6227000 391
+547800 6300800 224
+555500 6264600 204.5
+504700 6240100 398
+604100 6259300 267
+566900 6254900 242.5
+511300 6205900 865
+521400 6249900 276
+576600 6296500 161
+536000 6252200 294.5
+561500 6254400 225
+547600 6251700 285.5
+501900 6217300 718.5
+513400 6217700 589
+542900 6244400 305
+538500 6243900 307
+556100 6235900 365.5
+552100 6301200 198
+503600 6241400 395.5
+527600 6237800 403
+529100 6213000 616
+508000 6212900 783
+514300 6219400 503.5
+607700 6265000 247.5
+577600 6298900 167.5
+548300 6295100 216
+562500 6298400 132
+582600 6305600 143.5
+570500 6305900 149.5
+545700 6292400 226.5
+547000 6285300 166
+586400 6292000 192.5
+545400 6301300 227.5
+605800 6262500 250
+596500 6254400 222.5
+569700 6269000 152
+503900 6242300 363.5
+507000 6204700 1150
+545600 6247100 270.5
+504600 6200500 1150
+600400 6277500 177.5
+566300 6265900 171
+512300 6231600 430.5
+519600 6228300 403
+510200 6214100 719.5
+496400 6231100 503.5
+599400 6260900 218
+573600 6287700 131
+566700 6259400 229
+591100 6290400 194
+574800 6265900 225.5
+521700 6223200 404
+593100 6262900 226.5
+557700 6248000 249
+520100 6258100 246.5
+545900 6289900 212
+583900 6278400 197.5
+581500 6287500 181.5
+550400 6273600 259
+538600 6249800 291.5
+585500 6247800 260.5
+574600 6247000 263.5
+538300 6238600 323.5
+583400 6256800 238
+579000 6259400 212.5
+502700 6250700 310
+462000 6294000 156
+503300 6315000 156
+499300 6323500 160.5
+441400 6285100 161
+444300 6311400 87
+521800 6275600 206
+478000 6313500 130.5
+499100 6257800 275.5
+513000 6263000 263.5
+483100 6315400 131
+485600 6287000 182
+486900 6306300 157.5
+476100 6315600 135.5
+471800 6300400 184.5
+467000 6311200 149.5
+484000 6289200 180
+486000 6315700 121
+504200 6274100 212.5
+495900 6264900 231
+499500 6266700 231
+457200 6290400 158.5
+512300 6260900 272
+463900 6288100 152
+517100 6294300 201.5
+491700 6301200 145.5
+534700 6287500 179
+457500 6307000 142
+518100 6319400 134.5
+480200 6284900 182
+479100 6318900 132.5
+522800 6300500 157.5
+495400 6275200 211.5
+519200 6271800 216
+533700 6294300 166
+522900 6311000 148
+489800 6288800 180.5
+492400 6265300 215.5
+465400 6286800 183.5
+524800 6298200 157.5
+446500 6282800 179.5
+511700 6268600 244
+476300 6275700 228
+549100 6283100 173.5
+505300 6253500 278.5
+470100 6261900 216
+445500 6312900 94.5
+530900 6266200 224
+482400 6303800 132.5
+526700 6270000 238
+460500 6298600 143.5
+538900 6292900 175
+473000 6279000 215.5
+496900 6259600 243.5
+497900 6274200 214.5
+507200 6265900 239
+474800 6274100 217
+528500 6286900 183
+499300 6263100 248
+459000 6284200 132.5
+481300 6322900 120.5
+443900 6295000 139
+524100 6315000 180.5
+533300 6299400 153.5
+517400 6307200 148.5
+522600 6271300 237.5
+523000 6326700 144.5
+527100 6303500 149
+443400 6291200 87.5
+484900 6258500 267.5
+510100 6283000 222.5
+472100 6263400 229
+503800 6310300 121
+477600 6271300 215.5
+464900 6293100 164.5
+495900 6253500 298.5
+517100 6290900 183.5
+530800 6261500 239
+475200 6285400 210
+470500 6273600 194.5
+532600 6268200 203.5
+502600 6257000 263
+500800 6265000 246.5
+495000 6262100 247.5
+508100 6311400 120
+495300 6290900 204
+501200 6329600 156
+519000 6297900 190
+532500 6263200 233
+517600 6313200 165.5
+528100 6312600 216
+517600 6316900 145.5
+515100 6309100 144.5
+501700 6298000 185
+446200 6304900 102
+538800 6267600 215
+459100 6298000 129
+466100 6320900 134
+450900 6292700 139.5
+459500 6286800 152.5
+481600 6282600 192
+477500 6279400 218.5
+491900 6292000 179
+483800 6301100 163.5
+531700 6279600 211
+537300 6264800 234
+525700 6272600 228.5
+445800 6288700 127
+502900 6296300 186.5
+478700 6273900 230
+460500 6292100 150.5
+513600 6302500 117
+545000 6281300 220
+520500 6261700 244.5
+540900 6281800 185
+501100 6309200 168.5
+512900 6287300 194
+491000 6256300 256.5
+511400 6275900 234.5
+443500 6289300 122.5
+469500 6263100 217
+467500 6298800 169
+535300 6257200 272
+482800 6299200 166.5
+486200 6256100 261
+473100 6261100 241.5
+482000 6256600 270
+498600 6294800 208
+439200 6294700 118.5
+524300 6290800 176
+529300 6308200 188.5
+467800 6275800 181
+494100 6276400 192
+481400 6275800 215
+522200 6277300 209.5
+493500 6283100 202
+506100 6270900 223.5
+523900 6277300 196
+515600 6312000 155
+497700 6269600 221.5
+514300 6256300 266
+496000 6311900 153.5
+517200 6329400 146.5
+461000 6288900 167.5
+495300 6258200 238.5
+498800 6304700 178
+525600 6260400 212
+493300 6319400 153.5
+509400 6298000 139
+446400 6294800 142
+462200 6275200 198.5
+510000 6273600 233
+471000 6322000 129
+505300 6268900 225.5
+485000 6294000 167.5
+453400 6319900 137.5
+516500 6270500 229
+538800 6270200 203.5
+517800 6300800 191
+477400 6291700 171
+482600 6309100 143
+507200 6300400 145.5
+457400 6310300 138.5
+447600 6298300 131
+493900 6316400 161
+446300 6291800 99.5
+442900 6316500 88
+493500 6253600 252
+543000 6276100 227
+440500 6288400 152.5
+471900 6305300 164
+504900 6302100 166
+512400 6296700 158
+473300 6282800 215
+488400 6304500 154
+481400 6290400 177.5
+475400 6320700 128
+473000 6266300 241.5
+479500 6267800 217
+451500 6307300 129
+510100 6286500 196
+493700 6259500 233
+540600 6286800 191.5
+486700 6284400 186
+505400 6285900 198
+489200 6321100 126
+461300 6300800 138.5
+506800 6274600 212.5
+460300 6295400 143
+502200 6261200 264
+526900 6311900 193
+450100 6312400 119.5
+522800 6262800 243
+486200 6311600 156.5
+532700 6280900 213
+490200 6268300 212
+536900 6273500 195.5
+507500 6261300 263.5
+524800 6301900 149.5
+522500 6270100 241
+469500 6269000 206
+477900 6261700 273
+490100 6271900 203.5
+449600 6283800 148
+472500 6285200 198
+498300 6330000 129.5
+493100 6307300 149.5
+457100 6288200 114.5
+461900 6304500 158.5
+520500 6290500 175
+510000 6264400 259
+506700 6331800 122
+535600 6286600 183
+503900 6321400 128
+453400 6284100 172.5
+502800 6324300 137.5
+526800 6276100 210.5
+509000 6293300 154.5
+482900 6269200 226
+509100 6252300 292
+537300 6276600 196.5
+496000 6322500 153.5
+464900 6280600 187.5
+504900 6294200 172.5
+470300 6279200 202.5
+474600 6266300 262
+511000 6266400 250.5
+531900 6290100 172.5
+503600 6326800 140
+539000 6284800 192.5
+477900 6325500 122
+461500 6283000 154
+485000 6264600 248
+517100 6283300 205.5
+502500 6319100 150.5
+490900 6258400 221
+453500 6298100 132
+451000 6289000 151
+536900 6260200 252.5
+523700 6295800 169.5
+506000 6307400 139
+464000 6298300 152.5
+520500 6303600 173
+521100 6285500 185.5
+534000 6259400 241
+509700 6255700 289
+509000 6317900 145.5
+541600 6269400 216.5
+536700 6271000 186.5
+461800 6279900 166.5
+485000 6267900 230
+515700 6272800 233
+520100 6282200 191.5
+494400 6272800 210.5
+494500 6269000 223
+468500 6290300 185
+525100 6324400 110
+535500 6263200 220.5
+488500 6300900 152
+540200 6264300 257.5
+471200 6265700 216
+503900 6262000 247
+479200 6259100 271
+482300 6267100 231
+538700 6291000 178.5
+537000 6293500 174
+466600 6296000 175.5
+534800 6262400 223
+479000 6263500 265.5
+501100 6280100 203
+511400 6288400 191
+482000 6262700 245
+481200 6271800 220.5
+490900 6276700 184
+494400 6295600 188
+508200 6322500 133.5
+523900 6294000 164
+458400 6292100 149.5
+471000 6281500 207.5
+540200 6274400 190.5
+494800 6256500 242
+512100 6308400 132
+538100 6289200 180.5
+445300 6286200 166
+469800 6276300 190.5
+453200 6303600 114
+497500 6256800 293.5
+536900 6279700 198
+482100 6320100 114
+485100 6308300 170
+446700 6316600 110.5
+484100 6254500 306
+496600 6315800 179.5
+504400 6328900 142
+497400 6318200 166.5
+507300 6278900 213
+453800 6291900 141.5
+515800 6301000 155.5
+518600 6296700 205
+495400 6298600 173.5
+529000 6299100 149.5
+519900 6268500 234
+517700 6303300 165
+520700 6305800 158
+508700 6250600 305
+489600 6312700 138
+503900 6278100 198
+504100 6266900 220.5
+455600 6314200 124.5
+513100 6325600 142
+486000 6257400 247.5
+455700 6300200 118.5
+456000 6286900 126.5
+524700 6266900 257.5
+499800 6298900 185.5
+456000 6284500 174
+531500 6292800 168.5
+473500 6305600 173.5
+504900 6325700 126
+509000 6268700 242
+511200 6291100 189
+516600 6263900 251.5
+479000 6288200 182
+523300 6288600 160
+472700 6291000 194
+536100 6296000 158.5
+528600 6283100 188
+490200 6252900 273
+507300 6276600 211.5
+507000 6298400 142.5
+499600 6278500 208
+449700 6293000 145.5
+474200 6277400 216.5
+470300 6303900 175
+448900 6290400 102
+506600 6273100 199.5
+538400 6284500 204.5
+450500 6318300 120.5
+495600 6326500 151.5
+444300 6308900 103.5
+487700 6271000 211
+520800 6312900 143
+532800 6272900 205.5
+520000 6273900 223.5
+531500 6286200 183.5
+550500 6278600 249.5
+460600 6276800 184
+531000 6259500 246.5
+513500 6270200 242.5
+534800 6292300 176
+513900 6304700 135
+511700 6257300 276.5
+493200 6304000 159
+511600 6322700 145.5
+501100 6252700 281.5
+474000 6257000 252
+515500 6259200 268.5
+475700 6296200 172
+520600 6309200 144
+473100 6259900 241.5
+524000 6309600 159
+503700 6288500 196.5
+516800 6322700 133.5
+457500 6282800 134
+491400 6316300 144.5
+482800 6305600 158
+447500 6302500 106
+526900 6328700 131
+502200 6291100 207
+516100 6277900 224
+482400 6295000 165
+440200 6290900 124
+449300 6305800 106
+513400 6300000 153.5
+537200 6287500 185.5
+523400 6306300 149.5
+530800 6303000 158.5
+480600 6295700 158
+496100 6306200 163.5
+498200 6253500 306.5
+442300 6296200 122
+470000 6313900 149
+457100 6296000 128.5
+523500 6316100 171
+486400 6261500 259.5
+529600 6275100 223.5
+437100 6286100 137.5
+463000 6285000 162
+515900 6260900 256.5
+484200 6279100 200.5
+526900 6260200 235.5
+464800 6273300 181
+474600 6270800 207.5
+484400 6273900 215.5
+514100 6297600 179.5
+470500 6266500 214.5
+516200 6286800 207
+490600 6262300 227
+453000 6312000 139
+476900 6266600 238.5
+471300 6286800 188
+528400 6273900 222
+499400 6313400 165
+476900 6304000 162
+529000 6294700 158.5
+520700 6294000 181.5
+502100 6294200 200
+450800 6296900 129
+540000 6277600 183.5
+463500 6276900 177
+441900 6283300 167
+524800 6280400 189.5
+502900 6304800 180
+449300 6299200 122
+454600 6316600 125.5
+509200 6302200 135.5
+458100 6280600 166.5
+484100 6319900 126
+489700 6307700 146.5
+488700 6295400 165
+447900 6310300 103
+444000 6302500 120
+534800 6278800 205.5
+478300 6309400 136.5
+488200 6275800 197.5
+464200 6302400 170
+537400 6262100 244
+505400 6256900 267
+453100 6295300 136
+541900 6290900 201.5
+525500 6267600 245.5
+489700 6256700 250.5
+505300 6251200 308.5
+505600 6282000 196
+512500 6255900 285.5
+511000 6299800 147.5
+455200 6306100 133
+438600 6283200 161.5
+458800 6311800 129.5
+461100 6311700 147
+487600 6265300 235.5
+471600 6269500 216
+521300 6279700 196
+488700 6283500 178
+527000 6306500 159
+521400 6266400 245
+457800 6303000 130
+531300 6305900 159
+491000 6279800 204
+549300 6275500 238.5
+526100 6278700 199.5
+491600 6313500 134
+446700 6307900 98
+509400 6259800 273.5
+504200 6254200 274.5
+520400 6300300 174
+456400 6297800 125.5
+526500 6264300 240.5
+538100 6268600 212
+511500 6326900 133.5
+448600 6301600 108.5
+520000 6324700 153
+471900 6313800 140
+401000 6419500 47.5
+449200 6443000 36
+410900 6413800 39.5
+415800 6424900 14.5
+452800 6392200 65
+442700 6423000 39.5
+444100 6429300 15
+401100 6396800 62
+429100 6442300 44.5
+452400 6370900 115
+465800 6418600 43
+398000 6433700 46
+421600 6383200 57
+453500 6426800 61
+446200 6439400 37.5
+458600 6436000 50.5
+464100 6407800 94
+435400 6398100 13.5
+426600 6406500 12.5
+433700 6440900 38.5
+438300 6441000 33
+455800 6414300 52.5
+443100 6416400 51
+462100 6393600 84.5
+421400 6421500 41
+425000 6443100 22
+438200 6419200 68.5
+441000 6382700 71.5
+442000 6389100 36.5
+415100 6457800 31
+399800 6457400 22.5
+421800 6440800 4
+438000 6413300 85
+453100 6424000 55
+458900 6399000 54.5
+413300 6451600 39.5
+435600 6404600 58.5
+463500 6436000 74.5
+429400 6426200 47.5
+444800 6433400 9
+464400 6398400 61
+437200 6433200 40.5
+450900 6426500 55
+442100 6416500 44.5
+456700 6410200 76
+416100 6460800 14
+432400 6411800 60.5
+441800 6430300 42.5
+419400 6407900 33.5
+444900 6379900 81
+441200 6403700 60
+461200 6439700 17.5
+442900 6446600 59.5
+437400 6445400 40.5
+413900 6414600 30.5
+455900 6432700 53
+399300 6468500 20
+413300 6441700 9.5
+443100 6418800 43
+466600 6388700 60.5
+444300 6388900 28.5
+428500 6422800 53
+415000 6459200 16.5
+458300 6424700 60
+455500 6404100 72.5
+450500 6395100 76.5
+449400 6387300 35.5
+457700 6396400 48.5
+457200 6388400 37.5
+463400 6411600 81
+438100 6387300 53
+449900 6410800 53.5
+433500 6388700 42.5
+444000 6402400 69.5
+404300 6469300 15.5
+443000 6405500 60
+457600 6370100 107.5
+423400 6450700 29.5
+422300 6376000 65.5
+461800 6388300 23.5
+458800 6391700 69
+462000 6404100 72.5
+464500 6389800 61.5
+448200 6419700 41.5
+441100 6413100 81
+455800 6388500 38.5
+463600 6439500 43.5
+453700 6442800 39
+447600 6418000 49.5
+441300 6397600 70
+444900 6382600 81
+462900 6431900 62
+458100 6426700 65
+398800 6384800 47.5
+464600 6441200 48.5
+455500 6424800 51
+463200 6398300 55
+458400 6387600 39
+418400 6449600 65.5
+417100 6447400 55
+426300 6415000 44.5
+432500 6384900 58.5
+432300 6381300 58
+454100 6422200 11
+384700 6401800 22.5
+444100 6390500 15
+431000 6449300 39
+432000 6402100 17.5
+438400 6427500 20.5
+423200 6419000 44
+451400 6421300 8
+395300 6484900 9
+417200 6421800 21.5
+450700 6381200 72
+427800 6436100 21.5
+446900 6374700 83
+439300 6435200 46
+478200 6417300 60.5
+429300 6451700 29.5
+427700 6408900 49.5
+451400 6397900 67
+452600 6435200 42
+440800 6425900 21
+388700 6481500 8
+420500 6448500 50
+432400 6394400 32
+449000 6431300 32
+444600 6361900 83.5
+463200 6428200 59
+400600 6480200 8.5
+430400 6419400 67
+420200 6459400 28.5
+390500 6486500 7
+393600 6477400 20
+409400 6439900 23
+450500 6414200 53
+410600 6444700 12
+438000 6372500 70.5
+394700 6406700 48
+455500 6379800 83.5
+438500 6397500 55.5
+419500 6418400 10.5
+450900 6375800 90
+440200 6421200 42
+430700 6406700 51.5
+431900 6447500 36
+435600 6419000 64.5
+421300 6446500 37.5
+483000 6418000 66.5
+433000 6372400 59.5
+431800 6378900 37
+442800 6441600 43
+442000 6392900 52.5
+415400 6440900 13
+415800 6434300 7.5
+451300 6406400 68.5
+436500 6399300 46
+454900 6373600 105.5
+382100 6406400 29.5
+457700 6376900 84.5
+460400 6399500 48
+439800 6373300 105.5
+400900 6443600 30.5
+424200 6402900 35
+481100 6414000 93.5
+424200 6376400 49
+460900 6437900 56
+416700 6445900 41
+422500 6428900 29
+431100 6387400 41
+454700 6386800 39
+414000 6458000 17
+447800 6401000 83.5
+446300 6372500 91
+444600 6406600 77
+448500 6409900 49
+409400 6387600 65.5
+406100 6430600 37
+381900 6450300 32.5
+409700 6425900 27.5
+480900 6418500 66
+449200 6361900 108.5
+442200 6379800 84.5
+444000 6404600 75
+456800 6372200 106
+476600 6414400 78
+432700 6405000 49.5
+391500 6475200 20.5
+452700 6396500 50.5
+417100 6472200 28.5
+449200 6412500 42.5
+424000 6412300 44
+431700 6441300 35
+412200 6454300 20.5
+395300 6480500 9
+468500 6409200 82.5
+422100 6408400 27
+454800 6392000 50.5
+421700 6455200 52.5
+424300 6445000 23.5
+371400 6401200 50.5
+450100 6401500 87
+460100 6409600 74.5
+418100 6396100 49.5
+426700 6426000 56
+411800 6427200 24
+483400 6420600 22
+450300 6373700 91.5
+449700 6377900 84.5
+459200 6396900 53.5
+422400 6400700 41
+465400 6437100 49.5
+413500 6461100 18
+449500 6385200 40
+414600 6463500 16.5
+407700 6451000 9.5
+405800 6462600 14.5
+444400 6375500 78.5
+429900 6466800 52.5
+442000 6442200 36.5
+369700 6404200 22.5
+420800 6471400 37
+447600 6431000 23
+456500 6396900 47
+416100 6457900 21.5
+429000 6454700 56
+420000 6444200 41
+428900 6391200 48
+383100 6494000 8
+424900 6459300 41.5
+439400 6431100 40
+448200 6398200 79.5
+427700 6419700 52.5
+436900 6398500 47.5
+377500 6401200 14
+453600 6440100 35
+436800 6403300 80
+466800 6440800 64
+467600 6395600 73
+448500 6441300 8.5
+429600 6430100 29
+384000 6485700 15
+432500 6429200 33.5
+376400 6413200 15.5
+406600 6428700 28.5
+439900 6360100 102.5
+479100 6411100 95
+465200 6446800 66
+467500 6391300 73
+415500 6454300 44
+415000 6401300 47
+440900 6389700 17.5
+433600 6436900 27.5
+426800 6443300 24.5
+403100 6472400 12
+449100 6406300 58.5
+420000 6476100 59.5
+458100 6449700 47
+423800 6469400 44.5
+459400 6406900 79.5
+418900 6460300 21.5
+381000 6400900 17.5
+413000 6430100 19.5
+428100 6411600 61
+384400 6469700 30.5
+378100 6498600 12.5
+434200 6420500 61.5
+437700 6423000 41
+424100 6424000 55.5
+445400 6409600 84
+399000 6463200 19
+372800 6415900 18.5
+426400 6422600 57.5
+399500 6474900 18.5
+418800 6474700 49
+482400 6410800 90.5
+432000 6454800 63.5
+445800 6418300 43
+383200 6502200 18
+430400 6408200 48.5
+454000 6415800 45
+451000 6447500 48
+397100 6473000 17.5
+451800 6358500 112.5
+434000 6409500 56
+446900 6407800 61
+414800 6426900 16
+473100 6413500 64.5
+421500 6459600 34.5
+394800 6478500 14
+412300 6443200 11.5
+465300 6392700 73
+432500 6452100 63.5
+431600 6421700 59
+445900 6442500 42.5
+447100 6411900 53.5
+462800 6401500 67.5
+443600 6414700 59.5
+440900 6400100 78
+440200 6418600 45
+441100 6416000 71
+439100 6375700 100
+452700 6390500 12.5
+460400 6416600 53.5
+452600 6388300 34
+471500 6398800 72.5
+421300 6434400 3
+445600 6421600 39
+410700 6435100 21
+436800 6438000 40
+469100 6417800 54.5
+435700 6441700 44
+449700 6409300 64.5
+459300 6389000 34
+453300 6401800 67
+410700 6383800 74.5
+449100 6404200 69.5
+461000 6398700 49
+421000 6450000 54
+450500 6391400 58.5
+462700 6432700 62
+435900 6439900 45.5
+425400 6418900 48
+415500 6378800 76.5
+401800 6422900 34
+380300 6490900 17.5
+444700 6413200 64
+459600 6369200 126
+440700 6396100 72
+399400 6465900 19
+452800 6355100 109
+382200 6481100 28.5
+427800 6397300 42.5
+396300 6476700 20.5
+448500 6389400 28
+436600 6434300 36.5
+447500 6394600 75
+425000 6408900 3.5
+425000 6448600 27.5
+427300 6441400 26.5
+433000 6443500 38.5
+460700 6384200 46
+451800 6417600 48
+474100 6398200 64.5
+439900 6400200 61
+381500 6462300 32
+440000 6380800 78
+459100 6439800 37.5
+415700 6467500 14.5
+404200 6444300 27.5
+440000 6447000 47
+430000 6444400 32
+407000 6448400 9.5
+475100 6418000 59.5
+378600 6439400 33
+422000 6426200 32.5
+445100 6437500 31
+447600 6445300 44.5
+466000 6416800 55
+423300 6427900 32.5
+452900 6413700 52.5
+435600 6376900 64
+417900 6415300 22
+452700 6424400 58
+471000 6401400 66.5
+460900 6428400 77.5
+442800 6403000 65
+436200 6406900 66
+441200 6392000 49
+463800 6396700 61
+438500 6392800 30.5
+456700 6394800 52.5
+454300 6377200 102
+420500 6404300 35
+443600 6370800 96.5
+387700 6397300 34.5
+408600 6411800 50
+419200 6448000 52.5
+440500 6369900 84
+461800 6387400 37.5
+461100 6449100 56.5
+453000 6385300 66.5
+401800 6448800 26.5
+434400 6417100 70.5
+432000 6435400 32.5
+468600 6416100 65
+425000 6431100 17
+462400 6414900 69
+423500 6415600 37
+427200 6405700 17.5
+454000 6396700 50
+424300 6454000 43.5
+434500 6387000 51
+447400 6389000 27
+421900 6389400 73.5
+461300 6444600 57.5
+433900 6446600 49
+435300 6436300 19
+480100 6419600 13.5
+431800 6417600 75
+459500 6413200 63.5
+438100 6401100 60
+467500 6413900 67.5
+469500 6411900 74
+455800 6400700 68.5
+426000 6429200 35
+454500 6399800 55.5
+466200 6411400 75.5
+461900 6391000 62.5
+475100 6408800 97
+441700 6409300 77.5
+415000 6409800 37.5
+430700 6412900 64.5
+424300 6407300 19
+416300 6418600 20
+436400 6365800 87
+430300 6415000 71.5
+412900 6418500 34
+447000 6433600 21
+453900 6369800 119.5
+424900 6465500 36
+461400 6402400 49
+416800 6456300 31.5
+380500 6408700 27.5
+414700 6449300 26
+446700 6357700 101.5
+418300 6445600 43
+416600 6385700 71.5
+431000 6433900 16.5
+434800 6430200 11
+459500 6421800 53
+439100 6383200 61.5
+454000 6419200 9
+439700 6393700 59.5
+412100 6422600 32.5
+433700 6390400 16
+473600 6412800 80.5
+470500 6395000 86
+457500 6417100 48.5
+384600 6489300 6
+448400 6415000 48.5
+484100 6413400 78.5
+463000 6406200 93
+430600 6366100 104.5
+444500 6397100 78
+450300 6419200 32.5
+454700 6389300 28
+449700 6389800 31
+454200 6374100 111
+424900 6369200 81.5
+390300 6477300 13.5
+456100 6368600 122.5
+408900 6446400 11
+440000 6405300 72.5
+439900 6432600 58
+457600 6429700 73
+424100 6413400 41
+400700 6476400 7.5
+445600 6399600 81.5
+391200 6383600 30
+448500 6405300 63.5
+410400 6429500 21.5
+406200 6458700 14
+436200 6417200 75
+406700 6453000 14.5
+443100 6395700 77
+441500 6448400 66.5
+429000 6416700 56
+415400 6447100 33
+468600 6398900 64
+433400 6450300 49.5
+440500 6423300 27.5
+403300 6447100 24
+425900 6409700 44
+433800 6424700 47
+472800 6416800 54
+435200 6414000 80
+448300 6363700 100.5
+454800 6395100 43.5
+433400 6404200 48
+398700 6479000 8
+441700 6434400 41
+456500 6390700 12
+455600 6417400 42.5
+413800 6456300 20.5
+460700 6424500 57.5
+418000 6451800 51.5
+456500 6419300 6
+442200 6437800 29
+430700 6407100 42.5
+393900 6437100 37.5
+421000 6423800 39
+439000 6431600 40
+461500 6420400 47.5
+377000 6427700 25
+442300 6413800 56.5
+458000 6423000 48.5
+461600 6430900 73
+449300 6417200 45
+448200 6411300 44.5
+468000 6400100 66.5
+449000 6391200 59.5
+392800 6391200 41.5
+449700 6379300 82.5
+450000 6382400 68.5
+466500 6409100 78.5
+385300 6432400 31
+467000 6403800 78
+461500 6426900 59.5
+426500 6434400 4.5
+434300 6401700 59.5
+431000 6403100 18
+448100 6424600 10.5
+450500 6404800 75
+434100 6435400 31.5
+459200 6414900 51.5
+466100 6396600 60
+459700 6394700 75.5
+445100 6392600 59
+372200 6419000 21.5
+416100 6449200 46
+446000 6416500 56
+420800 6469500 19.5
+428500 6438700 37.5
+446600 6391000 57.5
+460200 6401500 62.5
+426200 6382400 41
+419600 6464600 12
+428800 6405600 19.5
+437100 6395500 12
+385000 6427900 38
+434000 6400300 13.5
+437300 6450900 62
+390100 6445700 33
+416000 6437900 8
+447400 6437600 25.5
+464100 6416300 63.5
+453200 6430600 57.5
+456300 6445800 18
+447600 6381200 72
+430500 6441000 41.5
+420700 6412500 19.5
+781400 6280200 25.5
+744400 6289200 279
+776800 6274500 6
+667600 6247900 532.5
+709800 6247900 61.5
+693100 6273000 454
+715600 6289900 501
+680400 6244400 136.5
+734400 6251500 42
+791900 6293400 38.5
+789100 6293200 41
+727900 6296500 461.5
+772700 6282300 56
+737100 6284900 100.5
+722200 6295000 515.5
+724100 6277500 319
+762700 6272700 113.5
+781700 6285200 35
+756900 6315300 339
+739600 6275200 58.5
+737000 6282900 95.5
+763500 6314500 340.5
+727700 6263500 76
+698100 6271300 408.5
+764100 6309100 313.5
+737700 6253900 45.5
+732500 6291700 302.5
+749100 6267100 133.5
+782900 6299200 60.5
+787100 6296200 48
+755400 6262600 98
+730400 6296800 501
+683200 6267300 656.5
+761800 6286800 169.5
+795000 6285800 5.5
+758400 6295100 253
+732100 6275200 204
+770700 6290100 113
+708900 6300500 623.5
+729700 6258000 61.5
+708000 6295400 636
+782200 6297400 143
+782300 6292600 76
+737100 6299000 697.5
+729800 6255300 38
+756800 6294100 346
+785100 6296600 50
+712800 6279700 352
+769200 6285900 92.5
+738200 6280600 45
+754500 6281000 225.5
+711700 6260200 119.5
+670500 6246400 344
+722000 6288100 443
+783700 6292200 74
+713700 6266700 142
+749800 6290800 268.5
+730700 6271300 136.5
+719900 6274100 317.5
+686300 6269500 664.5
+773900 6304900 197
+709500 6286000 573
+728800 6280100 348.5
+685300 6248700 170.5
+725100 6267400 147.5
+773400 6274900 12.5
+681000 6243500 172.5
+720700 6283800 406.5
+721300 6260100 91.5
+745300 6276000 169.5
+696400 6274700 585.5
+715300 6274100 357
+695700 6258100 366
+712300 6272500 362.5
+720500 6256900 77.5
+777900 6282800 36.5
+713800 6253900 47.5
+763000 6279400 114
+679400 6250600 370.5
+709300 6277100 349
+697000 6249700 124
+730700 6260800 57
+726700 6270600 200.5
+741000 6274400 63
+788100 6287100 28
+715900 6269400 172.5
+692400 6248800 133
+735400 6266100 49
+695200 6250700 142
+669200 6254100 642.5
+676000 6278000 875
+731100 6306400 754
+738600 6245800 55
+764500 6266000 108
+704200 6261200 141.5
+670100 6256000 622.5
+717100 6300200 653
+717500 6249400 62
+724200 6304100 712
+725500 6280100 312.5
+703300 6252100 122
+707000 6263900 218
+716800 6260100 101
+754800 6260400 84.5
+787000 6292700 58
+691800 6265100 465.5
+768600 6293800 102.5
+715600 6255700 80
+723000 6281800 304.5
+713800 6258100 73.5
+786600 6284200 8
+715700 6293200 562.5
+739600 6278200 40
+740400 6254800 34.5
+737000 6267600 20
+680600 6265500 649.5
+762600 6275000 33
+749000 6258800 37.5
+729300 6275400 278.5
+678700 6247300 170.5
+722100 6268300 171
+723300 6289800 360
+756500 6256400 88
+703600 6247700 60
+744300 6292900 433
+674900 6272500 942.5
+758500 6311800 221
+747200 6300900 470
+687600 6261300 547.5
+718000 6263600 139
+776000 6305500 145.5
+733800 6255400 40
+724200 6258700 61
+706300 6245400 57.5
+753300 6305700 529.5
+697700 6285400 756.5
+781600 6295800 62.5
+720400 6276700 347.5
+715100 6259100 102.5
+739400 6272700 50.5
+694000 6274500 619
+726100 6296300 422
+766600 6275600 34.5
+729800 6281900 336
+706100 6267800 400
+703800 6278200 491.5
+776900 6297200 191
+718100 6272600 289
+736700 6286500 179
+734600 6270800 67.5
+727500 6284700 219.5
+719200 6257700 74.5
+742000 6270000 119.5
+726000 6300500 522.5
+759500 6278600 151
+725700 6292600 408.5
+758200 6314000 307
+749700 6303500 475
+688400 6270300 654.5
+710400 6243200 61
+788600 6291400 40
+709600 6279900 334
+741300 6256300 36.5
+768300 6287500 96
+700300 6285300 697.5
+708400 6275800 394.5
+724800 6265400 91
+773500 6285000 65
+771700 6284700 75.5
+698200 6258700 386.5
+708400 6285400 424.5
+737100 6271400 50.5
+718200 6241200 32
+707500 6286800 635.5
+734900 6278700 164
+762500 6303400 276
+734200 6262400 49.5
+672500 6246100 284
+693200 6253500 229.5
+744100 6279900 157.5
+744500 6283800 157
+779100 6293200 102.5
+692600 6259700 417
+734100 6290800 321
+765000 6288500 167.5
+785700 6286000 25
+719100 6262100 104
+763500 6297100 400.5
+756400 6283600 212
+688600 6279900 831.5
+721200 6243700 22
+690200 6273500 632.5
+780800 6290800 80.5
+754200 6265700 143
+771300 6304500 262.5
+691000 6255400 290.5
+790300 6283300 2.5
+697900 6256000 190
+770200 6300600 374.5
+702400 6244000 12
+783500 6289200 56.5
+732300 6279100 216.5
+765100 6276600 44.5
+756400 6309100 435.5
+718200 6281500 384
+774500 6291900 144.5
+722600 6261200 87.5
+728800 6294800 425.5
+709700 6250900 59.5
+757000 6272400 95
+761500 6276400 123.5
+683500 6248200 176
+720200 6252600 70
+708200 6254800 110
+727300 6245100 20.5
+759200 6311000 300.5
+739100 6290300 419.5
+765400 6301800 339.5
+738400 6286400 110
+734200 6295000 489.5
+754300 6289000 305.5
+700200 6286900 722
+760600 6298300 283.5
+779200 6287100 87
+756300 6268800 164.5
+728500 6292200 336
+761200 6261200 111.5
+742800 6250900 16.5
+741700 6305500 509.5
+775800 6283600 56
+770800 6279500 64
+748300 6278400 202.5
+742500 6273400 100
+737600 6268900 24
+783000 6285900 27
+722800 6246200 26.5
+765200 6292700 180
+781600 6300000 139.5
+769600 6270700 65
+686400 6254100 468.5
+703200 6283700 610
+722500 6242300 12
+674600 6261100 626.5
+778200 6284800 55.5
+757900 6286200 191.5
+734300 6299400 570
+742200 6286200 87.5
+747300 6287500 201.5
+712800 6252000 50
+712000 6283800 474.5
+772700 6307400 272.5
+683700 6278600 773
+724400 6284000 417
+749700 6261400 85
+758100 6273500 174.5
+791600 6287100 27.5
+718800 6285400 478.5
+789900 6284900 5.5
+764700 6283500 108.5
+719800 6267000 174
+729900 6267600 96.5
+696500 6265700 405
+736300 6274200 88.5
+676700 6263900 640
+741600 6268400 101.5
+777000 6295100 130.5
+787700 6274100 1.5
+725300 6288400 241.5
+711400 6246000 60.5
+741400 6280000 63.5
+702300 6258400 174.5
+773200 6297500 212.5
+708400 6280900 449
+772500 6289600 111.5
+735500 6259600 53
+688100 6248700 163.5
+722600 6265000 114
+758800 6316800 441.5
+700800 6275700 570
+705800 6280300 449.5
+750200 6310100 558
+769900 6297100 239
+724700 6247200 25.5
+740800 6288600 453.5
+714500 6263300 104
+743200 6280200 88.5
+760200 6288100 189
+735200 6283200 153
+734000 6246000 16.5
+706400 6277600 316.5
+765400 6279700 88.5
+756400 6314100 327.5
+724500 6272600 276.5
+725700 6307200 770
+698900 6260900 363.5
+739100 6264800 90
+773600 6299900 164.5
+780900 6297300 86.5
+713900 6241600 45
+732900 6258100 40.5
+731900 6289900 244
+721600 6304800 746.5
+738000 6288500 419
+713400 6288200 511.5
+678100 6242800 105.5
+752000 6285200 251.5
+700900 6252900 137
+783900 6283600 12.5
+702500 6266800 393.5
+764800 6268000 98
+737500 6263100 56
+740300 6271000 70.5
+676900 6247400 235.5
+710100 6271800 419.5
+786200 6280700 3.5
+740600 6283500 74
+742400 6277200 93
+734900 6281000 181
+678400 6254300 444
+733600 6276400 200
+678900 6257600 587
+704900 6275600 271
+752100 6300900 354
+676000 6255900 525.5
+718500 6302200 715.5
+732200 6310500 670
+698600 6275100 592.5
+758900 6299400 289.5
+753300 6261200 30.5
+769700 6289300 93.5
+774900 6287700 83.5
+780600 6294400 78
+767200 6295200 265.5
+729300 6307800 730.5
+733000 6268300 75
+722300 6273700 303.5
+757500 6267000 121
+723900 6261200 74
+682100 6250400 297.5
+723600 6238700 5
+775300 6270500 1.5
+723300 6297700 528.5
+789700 6292100 42
+350000 6759500 65.5
+383800 6774700 76.5
+319900 6754000 48.5
+320000 6779100 98
+394800 6811900 156
+381500 6824500 146
+350100 6810200 85.5
+328600 6752300 51
+392100 6812300 129
+366200 6820600 48.5
+356000 6768600 77.5
+336800 6746600 49
+381200 6793000 97.5
+385700 6771400 79.5
+395100 6790200 122
+361500 6841900 51
+351900 6789600 47
+341300 6794700 65
+360400 6763300 69
+359800 6809100 81.5
+384300 6758900 92.5
+323400 6766300 59
+340000 6807900 116
+329400 6806200 90
+318500 6740200 36.5
+332300 6776500 86
+336000 6823900 57.5
+345400 6765600 61.5
+331300 6850300 25.5
+360500 6755000 67.5
+323800 6849300 32
+366400 6776800 59
+327300 6848900 28
+318500 6806800 90.5
+343000 6852800 28
+352900 6844200 5
+339200 6831200 56
+387000 6770600 70.5
+374100 6775900 68
+329900 6757000 56
+337900 6758200 59
+358000 6774100 62
+320200 6765100 56.5
+344600 6801800 73.5
+333400 6841500 36.5
+377300 6814600 85.5
+380100 6820200 114
+383400 6766700 84.5
+392800 6815900 167.5
+333900 6751800 63.5
+338300 6835100 35
+373100 6783500 69.5
+329400 6801600 82
+351700 6793700 58.5
+325200 6800700 79.5
+385400 6821300 151
+349500 6794500 48
+369900 6817700 68.5
+357400 6781600 46.5
+348600 6822600 74.5
+379100 6770500 66.5
+355900 6820700 63
+328700 6772800 86.5
+364900 6804600 79
+368300 6763000 77
+333500 6844700 30.5
+388500 6805300 119.5
+387800 6815800 121.5
+368700 6782200 61
+346200 6844700 5
+344000 6810200 73.5
+365300 6799900 76.5
+354300 6804500 68.5
+356300 6800300 61
+318500 6802100 95.5
+377500 6826600 106
+331600 6793500 79.5
+339200 6809700 97
+316600 6793300 89
+311800 6794200 91
+383900 6788000 79.5
+375600 6788600 77
+352000 6776800 68.5
+385100 6791800 89
+366100 6832900 54.5
+348200 6844200 5.5
+334600 6839000 26.5
+364400 6771800 74
+334400 6809700 131
+338600 6852900 26
+333600 6790200 76
+399200 6778200 125.5
+360100 6800700 69
+342600 6815900 59
+335100 6763000 67
+359200 6819600 58
+359100 6757600 65
+383200 6813200 114
+346400 6780000 55.5
+359700 6794200 58
+348200 6774700 57.5
+341400 6798900 84.5
+375400 6797100 82
+371900 6827300 63
+357500 6767200 86.5
+327200 6747200 48
+342600 6810000 86.5
+372800 6766100 80.5
+367300 6828100 62
+380700 6801700 108.5
+350600 6827100 85.5
+385100 6805300 101
+387600 6810400 84.5
+392700 6804300 137.5
+355000 6797100 58.5
+384600 6820200 149.5
+369900 6771100 62
+350900 6816800 81
+346100 6769400 53
+323800 6797200 84.5
+331300 6770300 72
+361900 6837700 57.5
+369000 6822900 63
+337500 6809600 108.5
+339400 6845100 24.5
+325800 6793000 83
+352300 6824300 98
+322100 6793800 70
+389000 6814000 116.5
+338700 6778400 65.5
+367500 6814100 64.5
+353900 6750800 63.5
+371400 6808700 78
+337600 6789500 44
+392000 6797400 149.5
+382200 6779200 85
+379500 6791700 82.5
+379400 6784300 76
+387700 6781600 80
+343800 6783400 27
+377500 6780900 69.5
+385100 6796100 104
+324700 6758000 48
+382400 6782100 86.5
+314700 6781200 160
+365100 6759900 65.5
+353100 6781700 35.5
+354500 6807100 79.5
+342800 6831600 46
+363200 6835700 49
+348600 6840500 31.5
+362900 6760200 67.5
+337600 6815700 58
+356400 6762100 64
+382900 6830000 131
+380000 6759700 90.5
+392900 6820600 157.5
+385000 6826900 149.5
+323200 6791300 66.5
+318900 6791300 71
+354000 6811000 73
+353400 6833600 59
+393100 6785600 116.5
+356000 6833800 63
+377600 6799800 92.5
+367700 6780900 63
+381800 6805700 90
+356800 6841900 51.5
+372100 6812300 69
+337600 6783100 50.5
+369800 6776900 58.5
+329100 6766900 63
+353400 6778900 34.5
+349000 6750700 63.5
+397900 6785900 145.5
+341400 6807300 100.5
+380200 6795000 98
+363200 6783200 60
+332800 6798100 75.5
+337100 6843300 28.5
+342900 6820200 53
+385200 6807100 87
+361800 6823800 63
+352000 6763700 61
+392500 6773400 81
+347000 6801500 76.5
+339000 6848700 30
+386900 6788700 91.5
+355800 6772900 73.5
+329400 6802000 94
+380400 6808600 77.5
+336900 6801900 101
+339500 6797300 87
+377000 6821200 102
+327100 6843000 46
+345200 6793800 59
+330000 6796300 57
+330500 6842400 30.5
+347900 6829100 75.5
+315800 6798900 85.5
+361200 6831700 75
+343300 6788800 33
+368300 6789500 62.5
+386700 6831500 137
+341600 6840400 7
+329400 6785600 82
+381500 6764300 83
+324700 6776700 94
+323600 6784800 122
+389500 6776200 88
+368600 6827200 45
+349400 6778500 30.5
+345300 6755300 56.5
+371800 6772400 58.5
+342300 6763800 59.5
+336900 6827600 66.5
+394600 6806100 139.5
+334700 6798500 77.5
+375600 6815600 85.5
+380400 6785800 75
+334600 6815500 79.5
+378800 6824100 115.5
+338500 6747700 43.5
+329000 6845900 27.5
+349300 6804600 93.5
+394100 6809100 96
+374600 6770000 62
+344700 6837800 25
+345200 6805000 92
+346300 6790500 44
+347700 6835600 51
+378700 6767200 67
+341900 6791500 41.5
+380500 6813400 108.5
+390600 6829100 162.5
+396500 6823800 153
+332800 6785800 60.5
+363500 6763700 76.5
+361500 6803200 60
+391300 6831600 155.5
+350600 6787100 32.5
+352400 6821000 67.5
+395400 6828100 147.5
+340000 6841700 25
+358500 6842000 50
+366600 6788200 52.5
+369300 6767000 74
+326000 6762200 43
+355400 6826700 74
+363500 6788700 61.5
+320700 6789200 81
+339900 6804900 96.5
+336900 6775500 74.5
+370300 6796300 83.5
+332600 6781300 80
+357900 6802400 54.5
+335900 6794100 48.5
+364500 6833100 61
+342600 6846500 6
+342400 6773900 57
+356300 6813300 80
+344000 6823300 57
+352100 6769900 80.5
+364600 6839400 43
+334000 6812500 128
+356500 6809400 69.5
+330400 6810300 118.5
+355700 6765100 72
+380800 6810200 89.5
+326200 6771400 83
+376500 6809300 79.5
+356500 6786500 54.5
+343100 6843800 4.5
+327200 6766300 67
+330400 6761700 43.5
+357600 6790000 54.5
+365000 6809200 78.5
+326400 6797800 70.5
+342300 6836100 40
+374700 6786200 68.5
+319900 6745900 44.5
+349600 6781400 33
+340400 6758100 46
+384300 6768600 71
+370600 6814000 69.5
+399300 6818200 196
+343300 6828500 66
+396500 6798500 150.5
+361400 6780900 48.5
+377100 6756300 81.5
+373700 6804600 88.5
+330100 6744900 35.5
+342200 6805300 96
+324300 6808400 91
+384700 6800300 117.5
+376200 6807900 84.5
+389800 6799800 140.5
+324600 6804000 91.5
+337300 6822000 53
+357900 6777900 50.5
+325100 6744500 34
+358400 6805700 76.5
+364600 6781500 52
+381200 6766700 69.5
+341900 6814200 60.5
+337100 6812700 82.5
+364000 6813300 61.5
+367200 6817800 49.5
+361500 6771000 79
+335300 6819200 40.5
+386600 6802400 109
+333500 6810900 145
+377400 6791400 94
+342500 6767000 59
+388600 6768600 80
+390100 6822400 145.5
+388500 6793600 119.5
+338200 6791600 46
+321900 6847900 31
+351400 6801100 74.5
+358000 6822600 67
+320900 6771700 65
+368700 6803300 83.5
+337100 6769000 71.5
+345400 6746500 47.5
+336500 6840300 22.5
+390700 6781100 115
+349600 6838300 29.5
+394900 6783900 124.5
+353400 6838300 45.5
+348400 6796800 68
+362700 6791200 62.5
+373700 6814500 74
+396200 6813100 164
+380200 6776500 78
+388000 6826200 152.5
+361600 6817600 64
+373700 6779700 69.5
+395100 6775500 88
+367100 6763500 76.5
+356000 6776100 65.5
+356500 6829400 88
+394200 6794400 121.5
+339300 6786000 35
+332800 6805900 111
+327200 6782900 99.5
+314500 6800300 101
+372500 6788100 76
+373600 6816200 91.5
+339100 6819300 53.5
+340400 6810000 83.5
+350000 6764500 52.5
+382700 6755400 86.5
+566800 6657000 141
+586900 6653400 161.5
+587500 6600900 227.5
+599700 6656700 159
+621800 6617100 226
+590600 6650100 169
+579800 6615600 140
+583600 6678200 118
+634300 6614700 224
+608800 6611400 220.5
+593100 6598600 211
+550800 6636000 105.5
+604600 6616100 188.5
+589300 6680800 113.5
+610100 6593300 363
+604800 6663000 144.5
+576300 6591100 237.5
+607900 6620000 174.5
+605600 6678900 113.5
+589800 6684100 92.5
+605600 6676600 119
+613300 6599400 343.5
+585000 6617400 135
+603200 6665400 137.5
+628300 6618300 226.5
+599600 6613800 193
+624500 6614200 220
+625100 6606900 257.5
+579900 6644500 128.5
+566200 6652200 135
+613200 6607600 235.5
+615900 6617200 214.5
+544700 6623800 92
+584000 6602300 218.5
+574800 6634800 118
+617100 6644800 149.5
+626100 6661100 144
+594500 6680100 104.5
+588200 6670000 127.5
+630300 6605100 251
+597000 6603400 238
+579500 6675800 122.5
+555700 6624500 118.5
+579500 6654900 154.5
+587200 6664800 141
+598900 6598200 292.5
+556300 6659500 110.5
+576300 6652800 151
+599300 6660800 163.5
+560100 6647600 128
+595900 6642000 155
+601400 6637400 152.5
+550600 6648000 121
+591400 6674300 122.5
+555600 6648700 121
+610700 6627600 179
+619800 6638700 151.5
+541300 6616600 101.5
+568100 6642400 121.5
+543800 6628100 102
+591600 6644300 151.5
+604100 6605700 264
+573500 6640500 116
+563700 6587600 197
+558900 6640600 118.5
+589100 6604500 185
+592400 6602500 199.5
+576400 6594600 210.5
+612000 6615200 202
+618000 6636300 156.5
+610600 6668000 134
+628700 6593500 348
+601500 6667900 130.5
+623400 6650300 141.5
+598800 6609000 212
+613300 6604000 304.5
+630100 6643800 153
+634800 6608000 250.5
+593100 6646900 168.5
+576500 6600900 187
+625700 6639500 161.5
+576400 6597800 190.5
+561800 6644600 125.5
+609700 6636900 158
+546000 6621300 101.5
+585000 6652500 145
+574600 6600700 174.5
+549000 6618100 106.5
+634300 6599900 350.5
+576500 6616300 129.5
+600100 6635200 148
+580300 6621600 142
+596100 6645400 164
+622600 6633200 173.5
+583700 6630600 135.5
+569400 6594100 187.5
+633400 6604300 305
+580700 6600600 210.5
+627500 6665300 137
+547300 6620200 103
+613200 6643500 157
+627400 6592600 346
+618700 6605100 290
+598200 6684700 103
+573600 6649000 132
+588800 6609700 179.5
+622800 6642600 149
+620300 6608000 250.5
+563600 6637200 111
+595100 6614500 171.5
+584500 6681900 106
+568900 6597900 155.5
+609700 6664400 159.5
+609200 6677300 122.5
+578800 6627600 123.5
+617900 6660300 163
+541900 6629500 95.5
+558700 6659000 111
+617900 6649300 145
+600400 6671100 129
+613600 6640300 155
+600600 6622300 158
+621600 6666900 134
+581200 6650000 144
+606400 6607900 241.5
+621000 6626200 211.5
+582900 6660800 158
+587900 6655500 156
+586300 6661800 145
+620500 6638000 153
+590400 6607000 187.5
+608100 6600100 334.5
+600300 6681000 102
+588800 6639500 136.5
+622100 6653900 143.5
+558900 6607400 125.5
+563300 6597800 150.5
+603500 6598600 313.5
+561200 6655800 115
+602900 6610000 211.5
+586600 6623700 154
+602200 6630100 165.5
+550100 6621900 107.5
+622100 6612000 220
+552500 6608700 114
+591200 6594600 230.5
+586300 6612400 138
+616800 6654100 164
+628800 6609000 235
+598000 6679500 100
+579600 6588200 290.5
+552900 6640800 110
+603200 6651500 190
+614400 6618200 205
+585000 6603100 183
+561800 6605600 128
+612100 6657900 192.5
+569900 6588800 212
+584500 6656900 146
+605200 6658900 177.5
+625800 6656800 143
+632300 6592500 376.5
+565600 6650500 119.5
+602200 6643700 158
+606700 6641100 156.5
+583800 6615600 137
+568900 6645900 118
+617400 6663500 157
+563600 6623900 110
+598700 6673300 121.5
+579200 6616200 130
+597900 6596100 284
+553600 6610000 115.5
+598000 6664400 154.5
+586600 6610900 166.5
+589700 6617000 140.5
+596400 6609300 235.5
+565700 6615600 116
+624500 6602300 283.5
+574600 6666200 153
+576800 6605900 160
+628800 6615700 225
+581900 6671100 139.5
+622500 6609600 230.5
+596800 6621800 150.5
+625300 6609900 233
+551800 6616700 106
+615600 6630500 182.5
+580500 6602100 189
+593600 6607700 215
+589700 6599700 207.5
+597800 6680700 97.5
+629100 6658700 132.5
+543400 6624700 100.5
+620600 6632200 174.5
+614000 6665000 132.5
+632100 6605700 256.5
+607300 6631600 156
+571500 6625400 117
+623500 6598400 347.5
+610000 6616400 190
+631200 6602900 307
+588600 6668400 146
+592100 6605500 185
+570300 6659300 159
+560100 6616000 109
+550600 6628900 120.5
+571600 6650700 143.5
+634600 6597200 345
+628800 6598900 282
+570300 6602500 152
+616100 6611900 219.5
+602500 6677600 116
+607600 6663200 149.5
+613700 6650800 173.5
+632800 6620200 232.5
+579100 6658100 167
+574500 6616400 119.5
+608400 6673200 124.5
+589900 6626900 155
+590300 6657700 160
+628800 6646000 150
+553800 6630100 112
+608900 6649600 184
+569700 6614200 123.5
+580400 6596000 249.5
+602500 6592600 313.5
+619200 6599000 369.5
+559600 6635600 93.5
+624300 6617700 220.5
+627600 6632500 175.5
+582100 6639300 131
+548200 6612700 104
+596200 6634900 155.5
+616900 6665700 138
+613500 6634700 159
+609300 6664600 140
+594500 6653900 157.5
+620400 6615900 218
+592100 6662900 158
+631000 6655800 139
+561900 6591200 182
+544100 6612800 103.5
+599300 6677200 104.5
+590600 6637400 142.5
+582100 6658500 144
+585300 6645300 149
+539800 6707900 84.5
+548200 6693600 82
+537500 6688000 78
+531500 6683100 93.5
+514900 6697000 66.5
+524900 6702900 73
+519800 6696200 71
+532700 6689500 74
+547900 6703200 89.5
+548600 6706800 83
+488000 6674600 71
+548300 6694900 84.5
+490500 6690400 72
+524900 6721400 130
+486000 6690700 72.5
+505700 6694100 38.5
+504800 6691700 67
+508400 6697200 69
+529400 6678400 112.5
+509700 6664800 81
+537600 6729900 143.5
+534400 6697800 70.5
+563100 6686100 135
+510600 6683100 84
+532500 6667400 96.5
+513300 6663400 76.5
+532800 6672900 103.5
+542200 6641500 102
+493100 6720800 85.5
+537600 6704500 88.5
+519600 6670700 90
+548000 6671700 105.5
+522300 6675700 110.5
+482800 6691100 71
+545400 6711600 94.5
+483600 6677900 63.5
+541200 6718300 113
+530100 6707000 98
+552500 6708400 84
+553900 6709300 85
+525000 6655100 79
+515900 6654400 80
+553200 6702700 86
+551400 6663600 111
+523100 6715600 105
+527300 6708900 97
+543800 6628600 99
+491200 6677700 69.5
+545400 6696000 83.5
+545800 6662700 123.5
+536100 6681500 90.5
+503400 6653000 99.5
+507700 6708800 92.5
+539100 6640100 99.5
+556100 6669100 120
+543500 6717800 105
+539000 6656900 106
+555800 6663900 113.5
+532500 6698800 70.5
+505800 6669500 70.5
+537600 6633900 96
+498800 6663100 81
+489500 6692200 73.5
+496500 6690800 73
+564900 6667300 125
+478500 6683100 64
+500000 6688500 78.5
+542000 6656700 117.5
+543000 6701700 80
+510100 6671100 65.5
+527400 6695500 80
+514200 6685800 77
+525600 6701700 76.5
+564200 6676800 115
+517600 6707800 95.5
+541700 6648900 108
+546100 6677700 90.5
+528600 6701400 48.5
+543500 6686400 89.5
+500100 6721500 93
+503100 6675000 73
+514000 6692800 85
+523500 6697100 70
+489000 6670400 67
+508400 6687600 69
+514200 6660100 77.5
+499800 6693100 70
+519900 6710400 97.5
+510900 6725400 99
+496800 6666400 73
+527800 6670400 112.5
+522800 6708400 78.5
+498000 6722800 83
+518500 6688700 72.5
+493400 6690500 73
+493900 6675300 67.5
+520400 6689000 73
+539100 6725000 126.5
+555800 6677900 107.5
+492600 6720300 84
+543800 6673900 104
+530700 6704000 85.5
+512100 6696200 67.5
+525700 6684900 95.5
+549200 6715700 102
+527300 6727000 135.5
+563700 6674400 104
+556500 6682700 117
+509700 6675200 82
+516900 6683100 83.5
+494400 6667300 65
+510400 6727000 89.5
+530200 6643000 96.5
+498800 6719700 84
+509200 6656400 94
+499000 6676400 74
+507000 6662900 90.5
+516100 6730000 95
+526200 6663300 89
+537300 6718000 123.5
+537400 6696500 75.5
+533300 6640400 91.5
+541900 6665300 114
+525500 6713600 92
+537600 6667200 107.5
+498100 6708300 87
+502300 6662500 90.5
+521600 6713300 93.5
+497800 6668200 75
+549300 6668500 110.5
+514200 6664200 40.5
+504800 6672100 49
+542400 6683400 80.5
+539400 6685500 78
+533300 6713500 118
+523500 6731300 119.5
+482000 6679600 66
+490100 6686800 32
+496700 6660600 62
+542900 6723300 106
+532100 6660600 94.5
+535800 6655800 99.5
+536100 6700900 71.5
+519300 6725300 101.5
+506500 6661300 97
+534100 6703600 84.5
+516400 6664200 76.5
+531400 6701900 49
+540400 6676000 108
+528500 6698700 72
+548100 6686800 102
+557200 6688400 106
+492200 6685000 74.5
+500200 6691600 36
+508700 6670300 73.5
+548600 6680800 86
+540700 6711200 96.5
+481900 6674500 80
+520900 6732500 97
+513400 6674600 84.5
+555200 6692000 85.5
+505900 6665100 83.5
+549600 6671700 94.5
+498400 6658000 78
+497400 6683500 84.5
+512600 6699600 72.5
+520800 6680500 105.5
+515600 6719200 105
+505800 6701200 80.5
+496100 6674300 57.5
+479000 6677300 72
+556900 6707900 84.5
+503300 6706000 95.5
+541100 6704500 81
+530300 6718300 119.5
+518900 6703200 71
+542700 6714500 93.5
+550400 6680000 96
+542600 6693200 76.5
+532300 6675700 103
+483900 6681800 35
+497800 6654200 96.5
+504100 6694900 72.5
+492700 6709100 93
+565300 6672700 118
+515400 6657600 75.5
+552600 6694200 87.5
+527200 6645200 55
+495800 6687000 74
+522100 6706800 72.5
+497300 6712500 94.5
+545700 6705600 82.5
+538500 6664300 104
+542200 6697200 78.5
+529000 6689900 72.5
+553300 6686500 100
+548900 6709600 89.5
+540100 6667600 119
+506700 6676100 78.5
+503700 6722100 103.5
+509100 6717200 108.5
+531400 6731700 131.5
+501900 6658800 93.5
+544500 6680800 83.5
+534400 6662600 97
+546700 6647900 115.5
+508000 6686900 78.5
+539800 6651400 107
+536400 6687500 75.5
+554100 6694200 91.5
+521900 6661600 81
+503000 6670100 77.5
+515500 6701100 72
+532000 6655100 93
+519700 6664400 84
+527200 6651500 82.5
+504200 6716600 101
+533000 6723100 140.5
+507400 6672300 67
+530800 6727700 144
+523600 6726700 132.5
+552000 6717400 112
+518000 6660700 70
+556000 6703000 102.5
+488500 6702900 77.5
+551600 6705400 82
+493600 6715400 91.5
+567600 6662900 139.5
+517900 6713700 113
+544700 6638900 105.5
+547700 6724600 119.5
+511600 6707800 89.5
+523500 6665700 89.5
+486500 6675800 68
+527200 6690000 72
+502000 6672800 55
+496200 6706300 84
+492700 6716300 87.5
+490400 6702300 78
+541100 6662200 109
+537200 6643400 97.5
+571000 6672000 131.5
+512900 6667600 65.5
+487000 6681100 54.5
+550400 6719900 125.5
+502900 6664300 90
+518800 6700300 45.5
+482700 6685700 30.5
+500700 6656100 95
+496300 6697400 78.5
+495300 6702900 76
+523600 6701400 47
+485700 6674300 73
+511600 6677500 88.5
+513200 6698800 41
+509200 6693200 67
+556000 6694100 95
+532800 6649000 93.5
+516700 6687300 70
+514900 6670600 77
+498600 6674000 57
+561100 6675100 112
+552500 6722400 129.5
+494000 6712400 81
+486800 6682100 35.5
+566300 6680400 140
+514500 6730700 92
+551300 6672700 109.5
+493400 6671600 71
+504100 6729400 96.5
+550000 6653800 124
+550900 6666600 109.5
+527600 6664900 91.5
+527000 6710400 91.5
+554400 6660300 110
+542900 6726400 116.5
+536200 6677800 90
+902700 6477100 534
+897700 6477600 372.5
+929600 6473600 637
+934500 6430800 1903.5
+877400 6484400 519.5
+930800 6479300 550.5
+925000 6424100 1024.5
+870100 6507800 304
+903000 6485600 644.5
+896600 6511000 208.5
+860900 6473100 270
+849400 6478700 329.5
+948800 6447700 2244
+892100 6466300 526.5
+887800 6457700 257.5
+840700 6476400 198.5
+902800 6493400 487.5
+919900 6462500 285.5
+895800 6487200 627
+899700 6456100 1358
+923000 6423500 688
+891600 6480700 593
+909700 6427600 778
+875300 6520100 311.5
+917200 6455700 408
+872700 6470900 456
+929200 6463900 1619.5
+906800 6491100 510.5
+916600 6435700 1294.5
+914700 6418200 799.5
+927100 6419200 1122.5
+931700 6416100 1165.5
+888900 6506100 332
+868000 6482000 442.5
+857600 6497700 304
+926200 6471900 1353.5
+883400 6461900 515
+920300 6437800 1522.5
+933300 6475900 756.5
+904800 6476300 450.5
+923200 6483600 1322.5
+880600 6474800 381.5
+932100 6479900 311
+845900 6485800 313
+893200 6458900 821.5
+854100 6483000 370.5
+838900 6470300 144.5
+908900 6481300 680.5
+900700 6444400 1503
+929000 6423000 1489
+886700 6442700 749
+881200 6482600 544.5
+912700 6438200 820
+855500 6478300 375
+928200 6471700 551
+932900 6417600 1239.5
+884100 6526200 295
+883700 6473800 457
+905300 6474000 559.5
+874100 6483400 491.5
+918100 6420900 793.5
+888700 6462700 435.5
+890600 6484300 593.5
+862900 6474000 292
+881900 6493500 494.5
+918200 6460400 759.5
+889400 6499900 387
+878900 6495300 410
+911700 6490800 528.5
+883400 6464500 573.5
+930400 6482800 1201
+931500 6413000 1562
+919100 6409200 1773.5
+891400 6494600 481
+842500 6470400 182.5
+905500 6456900 1132
+879400 6452000 303.5
+868200 6518500 225.5
+868900 6519100 216
+901700 6496300 347.5
+883700 6488000 580.5
+886600 6496300 432.5
+921100 6435000 1558
+899500 6489500 599.5
+915900 6422900 985
+930000 6465800 1460
+918500 6437100 1072.5
+866900 6506400 255
+918100 6445900 642
+893500 6500200 369.5
+915700 6447900 496
+896700 6502200 358.5
+910200 6414100 1246.5
+890700 6499200 385
+934100 6414200 1412
+865600 6468800 408
+909500 6491900 452
+911700 6410100 1359
+903500 6451000 1431
+841800 6476400 205.5
+909500 6414900 1235.5
+910800 6410800 1323
+838200 6485300 177.5
+936100 6478800 714
+879800 6492600 473
+871700 6492800 468.5
+906400 6463900 920
+921700 6465000 852.5
+926400 6428800 1687
+852400 6472400 226.5
+860700 6505400 320
+903100 6434000 1520
+849300 6474600 316
+910800 6458400 604.5
+917300 6438600 1260.5
+920300 6456400 609.5
+863800 6483600 440.5
+894700 6504300 357
+901800 6503300 262.5
+908500 6439700 1250.5
+897700 6497500 422
+924300 6418300 1686
+902300 6490900 604.5
+930000 6421000 1272
+898300 6492000 598
+931800 6482000 619.5
+856200 6487900 334
+883600 6482700 580
+904100 6431800 1141.5
+870500 6486700 497.5
+911100 6420200 782
+930800 6477400 622
+890300 6471500 611
+939700 6445700 1287
+932800 6486100 595.5
+883300 6468600 595
+924600 6461500 328.5
+908100 6496300 285.5
+934800 6471200 1222
+926200 6461100 741
+897100 6500900 369.5
+884600 6470100 593.5
+880100 6517700 327
+893400 6474300 542.5
+875000 6500900 340.5
+915000 6444800 770
+857000 6503400 324.5
+949400 6446400 2175
+929700 6462400 1460
+913600 6452900 306
+914600 6449600 377.5
+906600 6455800 1380
+931900 6472100 672.5
+879100 6448400 215
+908200 6472200 1096.5
+899700 6507300 246
+859500 6478100 355.5
+863300 6501000 355
+892000 6501400 388
+915000 6485200 896.5
+889900 6473500 552.5
+894500 6447800 1128
+909000 6465300 718
+872800 6511400 340
+911700 6466200 1054
+931000 6419100 1347.5
+874600 6471500 436
+894800 6458900 857
+891500 6452700 940
+838600 6483800 230
+897900 6474700 332.5
+873000 6480300 455.5
+940700 6447200 2052.5
+878200 6524600 311
+916100 6452300 380.5
+886600 6526700 273.5
+914100 6457900 402
+911000 6446600 1103.5
+897000 6513600 220
+877100 6472400 482
+891300 6488600 525.5
+872600 6519500 208
+925200 6458100 1569.5
+934400 6443200 1827.5
+879700 6444300 240
+889100 6512700 293.5
+917800 6466400 1459.5
+871600 6511200 306.5
+920600 6449100 806.5
+905000 6467000 899
+901200 6432300 1439.5
+868700 6522100 216.5
+922800 6459900 367
+868500 6523600 215.5
+877700 6501600 298.5
+868400 6501100 391.5
+913200 6459600 752
+880800 6488300 585.5
+915100 6460100 626
+911000 6493100 387.5
+870100 6517300 218
+864500 6495200 404.5
+908100 6486300 662.5
+873400 6502100 346
+907800 6444800 1170
+893300 6490400 579.5
+892300 6491300 508.5
+890400 6497100 410.5
+842200 6482200 212.5
+879600 6505900 309.5
+940500 6481800 1574
+908700 6493200 402.5
+886000 6486700 585.5
+950500 6433700 2588
+920500 6475400 1359.5
+849600 6497300 257
+888700 6459600 374
+902700 6500800 295
+907100 6419700 1300.5
+937500 6485300 739
+909500 6432400 593.5
+918400 6440000 971
+886300 6464900 530
+849300 6500600 280
+888400 6469000 638
+879900 6497900 349.5
+884500 6472000 580.5
+881200 6519700 347.5
+925300 6431100 1456.5
+921500 6427700 751
+907300 6429000 1157.5
+908400 6423800 1143
+912200 6427600 1107
+852300 6500700 286.5
+941800 6473700 1868.5
+861200 6478500 390.5
+874300 6458400 508.5
+921100 6420400 1255
+914900 6423200 1126.5
+883100 6455300 378
+898300 6504100 288.5
+871200 6501000 399.5
+902200 6474600 245
+935000 6420100 1692.5
+882100 6479500 504
+892400 6508700 260.5
+883600 6533100 278
+932800 6469800 733.5
+863600 6469500 360.5
+876000 6464700 582.5
+926100 6449900 1912
+877800 6458500 527.5
+871800 6513200 310
+892200 6511700 262
+878300 6510700 302.5
+912100 6450700 309
+924900 6440800 1858
+862100 6497300 363
+910500 6462700 748.5
+915900 6460600 774.5
+877300 6509200 318.5
+922500 6442300 1113
+942700 6477800 1704.5
+909500 6430900 745
+875700 6512300 355.5
+917600 6443000 815.5
+893800 6464100 293.5
+909500 6435000 635.5
+911700 6484700 615
+865800 6512700 242.5
+883300 6510200 309
+886300 6504300 380.5
+892900 6507200 319.5
+898900 6440100 1670.5
+886900 6480500 565.5
+868500 6511200 271.5
+887000 6456500 286.5
+923100 6454300 1260
+882300 6452900 314
+938700 6452500 1835.5
+927400 6474200 1320
+918100 6425400 1104.5
+879500 6491400 559
+928300 6447700 1564.5
+873100 6445600 275
+855900 6500400 295.5
+847400 6473700 300.5
+875800 6494100 478.5
+876900 6479700 458.5
+876700 6499100 373
+847400 6478100 321
+843800 6487100 272.5
+856400 6496700 287
+895900 6475500 391.5
+867500 6476100 340
+846100 6480400 313.5
+882500 6494700 447.5
+851000 6484800 362.5
+878400 6498100 341.5
+887500 6471000 618.5
+910100 6490000 431.5
+899900 6476600 365.5
+842500 6473300 185.5
+881600 6523800 317
+917300 6447800 497
+885700 6449600 785
+878800 6515800 323.5
+900900 6472800 260.5
+916200 6467600 1485.5
+862300 6493200 381
+913100 6413700 1158
+873400 6498300 464.5
+881100 6443100 250
+874100 6455300 426
+879700 6479700 489.5
+877000 6493600 466
+934200 6479100 721
+838900 6479100 202
+907300 6417700 1040
+884700 6488800 558.5
+939300 6423800 2244
+895600 6492100 490
+899300 6467600 592
+871400 6479200 368
+913200 6465200 979.5
+946000 6443300 2158
+919500 6452700 676
+841600 6486200 234.5
+938400 6444100 1911
+878300 6520100 366
+872300 6451500 409.5
+867400 6503800 280
+891200 6506500 335.5
+864400 6505800 285
+849200 6494100 243
+874000 6515400 314
+880700 6501400 374.5
+853400 6492700 269
+909200 6459700 804
+923000 6430200 1281
+898800 6494100 493.5
+871000 6473600 319.5
+856700 6484300 395
+921300 6432300 1639.5
+857400 6492300 329
+887100 6474100 480
+849000 6490400 300.5
+920800 6425000 683
+843800 6482700 217
+889300 6480600 579
+840200 6484300 232
+887300 6494100 483.5
+879000 6471000 550.5
+929300 6468000 592
+927400 6462700 1564.5
+923900 6426700 1093.5
+868200 6464600 464
+894700 6473500 346.5
+934700 6446100 1643.5
+921400 6458700 606
+918900 6432500 1156
+939700 6440200 1871.5
+844000 6497300 249
+920000 6426600 962
+860500 6487700 378.5
+917000 6454800 469
+903300 6415800 1440
+947300 6443900 1959.5
+864300 6491800 400.5
+916900 6445100 773
+899300 6486500 649
+884000 6453100 230.5
+855900 6474600 273.5
+897800 6506100 263
+858800 6480100 392.5
+893700 6498100 441
+892200 6468100 520.5
+887000 6466800 625.5
+875400 6449900 274
+874000 6504700 255
+884000 6445700 615.5
+849000 6482100 313
+913200 6434400 1037
+882800 6515000 292
+906500 6434000 966
+861800 6489900 380
+907900 6427700 874.5
+904900 6422200 1320
+917400 6416900 1270.5
+875100 6516400 309
+919000 6413300 1707
+889200 6491800 536
+882900 6498100 366
+874100 6507800 331
+884300 6506600 329
+941700 6455700 2108
+845900 6475400 293.5
+938500 6479600 1097.5
+879000 6486400 550.5
+885000 6517200 297
+890000 6485600 536.5
+889000 6515300 252
+885400 6499200 394
+851400 6483300 346
+933700 6489300 1089.5
+926200 6422200 1029.5
+933000 6482500 331
+873200 6480100 438.5
+938500 6448200 1442
+866200 6471900 320
+903900 6481000 699.5
+887500 6446400 919
+887600 6489500 573
+861900 6509400 270.5
+894900 6481000 572
+866000 6501800 359
+893300 6493300 490.5
+943000 6443300 1442
+919200 6457500 432.5
+886400 6528900 293
+877700 6456900 486
+899900 6482600 658.5
+914300 6431600 1099
+878300 6471800 460
+902600 6425900 1650.5
+923800 6465200 977.5
+906000 6500200 291
+873100 6476800 340
+942000 6485100 1442
+866900 6491500 428
+840100 6481000 206.5
+926600 6464000 333
+894600 6469500 481.5
+870300 6464000 481
+897400 6472200 291.5
+874400 6491400 486
+926000 6469200 609.5
+896800 6462900 891
+932400 6468000 1500
+893500 6483300 643.5
+886300 6490800 564.5
+898700 6478900 583
+931100 6470300 338.5
+869900 6470900 389.5
+848900 6471900 202
+865800 6480100 390.5
+894800 6513800 238.5
+891500 6461400 292.5
+883000 6449000 511.5
+897100 6478400 432
+929200 6426500 1608
+906600 6469900 943.5
+929900 6415200 1716
+919900 6464000 849.5
+877300 6522300 312
+932700 6426800 1659
+864300 6524000 219.5
+887500 6524600 269
+887600 6510800 304
+923100 6443500 975
+901500 6495000 500.5
+881700 6459700 506
+846400 6500200 263
+886700 6452500 803
+896000 6495700 443
+888200 6443700 700
+903400 6502100 231.5
+910500 6454300 1058
+907000 6479000 626.5
+898600 6450700 1282.5
+911000 6478800 1133.5
+900800 6465900 1021.5
+853400 6477500 332.5
+919100 6449700 521.5
+945500 6437200 2140.5
+924600 6467300 709.5
+924100 6469900 1410
+889100 6464800 569.5
+870000 6503800 269
+880500 6512300 289.5
+910000 6450300 1093
+916400 6432900 1127
+910100 6443100 770
+876800 6447100 215.5
+933900 6436000 1999
+946300 6442300 2008.5
+875100 6495900 411.5
+912900 6441300 828
+939800 6453700 2018
+872400 6489800 519.5
+905900 6487600 551.5
+893400 6517300 271.5
+937600 6441700 1786
+873600 6496800 416
+903900 6488900 645.5
+864200 6488400 434
+927500 6435700 1907.5
+875300 6468600 535.5
+851800 6487200 323.5
+916800 6485900 1073.5
+889400 6455300 643
+930400 6468900 528
+871600 6483800 476
+882800 6529400 338.5
+864200 6519200 250
+888500 6500900 394.5
+899800 6497400 343.5
+840400 6499500 217.5
+869700 6483000 460
+914000 6480200 1057
+908400 6475800 1177
+884700 6479600 538
+912000 6457200 887
+905000 6495200 397
+868900 6495200 435.5
+883800 6449600 383
+882200 6485100 561
+846300 6493500 272
+909700 6467100 1182
+896500 6484400 620
+941400 6486100 704.5
+935700 6486000 730.5
+837300 6482300 157.5
+869300 6479400 393
+916100 6453700 312
+879900 6456900 485.5
+881300 6530800 287.5
+920900 6450500 1026
+845400 6472900 249
+884400 6443200 485.5
+919200 6424100 705.5
+891800 6463300 368
+919400 6427900 1237
+894900 6641400 232
+891500 6584500 582.5
+897700 6675700 227
+892000 6603400 520.5
+890200 6687400 215.5
+887000 6649000 209.5
+897100 6617500 455.5
+897200 6639100 287.5
+902100 6661500 234
+931600 6635800 776
+919200 6651800 485.5
+931600 6634900 747
+897800 6686600 251.5
+896700 6624700 325
+901700 6604000 496
+934800 6610900 1031
+917000 6581300 970
+903700 6651500 263
+884700 6608900 294
+911800 6611300 674.5
+890000 6634600 224.5
+910400 6587900 637
+905600 6591200 524.5
+895000 6577700 455
+932800 6632900 853
+894200 6684500 282.5
+926800 6636600 769.5
+896700 6634700 316
+891400 6614000 389
+924600 6632000 649
+914400 6599400 892
+908000 6659000 250
+907800 6641200 528
+900600 6680300 256
+922900 6623500 781
+904400 6686700 275.5
+890800 6622500 245.5
+894700 6586900 507.5
+930000 6621500 815.5
+912600 6587800 510
+922200 6604200 980
+899600 6596800 560.5
+908100 6640200 563
+901800 6685700 282.5
+915900 6652300 488.5
+905600 6646800 312
+897800 6656600 231.5
+896800 6587500 394.5
+890700 6682700 258.5
+905400 6658800 243.5
+910000 6679100 251.5
+898200 6632600 319.5
+894300 6670100 232
+889500 6637400 211.5
+896200 6656700 227.5
+887900 6680000 226
+876000 6655900 185
+900700 6678200 241.5
+881800 6647700 208
+906200 6675800 235.5
+922000 6615500 891
+908100 6599800 575
+895800 6609800 580.5
+890900 6608900 510.5
+891100 6637200 217.5
+907800 6676400 241
+904800 6684000 289.5
+900900 6673400 234
+922100 6626300 737.5
+887000 6657000 217
+886700 6611000 382.5
+896000 6660800 227
+920800 6653600 639.5
+929000 6631900 707.5
+893000 6681800 291
+894300 6619200 382
+903300 6686300 276.5
+886600 6619600 210.5
+909900 6598900 746.5
+917700 6605200 961
+888100 6629300 200.5
+894500 6609800 572.5
+920100 6627100 693
+906500 6639100 531
+893000 6632100 268.5
+902200 6652500 254
+893600 6626900 329.5
+898200 6643200 261
+910000 6594500 704.5
+886800 6587300 437
+894300 6594500 499.5
+886800 6643300 205.5
+909100 6675800 244
+898800 6620500 426
+897900 6587700 630
+913600 6615200 628
+901900 6609500 625
+914000 6604600 893
+918100 6621400 715.5
+913000 6582100 800
+889000 6639200 209
+903600 6598500 582.5
+898100 6681600 301.5
+892800 6629100 303.5
+908900 6659000 258.5
+889200 6676600 278
+896200 6606300 524
+887400 6584000 458.5
+889400 6663900 213.5
+920800 6645300 605.5
+903200 6681800 296.5
+901300 6643100 255
+899800 6683300 276.5
+914700 6631800 555.5
+886100 6667500 240.5
+915200 6595500 785
+901600 6639500 361
+903500 6592600 554
+905200 6676500 234
+888900 6597600 469
+933900 6639400 826
+915900 6592300 655
+902500 6621700 528.5
+883100 6666600 216
+884300 6603800 461
+883100 6663200 193
+880800 6597800 321
+875400 6658600 184.5
+889300 6615000 271.5
+927100 6627000 759.5
+895400 6594800 392.5
+896300 6626300 327.5
+914400 6655800 363
+881100 6592100 445
+880400 6653600 185.5
+929600 6637200 810
+894100 6585400 524.5
+892200 6590300 590.5
+907500 6653500 286
+888700 6632300 213.5
+886200 6674600 227
+937000 6630500 1081.5
+926800 6621800 709.5
+924300 6635000 719
+928300 6604500 850
+924200 6654900 606
+885500 6662700 195
+914600 6645400 551.5
+900600 6661100 229.5
+924700 6639400 693
+897000 6627600 332
+907500 6640000 477
+891600 6653300 222.5
+924200 6636500 727.5
+915800 6659700 324
+887300 6630300 207
+886700 6670900 280.5
+886000 6597400 509.5
+920000 6591500 791
+905700 6680900 249.5
+922300 6584700 1095
+906100 6584700 603
+885200 6652400 210
+879800 6657400 188.5
+881300 6636400 200.5
+909500 6650500 293
+890300 6653300 218.5
+908700 6621200 597
+891000 6680500 297
+916900 6611600 857
+923700 6650500 675.5
+915300 6610100 656.5
+900100 6605800 513.5
+888700 6586700 455.5
+897200 6613000 612
+901600 6673200 232.5
+893500 6617200 464
+894100 6661700 223.5
+896100 6645900 229
+893000 6643900 215
+921600 6655400 617.5
+891400 6658800 220
+927200 6620100 826.5
+894500 6599400 474
+887000 6636600 208
+907400 6604800 489
+903300 6675300 235.5
+915400 6653800 446
+888200 6621500 215.5
+934900 6622200 981
+923800 6638000 693
+901300 6675400 236.5
+878300 6664700 186
+922200 6629800 663
+894300 6677100 293
+897800 6596600 460
+931600 6606900 976
+903300 6624100 505.5
+934200 6635000 822
+890500 6674900 290.5
+894100 6605900 520
+896800 6604100 500
+889300 6643400 209
+890100 6619900 240
+896400 6599200 469
+890900 6580000 525
+906300 6600900 488
+883200 6606300 263
+897200 6591300 588
+885500 6605900 426.5
+895200 6636100 300.5
+895300 6606000 529.5
+921500 6637400 619
+926300 6612600 959
+913800 6591100 646
+883400 6604600 304
+924800 6584600 1265
+899800 6663600 234.5
+911100 6660700 284.5
+929400 6616100 1005
+931800 6637900 788
+901800 6585300 450
+890600 6584800 530
+891400 6669300 217.5
+893300 6619900 352.5
+896000 6618500 386.5
+915900 6594200 689.5
+885100 6586600 559
+922200 6639200 623
+901800 6607000 555
+894700 6647700 225.5
+907800 6680500 259
+883100 6598100 411.5
+897000 6660500 228
+925400 6643100 746.5
+918400 6615200 821.5
+898600 6581600 520.5
+887000 6655800 209
+902800 6683900 282.5
+887900 6606400 498
+890500 6630100 252.5
+916500 6615100 677.5
+887900 6675800 254.5
+881200 6659300 189.5
+889600 6612900 398
+907000 6613100 454
+898300 6627300 396
+911500 6677600 243.5
+909300 6613900 477
+903900 6638200 432.5
+925300 6626400 657.5
+883800 6660600 193
+919900 6658500 564.5
+898200 6616000 584
+889500 6594200 459
+907400 6591200 637
+932600 6600200 1093
+885500 6594500 476.5
+899800 6609900 565
+888800 6661000 203.5
+893100 6651800 225
+896800 6587300 421.5
+899000 6676100 235.5
+889100 6683500 206
+925600 6652300 656
+896400 6620900 407
+888600 6674200 272
+904000 6649400 263.5
+903800 6631100 416.5
+898000 6628900 293
+932100 6625500 971.5
+897500 6647400 237
+906300 6640900 439
+923500 6643300 668.5
+891700 6618200 364.5
+906300 6612800 497.5
+888100 6599400 485.5
+896500 6584700 559.5
+895400 6632000 304
+907100 6644400 432.5
+904300 6652300 256.5
+887100 6645900 209
+935800 6632600 900
+888900 6649600 210
+927900 6592600 1279.5
+884800 6656300 202
+894500 6645000 220
+913700 6645900 445.5
+900900 6587800 552.5
+904100 6662000 237
+885000 6625500 212
+905200 6648200 270
+893300 6622700 289
+918300 6647300 634
+899400 6635000 406.5
+885700 6616000 205
+906800 6617100 513
+912100 6628600 602
+881100 6594100 402.5
+927400 6631400 716.5
+884600 6623100 209.5
+910400 6617800 551
+899800 6644500 266.5
+919900 6648000 570.5
+885800 6650300 211.5
+883200 6654400 198.5
+890400 6640600 213
+911100 6648400 429.5
+892400 6687100 216
+883500 6630400 201.5
+908700 6615900 521.5
+927800 6630200 725
+912500 6620900 541
+910200 6646200 452.5
+891100 6641400 210
+926300 6614600 874
+937000 6639000 861.5
+899300 6631500 371
+914600 6584600 729
+915600 6620600 681
+912500 6673700 265.5
+912700 6624000 541
+904000 6606400 554.5
+882800 6591300 493
+925800 6629600 666.5
+902100 6618100 570
+890100 6606200 534
+916400 6617700 660.5
+897600 6622000 417.5
+938400 6637100 994
+925000 6599800 940.5
+914300 6588100 502.5
+885200 6629500 206.5
+890900 6594300 499.5
+886000 6641800 204.5
+883900 6594300 516
+913100 6635500 577
+898000 6678400 301.5
+892100 6644400 214
+931700 6619700 955.5
+899200 6595200 591
+888500 6591200 468.5
+913500 6628200 584
+904400 6586900 611
+917700 6622700 717
+917900 6586300 818
+914400 6586400 695
+900300 6599700 567
+891100 6616900 327
+922400 6601300 723.5
+884300 6589800 420
+898100 6609500 590.5
+902300 6614400 560
+893400 6649600 229
+887400 6678100 243.5
+914300 6654100 454.5
+897400 6672600 233
+894900 6624400 325
+905100 6620500 556.5
+895500 6678700 302
+940500 6608700 1176
+923900 6589800 864.5
+907300 6633600 541
+920400 6630200 604
+931100 6608500 915
+900400 6648700 262
+884700 6670100 239
+917800 6656400 615
+902000 6627200 475
+893700 6658100 224
+912300 6590200 674
+886600 6665400 212
+899300 6656500 235.5
+904800 6636900 543
+914100 6606800 799.5
+885000 6644000 204.5
+892900 6597700 513.5
+891700 6626200 271.5
+918700 6586500 822.5
+895500 6615900 482
+887500 6588900 446
+888800 6641400 210
+905500 6651700 279
+918900 6653000 510.5
+912200 6653600 328
+922500 6634400 682.5
+904800 6632500 449
+909500 6631800 579
+921500 6648700 653
+883400 6652400 201.5
+913900 6639800 623
+895100 6628700 338.5
+877000 6661700 186
+889000 6645400 213
+911900 6651100 417
+887300 6617500 212
+895900 6673700 230
+901500 6647600 269
+903200 6586300 490
+925600 6645900 685.5
+906600 6674700 239
+917600 6649800 588
+878200 6651200 196
+933900 6640900 841.5
+891100 6590900 512.5
+900000 6633100 408.5
+887000 6647800 209
+930100 6634000 715.5
+932200 6638800 817
+893700 6612600 533.5
+891300 6649900 226
+897000 6648500 237
+900600 6621100 530
+877300 6648100 197.5
+912700 6627100 560.5
+931500 6632500 805
+908400 6625600 603.5
+926500 6605000 822.5
+914500 6659700 340
+899300 6618300 454.5
+916000 6636900 595.5
+915700 6622500 576
+932200 6627400 1017
+933900 6636500 809
+909700 6629000 639.5
+902200 6611700 605
+898500 6625200 403.5
+895100 6612700 549.5
+890400 6676000 294
+898500 6638400 262
+921500 6600600 719.5
+886700 6632100 210.5
+891100 6620600 249.5
+901300 6614000 562
+921600 6619100 805
+910500 6612000 638
+897300 6628800 295
+893600 6588600 512
+916700 6627100 623.5
+879800 6666000 190.5
+884100 6607000 373.5
+936000 6630600 1055.5
+904900 6609500 552.5
+908900 6603400 657
+909700 6607400 651.5
+936200 6637900 829
+914800 6616100 596
+896100 6582500 492.5
+902300 6626500 424.5
+928400 6634300 717
+888100 6613000 247
+895400 6639600 261
+919200 6580100 1120
+918200 6640100 688
+887700 6612000 385.5
+900800 6630200 391.5
+916900 6603400 957
+882200 6596000 457.5
+905200 6662200 241
+905900 6682800 269
+888900 6601300 504
+934800 6603000 1010
+894100 6597100 476
+909200 6596000 702
+916900 6598600 882
+892100 6621100 294.5
+931000 6638400 820
+900400 6631600 408.5
+885600 6589500 464
+896300 6649100 232
+898500 6636100 285.5
+892300 6689500 210.5
+889700 6614100 317
+932500 6634400 822
+908100 6588900 505.5
+906600 6661400 252.5
+886400 6591300 486.5
+923000 6652100 668
+919800 6604800 918.5
+892600 6614200 424
+909800 6614300 527
+896400 6614000 559.5
+879900 6595500 323
+930400 6637700 820
+911400 6584400 685
+886200 6672400 267.5
+918700 6591800 748.5
+879900 6592000 250.5
+893400 6675000 277.5
+907700 6609000 495
+887500 6626400 216.5
+928400 6590400 1215.5
+923400 6625600 694
+885500 6609500 383
+897100 6676400 234.5
+924800 6587000 1040
+920900 6589800 749.5
+884300 6592600 501
+889400 6681200 268.5
+888400 6666000 207
+904000 6673400 234.5
+910700 6581400 826
+904300 6643500 270.5
+912600 6656400 313
+894200 6672600 228.5
+894800 6592800 484.5
+905800 6614700 568.5
+888800 6668800 268.5
+930400 6630400 823.5
+905600 6672900 240
+923500 6611700 990.5
+908800 6655900 267
+892500 6670000 219
+895200 6622500 329
+902600 6658500 233.5
+917100 6659200 400
+922400 6649900 678.5
+908000 6631600 543
+897700 6640600 291
+929200 6635500 736
+913600 6663700 286.5
+893200 6639200 217
+873200 6653400 181.5
+897000 6589800 574.5
+899700 6636400 370.5
+924200 6633000 681.5
+912900 6648400 451.5
+890500 6639300 215
+884000 6648400 206
+911100 6612700 599
+891800 6683400 248.5
+935400 6629300 1040
+923200 6608700 999
+906000 6629600 543
+914500 6592600 662.5
+910600 6608300 684
+888700 6618900 229
+920300 6634400 581
+928700 6617500 850
+925600 6641600 714.5
+925900 6648400 746
+921900 6631500 629.5
+891300 6634700 231
+889700 6672500 280
+400000 6292600 84.5
+418700 6288400 127.5
+426900 6311100 100.5
+400300 6353200 74.5
+340600 6283700 28
+444800 6355100 120
+378000 6302400 36
+406600 6371200 48.5
+445500 6324900 111
+450500 6330500 132
+398400 6289600 80.5
+430600 6315900 72.5
+389200 6303400 40
+359100 6322700 42.5
+410400 6319900 37
+426800 6325000 67.5
+410200 6286200 92
+418400 6309700 68.5
+434400 6316000 82
+347800 6311600 30
+392600 6302700 55.5
+411300 6314300 57
+412200 6301800 72
+423500 6321800 65
+359200 6291600 19
+363400 6334900 28
+394900 6287400 49
+390700 6297700 67
+366900 6288200 54.5
+406900 6282700 102.5
+371600 6280400 69
+432500 6321000 82.5
+362400 6282900 31.5
+347400 6294200 11.5
+380200 6284500 69.5
+413900 6306100 54.5
+348400 6282800 34
+372300 6295900 20
+430400 6324900 99.5
+418600 6291500 101
+378000 6293900 40.5
+427300 6285900 138
+386300 6333800 77
+384100 6306600 40
+394200 6316500 57
+379100 6314200 62
+416200 6294300 92.5
+394100 6297800 63
+400400 6369400 41
+433200 6324500 92
+398000 6294300 77
+402100 6314200 51
+413500 6280600 108
+428100 6289900 135
+437000 6294800 122
+403200 6302100 58.5
+374100 6337600 59
+407700 6375500 56
+349800 6278000 35.5
+391900 6295000 66.5
+425300 6336100 88
+402100 6297200 69.5
+417500 6298800 105.5
+387400 6292600 34
+451000 6326700 136.5
+386600 6283700 85
+400800 6281300 90
+355000 6279700 38
+405500 6300300 73
+394000 6306200 22.5
+384600 6285700 75.5
+349700 6315200 27.5
+431100 6306600 96.5
+437200 6322300 101
+372300 6278400 68.5
+354300 6318100 36.5
+386600 6303000 31
+369500 6367300 31
+375400 6369500 38.5
+385300 6321900 74.5
+362200 6353700 40
+429300 6321500 82.5
+451300 6324200 128.5
+368500 6374800 39
+364900 6281400 53.5
+406100 6281500 120
+390000 6292600 56.5
+424900 6296100 115
+410100 6290600 107
+432300 6297400 111.5
+422100 6298300 93.5
+342600 6287100 27
+366600 6339600 42
+394300 6294800 77
+371600 6285800 73.5
+413200 6293400 94.5
+368700 6280400 71
+404500 6287500 83.5
+362700 6347600 45
+400900 6345900 82.5
+354900 6282900 31.5
+379300 6298400 26
+416800 6333500 82.5
+403000 6284800 91.5
+449000 6325400 125.5
+419500 6299900 81
+393400 6283100 70
+386400 6280900 95.5
+439900 6320200 89.5
+429200 6302900 71
+373500 6298100 24
+345600 6308500 10.5
+394600 6326100 63
+390900 6331300 72
+438200 6316100 83
+425200 6290200 126.5
+414100 6309400 70
+342500 6292600 25.5
+424900 6284300 128.5
+366300 6361600 32
+377100 6297600 24
+365900 6331700 51
+422200 6289400 116
+416300 6340300 91.5
+417200 6315600 63.5
+379200 6318400 74
+394900 6302500 56
+375600 6278800 74.5
+439700 6302700 114
+439900 6341800 118.5
+371000 6357700 32.5
+402800 6290900 89
+343000 6294400 27.5
+421800 6292300 103
+387900 6306600 24.5
+361600 6338400 32
+348200 6291400 13
+381900 6356100 56.5
+363000 6291300 51
+397400 6284300 89
+431300 6283000 166
+368700 6279100 35.5
+409500 6369700 56
+463900 6332500 121
+422800 6335500 86.5
+405200 6283200 95.5
+427500 6339200 101.5
+429400 6300200 99.5
+408200 6299800 79
+370800 6291100 40.5
+382600 6282600 68.5
+384800 6293500 28.5
+406100 6294800 92
+384500 6366600 54
+361000 6290300 29.5
+392100 6307300 31.5
+429800 6279500 177
+386300 6304800 20
+364200 6355700 19.5
+419100 6357900 91.5
+406500 6286200 83.5
+410000 6308300 54.5
+339500 6281500 26.5
+377600 6348800 53.5
+406000 6305900 50.5
+436300 6339200 101
+380700 6333400 76
+431600 6334700 80
+403300 6295500 82.5
+391000 6302800 50.5
+394400 6353100 66.5
+410600 6281900 102
+400400 6296400 70.5
+422700 6285300 128
+385900 6300000 38.5
+411300 6296200 82
+400300 6326800 72.5
+414500 6364800 72
+402400 6338500 91
+427400 6288100 151.5
+364700 6279400 42
+376700 6298600 8
+390700 6365200 67
+402400 6281700 107
+353900 6309400 26
+377400 6286600 69.5
+434600 6286500 159.5
+429400 6291800 134.5
+395200 6312000 44
+414100 6284800 105.5
+424100 6302700 89.5
+383100 6295000 29
+359100 6296700 33.5
+386800 6346300 79.5
+460200 6325400 156.5
+435700 6284100 147.5
+414200 6320800 51
+368500 6294400 32
+432200 6312600 83.5
+350700 6297400 33
+421500 6311500 79.5
+407100 6304800 47.5
+391200 6305400 29
+416400 6290500 97
+379900 6302700 19
+408600 6285900 88
+388000 6300300 53
+368200 6285600 82.5
+383500 6297000 29
+423400 6283100 134
+349400 6295500 22.5
+440400 6333700 96.5
+424200 6292400 119
+431000 6285600 162
+393200 6291500 66
+374400 6287700 52
+384100 6291500 34
+390400 6310600 29.5
+347200 6288000 17
+390200 6282700 105
+399400 6317200 36
+406200 6309400 68
+352200 6281900 33
+374400 6308900 55
+414000 6297600 83
+362300 6293200 16
+416600 6282600 138
+401900 6288400 83
+360600 6306900 37.5
+435500 6282500 153
+419900 6342600 105.5
+358900 6335100 36
+371600 6327500 68
+460500 6320600 134.5
+351800 6288600 43.5
+465900 6338500 124.5
+387000 6353700 70.5
+385200 6331500 76
+444800 6332500 117
+416600 6327800 70.5
+427500 6316000 65
+399200 6302200 59.5
+366600 6309700 56
+432900 6301300 100.5
+395000 6299800 55
+457500 6327800 145
+435300 6303200 102
+421000 6290500 108.5
+441900 6309700 105.5
+436100 6314200 89.5
+442900 6313700 86.5
+436700 6308300 107
+413400 6338900 87.5
+409600 6298100 76.5
+418800 6295500 103.5
+457800 6338600 145
+366900 6318000 54.5
+357800 6319700 32.5
+406000 6291700 97
+418800 6316400 60
+428800 6308600 94
+402100 6299600 65
+345500 6281400 36
+356600 6289900 46.5
+433800 6331600 72
+357600 6282200 54
+426400 6286700 122.5
+398100 6301700 62.5
+398200 6324600 59
+407500 6314100 56
+407700 6321100 42.5
+440800 6325400 106.5
+463900 6336600 132.5
+374300 6293900 31
+351400 6304300 31
+411800 6285100 96.5
+391000 6288700 46
+374500 6290900 58.5
+451700 6339300 126
+395400 6374900 42
+408200 6326900 58.5
+407500 6334300 85.5
+392600 6321200 69
+385300 6303300 20.5
+415600 6280500 120
+371000 6294300 23
+393700 6311100 39
+424300 6296200 109
+369000 6297800 25
+365300 6295500 29.5
+401500 6305900 49.5
+444400 6324100 103
+434500 6309600 98
+449500 6322000 107
+376100 6384500 32.5
+372800 6316600 73
+434600 6330000 83
+389400 6306000 27
+424000 6331500 81
+398700 6363900 54.5
+373500 6300200 31.5
+366800 6292100 49
+392000 6298300 64.5
+394700 6290900 61
+427700 6294400 120.5
+347500 6297600 31
+355100 6285200 53.5
+388200 6295000 59.5
+427100 6281000 156.5
+410000 6293800 91.5
+408100 6280200 116
+421600 6279800 164
+378000 6280500 65
+410500 6279200 138
+423900 6314500 70.5
+424000 6329100 73
+425000 6308500 86.5
+355000 6326100 38
+362600 6285400 29.5
+462900 6328300 131
+366500 6296400 29.5
+423900 6303400 66
+426300 6313400 85
+386400 6313700 46
+431300 6287500 161.5
+420900 6304600 58.5
+396500 6329900 67
+379500 6291300 38.5
+352900 6294100 34
+422700 6361600 92
+368400 6356000 30
+595100 6702300 109.5
+617800 6724000 120
+604000 6717800 99
+560800 6738100 123.5
+544400 6742300 95
+570500 6745100 120.5
+599200 6721700 109
+571900 6693100 91.5
+605100 6696100 102.5
+594600 6726400 104
+545200 6737400 113
+587800 6740700 111
+610100 6715700 104.5
+536300 6755500 120
+570700 6692200 122
+578300 6755400 135.5
+585100 6757000 126.5
+570000 6724500 112
+581700 6729000 91
+557400 6746200 103.5
+556100 6729600 122
+565600 6748700 121
+583100 6727700 78.5
+594900 6719000 102.5
+545400 6772600 175.5
+569600 6728500 104
+595300 6715900 96
+599400 6687100 87
+572400 6748400 127
+533300 6737300 124.5
+545400 6757600 150.5
+570900 6700000 95
+626700 6722900 126
+545100 6775700 159
+584400 6719200 97.5
+612300 6685700 116.5
+534100 6750500 114
+568600 6763300 138.5
+548400 6762000 184.5
+541000 6778700 190
+547100 6775600 180.5
+569600 6709100 85.5
+558700 6732300 127.5
+557000 6759300 155
+591000 6764200 123.5
+530600 6740700 98
+566300 6717400 91.5
+580300 6705000 99
+543300 6766600 138
+560300 6704100 105.5
+547600 6745100 103
+550300 6752000 117
+629300 6727700 127.5
+588800 6702500 114.5
+566100 6759800 129.5
+563500 6746200 115.5
+557900 6711200 79
+529700 6737400 117.5
+574000 6753000 125.5
+531600 6748200 109.5
+544000 6747500 111
+561700 6769700 190.5
+582400 6747100 129
+577700 6721300 84
+577400 6739200 113
+526800 6741800 95
+552500 6741600 112.5
+529000 6739500 107
+589500 6730900 88
+583900 6751200 137.5
+547600 6736600 116.5
+572400 6742700 116
+574100 6726000 114.5
+581300 6736400 114
+577200 6725000 90.5
+552000 6726400 128.5
+569100 6711900 86.5
+539700 6760300 140
+600600 6712100 99
+587000 6761400 121.5
+578800 6685000 102
+586100 6747000 132
+609300 6696900 98.5
+561200 6767200 188
+556700 6763700 179
+542100 6743900 100
+575100 6706600 99.5
+565900 6719500 101.5
+577300 6712000 91.5
+539000 6765300 127
+577800 6730300 109
+585700 6766000 124
+569200 6743900 125
+559500 6708900 83.5
+565900 6721300 108.5
+537500 6746500 108.5
+533600 6739000 99
+567300 6693800 115.5
+571200 6727300 102.5
+550800 6737700 110.5
+577600 6700100 114.5
+606500 6725400 114.5
+582800 6763100 119.5
+555200 6745400 108.5
+579100 6692200 92
+562200 6744500 120
+546300 6749100 113.5
+545500 6768500 162
+564300 6693400 109
+555100 6734400 123.5
+544100 6751500 121
+595400 6728700 94
+613900 6726400 116
+628500 6703200 113.5
+577700 6682300 119.5
+583800 6713300 95.5
+539900 6741500 103
+607000 6688800 102.5
+594100 6738000 97
+561200 6753400 115
+556700 6738100 112.5
+575900 6705500 100
+561900 6733200 125.5
+580000 6711100 100
+571600 6709800 87.5
+555500 6754000 131
+581000 6725100 80.5
+596600 6708900 104
+592400 6736800 96.5
+637200 6727500 137
+558900 6750800 109.5
+614300 6686100 110.5
+574300 6722700 99
+545600 6741200 106
+636100 6712800 128
+574200 6758500 127
+541600 6740100 104.5
+583500 6693100 93.5
+585100 6695000 110
+552500 6745500 104.5
+608200 6721100 116.5
+534800 6743900 63.5
+589500 6745000 119
+558400 6693300 98.5
+577200 6686600 114
+567600 6725100 106
+615100 6707800 111.5
+568300 6700200 107
+564600 6722600 111.5
+599600 6692200 92.5
+638200 6706800 131.5
+589600 6691200 88
+590300 6717500 81.5
+535100 6744100 106
+581800 6739100 114
+564400 6738500 125.5
+579500 6697100 106.5
+571900 6762800 116
+571300 6695400 98
+566200 6755700 118
+627500 6690800 132
+572600 6709400 88
+572900 6717100 86.5
+549600 6779100 196.5
+578200 6715400 87.5
+571600 6740100 111.5
+566400 6734100 116
+572900 6728900 102
+583900 6745000 124
+588800 6724700 100.5
+521800 6739800 81.5
+560200 6724400 126
+632800 6688200 145
+544900 6778900 198
+599700 6703100 110
+568100 6757300 119
+556600 6747300 108.5
+584500 6730700 95
+558100 6769200 198
+551200 6730800 120.5
+549900 6747000 105.5
+576100 6761500 124.5
+553500 6767400 199
+585900 6726800 85.5
+559100 6752000 114.5
+586600 6729500 82
+586300 6684400 100
+542100 6729200 123
+559000 6694700 96.5
+562800 6695200 96.5
+575300 6698300 98.5
+582000 6684200 100.5
+549400 6728600 126
+587600 6748100 130.5
+581200 6744000 116.5
+582500 6700400 118
+615700 6683600 118
+621200 6698900 110
+600500 6729200 104.5
+593000 6694800 94
+552600 6756600 145
+569100 6746700 122
+617300 6685500 122
+562800 6750800 116.5
+560400 6756400 125
+557700 6747400 103.5
+545500 6729700 122
+540500 6736300 118.5
+590900 6713100 99.5
+529800 6743500 101.5
+613500 6716300 102
+558800 6709600 61.5
+579000 6760400 127.5
+562600 6712600 89
+558400 6720200 119
+581500 6703200 111.5
+559100 6729300 117
+571600 6705600 102
+523700 6738100 96.5
+573700 6689400 125
+587200 6716500 97.5
+578800 6749100 132.5
+567900 6731500 109
+556000 6775800 178
+559200 6725800 120.5
+576700 6720000 88.5
+607500 6705900 108.5
+579900 6748200 137.5
+573400 6744300 119.5
+561400 6739400 114
+566100 6695600 96
+556300 6741400 121
+583700 6722500 84.5
+588100 6734200 94
+637800 6723500 131.5
+619700 6714200 112
+627600 6715600 118.5
+580500 6728100 89
+574600 6712700 86.5
+541000 6772800 144
+568100 6715300 88
+548600 6770700 173
+581600 6754600 136
+550300 6742300 106
+596100 6697900 98
+543100 6741900 98
+569200 6736100 110.5
+584100 6712100 97
+558700 6713800 89
+563400 6710400 87.5
+618700 6698900 109
+579000 6687500 92
+563000 6692800 101.5
+590800 6735900 94
+583400 6742100 116.5
+544100 6734800 126.5
+578900 6734100 113
+595900 6736100 92
+604700 6686300 117
+542800 6765200 156
+545800 6761100 176
+554500 6723900 135
+537100 6738000 108
+578800 6726200 92
+586100 6687400 92.5
+607300 6687600 117
+590700 6687100 86
+571800 6711900 81.5
+611300 6687800 106
+585700 6742300 115.5
+590100 6752300 127.5
+552800 6775100 179
+570200 6740700 118.5
+556700 6772900 178.5
+549300 6740700 109.5
+563600 6729600 112.5
+564200 6753200 116.5
+547300 6765400 180
+564100 6767000 166
+553600 6762800 177
+590000 6757800 127
+561400 6746800 109
+561000 6744200 109
+551200 6734100 118
+569400 6750100 132
+589500 6696700 101.5
+611800 6700500 106
+572100 6732900 109
+554500 6737000 118
+564600 6741000 119
+561400 6717700 102
+765700 6520800 984.5
+790300 6483200 584
+790400 6514900 362
+831900 6475100 354.5
+826200 6493500 310.5
+800700 6477300 623
+778100 6493800 893
+776600 6504700 804
+800900 6522400 529.5
+804500 6483900 567.5
+784400 6484100 800
+797200 6480700 596.5
+784300 6487800 588.5
+797100 6478300 567.5
+768700 6546000 833
+764000 6524200 656.5
+772000 6534700 684
+820300 6492700 565
+760800 6533300 885.5
+771900 6558600 325
+775900 6517300 485
+799600 6535700 616.5
+758900 6517600 1163.5
+771800 6519700 657.5
+793400 6500000 366
+798900 6560500 559
+805200 6507800 555.5
+795700 6501400 358
+802700 6499800 454
+777700 6497300 906
+811900 6487900 584.5
+780700 6561700 299.5
+771500 6550700 573.5
+784600 6565000 340
+794200 6508000 349
+778100 6516700 465.5
+798700 6478800 540.5
+786400 6556600 312
+772700 6566000 323
+800100 6563100 582
+787400 6544400 346
+798100 6505900 365.5
+804600 6518000 523
+796000 6565100 384
+770500 6508600 1135.5
+772000 6548500 567.5
+791100 6505800 360.5
+800900 6558800 631.5
+823400 6493800 421.5
+793900 6539400 463
+792400 6530500 417.5
+790000 6556100 347
+778800 6512900 585.5
+797800 6559400 499.5
+836900 6477400 287.5
+784800 6535400 412.5
+806200 6567900 577.5
+783300 6508700 415
+785600 6561100 291
+777600 6541200 536.5
+770200 6553200 581
+781400 6505500 545
+773800 6529700 532
+799700 6496600 377
+784800 6541400 414
+807000 6497100 588
+797300 6520800 398.5
+813300 6488600 628.5
+766200 6512000 1167.5
+798700 6496600 361.5
+806200 6500700 521.5
+830200 6496300 269
+835100 6477500 282.5
+822900 6473300 1122
+763100 6523100 713.5
+795900 6505600 351
+825300 6472200 1039
+796300 6499000 363.5
+767700 6524400 583.5
+773200 6523100 575
+772500 6519800 494.5
+801700 6512800 441
+822300 6467600 726.5
+780300 6519800 424
+761600 6567700 443.5
+783000 6501400 461
+787600 6509500 364
+803000 6498500 455.5
+798400 6527200 614
+775900 6544400 380
+792600 6478700 619
+793500 6564500 348
+791200 6508600 361.5
+768800 6560600 427
+800200 6516100 418
+828700 6488000 652
+808600 6482500 769.5
+837000 6485400 256
+819700 6496300 640
+813100 6484600 540.5
+798300 6501900 369
+775800 6554300 325.5
+792300 6493800 408.5
+836400 6484500 288
+798400 6492600 394
+759400 6524500 1003.5
+820700 6488600 356.5
+792200 6525000 398
+801300 6533300 709
+776400 6546700 335.5
+796800 6483300 550.5
+766000 6563800 469.5
+816500 6476000 1076
+781600 6474900 808.5
+822900 6464600 927
+778900 6499200 844
+758100 6540400 948.5
+778000 6476200 925.5
+778400 6515100 552
+807100 6506800 535
+780700 6511100 542.5
+803900 6494600 489
+786800 6549300 345.5
+799200 6545700 452
+790400 6562800 323
+803700 6478300 656.5
+816000 6495000 712.5
+773700 6502100 1087
+824800 6489500 553.5
+804200 6514200 482
+818600 6480700 914
+805400 6514400 540
+801900 6517100 467
+809400 6465800 1000
+781900 6499600 541.5
+772700 6531700 595.5
+781400 6490500 647
+798900 6531800 621
+787600 6495700 445
+774800 6522900 566.5
+810000 6496300 685.5
+794900 6492300 370
+777800 6484900 1066
+786600 6562100 330
+785700 6495600 527.5
+823000 6488300 630
+765200 6571300 350
+765100 6559400 680.5
+768700 6530700 695.5
+793400 6556000 383.5
+805300 6510800 539.5
+808400 6505300 522.5
+773000 6518300 541
+796500 6493900 367
+777300 6485300 1045.5
+768500 6515000 922
+769200 6556500 570
+778600 6526100 435
+773500 6507200 990.5
+791100 6545000 380.5
+765600 6553300 760.5
+773600 6542600 671.5
+765900 6549400 809.5
+832700 6477700 354
+784100 6548100 291
+818300 6487500 688.5
+762100 6538600 870.5
+779000 6480200 1017
+826800 6492700 432.5
+783400 6481100 865.5
+786200 6491000 522
+795300 6535900 492.5
+799100 6477300 591.5
+812400 6497200 742
+786800 6545900 325.5
+817200 6464500 979.5
+830100 6497000 262
+829400 6472700 714
+790500 6522400 356.5
+780300 6522000 436.5
+764800 6529000 721
+784400 6501400 377.5
+782100 6515500 383
+777100 6549400 317.5
+777300 6528100 472
+781600 6487100 902
+797700 6548100 408
+821800 6471000 956.5
+799100 6553700 516.5
+801000 6536600 676
+782700 6497000 631.5
+796800 6489600 515.5
+775200 6500600 1085.5
+821200 6494000 409
+812700 6477000 848
+775500 6515400 542.5
+775600 6535200 548.5
+819500 6469800 1026
+822500 6490500 350.5
+830200 6475700 903.5
+815600 6498000 800.5
+795700 6522800 432
+824300 6495300 443.5
+801500 6527300 668.5
+758200 6516700 1161.5
+780200 6544300 343.5
+807700 6487000 513.5
+795600 6548800 429
+780800 6493800 633.5
+835400 6481000 301.5
+799100 6518600 446
+801200 6509400 476
+777100 6492900 992
+775900 6549200 331
+804300 6522200 630.5
+780200 6531500 442
+831500 6481300 790
+764200 6532300 739.5
+796200 6562200 461.5
+771700 6526300 642.5
+791500 6511500 359.5
+784100 6509300 435
+770700 6552200 413
+784300 6496900 473
+806700 6469200 875.5
+784200 6532300 385
+799300 6522800 531
+783000 6513400 435.5
+777800 6502700 727
+787800 6519400 364
+794500 6503100 358
+768700 6573100 299.5
+788500 6480000 682.5
+808500 6488300 575.5
+813200 6466000 1139.5
+776300 6520100 523
+802600 6490200 507.5
+801100 6506100 483.5
+826200 6496600 358
+765000 6515200 1141.5
+781100 6489900 951.5
+824000 6482100 938
+784600 6515400 367.5
+797300 6499300 369.5
+795200 6557300 457
+833400 6476200 322.5
+782300 6554600 305
+807700 6488300 558
+787800 6528400 360
+783800 6561600 299
+789800 6499200 381
+783300 6492300 646.5
+834100 6487300 551.5
+779600 6475500 827
+776600 6530400 482
+806700 6479100 684.5
+788200 6531000 386
+830800 6477800 866.5
+796000 6527300 491.5
+818600 6475500 1004
+803900 6563700 612
+759900 6527900 817
+773700 6477200 952
+826600 6470500 660.5
+770400 6541000 875
+766900 6564300 369
+803500 6482500 584.5
+809200 6499700 598
+802100 6526000 647
+832400 6485600 599.5
+814200 6500700 669
+807200 6493100 668.5
+784600 6478800 807
+784900 6544000 361.5
+791400 6558700 372
+762600 6521400 975
+771500 6516500 720.5
+777400 6524600 500.5
+791200 6489300 509.5
+789700 6523500 350
+780200 6507900 557
+786400 6475300 735.5
+782500 6544400 355.5
+794400 6558700 419.5
+765600 6521900 678.5
+782200 6538800 418
+774400 6556400 315
+794000 6544200 407.5
+810900 6502900 586
+791400 6541000 450
+784800 6480100 745.5
+805400 6529100 769
+794400 6540300 465.5
+791200 6561800 371.5
+805800 6486400 514
+772400 6545900 575.5
+779500 6534100 433
+808800 6564100 677
+782600 6549000 280.5
+830600 6486500 695.5
+816500 6492500 589.5
+761600 6527900 799.5
+791500 6534300 491
+788000 6538600 433.5
+769100 6532000 663
+789800 6502700 370
+807700 6473900 809
+798400 6538300 511.5
+793600 6553300 420.5
+791700 6519500 358.5
+794100 6522100 331.5
+795300 6516400 346.5
+787800 6531800 382
+780500 6549800 305.5
+766200 6518100 995
+823400 6491500 378.5
+823800 6484400 636.5
+765600 6535200 769.5
+811200 6472200 986
+777900 6536900 507
+778200 6560000 315.5
+796400 6533500 532.5
+772500 6511700 793
+782700 6526100 363
+800100 6556200 539.5
+794300 6510100 346
+812100 6495100 766.5
+777000 6440200 752.5
+735600 6435400 919.5
+747900 6447200 953.5
+758900 6443500 900.5
+794800 6444800 978.5
+752300 6472500 891
+731600 6463000 575
+783600 6437900 1089.5
+715300 6465400 599
+754900 6446300 1037
+801500 6446900 965
+733300 6465600 473
+766200 6445800 742
+762800 6444800 802.5
+802500 6441000 1006.5
+731400 6452400 697
+786700 6429000 1121.5
+738500 6477600 883
+749100 6424200 923
+791900 6466600 654
+777000 6469900 767
+726800 6468300 556.5
+729900 6473700 532.5
+746400 6422300 1024
+717000 6472400 575
+747800 6457200 863.5
+778200 6461900 698
+740100 6437100 815.5
+724700 6451200 829
+774000 6448100 745.5
+767600 6441500 727
+764700 6451700 924
+745900 6438800 721
+717500 6473600 580.5
+750700 6430100 812.5
+739200 6431800 970
+764900 6462900 881.5
+773800 6423400 955
+769400 6426600 912.5
+730100 6466200 518
+724800 6478500 455.5
+782900 6430600 993.5
+739100 6454400 621
+710400 6470100 790
+792900 6454900 695.5
+758100 6468300 933
+763900 6448900 887
+753800 6464200 988.5
+781400 6439100 877.5
+786200 6462800 704.5
+790100 6431500 1195
+765700 6416300 1107.5
+771500 6454500 729
+749700 6444000 920.5
+773100 6421500 875.5
+720900 6470700 602.5
+786900 6468000 667
+738300 6463300 616.5
+755900 6455800 1026
+771500 6467600 803.5
+781800 6468500 722
+741600 6474800 921
+731700 6450000 543.5
+761300 6439500 812
+780100 6451700 947
+800000 6461600 792
+792600 6436600 1272
+777400 6467700 705
+743300 6441100 771.5
+721100 6476200 485.5
+732900 6430200 1122.5
+812000 6455100 1098.5
+771700 6412000 1137.5
+773700 6429500 825
+727300 6466900 541
+781700 6450800 911.5
+798000 6467000 761
+757200 6437400 1080.5
+812800 6450300 959.5
+779100 6434000 880.5
+746700 6436600 707.5
+754800 6441300 1084.5
+769900 6430300 885
+767700 6438900 755
+785900 6422300 1279
+801700 6455100 772.5
+738600 6418100 1281.5
+729100 6446900 785.5
+794900 6428600 1422
+768700 6432700 858
+745600 6451200 833
+796700 6432700 1229.5
+762300 6421600 1209.5
+781100 6423000 1121.5
+748700 6469300 933
+710800 6468000 779
+719000 6475600 576.5
+719200 6461500 780.5
+742500 6450900 734
+729100 6477000 577.5
+774300 6443400 754.5
+735100 6454400 614.5
+738900 6444700 719.5
+741500 6447000 740.5
+731500 6443800 821
+721000 6464000 722
+772900 6418900 967.5
+736000 6438100 821
+785800 6454800 697.5
+761100 6434800 1105
+794100 6475100 617.5
+778500 6427200 1017.5
+773900 6458500 790
+746600 6465200 937.5
+734400 6450900 624
+776300 6438100 760.5
+792300 6444100 1153
+745600 6434300 847
+766100 6409300 1018
+753600 6418900 879.5
+743200 6429100 1072
+765800 6438000 777
+732600 6439200 1067
+749000 6449100 979
+760300 6448500 849.5
+770700 6415600 1101.5
+810000 6460100 1080
+748400 6422400 1009
+777900 6421700 1154
+789400 6459000 676.5
+778200 6416400 1007.5
+764400 6458300 830.5
+724900 6471600 516.5
+769700 6439500 680
+792800 6460200 649.5
+724000 6476400 447
+803200 6454800 922
+734200 6475800 701.5
+750900 6457900 908
+763700 6473800 1035.5
+744800 6436500 875
+731700 6433100 1126
+771200 6447000 727
+764600 6433400 916
+798000 6439400 1079
+742200 6466900 819.5
+755200 6450200 1006.5
+775400 6417700 951.5
+806900 6447800 1044.5
+795600 6454800 757
+805500 6458300 872
+777400 6456200 739.5
+778800 6441900 851
+727100 6478300 515.5
+752500 6449500 1073
+737700 6465600 628.5
+772000 6441100 686
+726700 6464500 580
+738000 6468700 661.5
+772300 6433500 777.5
+769500 6466900 853
+738000 6456900 641
+754600 6432300 918
+756700 6428900 1025.5
+741800 6441600 693.5
+739400 6461200 612
+794500 6471400 609
+799400 6433000 996
+735200 6471700 652.5
+774300 6432800 789
+796900 6461200 707
+783300 6444700 1067
+769700 6438600 744
+749900 6437300 926
+776000 6464200 759
+805800 6451900 1000.5
+772900 6416000 1083.5
+798400 6449000 881
+786400 6442000 1192.5
+748600 6452300 898
+782400 6442000 975.5
+725400 6442700 1035
+771300 6440900 653.5
+791100 6423500 1379
+759000 6441300 891
+738400 6424600 1250.5
+770600 6461400 797
+774900 6473500 839
+804600 6463900 882.5
+718200 6467600 659.5
+767100 6422100 1123
+746400 6456500 739.5
+771500 6449800 730
+737200 6459100 658
+744000 6472600 876
+742200 6457400 700
+797700 6471700 677.5
+766400 6470500 917
+758300 6463900 1040
+734400 6449000 656
+723100 6471400 555.5
+785500 6447400 948.5
+799900 6467800 782
+763700 6425500 1176.5
+758200 6423000 1042
+761700 6429300 1201
+763000 6442000 803
+729300 6471000 432
+750100 6453500 947
+760600 6470900 851.5
+738500 6435700 819.5
+776300 6418700 983.5
+731700 6449600 746
+737600 6451400 611
+730400 6455200 597.5
+733300 6468300 531
+728400 6443700 898
+746400 6462800 922
+743200 6423500 1052
+733000 6446400 739
+756100 6458100 1015.5
+788300 6449900 954.5
+790700 6473500 632
+740300 6456600 591.5
+713400 6468800 673.5
+753900 6423300 854
+802800 6472000 727
+783600 6427200 1104
+773000 6439000 718
+781100 6456600 771.5
+754600 6469400 1018
+750700 6466800 1009
+768900 6436900 776
+764000 6464800 979
+730100 6455500 669
+748000 6460700 939
+739400 6473300 810
+740900 6463600 642
+798200 6473600 637.5
+762000 6467800 963.5
+752900 6437700 1185.5
+758700 6453800 989
+722900 6454900 804.5
+753500 6432600 884
+759900 6416600 964.5
+788600 6435500 1080
+777700 6448700 833
+744400 6418600 1165.5
+725000 6474700 443
+727600 6459900 727
+755600 6417600 911
+742500 6461800 679.5
+776000 6444800 755.5
+757300 6471100 871
+735600 6462700 582.5
+769800 6408200 1091
+762500 6413500 989.5
+751000 6462400 996.5
+802900 6466700 842
+744000 6454300 751
+362600 6738000 51
+352200 6661800 39.5
+346600 6688000 13
+309300 6707300 6.5
+367600 6675600 33
+281900 6712400 18
+374200 6687200 49.5
+372500 6714300 31.5
+335400 6678100 20.5
+367400 6719900 36.5
+327300 6724900 36.5
+342600 6685000 17
+376100 6737200 74.5
+360700 6698200 38.5
+348200 6689400 32.5
+376500 6702800 38
+359400 6734200 36.5
+320600 6696000 25.5
+336000 6668900 19.5
+376900 6682200 52
+339900 6665900 21
+318400 6690700 31
+338900 6712600 52.5
+386100 6739300 77
+373100 6671400 38
+382300 6668900 69
+316800 6703700 15.5
+311800 6721800 31.5
+377700 6715500 40.5
+399700 6712100 54
+341400 6719200 25.5
+376300 6707800 40
+313300 6680900 30
+363200 6666800 32.5
+380900 6718100 50.5
+284600 6708400 22.5
+377800 6732100 59
+379100 6690500 69.5
+367900 6670900 39
+320000 6699600 5.5
+400900 6706200 34.5
+317800 6698600 13
+358200 6703600 24.5
+403800 6707400 34
+300000 6713200 11.5
+384900 6733100 72.5
+322000 6707800 35
+393600 6712600 50.5
+352600 6706200 39
+333100 6706900 45
+289800 6700400 11.5
+325700 6739900 40.5
+391300 6708900 42.5
+311400 6704700 7.5
+362200 6689000 22.5
+370800 6717600 37
+371200 6691000 47.5
+310400 6688300 28.5
+308300 6703700 5
+366300 6714000 27.5
+364400 6694700 37
+299100 6703900 20.5
+349900 6685700 21
+356900 6681600 23.5
+356000 6747200 52.5
+352800 6723700 54
+383300 6704900 28.5
+359400 6688300 17.5
+294000 6717100 24.5
+327200 6707300 43
+350400 6675800 11
+371800 6700000 43.5
+338700 6662300 27.5
+374700 6730100 62.5
+379800 6750300 91
+342500 6687800 17
+299600 6718900 27.5
+365500 6680800 25.5
+372200 6694700 40
+305000 6682800 18
+327100 6718500 19
+341500 6681400 14.5
+373700 6675700 27
+337300 6736600 42.5
+369600 6753200 79.5
+352600 6679400 15.5
+348300 6717900 30
+356200 6708300 24.5
+381400 6722700 50
+367700 6705500 40
+350800 6702500 41.5
+375600 6680000 43.5
+383900 6727800 65
+324200 6672100 19.5
+345600 6687100 20
+346700 6727700 58.5
+318400 6728900 35.5
+342700 6690100 37
+331500 6699200 45.5
+319400 6720600 16.5
+350600 6695900 40.5
+325800 6680200 31
+377500 6746200 84
+357600 6671500 26.5
+350900 6664900 29
+334700 6713200 46.5
+288500 6714100 17
+349600 6740100 42.5
+342900 6724100 42
+363500 6749200 65.5
+347200 6695200 52.5
+375200 6674000 39
+333700 6665900 18
+386500 6714400 47
+365100 6678800 31
+370100 6710400 42
+349000 6724400 51
+330700 6689000 30
+305300 6718300 5.5
+316800 6716400 26
+338800 6697200 44.5
+332200 6687400 30
+327000 6694300 23.5
+344800 6708400 55.5
+370000 6679200 31.5
+368500 6692900 26.5
+296500 6698700 22
+350000 6653000 46
+322400 6684200 31
+341400 6672300 24.5
+363100 6661800 43.5
+376900 6721900 52.5
+320600 6674600 19.5
+381900 6735400 73
+331300 6678300 16.5
+321100 6725000 37.5
+371400 6684200 19.5
+308800 6717300 18.5
+364100 6708800 22.5
+361500 6683800 28.5
+369200 6726900 60
+355500 6689600 27
+367100 6751900 74
+360800 6692900 19
+291100 6713100 15
+349200 6679600 14.5
+381200 6712200 41.5
+286100 6700700 10.5
+371800 6733600 53.5
+335500 6686800 13.5
+283900 6702600 10
+354200 6686700 21.5
+319900 6739300 36.5
+372000 6744300 77.5
+347800 6669800 25.5
+327600 6680700 31
+344900 6742500 40
+366300 6673300 29
+380900 6689800 78
+353600 6734700 34.5
+349400 6711700 41.5
+332600 6727100 33.5
+376100 6695200 45.5
+390600 6706000 19.5
+344900 6682000 17
+339400 6658600 28
+290300 6706100 30
+318100 6676700 23.5
+331400 6741700 27.5
+374600 6750700 88
+365500 6757100 73
+325000 6701400 7.5
+323300 6718600 18.5
+307900 6710900 4.5
+352000 6666600 19.5
+388100 6712700 45.5
+343700 6655300 39.5
+355900 6741200 46.5
+384800 6705300 23
+359400 6726700 58.5
+371100 6673800 31.5
+343400 6735600 32
+396100 6706000 40.5
+361100 6714000 37.5
+309500 6695700 19.5
+316200 6712100 8
+306900 6683700 19
+310600 6714000 11
+329400 6702700 14
+342300 6702500 58
+338500 6702900 83.5
+341100 6678800 19
+351800 6743000 35
+377700 6672600 55
+292800 6701200 28
+394200 6728000 63.5
+359500 6671600 29
+321100 6732600 31
+363800 6745100 62
+391000 6717200 55.5
+340300 6688400 13.5
+371600 6679900 27
+383900 6684100 71.5
+348500 6732100 53
+368200 6697600 42.5
+325000 6708700 38.5
+352400 6728400 54.5
+355500 6721300 47.5
+365900 6734300 49
+356200 6698700 29
+366900 6682100 32
+306400 6699600 23.5
+364900 6687000 28
+340300 6681100 26
+359600 6676100 30.5
+325600 6713100 41.5
+388000 6729200 65
+385300 6722200 55
+396700 6715200 70.5
+329900 6669700 21.5
+367500 6739800 63
+692200 6773800 120
+653500 6750300 127.5
+682900 6763700 112.5
+658000 6766600 119.5
+634600 6751900 102.5
+653000 6783300 111
+635000 6752900 110.5
+655100 6769000 125.5
+661900 6724600 167.5
+655500 6779200 108.5
+686600 6735000 167.5
+675200 6768800 95
+676200 6727500 165
+636200 6731200 129
+695600 6775800 138
+649700 6801200 125.5
+660200 6766000 112
+633600 6785100 127
+602600 6763400 121.5
+605600 6773900 126
+596100 6740700 97
+691200 6770900 125
+694600 6758900 146
+649800 6769400 143.5
+620600 6735700 115
+597900 6768100 124
+628800 6753000 99.5
+607800 6760200 118
+643500 6797800 128.5
+678100 6753400 113.5
+672400 6760100 100.5
+644000 6781200 114
+670000 6778400 89
+641000 6799800 121.5
+665600 6767000 98.5
+609100 6767200 123.5
+650900 6763000 134.5
+628700 6765700 127.5
+610900 6738900 106.5
+666400 6774700 87.5
+626600 6762300 120.5
+634000 6782700 123
+682400 6755200 113.5
+646600 6800300 128.5
+693900 6728600 190
+599100 6750200 107.5
+680400 6726400 155.5
+674600 6751700 128.5
+691200 6723500 183
+680400 6771800 95.5
+682700 6782600 91
+684700 6740300 156.5
+668500 6734800 138.5
+691100 6742600 151.5
+606100 6768500 123.5
+688600 6761400 121.5
+660300 6756500 118
+627200 6790600 129.5
+655100 6771800 124.5
+660700 6789600 111.5
+688400 6768600 119.5
+643500 6744100 127.5
+648100 6745800 110
+703900 6760300 155.5
+639600 6781700 112.5
+660700 6732400 145
+684700 6770600 104.5
+666800 6761900 101
+643000 6778300 113
+670200 6758000 107
+640000 6744100 126.5
+623000 6763200 123.5
+641500 6802800 120.5
+633200 6764000 125.5
+658600 6769400 114
+688500 6746900 147
+692400 6782300 115
+630500 6780800 129.5
+705300 6763200 171.5
+658600 6785100 110
+629500 6774800 130
+597500 6755400 115
+644400 6782700 110.5
+623100 6757400 111
+658100 6778200 105
+615700 6742600 110.5
+668600 6770800 89
+647500 6773100 136
+609800 6773300 127.5
+672200 6732100 153.5
+649200 6777600 107.5
+678300 6765600 91.5
+629500 6754500 110.5
+694100 6773200 127.5
+688900 6760800 121.5
+646700 6777500 110
+652000 6726400 152
+640900 6735000 133.5
+674500 6715600 221
+674700 6775400 91.5
+632300 6791800 129.5
+616700 6765600 126
+658300 6793700 93.5
+669500 6768900 98
+657700 6792900 105
+665600 6733300 140.5
+683200 6778200 89.5
+662700 6762800 111
+698600 6776600 149
+679900 6725100 180
+645500 6763500 144
+660900 6740800 133
+594000 6759700 120.5
+672000 6748600 150
+608300 6754400 103
+652800 6741800 112
+638700 6798100 122
+597500 6742900 98
+653100 6797000 117.5
+644400 6786000 113.5
+653600 6787600 108
+616100 6770400 127.5
+592000 6768700 127
+680100 6766300 97
+677000 6778700 89.5
+693100 6720000 169.5
+653900 6775000 113
+600500 6746400 98.5
+627500 6771600 133.5
+647500 6791900 113
+641300 6774100 132
+668000 6750800 140.5
+687300 6775400 110
+645200 6760200 122.5
+634100 6787200 125.5
+639000 6764200 126.5
+677600 6771600 91
+699000 6781400 136
+602600 6748400 97.5
+658500 6754100 127
+671700 6765800 100.5
+673200 6756300 115.5
+603100 6761000 115.5
+626200 6779000 127
+645800 6745100 110.5
+646900 6791500 125.5
+621000 6779600 125.5
+657400 6787800 109.5
+661500 6773500 97.5
+695100 6772200 132
+658200 6794800 96
+681300 6738400 165
+621500 6759600 118.5
+694800 6719400 192
+652400 6766400 128
+635600 6775000 132
+644000 6793400 127.5
+613200 6765800 122.5
+624100 6771600 128.5
+680300 6768000 95.5
+697400 6766900 159.5
+623200 6782400 130.5
+627600 6749900 109.5
+599500 6772500 123
+653700 6744300 114.5
+674300 6728800 156.5
+675800 6744200 150
+613300 6755000 100
+670100 6722000 188.5
+690400 6725200 172
+641700 6780300 115.5
+678700 6712000 235.5
+633100 6757300 111.5
+624900 6795600 132
+686200 6715800 195
+638600 6794700 124.5
+657500 6792200 106
+655300 6746000 131
+657500 6774500 105
+658000 6738200 135.5
+700900 6777000 153
+685600 6756200 117
+619400 6759600 121
+685600 6730300 161
+641600 6795800 127
+692100 6767800 134
+628900 6785100 128.5
+610200 6750300 92.5
+686400 6746400 140.5
+688000 6717800 159.5
+620700 6782100 129
+678800 6773500 90
+644100 6730400 143
+596800 6762000 121.5
+663600 6754400 143.5
+647700 6736700 132
+620500 6784400 132
+622900 6748200 109
+633900 6780600 121
+645100 6749800 107
+638900 6789800 129
+684000 6721100 154.5
+607000 6747500 95.5
+646300 6795900 124
+633300 6748700 103
+645300 6750900 122.5
+684300 6761400 112
+696800 6772400 141
+698600 6759900 152
+609300 6765100 124.5
+641300 6765900 128
+624600 6756000 102.5
+651100 6793300 122.5
+650400 6774500 116.5
+649900 6783000 109.5
+665900 6760900 108
+627300 6755200 105.5
+653700 6774400 119.5
+610500 6747100 99.5
+692400 6769200 136
+626700 6740900 116.5
+619300 6773900 124.5
+686500 6751200 128
+669900 6730900 149.5
+633400 6797600 114.5
+610200 6769400 125
+626700 6733700 121.5
+628400 6793600 123.5
+692000 6731400 173
+695900 6780400 132.5
+625300 6785800 130.5
+679000 6742900 152
+649900 6787600 109
+612000 6760700 118.5
+680700 6749600 129.5
+667100 6766200 98.5
+628100 6797100 125.5
+672000 6762500 96
+655900 6799700 103.5
+616400 6761800 122.5
+622100 6776600 126
+662600 6791900 121.5
+676700 6760800 96.5
+631800 6767200 130
+654000 6770900 127.5
+642100 6748300 106
+694300 6783100 126.5
+662600 6787400 110
+601500 6765300 121
+595000 6745400 112.5
+643600 6775900 138
+603700 6744800 93.5
+663900 6740200 139
+635300 6744900 120.5
+652600 6747900 127
+674300 6772300 91
+654900 6757700 124
+684300 6776700 96.5
+664400 6757300 116
+624700 6774800 126
+674500 6746700 135
+633900 6779500 124.5
+678000 6755700 103
+662000 6770600 101.5
+608600 6732300 100.5
+661700 6736400 132.5
+704100 6771000 161.5
+633600 6792800 120
+593300 6748500 119.5
+612900 6752300 96
+652400 6780200 114
+596500 6771200 127.5
+670200 6772800 87
+629500 6761900 120.5
+603100 6755500 108
+639600 6778200 114.5
+692900 6779800 121
+626000 6759000 109.5
+693400 6762800 148.5
+659200 6759900 113
+701000 6772500 150
+689500 6781600 108.5
+647900 6761900 131
+650200 6798200 121
+681900 6779000 88
+641200 6785000 115
+671300 6778100 87.5
+672100 6771900 89
+680400 6757700 105.5
+654900 6793900 120
+636400 6778700 118
+689700 6751800 148
+665300 6772900 92
+606800 6751600 95
+638500 6748300 104
+649100 6749200 119
+602800 6772800 123
+660900 6780000 99
+616500 6776400 123
+656900 6771300 119
+680400 6760800 98
+636700 6799500 128
+694500 6750100 165
+658900 6783500 109.5
+601600 6741900 96.5
+658400 6765600 120.5
+600200 6759800 114.5
+681400 6753400 115.5
+696400 6754900 162
+694700 6743600 167
+669700 6754700 115
+664800 6777700 87.5
+646200 6786400 112
+653200 6740700 129
+632600 6751200 100.5
+615800 6757600 105.5
+688100 6738400 164.5
+615400 6754000 93
+619100 6755200 95.5
+681400 6721200 186
+603000 6767500 122.5
+672200 6770000 101
+612200 6758400 118
+622300 6753500 96
+699600 6744400 181
+653900 6788500 109.5
+618100 6756300 107
+650100 6731800 140
+641800 6752000 115.5
+656000 6789100 104.5
+617700 6752000 99
+597800 6746200 108
+635700 6759100 114
+657000 6780300 106
+611700 6424000 335
+574700 6411300 196.5
+605500 6419800 272
+596600 6373900 248.5
+561200 6390800 235
+566700 6394600 273.5
+612600 6379100 268
+609200 6422400 214.5
+566000 6378200 198
+609300 6368300 326
+562000 6384800 212.5
+570300 6369700 237.5
+630600 6408000 595.5
+608300 6424600 187
+544600 6374800 168
+565600 6358600 219.5
+567400 6361500 231
+602300 6422500 243.5
+594300 6403500 332
+550300 6368600 215.5
+590200 6370100 244.5
+614800 6424900 336.5
+553500 6380100 100
+606900 6417900 265
+583700 6353200 230
+587300 6386500 295.5
+582600 6418500 204.5
+572500 6366800 228.5
+608200 6394900 316.5
+635800 6391300 372.5
+558700 6379600 175
+615900 6380900 265.5
+593300 6434000 163.5
+610600 6362100 369
+586200 6423200 203.5
+632000 6387100 296.5
+607300 6369600 271.5
+623200 6390400 310.5
+611400 6427300 275
+605600 6364800 368.5
+620200 6427400 396
+601100 6359900 329
+589200 6421700 205.5
+609100 6410200 465.5
+556000 6356500 187
+576300 6395400 291
+573100 6363700 273.5
+560700 6386900 210
+569300 6412400 145
+542300 6378600 149.5
+630500 6415400 676.5
+629800 6396700 338.5
+608900 6418900 270
+611600 6425300 250.5
+603900 6410000 358.5
+561900 6380700 192.5
+566700 6411700 139
+564500 6383600 209
+620500 6398400 400.5
+549200 6372400 217
+612700 6419400 308.5
+587700 6420800 187.5
+612400 6418400 332
+545400 6379500 104
+622300 6405000 529
+583500 6436800 284.5
+596800 6412800 346.5
+618000 6417700 378.5
+598400 6380600 254.5
+633300 6396700 344
+584000 6361000 264.5
+609100 6402200 361.5
+575700 6388400 293
+576900 6390900 342.5
+594700 6433200 182.5
+619700 6392400 274
+618600 6401100 446.5
+554500 6378800 152
+588500 6393600 360.5
+558900 6363600 220
+561500 6358100 211
+604000 6405500 336.5
+586100 6417200 214.5
+604000 6386300 254
+606400 6410500 383
+592900 6390200 368.5
+593900 6397200 389.5
+561800 6364800 240
+590900 6421200 208.5
+579700 6397100 317
+546400 6375900 170
+567100 6380400 201.5
+614400 6389800 255
+559700 6375900 208.5
+629300 6391700 316
+610900 6377600 267
+625700 6414400 620.5
+585600 6387900 306.5
+608000 6376900 267
+616200 6399800 442.5
+564800 6388100 241.5
+599300 6394800 362
+557300 6361600 213
+566500 6390500 268.5
+556800 6378300 160.5
+590100 6403400 278
+581500 6401500 340.5
+574100 6401300 266
+577900 6402100 300
+598300 6386000 290
+602800 6376000 257.5
+605700 6413400 379
+596600 6431600 194.5
+590300 6427400 214
+559200 6369900 215
+582700 6396700 332
+593100 6379500 248.5
+576400 6365800 217.5
+594200 6374800 254.5
+618300 6382800 260
+578100 6376400 220.5
+553800 6361800 222
+581700 6409000 260.5
+602000 6411800 359.5
+584300 6404000 330.5
+626700 6394000 351
+592900 6435300 189.5
+566000 6395000 241
+605900 6408100 377
+614800 6429200 322
+571800 6354600 221
+627300 6389800 300
+559400 6395400 240.5
+566200 6404000 196.5
+591800 6360700 268
+616700 6389500 244.5
+607300 6387200 271
+614500 6383700 340
+587200 6376500 234
+573900 6410800 210
+619500 6385700 261.5
+591100 6364000 268.5
+556000 6380000 182
+588500 6366500 228
+581100 6364300 240.5
+619100 6396600 288.5
+565100 6361500 230
+561100 6370300 244
+596100 6399900 375.5
+555200 6368300 222
+559900 6365200 237.5
+590500 6408400 257
+618500 6413400 341.5
+594100 6362200 278.5
+547500 6367500 224
+572900 6416400 159
+606800 6425400 136
+580200 6420600 210
+572800 6396800 257.5
+599300 6368500 256
+627800 6400200 391
+607200 6405200 364.5
+583800 6366300 218.5
+588900 6436300 237
+585000 6377400 230.5
+578000 6398900 298.5
+579200 6412000 244.5
+616000 6416100 320
+624400 6429400 455
+547000 6384400 187
+572800 6360100 261.5
+594400 6427700 208
+613100 6401700 450.5
+608700 6406100 368.5
+580000 6383900 306.5
+611200 6403200 380.5
+592000 6377100 234
+569400 6377800 185.5
+552200 6386200 224
+599100 6409700 312
+608500 6400600 350.5
+552500 6370700 200
+612600 6390500 293.5
+603800 6361500 347
+582300 6385900 298
+626100 6387300 262
+547400 6381600 168
+597900 6418000 324
+586000 6425900 230.5
+575900 6417900 179.5
+579800 6375400 220.5
+606400 6360700 372
+632900 6412700 596
+574200 6392400 286
+627100 6411600 621.5
+586600 6421100 189
+547900 6378700 168
+566000 6367200 269
+602900 6398300 340
+600100 6428000 169.5
+562500 6399500 215.5
+616700 6405500 484.5
+568500 6353600 201.5
+621000 6403200 486.5
+590900 6354700 277
+614000 6395700 335
+615800 6411100 459.5
+601700 6414300 372.5
+593800 6425000 217.5
+596700 6415000 334
+614900 6397900 355.5
+572100 6382100 231.5
+620500 6394300 296
+598500 6401000 354
+585200 6390700 335.5
+609700 6400300 363
+624500 6397600 393
+616200 6420500 356
+553900 6391500 246
+610000 6414400 428
+580900 6389400 356.5
+609000 6426100 195
+577100 6381700 257.5
+622500 6408000 477.5
+564800 6375500 210
+613200 6416100 399
+621100 6417000 465
+614900 6403900 474.5
+586400 6395300 357
+603100 6401900 329.5
+633200 6408800 581
+572000 6405600 226.5
+556800 6397900 260
+572700 6389300 293
+589100 6386300 277.5
+577000 6387900 309.5
+604300 6425100 195.5
+576300 6383200 275
+630700 6404700 470
+544500 6383200 171.5
+554200 6388700 223
+615900 6428700 330.5
+584800 6430500 260.5
+561200 6394000 247
+576400 6406000 296.5
+602900 6374700 240.5
+611000 6398000 357
+606300 6422900 193.5
+606400 6392700 355.5
+610000 6418800 274
+571300 6383500 229
+580500 6406200 295.5
+570900 6380500 201
+604800 6381800 275.5
+573100 6376800 200
+581800 6374100 226
+563500 6371300 231
+553900 6359900 202.5
+550100 6362900 226
+576200 6356600 209.5
+579500 6423200 197
+559800 6383700 198
+578300 6414400 196.5
+569500 6407600 163.5
+614800 6407600 511
+616000 6391200 300.5
+616900 6396700 318.5
+563800 6377000 203.5
+592400 6392300 387
+586000 6399800 341.5
+584900 6401200 324
+591900 6385700 256.5
+566500 6397600 223
+608000 6388800 293.5
+630200 6388400 278
+584500 6368700 200.5
+598300 6362900 312
+624800 6425300 603
+569500 6375800 205
+574700 6416300 185.5
+554800 6386800 219.5
+590700 6412100 237
+623800 6419800 572
+601500 6416600 372
+619600 6409900 421.5
+617500 6424900 399.5
+558000 6392800 232.5
+556300 6375700 177
+572300 6386400 253.5
+611600 6421800 276
+575900 6373300 218.5
+602700 6394000 349.5
+552000 6380100 182
+622500 6393200 353.5
+602400 6384600 265.5
+572900 6384000 240.5
+590600 6434200 219.5
+579400 6424400 206
+579800 6381100 250.5
+571700 6378900 202
+600300 6374500 240
+567900 6385500 235.5
+592300 6372500 325.5
+611600 6382600 299.5
+616900 6381500 264
+599200 6374800 256.5
+552900 6364700 240.5
+597800 6429000 211
+573200 6412900 165.5
+592000 6367900 281.5
+599900 6425200 225
+620300 6404900 491.5
+622900 6411100 463
+616600 6387400 290.5
+630000 6390600 287.5
+613800 6413000 433.5
+553100 6376800 168
+556800 6388000 218
+581400 6391400 356.5
+578500 6435200 254.5
+594200 6383800 247
+584400 6413700 197
+583500 6398400 330.5
+583500 6386500 276.5
+613400 6405100 444.5
+631400 6389800 319.5
+603400 6423800 141.5
+587500 6389200 345.5
+613000 6410200 511.5
+602100 6367300 308.5
+550500 6373400 190.5
+596100 6375100 251
+558600 6356400 198.5
+581900 6355100 229
+580200 6358100 247.5
+580500 6368500 219.5
+584000 6381000 252
+576900 6419800 204
+592600 6432700 225
+625600 6404500 481
+488800 6394500 75
+463400 6376600 90.5
+468500 6369400 107
+498100 6367400 48
+531200 6353400 168.5
+474200 6395500 89.5
+492200 6353600 121.5
+482500 6380100 78.5
+519400 6352700 147.5
+478500 6347600 132
+495200 6348100 96.5
+514600 6380300 147
+475900 6392200 87
+485000 6395700 61
+516600 6342200 49
+471700 6327900 114
+496000 6352100 110
+461500 6373200 111.5
+537000 6385000 159
+511200 6368300 130.5
+478900 6382600 79
+487600 6362000 92.5
+502600 6363900 118.5
+485800 6403100 116.5
+503100 6375100 122.5
+526900 6387100 133
+473100 6367100 107
+513900 6345800 128.5
+467800 6383700 17
+513800 6335400 112.5
+536200 6377100 81
+542400 6389800 199.5
+482300 6354300 96
+482100 6336900 83
+479800 6351500 121.5
+525300 6392200 143.5
+463000 6348700 125
+474000 6405100 77.5
+483900 6345700 99
+508700 6340900 112
+504300 6398400 99.5
+478700 6389300 84
+481300 6405200 84.5
+463600 6367000 113.5
+522500 6393200 139.5
+493800 6335800 123.5
+465600 6386700 15.5
+475700 6375100 51.5
+482700 6390000 92
+493400 6391500 87
+527200 6396300 147.5
+519500 6377000 122
+512200 6351700 125
+506800 6335100 149.5
+481700 6398200 69.5
+511400 6384700 153.5
+473000 6372400 61
+485600 6369300 93.5
+487300 6354000 33
+474900 6388100 76.5
+456000 6349500 127
+509200 6379500 129
+472800 6353000 132
+491400 6383800 91.5
+515900 6357800 166.5
+485800 6407200 130.5
+499900 6341200 132.5
+470300 6380900 17.5
+484500 6399800 84
+502700 6379700 128.5
+515200 6392100 134.5
+530100 6362300 175.5
+517900 6361800 169.5
+476800 6379200 27
+473600 6362800 110
+497500 6375700 110.5
+528800 6360100 163
+480200 6362700 75
+512400 6360500 174
+526500 6359200 159
+537400 6365700 172
+491100 6365800 106
+461700 6363700 125.5
+504900 6395800 108
+516200 6398200 92.5
+479600 6365300 68.5
+508100 6393900 113
+504400 6347900 47.5
+515900 6367900 138
+504500 6349800 109.5
+497600 6361300 130
+513200 6401800 105
+490900 6358800 111.5
+526300 6367900 141.5
+515700 6334300 121.5
+514800 6350800 128.5
+477200 6404200 80.5
+492200 6363800 86
+532200 6386800 174
+505100 6388600 119
+501400 6333800 144
+497500 6381900 109.5
+504900 6393700 127
+509700 6347800 99.5
+500800 6334900 132
+495100 6394200 92
+484300 6373400 55.5
+522900 6342800 113
+519600 6359700 161.5
+483100 6330000 114.5
+481100 6375100 28.5
+512900 6340000 112.5
+514500 6371300 59
+489400 6376900 95
+499500 6384200 104.5
+510700 6374400 121
+517200 6370200 125.5
+525500 6356000 148
+480200 6367700 60
+518900 6337900 83
+524100 6349900 129
+507900 6365500 134.5
+493200 6348500 97
+509100 6397700 103.5
+496900 6343500 122
+486400 6393000 80
+460100 6353200 125
+467800 6361600 111.5
+511900 6332200 133.5
+526300 6401000 154
+502400 6337900 143.5
+504900 6344700 104.5
+510400 6342900 48
+497900 6336100 103
+512200 6396400 108
+474800 6336400 108.5
+488200 6402500 108.5
+483000 6344800 92
+484800 6376700 79
+521000 6395600 123
+524300 6378200 111.5
+476400 6360500 113.5
+514500 6375500 111
+492000 6372600 107
+467700 6380000 48.5
+485900 6347800 81
+527500 6352800 148.5
+469200 6385500 49.5
+473000 6344600 138.5
+506500 6398600 101
+480400 6332400 107.5
+476800 6401400 78
+493200 6340500 119
+464300 6384700 51
+526600 6340300 116.5
+535600 6373600 106.5
+500500 6369600 113.5
+507000 6389100 127
+529900 6373000 137
+508500 6347600 73
+470200 6374700 78.5
+489500 6373400 86
+480900 6349000 138
+489200 6386800 98.5
+489000 6397800 79.5
+484900 6392200 88
+507900 6385400 126.5
+505400 6371900 63.5
+538900 6391100 189
+474700 6381900 72
+535000 6368800 158.5
+467600 6342800 138
+499100 6349300 74.5
+466600 6366300 101
+473900 6358000 115
+473900 6376200 47.5
+497200 6356500 128.5
+478500 6371900 68.5
+499600 6393800 101.5
+477900 6396200 77
+485800 6396600 74
+470100 6359600 125
+501300 6350600 114
+540400 6368800 182
+493700 6358900 112
+498900 6363400 114.5
+462700 6357100 108
+501400 6345200 101.5
+492400 6353200 35
+504900 6341000 124.5
+504200 6386300 128.5
+515200 6393900 116.5
+524200 6386900 137.5
+525700 6350000 135.5
+522600 6383900 135.5
+484400 6354700 82.5
+494400 6377300 90
+486700 6382900 84
+529200 6377600 146.5
+508000 6369500 115.5
+512500 6377400 117
+524000 6345600 124
+461600 6366000 129
+489300 6329600 118.5
+543800 6366200 204
+492700 6397100 82
+520900 6396500 101
+516200 6343700 95.5
+472300 6388700 78.5
+530900 6385600 140
+525500 6342600 122.5
+538400 6379800 131.5
+533000 6391200 194
+469800 6378500 75.5
+519700 6348600 126.5
+545000 6369500 206
+542000 6372000 188.5
+505200 6342700 109
+496700 6368800 112
+483800 6349000 106.5
+487900 6359200 95
+512200 6381300 150.5
+498700 6389300 104
+515300 6359900 170.5
+523300 6360600 143.5
+525500 6361900 145.5
+480000 6358700 104.5
+526700 6397800 153
+511400 6390000 132.5
+504000 6390600 115
+495500 6381900 115
+490600 6392700 81
+495600 6359000 123.5
+485400 6363800 27
+489000 6380400 82
+486000 6387100 89.5
+536300 6379000 107
+501200 6357400 136.5
+498900 6377500 116
+534300 6378600 114
+539900 6377600 142
+523900 6352200 147.5
+486100 6358100 28
+461300 6380400 77.5
+530000 6342900 129.5
+538500 6370900 165.5
+492500 6387700 99.5
+515500 6344400 113
+464600 6355200 112
+482600 6358300 87.5
+531900 6367200 149
+508900 6359300 168
+527500 6346600 127.5
+471600 6369100 98
+490700 6380100 93.5
+519500 6342000 115.5
+502800 6367600 111
+470900 6331200 112.5
+522600 6339100 58
+487100 6341000 114.5
+521000 6344800 114.5
+521400 6356300 154.5
+473300 6385900 65.5
+470900 6388300 70.5
+491100 6333000 102
+506400 6374100 120.5
+494200 6354900 115
+482600 6366300 32.5
+506400 6356100 143
+487100 6389900 97.5
+528800 6384800 158
+466700 6372200 101.5
+479600 6373100 22.5
+485500 6335400 97
+476400 6331400 110.5
+467600 6326900 117
+468500 6389000 64.5
+468800 6370300 89
+480400 6370700 33
+525300 6369000 135
+532700 6370100 141
+482700 6407100 111
+472200 6403200 73.5
+518000 6397500 95.5
+531600 6347700 146
+513500 6365000 147
+494600 6385600 101.5
+482400 6395300 80.5
+498600 6395500 87.5
+490300 6344600 121
+531400 6378400 159
+474600 6402400 66.5
+488100 6350500 99.5
+527200 6381000 125
+521100 6340000 59
+491600 6393700 83
+478200 6397700 49
+509900 6401300 94
+517300 6388200 134
+502400 6355600 122
+478600 6377500 27.5
+523700 6400000 127
+480600 6387100 91.5
+516900 6354500 137.5
+495300 6364700 47
+494000 6332800 117
+476700 6354900 134
+481300 6408500 92.5
+539000 6388500 187.5
+516400 6384900 119
+496600 6339100 104
+477900 6375900 21
+531000 6355300 157.5
+507700 6361100 154
+470900 6364200 111.5
+503600 6369400 107.5
+464500 6362500 120
+529500 6358400 156.5
+523600 6358100 163.5
+719500 6420300 953
+727400 6393600 1011.5
+724500 6421000 990.5
+725500 6356000 725
+716200 6417700 1040
+721000 6387000 951.5
+729600 6382900 958.5
+748900 6357700 865.5
+710700 6400200 1203.5
+716400 6389300 1178.5
+774200 6371600 734.5
+765600 6383900 1216.5
+747300 6358800 831.5
+746900 6345400 1001.5
+759300 6363000 1182
+757800 6342300 608.5
+754400 6378200 1227
+747900 6380200 1002.5
+732800 6363100 770
+762100 6408200 933
+718100 6353200 711
+723900 6388400 912
+720200 6424800 882
+742400 6376200 905.5
+738600 6396700 1321.5
+752100 6417300 1022
+767700 6403400 991.5
+723000 6383800 775
+705600 6406200 1126
+712000 6369400 719.5
+741200 6401800 1361.5
+755800 6364200 1184
+706800 6414300 987
+709600 6413000 1074.5
+726100 6383700 871.5
+744600 6384700 1177.5
+770600 6395000 1155.5
+778300 6375700 618
+712900 6381700 1120.5
+744800 6373100 1155.5
+758100 6399300 1179.5
+774200 6371500 1131
+750100 6409700 1092
+764700 6351300 863.5
+759200 6385200 1326.5
+764700 6346900 711
+730000 6427600 1276
+724400 6416500 965
+773700 6350000 580
+745200 6410400 1311.5
+737400 6404200 1240
+726100 6417500 944.5
+739800 6384600 1030.5
+710500 6379700 975
+728200 6361700 735
+716800 6343500 618
+726800 6424200 1148
+721800 6411600 1030.5
+731500 6393400 1060
+720200 6379600 811.5
+748100 6352600 867
+768500 6375400 1147
+708500 6394700 1221.5
+725600 6407400 1007.5
+772400 6355200 674.5
+771600 6350500 642
+722500 6379400 769.5
+766100 6358500 1066.5
+713400 6397300 1185
+762000 6401900 1109.5
+720000 6408200 1123
+710900 6374800 880
+728700 6375900 814
+724400 6425700 1115.5
+717100 6370400 764.5
+739900 6376000 898.5
+753100 6355800 1000.5
+766400 6403500 966.5
+713700 6375500 821
+752500 6382700 1126
+765400 6399900 1091.5
+715100 6411500 1133
+718600 6392100 1084
+771400 6359800 922
+777100 6351200 486.5
+768300 6354400 753
+763600 6394600 1273
+752300 6344200 713
+725900 6417300 1170.5
+754800 6400400 1217
+754400 6345700 700
+722200 6375900 760
+720600 6344500 728.5
+723700 6380200 845
+736400 6375800 872.5
+733700 6415500 1250
+729400 6390300 1013.5
+718900 6399100 1138
+762600 6373700 1292.5
+756300 6375900 1349.5
+712100 6406600 1161
+760000 6395900 1277.5
+757500 6406200 1090
+749400 6361200 770.5
+735700 6396100 1157
+760200 6346600 761.5
+760000 6385800 1308
+715900 6370800 715.5
+769000 6350900 630
+733700 6396700 1068
+753500 6393700 1227.5
+756800 6388400 1311
+712500 6365000 839
+771900 6388600 1039.5
+761500 6375200 1194.5
+710100 6419500 950.5
+721100 6380600 929.5
+717200 6352800 694
+752200 6349700 782
+741800 6363600 779.5
+746100 6349100 928.5
+730600 6400600 1032.5
+748200 6360400 855
+708400 6412500 1084
+710200 6408000 1150.5
+728100 6349600 852.5
+722500 6402700 1067.5
+731600 6356700 978
+767300 6341200 559.5
+730600 6404500 1016.5
+707300 6377800 1091.5
+730700 6409200 1088.5
+743100 6346400 1001.5
+740200 6359900 792
+749000 6385700 1145
+750100 6396100 1344
+722800 6395500 1016
+727300 6374200 808
+762700 6340800 512
+730000 6377200 825
+750000 6342500 1057.5
+715000 6368100 765
+717700 6405500 1119.5
+775500 6369100 755
+756900 6413200 954.5
+727100 6414200 994.5
+759800 6403200 1060.5
+732600 6378500 931
+748000 6400800 1352.5
+759300 6342600 622
+742700 6363600 866
+727100 6399400 1024
+750400 6380300 1102
+739800 6380100 963.5
+766700 6353600 853.5
+745500 6378100 1099.5
+743700 6382100 978
+709400 6416900 948.5
+759600 6352700 1032.5
+711700 6359900 902
+702900 6404500 1126.5
+734300 6342300 1086.5
+739100 6344500 1160.5
+750800 6387600 1307
+772300 6380700 815.5
+706600 6410700 1087.5
+746600 6403600 1341.5
+720000 6400400 1113.5
+703700 6395900 1233
+736900 6410300 1303.5
+737900 6392900 1292
+718400 6357800 712.5
+749400 6415800 1092.5
+755000 6412300 1001.5
+701900 6399200 1211.5
+773700 6345000 562.5
+713200 6412700 1119
+713900 6356700 910
+758400 6376600 1259.5
+732100 6386300 1052.5
+749300 6365400 1084.5
+752900 6378800 1021.5
+726900 6379400 870.5
+722600 6420800 949.5
+734000 6398600 1199
+405900 6747000 64
+444800 6674100 90
+390600 6743000 69.5
+465200 6679500 32.5
+455600 6716300 59.5
+471300 6720800 69.5
+444100 6687900 65
+432000 6701300 53
+459600 6697100 23.5
+378500 6695800 52
+418000 6685800 78
+373600 6699200 41.5
+395700 6680100 84
+471300 6726200 66.5
+405600 6669300 123.5
+415200 6679000 144
+436100 6680900 92.5
+477700 6703400 72
+413000 6737900 43.5
+440500 6683400 67.5
+418200 6720500 71
+460900 6726500 67
+450300 6677800 78.5
+378000 6701700 44
+454800 6674500 69
+413600 6723900 74
+423800 6722200 58.5
+403500 6698600 119.5
+414200 6668500 134.5
+397700 6685600 74.5
+386900 6743500 73.5
+396500 6725600 49.5
+458300 6718700 50
+424800 6726100 47.5
+457100 6686200 79.5
+459400 6732700 32.5
+461200 6686400 59.5
+383400 6695800 65.5
+437200 6673300 105.5
+477200 6719800 81.5
+455300 6724900 61.5
+483000 6716400 70
+402700 6745400 68
+424000 6719700 60.5
+487400 6721400 76.5
+425600 6695400 56
+462200 6695300 24.5
+450700 6673700 64.5
+468400 6679100 65
+412200 6672900 148
+447200 6690100 74
+463900 6681800 47
+469200 6712200 57
+416000 6746100 64
+426500 6714600 54.5
+418800 6664500 153
+408800 6708400 47
+438800 6691200 69.5
+412900 6686200 108.5
+432300 6714100 38
+388800 6683700 76
+429700 6691200 57
+432300 6677800 131.5
+441000 6707800 18.5
+418100 6693400 62
+405200 6688100 91.5
+390200 6739200 72
+394900 6670100 90.5
+436300 6724100 38.5
+405100 6677800 100
+445100 6723200 41.5
+457700 6709300 34
+438400 6736900 44
+431100 6670500 158.5
+456800 6735200 57.5
+391800 6697000 59.5
+413000 6676000 131
+464600 6685000 51
+428300 6720400 42
+405300 6681900 91.5
+485900 6707900 83.5
+395700 6683600 78
+441300 6739000 47.5
+450200 6729000 63
+434200 6702000 56.5
+428800 6742000 51.5
+412700 6697700 71
+443100 6724300 36
+470800 6688000 27.5
+383900 6745300 77.5
+435500 6691100 60.5
+437400 6734100 46.5
+459900 6714500 55.5
+388800 6689400 88.5
+468300 6681600 67
+459500 6729300 52
+387200 6746100 78
+420100 6682300 143.5
+466600 6720400 71.5
+403500 6741100 67
+450000 6704900 47.5
+457200 6675700 67.5
+424600 6691200 61.5
+446500 6698800 61.5
+403600 6673200 112.5
+488600 6715900 83.5
+410300 6667600 125.5
+406500 6742400 59.5
+397500 6746800 74.5
+435300 6687800 59
+414500 6732500 45
+396300 6734000 74
+464700 6714800 65
+432000 6735400 50.5
+441200 6719200 42.5
+416400 6707700 46
+461800 6694500 58
+443100 6672900 87
+436600 6730400 33.5
+392200 6747200 79.5
+411000 6708000 40.5
+424500 6712800 54
+440600 6671400 91.5
+429200 6730700 51.5
+382500 6701700 48.5
+402000 6701900 72.5
+423200 6715700 57.5
+424100 6704500 44.5
+400200 6719800 63.5
+444000 6743900 41.5
+438500 6745500 52.5
+423100 6698400 58
+436500 6742400 48
+441500 6733500 34.5
+448000 6738900 42
+438100 6684800 58
+422600 6734300 39
+410800 6692200 85.5
+438900 6710800 22.5
+453500 6711300 35.5
+410400 6697300 116
+394300 6687900 68.5
+424600 6679200 146.5
+423500 6661900 162.5
+424200 6669400 168.5
+465300 6719200 58
+391800 6673500 78
+458700 6681400 74
+436800 6713300 35.5
+468000 6716400 68
+408800 6705800 43
+453300 6719000 58
+432900 6740500 54.5
+425100 6704000 14
+466700 6725200 79.5
+442500 6696600 61
+487000 6723700 78.5
+401400 6726400 62
+445800 6705400 54.5
+431900 6708800 28.5
+450000 6725200 64.5
+447100 6680300 70.5
+419400 6743000 66.5
+453600 6701900 50.5
+478100 6717300 78.5
+433000 6725900 36.5
+414900 6739200 48
+453600 6705300 21
+447300 6697100 72
+420500 6672600 159.5
+429800 6694400 54.5
+438800 6719000 35
+382600 6674900 56.5
+397000 6703400 68.5
+414000 6718200 53
+452700 6731400 40
+429900 6718000 39.5
+463600 6729900 64.5
+448900 6693700 76
+417300 6727200 71.5
+423800 6724300 57
+403000 6713300 55
+442300 6705500 49
+391800 6665500 94
+407700 6720700 59
+447900 6732000 39.5
+477300 6683700 57.5
+475300 6711600 66
+421500 6680100 147.5
+389700 6701100 54.5
+440900 6705000 51
+478300 6725500 69
+420700 6713200 58.5
+393200 6740500 68.5
+447800 6724500 39.5
+444500 6693900 60
+387600 6667800 86
+408600 6745400 59
+401100 6670000 93.5
+473700 6685500 63.5
+400700 6682100 84.5
+484500 6718300 72
+462100 6709400 54.5
+445100 6682900 62.5
+395200 6747600 75.5
+469400 6696200 33.5
+443000 6710600 29
+423800 6676100 136
+442900 6744600 43.5
+384500 6679900 64.5
+470800 6700200 67
+397100 6674300 78
+461800 6721600 67
+457000 6682400 76
+481100 6724400 66.5
+479800 6710800 61
+399000 6695100 85.5
+436500 6702400 40
+421200 6731800 47.5
+465800 6682300 40
+424100 6701600 58
+424900 6742200 53.5
+411900 6729200 60
+401200 6731300 61
+437500 6698300 60.5
+423500 6728900 56.5
+392700 6703300 21
+409600 6738900 57
+484500 6702800 88
+430000 6725100 39.5
+387300 6674800 74.5
+410400 6733600 38.5
+434100 6694000 63
+469500 6729500 63.5
+409200 6694400 88.5
+456800 6678700 74.5
+456000 6698400 60
+438900 6678800 90.5
+421900 6703700 39.5
+387600 6676800 69
+449800 6706700 20
+429100 6707200 15.5
+452400 6688100 77.5
+483300 6710700 75.5
+398700 6738500 68.5
+447800 6713100 38
+461000 6674900 51
+431600 6720800 30.5
+463900 6669500 55
+459500 6684700 68
+442600 6723400 32.5
+439900 6705500 48.5
+459600 6689900 77.5
+470900 6697800 69
+477200 6686200 27.5
+440600 6687100 60
+397800 6741500 69
+457200 6715800 54
+453200 6720700 48
+475200 6719400 82.5
+468100 6722200 73.5
+468300 6684800 53
+392200 6679800 78
+485900 6712200 89.5
+392000 6693600 63
+439400 6694800 68.5
+476600 6679900 75.5
+449400 6687400 74
+441900 6680500 72
+416000 6701200 54.5
+444300 6728600 34.5
+461000 6682600 57
+397800 6697300 76
+446800 6701200 59.5
+445200 6716700 39.5
+385700 6702000 55
+439600 6729600 43
+478300 6693200 67
+483100 6714400 69
+475100 6692300 66.5
+379400 6693600 61
+423800 6738700 46.5
+398700 6691500 82
+419500 6740600 50
+404200 6707600 38
+451900 6732700 47.5
+420200 6698300 53.5
+407500 6663200 118
+425100 6739600 44.5
+392300 6676800 74
+434400 6720300 31
+450900 6700500 62
+466600 6729800 48.5
+428000 6708700 42
+420800 6710000 54.5
+470400 6703600 41
+444100 6711800 27
+434700 6681700 80.5
+414600 6690100 94
+405200 6691000 104
+428900 6696200 60.5
+389000 6694900 68.5
+393800 6700500 54.5
+438000 6706600 41
+407200 6684600 89
+390100 6724600 56
+470600 6714900 75
+411800 6743800 69
+472400 6686100 59.5
+441900 6716700 33.5
+383900 6692100 89
+439700 6700700 55.5
+452100 6682100 76.5
+454500 6684900 81.5
+444700 6708000 18.5
+414200 6713400 48
+434300 6708600 25.5
+426200 6665500 145.5
+442600 6700600 63
+479700 6702600 82.5
+450200 6716200 49
+403100 6703600 67
+451500 6716200 49.5
+425000 6732900 41.5
+466500 6713200 63.5
+428000 6685500 80
+465500 6702200 49
+456600 6711300 26
+404400 6695300 121.5
+401400 6678600 95.5
+386300 6686100 79
+479400 6697400 86.5
+415600 6663300 131.5
+419900 6678000 168
+408600 6737600 42
+418700 6675500 148.5
+427900 6703900 51
+469200 6676000 70
+446000 6691500 72
+467300 6688800 57.5
+416400 6736200 39.5
+440300 6681400 82
+394200 6692400 64.5
+400500 6666200 97
+428400 6737200 58.5
+456600 6699500 22
+467800 6683900 49
+399300 6744900 78.5
+443700 6692700 69
+402500 6738600 61.5
+432100 6705500 46
+432500 6729900 43
+397500 6677000 75.5
+407700 6731400 55
+456900 6722200 67.5
+395700 6693300 59
+475100 6684500 64.5
+408700 6702100 93
+425800 6736100 50.5
+406900 6714200 51
+393900 6744000 73.5
+415400 6740800 57.5
+432200 6743600 59
+408900 6856200 235
+409800 6845900 214.5
+371500 6832500 40
+389300 6854500 50
+383000 6868000 106.5
+387700 6864400 165.5
+387400 6937400 20
+396100 6920400 16
+363900 6959800 86.5
+378700 6871400 80.5
+389400 6835400 124.5
+372000 6934100 19.5
+376600 6836300 62.5
+414900 6890700 136
+393600 6834000 130.5
+364000 6928600 63
+386400 6869400 155
+373500 6906800 24
+408000 6834400 171.5
+372400 6946400 77
+378300 6832200 89
+392700 6933500 20.5
+382200 6952500 74
+369500 6834600 33
+378700 6943600 73.5
+386100 6925700 10
+412600 6900900 116
+369000 6886000 31
+391300 6891000 115.5
+365600 6892200 24.5
+353300 6936500 77.5
+363200 6918500 19.5
+396800 6881100 144
+356600 6931700 68.5
+399800 6872300 172.5
+381100 6866200 117
+392600 6919800 15.5
+376900 6912400 21.5
+346100 6964700 90.5
+367800 6884700 24
+379300 6929000 16
+386800 6884300 105
+371300 6917500 71
+411200 6883700 166
+400300 6905200 45.5
+381100 6888700 75
+382900 6904900 49.5
+414500 6888200 168.5
+385900 6838700 86.5
+395200 6903100 35
+403700 6841100 96.5
+368200 6874100 36
+405600 6897700 107
+394600 6864800 201
+406100 6838400 117.5
+398300 6834700 138.5
+390400 6927500 20
+389200 6872200 126
+367300 6928900 27.5
+405400 6908600 25.5
+401200 6885000 75
+387700 6880300 106.5
+386400 6874400 118.5
+402400 6872200 120
+353200 6933000 63.5
+404600 6881400 92
+367600 6870000 45.5
+401800 6842500 96.5
+398200 6861900 222.5
+379100 6879300 77
+401100 6857600 181
+398800 6885700 97.5
+381500 6907800 16
+347900 6962900 89
+416100 6855300 304.5
+376700 6866100 96.5
+379700 6936900 14.5
+387800 6903500 19.5
+409800 6895400 133.5
+366600 6923400 65
+383700 6856400 81
+409100 6906800 59
+361100 6931300 65
+350600 6966700 66.5
+379000 6924400 21.5
+383800 6949200 63
+368200 6883100 31
+400500 6907100 34
+370000 6921900 53.5
+391600 6906400 17.5
+374000 6920400 69
+407900 6903600 103
+366300 6944400 100
+386400 6854000 78.5
+367400 6945600 88.5
+370700 6852100 22
+353600 6942400 70.5
+375900 6885500 54.5
+382900 6938000 17
+402700 6893100 63
+396000 6922700 14.5
+384900 6903200 58
+363300 6921600 24
+412000 6830100 191.5
+387000 6963300 26
+407400 6900700 117.5
+415200 6895700 134.5
+362300 6937300 67.5
+379000 6891300 80.5
+395500 6869000 177.5
+383000 6879800 76
+396400 6874200 213
+381100 6956500 84.5
+382700 6871400 103
+358800 6957200 112
+365400 6951500 122
+388600 6849100 118
+361200 6953800 94.5
+369700 6863200 64
+368800 6877600 38
+377200 6862000 106.5
+384800 6938800 23.5
+383100 6852900 62
+381100 6891000 88.5
+373100 6856500 62.5
+389000 6862800 173.5
+380600 6863600 125
+383900 6860100 153
+384800 6941200 44
+391400 6860100 148.5
+389400 6955200 61
+369100 6865500 52.5
+392200 6835400 124.5
+386700 6931900 21
+419700 6836300 159
+371600 6896700 74.5
+395300 6891800 116
+382200 6847300 50.5
+386900 6859200 119
+379400 6851500 57.5
+373600 6830800 71.5
+375200 6845400 16
+376300 6867200 93.5
+385900 6934000 19
+411900 6841500 194
+382900 6920800 14
+369300 6958700 66
+381400 6856200 73.5
+356600 6944800 96.5
+406200 6856000 203
+374300 6937800 25.5
+397000 6858100 129
+355900 6929300 39.5
+365900 6870500 42
+394500 6849200 188.5
+395200 6839600 101
+366200 6924800 24.5
+398500 6882100 114.5
+385500 6919300 13
+381900 6963900 42.5
+358500 6947500 93.5
+373400 6853700 41
+381900 6939600 32.5
+365900 6872300 34.5
+393200 6862000 171
+371200 6875900 48
+389700 6931200 22.5
+383900 6849500 70
+372500 6935700 25.5
+352000 6964300 76
+364600 6862400 60
+368600 6881800 31.5
+383300 6834400 131.5
+383000 6892000 85
+407600 6850500 196
+405000 6891100 85
+404600 6838500 131.5
+347800 6947700 45
+369000 6915500 29.5
+396900 6893200 63.5
+382200 6839300 93.5
+396900 6854500 81.5
+368000 6857300 47.5
+393700 6855300 66.5
+368400 6895200 42.5
+397000 6888500 120
+408000 6884200 116
+407000 6832100 176.5
+385200 6937500 22
+351200 6939500 42
+363500 6869500 33.5
+375200 6892000 81
+360900 6945500 101.5
+398300 6891100 93.5
+362500 6934900 67.5
+384000 6871400 119.5
+364300 6870700 36
+413100 6906600 82.5
+402600 6895400 53.5
+390400 6912200 10.5
+381800 6945900 61.5
+396700 6911000 26.5
+389000 6938900 18
+376700 6930500 17.5
+370500 6934000 38.5
+392000 6850500 137.5
+381700 6911300 11
+393100 6876700 167.5
+357900 6935200 81
+390100 6856800 71
+388700 6929300 20.5
+418300 6852400 260
+356600 6928600 41.5
+382100 6961000 71
+391100 6919800 15
+387200 6946400 21.5
+403500 6892200 63.5
+373600 6960100 78
+387300 6907100 11
+386400 6850800 114.5
+400700 6845600 151
+351500 6956600 90.5
+391000 6902900 17.5
+370400 6937100 28.5
+368600 6897600 53
+363500 6949700 94
+373100 6957300 71
+386200 6944900 23
+365800 6900600 8
+358100 6952900 87
+372400 6867900 71.5
+393900 6884100 114.5
+351700 6947500 67
+377800 6927500 19
+388500 6962700 19
+390400 6937000 16.5
+369400 6891200 47
+374500 6930300 18
+377200 6939700 25
+364900 6859800 38.5
+389100 6902000 49
+370000 6859400 103
+378200 6868900 94
+372600 6841700 29
+404100 6852100 175.5
+368100 6927000 23.5
+403200 6889300 70.5
+385100 6865900 145
+421200 6849100 251.5
+354500 6961100 131
+410400 6901600 131.5
+379100 6858300 92.5
+373200 6900500 51.5
+396200 6919000 17.5
+413900 6848600 273
+375300 6932300 25
+393200 6928100 21.5
+386900 6847100 90
+391800 6858800 117.5
+369400 6875900 37.5
+355000 6954400 89
+398700 6911000 23.5
+401100 6853700 126
+390800 6857600 75.5
+398100 6854400 80
+390900 6901300 61
+383500 6944100 42
+383600 6910600 10.5
+352900 6953000 73
+390300 6852200 107.5
+388800 6952200 52.5
+386000 6947800 44.5
+380300 6949600 84
+362900 6916600 21
+369300 6939100 45
+385100 6955700 71
+391300 6935200 16.5
+377500 6923000 24
+360700 6925000 20.5
+408300 6838700 111.5
+373200 6886400 30
+388700 6859900 130
+378100 6903800 28
+409100 6849700 236.5
+387400 6893900 95
+371200 6879800 46.5
+388100 6950000 45.5
+368900 6920200 52
+412900 6837000 105.5
+377700 6946200 79.5
+404100 6859000 271.5
+368000 6892500 54
+387200 6917200 14.5
+383000 6839300 96.5
+375400 6914200 58
+350200 6942700 51
+381300 6876500 105
+377100 6857200 64.5
+370000 6944800 46.5
+361800 6947400 98
+345200 6968100 61.5
+353500 6940900 76
+380200 6873400 80.5
+372100 6843500 22
+381300 6932300 16
+347800 6966600 90.5
+402200 6886700 79
+378800 6907500 21
+374200 6860800 85
+361900 6919200 22.5
+373000 6939800 29.5
+375500 6939800 26.5
+384900 6888900 92.5
+395200 6897500 58
+398300 6916300 19
+377100 6896000 122.5
+361000 6961700 57.5
+387300 6958000 47
+384400 6959500 95
+380800 6833500 89.5
+390200 6868100 157.5
+398300 6838700 88.5
+403100 6844000 108.5
+402500 6834800 128.5
+378800 6940100 34
+370100 6924200 65
+400000 6844100 138.5
+393200 6859900 109
+363900 6952000 119.5
+367300 6920900 25.5
+396900 6864100 220
+407900 6859000 298.5
+377600 6860800 100.5
+371000 6930200 46.5
+404100 6849400 209
+405900 6887700 83
+395600 6875000 171.5
+377900 6885200 70.5
+409400 6846900 223
+380100 6902100 67
+384500 6864600 137.5
+392100 6960700 4
+402000 6910000 26.5
+366200 6871100 44
+409000 6886700 101.5
+366600 6958600 69.5
+383000 6885300 82
+349900 6959400 92.5
+422200 6840300 201
+393400 6872000 167.5
+362800 6954000 86
+358200 6951300 63
+365900 6926200 24
+381400 6922600 20
+357000 6949900 71.5
+361900 6942000 96.5
+353900 6950000 99
+359400 6959600 95
+375300 6934600 27
+383100 6924200 19
+384100 6935400 18.5
+379500 6845400 39.5
+354000 6947000 83
+373200 6924800 66.5
+407700 6898600 126
+391400 6951500 5
+401400 6898200 70.5
+384600 6929200 9
+398800 6901800 42.5
+355000 6930600 50
+379800 6895600 117
+387400 6940700 22
+399900 6889900 86.5
+396600 6908500 30
+392600 6897600 76
+386200 6845500 76
+401200 6832200 153.5
+375700 6950400 117.5
+388600 6885600 95.5
+367100 6858300 51.5
+380400 6853600 39.5
+381000 6903500 51.5
+373000 6930300 24
+380600 6959300 97.5
+417600 6840100 192.5
+393700 6887500 130.5
+377000 6853100 26
+364700 6866900 37
+363100 6925700 25
+378100 6937800 17
+377900 6928900 16
+378000 6918100 66
+390500 6897100 72
+370100 6911500 23.5
+379800 6941000 45.5
+414000 6898500 143
+382500 6926300 19.5
+371800 6899900 59.5
+390900 6962500 18
+411200 6842700 190.5
+387100 6853600 74.5
+398700 6904200 44
+385700 6942300 46
+413000 6836300 155
+377400 6843100 43
+344300 6968100 66.5
+397100 6848800 156.5
+384000 6844000 59.5
+408200 6854100 184
+405000 6883900 104
+384700 6961700 65
+388600 6956900 65
+378500 6937000 19.5
+407900 6845100 178.5
+375400 6831500 79
+376400 6943600 53
+353500 6963400 83.5
+367300 6909800 17.5
+385600 6963900 22.5
+387600 6876200 119.5
+412200 6857600 256
+372200 6894300 90
+359100 6929000 48
+395100 6894300 77.5
+382700 6940800 68.5
+373700 6941600 44
+379300 6853700 67.5
+351600 6936200 40
+406400 6906700 53.5
+377200 6864000 98
+411700 6854200 254.5
+411800 6896300 149
+390400 6957000 56
+386900 6910000 10.5
+386900 6961000 39.5
+367200 6943400 78.5
+378100 6874900 69
+388500 6930900 21
+392700 6843500 119
+384900 6946900 51
+351900 6945500 68.5
+373100 6898500 86
+367400 6918600 48.5
+378500 6920500 22.5
+366900 6905900 20
+374000 6869900 97.5
+381200 6924800 19.5
+349500 6966300 91
+376600 6870100 79
+379000 6960700 84.5
+364500 6939900 84
+410300 6889800 130.5
+376800 6840600 52
+367800 6846800 31
+398100 6920800 16
+380000 6913200 18
+374400 6842500 27
+361300 6922600 21
+385900 6912900 14
+384400 6851900 88.5
+389100 6934100 27.5
+370700 6884600 40.5
+391300 6934800 20.5
+372700 6890900 50.5
+367900 6867600 57.5
+400000 6878100 175.5
+376000 6882400 61.5
+368000 6889700 24
+394100 6912400 18.5
+390900 6909900 12
+372200 6915200 64.5
+395000 6881400 141
+401400 6848400 188.5
+388800 6943200 34
+372500 6859500 77
+369300 6855200 60.5
+378000 6901300 73
+406900 6881700 138
+390300 6893400 93
+400200 6852200 139
+358500 6938200 72.5
+367400 6902000 20.5
+416000 6893800 121
+374900 6862900 88.5
+414500 6893800 138
+349900 6950600 52
+399700 6894800 56
+384300 6922300 17
+394800 6907000 27
+373100 6888600 46
+375100 6857700 74
+383200 6899900 91
+381600 6913300 7.5
+380000 6883300 73
+402900 6882600 122
+374200 6896000 99.5
+385600 6896800 92.5
+416000 6896800 134
+365200 6894900 34
+397900 6878400 178.5
+392500 6900200 64.5
+386100 6900400 61
+371100 6888100 33
+376000 6901000 63
+401300 6899800 66.5
+376200 6934300 24.5
+403900 6902800 76.5
+409100 6889100 96
+376800 6954700 89.5
+373400 6897500 73.5
+361400 6921300 21.5
+385700 6958300 89.5
+383800 6878000 104
+365700 6898300 23
+379300 6915300 19.5
+358500 6931400 80
+382500 6844000 38.5
+382700 6901400 76.5
+355200 6959200 121
+389300 6914100 12.5
+392500 6880900 137.5
+404500 6900800 98.5
+356000 6948100 96.5
+399400 6840500 88
+380200 6868000 94
+388500 6925300 14
+403300 6846000 152
+388600 6959400 34.5
+393200 6893500 80
+379900 6842100 55.5
+376900 6845800 38
+382600 6859400 131
+382600 6896400 124
+372800 6838200 45
+404600 6852900 175.5
+394600 6927500 10.5
+387000 6889200 113.5
+375800 6888000 59
+375100 6907600 30
+358000 6963000 74
+369700 6919600 61.5
+367500 6837600 39
+403100 6909200 22.5
+356800 6955900 125
+392600 6867600 169
+385600 6927900 18
+400000 6898600 46.5
+392300 6954900 8
+358800 6925200 46
+367300 6955800 91.5
+401800 6875500 163.5
+391600 6926200 12.5
+375300 6851500 22
+381200 6849800 59.5
+373000 6954600 125.5
+350800 6962300 92
+375100 6877600 64.5
+377200 6933800 21.5
+378000 6849300 57.5
+389600 6923600 16
+388500 6927800 20
+396000 6899800 57.5
+374800 6890900 68
+372900 6834200 53
+384200 6945300 35.5
+365400 6934100 53.5
+390600 6883000 120.5
+390800 6929400 20.5
+400400 6887000 113
+359500 6934000 85
+373000 6883700 38
+410700 6894600 132.5
+370600 6871900 72.5
+402000 6901900 101
+377400 6957900 104
+411000 6897400 154.5
+380100 6933500 17
+361700 6957200 97.5
+391900 6864000 177.5
+368700 6948100 107.5
+376900 6889800 61.5
+404000 6856300 198.5
+391000 6924900 17
+397500 6842800 100
+414200 6833500 162.5
+361000 6949400 87.5
+365600 6913700 19.5
+404700 6834500 169.5
+368000 6842500 22.5
+389800 6906300 23
+380500 6851500 66.5
+376200 6960200 76
+375400 6835900 70
+376900 6880800 65.5
+381600 6881400 81.5
+375100 6872400 87.5
+391700 6958900 14
+375500 6838100 51.5
+392200 6931700 11.5
+379600 6963200 68
+394900 6866100 184
+783800 6887200 185.5
+810000 6850900 154.5
+746900 6888100 146.5
+830400 6853200 119.5
+769200 6865500 179.5
+796500 6874500 99.5
+775900 6899700 134
+809300 6859000 126.5
+747600 6861000 178
+804300 6840700 162
+775800 6901200 116.5
+837300 6874000 178.5
+771800 6907300 79.5
+778700 6895500 186
+758300 6912900 133
+771900 6895900 195.5
+768600 6914700 135.5
+767500 6856200 146
+782500 6900400 112.5
+792800 6874200 110
+833600 6889600 161.5
+814500 6859200 138
+832300 6858400 116.5
+785000 6918800 100
+776300 6868100 109
+830100 6894000 164.5
+829400 6829800 140
+748600 6834900 153
+769100 6900100 174
+776900 6910000 111.5
+781800 6871900 96
+796100 6865000 121
+837000 6865000 157
+733800 6855100 166.5
+760700 6862500 189.5
+752500 6912100 122.5
+813100 6866700 135.5
+846300 6876000 165
+797900 6866900 112
+814300 6867100 152.5
+753100 6862400 180.5
+784100 6852200 158.5
+811800 6860400 137
+819500 6850900 149.5
+758800 6851600 171.5
+813800 6843200 163
+751300 6839900 150
+763000 6897600 187.5
+756000 6839900 99
+743900 6833200 148
+768300 6876200 167
+803800 6835200 160
+821800 6829500 131.5
+829900 6861700 138.5
+739400 6855400 183
+760000 6898500 166.5
+768900 6913200 152.5
+766700 6895600 200.5
+819600 6847700 107
+766700 6890300 204.5
+811800 6853500 114
+816500 6877300 177.5
+843400 6848200 188.5
+813400 6906900 167
+751300 6859900 174
+766900 6860800 190
+774900 6907800 105.5
+770100 6882700 159.5
+826000 6889700 169.5
+830300 6893400 167.5
+799200 6870200 109.5
+774800 6872300 174.5
+836200 6881800 171.5
+767500 6902600 153
+804600 6885600 143.5
+753800 6903100 165.5
+796300 6863100 118
+739600 6863500 168
+791800 6913200 113
+835000 6843900 140
+760100 6892700 179
+802400 6867800 110
+826100 6904200 157.5
+766600 6844800 103.5
+753900 6890000 149.5
+769500 6898900 182
+775400 6883600 129
+757900 6868300 226.5
+767400 6879800 158.5
+796000 6911600 164.5
+761300 6912700 150.5
+789100 6870600 116
+803600 6831900 139.5
+825800 6837300 125
+762900 6831600 84.5
+831400 6880300 179.5
+789100 6897900 122.5
+810900 6877300 154.5
+783700 6846500 174
+797600 6896400 138.5
+752300 6828700 91
+775800 6856900 144.5
+747800 6845100 184.5
+809700 6884400 150
+740900 6837000 150.5
+812900 6832800 142
+747500 6832100 107
+819700 6842300 107.5
+755300 6894400 181.5
+798000 6876100 113
+827700 6891400 172
+815400 6891800 172
+786300 6890300 203
+748900 6893600 159.5
+774800 6896700 191.5
+828300 6854800 108.5
+762000 6863600 196
+760100 6901100 148.5
+813600 6852000 132.5
+757700 6909200 147.5
+823800 6843100 112
+762700 6899800 166.5
+779600 6921300 86.5
+781200 6899800 114.5
+777600 6921100 78
+846600 6882300 198
+755800 6905900 139
+745200 6864700 216
+760800 6895200 193
+790900 6877800 94
+781400 6870100 109
+766100 6915500 145
+766500 6835100 85.5
+799600 6894300 125.5
+764800 6908600 89
+761300 6836700 90.5
+816500 6848400 102
+830400 6876800 189.5
+825100 6905600 158
+771200 6890500 264.5
+791400 6895100 121
+811700 6858100 133
+749900 6847700 187
+789500 6888700 121.5
+836500 6884500 172
+834200 6876100 194.5
+779500 6859200 137.5
+769800 6904700 98
+830500 6848700 124
+798600 6888200 128
+831900 6848700 126
+836500 6890400 176.5
+744900 6849400 191.5
+835700 6898000 146
+759600 6848900 149.5
+749200 6909100 116
+761600 6834200 82.5
+757300 6830900 84.5
+767700 6886200 140.5
+785700 6887000 184
+820700 6854700 150
+799900 6873800 116
+837900 6906100 177
+749700 6873700 171.5
+831800 6865000 145
+769000 6911200 135
+750000 6835000 143.5
+779600 6883400 135
+828300 6884200 174.5
+733500 6852300 158.5
+741100 6848100 175.5
+822500 6852500 131.5
+816600 6842400 130.5
+779400 6863800 123
+770000 6913300 112
+754300 6901300 176
+772900 6914200 118
+767800 6874600 185
+765100 6919500 124
+759800 6908100 133
+756100 6897200 189.5
+832700 6892400 157.5
+785100 6880500 81.5
+818000 6880900 177
+763500 6879500 175.5
+803100 6869500 116.5
+754500 6873400 189
+770000 6902500 101
+751200 6872500 178.5
+819000 6831700 130
+750500 6904200 174
+807600 6876200 135.5
+762300 6848100 126.5
+774100 6900300 116
+750100 6828100 79
+840400 6855400 155.5
+758300 6891700 166.5
+789600 6893800 127.5
+765100 6911800 141.5
+822800 6847800 113.5
+769500 6906700 90.5
+750600 6836400 152.5
+825100 6898100 162
+776600 6903100 112
+801600 6884000 133
+795500 6891300 118
+795600 6893000 123.5
+841700 6883800 193.5
+778900 6892400 216.5
+793600 6912600 132.5
+823900 6882900 177
+752000 6883500 177
+826700 6879000 187.5
+752900 6898100 199.5
+832700 6845400 140
+802500 6903300 156.5
+795200 6875600 91.5
+746400 6892500 174.5
+796000 6877400 111.5
+760700 6855000 158
+772800 6850800 136.5
+780600 6888500 178
+770600 6885500 159.5
+777500 6895700 196.5
+751000 6856700 206.5
+795400 6852600 166.5
+736700 6861300 168.5
+794200 6899900 177.5
+771400 6887600 190
+767200 6875200 193
+835900 6851500 147.5
+766200 6899200 205.5
+764600 6854500 169.5
+737500 6838900 178
+747900 6850500 203.5
+775000 6885700 204
+821300 6837900 121.5
+820200 6845200 113
+761900 6911400 136
+806700 6905100 148
+822500 6856600 161.5
+838600 6889500 196.5
+839900 6850200 164.5
+832600 6873300 195.5
+770700 6877900 164.5
+761200 6859100 174.5
+776400 6886000 164.5
+756900 6864600 226
+826300 6883100 169.5
+801200 6885000 132
+749100 6889100 147
+788800 6917500 113.5
+838300 6873900 171.5
+744300 6868600 200.5
+804600 6868500 115
+753200 6846800 159
+787300 6918100 105
+782500 6880200 83.5
+788000 6849400 179.5
+792600 6856800 149.5
+802400 6906500 171.5
+798600 6860900 127
+788400 6882400 99.5
+777800 6869300 110.5
+755400 6885700 159.5
+827300 6858400 162
+768600 6880300 147
+829600 6888600 176.5
+768600 6870800 216
+774500 6916200 124.5
+756200 6871700 192.5
+764900 6878100 174.5
+778300 6880300 84
+837800 6894200 173.5
+826600 6864100 180
+810500 6832000 144
+784700 6864800 129.5
+758000 6886300 152.5
+760000 6832000 76.5
+766200 6832700 84.5
+762200 6891900 192
+761700 6884800 157
+759800 6902100 154.5
+788000 6860600 138
+821600 6870600 172.5
+787300 6893500 194
+822600 6893200 166.5
+797500 6862400 120
+824300 6860500 181.5
+772500 6876900 175.5
+757500 6888500 154
+751700 6865700 218.5
+768000 6867700 210
+791200 6865700 138
+832300 6866900 160
+816900 6845700 106
+772000 6903100 98.5
+815000 6838500 157.5
+747500 6866200 222
+827700 6837100 128
+817000 6839500 132.5
+833700 6863500 135
+737300 6863000 163.5
+745300 6834900 146.5
+769100 6839300 105.5
+837600 6900700 190
+749500 6892000 152
+781900 6883800 131.5
+810200 6856800 127.5
+740900 6840200 184.5
+807000 6861200 124.5
+746700 6886500 156
+756000 6837300 95.5
+772100 6906100 88
+763600 6859000 184.5
+786700 6879600 82.5
+759100 6842800 99.5
+764600 6883700 157
+823300 6854000 130
+836700 6879400 169.5
+825200 6851200 108
+785500 6875300 100.5
+775200 6843700 134
+818400 6843600 104
+758600 6859000 183.5
+761400 6887200 163
+750100 6830800 97
+756000 6914800 128.5
+758600 6903000 139
+753900 6830100 89.5
+808100 6860200 129.5
+750700 6907800 133.5
+827500 6847800 120
+761400 6826200 79
+760500 6846600 109
+796400 6882000 113
+810900 6828900 142
+762600 6901800 143
+737800 6844200 184
+803200 6901400 135
+765700 6870400 215
+784000 6872500 104.5
+767800 6847600 120
+841500 6881800 164
+798900 6871800 105
+802300 6886700 133
+832100 6898900 145
+830400 6885100 170
+806700 6897800 142.5
+754500 6883800 166.5
+799500 6911300 118
+844200 6880100 161.5
+820600 6841600 109.5
+834100 6903300 158
+828900 6868000 185.5
+816100 6868300 158.5
+827300 6844700 123.5
+811900 6869100 149.5
+781600 6910900 137
+753800 6906300 154
+769000 6894300 209.5
+823200 6850900 106
+813500 6845000 156
+809400 6905400 163
+835500 6887000 162
+781100 6895700 190.5
+777900 6917200 83.5
+815500 6852200 150
+805200 6831800 144
+835100 6853700 140.5
+821900 6840100 114
+775200 6891000 198.5
+788100 6879300 87
+808800 6863000 128.5
+820400 6869100 169.5
+743700 6883800 152.5
+780700 6871100 99
+803300 6865600 117.5
+830400 6838900 132.5
+836200 6858600 129.5
+747300 6875300 172
+813400 6845800 153
+785800 6850500 170.5
+757800 6856600 178.5
+823900 6896500 167.5
+770600 6875300 183
+825400 6856700 152
+752100 6880100 198
+800000 6858700 143.5
+756100 6861900 186.5
+758400 6887200 160
+773500 6867600 172.5
+757900 6828500 74.5
+823600 6853200 120
+762700 6864700 198
+764500 6888900 183.5
+826200 6838700 125.5
+807100 6864500 118
+828300 6898800 161
+809600 6862000 129.5
+766800 6866200 201.5
+806000 6862400 123
+832700 6853200 122.5
+846500 6879600 184
+749000 6857100 202
+806000 6865800 118
+768000 6884300 138
+828000 6849000 118
+779800 6915900 96
+738200 6849700 170.5
+765200 6896700 196.5
+751900 6887000 157.5
+828700 6852700 114.5
+831100 6897600 164.5
+838200 6876000 168
+766700 6910400 102.5
+814300 6848600 154
+792400 6880700 100.5
+791800 6914700 121.5
+764800 6840200 97.5
+774100 6873600 171
+802400 6849900 181.5
+770600 6884000 69
+812600 6885900 154.5
+770700 6907900 92
+761500 6894000 223
+835400 6870700 174
+796400 6849600 189.5
+780300 6907700 156.5
+776300 6896700 192.5
+737900 6852400 161.5
+768100 6900500 175.5
+776800 6880900 98
+753700 6856900 193.5
+833300 6856300 122.5
+835400 6838700 136.5
+758100 6916000 141.5
+784100 6860700 132
+783200 6919600 91
+814900 6833600 145
+802800 6905300 138
+770100 6912000 108.5
+783400 6915700 98
+760700 6915700 150.5
+755300 6889100 154
+767200 6917000 139
+755700 6843400 104.5
+769600 6897300 191
+761100 6828900 77.5
+773600 6864900 170
+735900 6845900 173.5
+772100 6918000 81
+759300 6909900 105
+763800 6905400 155
+766500 6904200 165
+779800 6902200 123.5
+754400 6910400 139.5
+830000 6900000 136
+831400 6884600 169.5
+751900 6914100 126.5
+824400 6839200 112
+812500 6899300 165
+761500 6907200 135
+767400 6892700 210
+813300 6846400 154.5
+825800 6852300 110.5
+830100 6844600 129
+827800 6842500 118.5
+783900 6912200 122.5
+758900 6855300 177
+749500 6912200 118
+820600 6858300 173
+801300 6873400 112.5
+766100 6865200 201.5
+758100 6834100 86.5
+757700 6894200 177.5
+763800 6840700 92
+781500 6889600 195
+788700 6906300 164
+784200 6906600 182.5
+763100 6905300 154.5
+833600 6840500 124
+823000 6894400 168
+773400 6884400 167.5
+755600 6901400 174.5
+768400 6877400 160
+756900 6905300 157
+823900 6844800 118.5
+757700 6904200 138
+838200 6858300 133.5
+765700 6879300 159.5
+768000 6878600 171.5
+835600 6893200 153.5
+825700 6828600 131
+827600 6900000 161
+804100 6881500 136
+777500 6875600 96.5
+767800 6835600 95
+784900 6894700 193
+790500 6881600 94.5
+786300 6900300 123
+839400 6886700 159
+783500 6896000 184.5
+775700 6847100 139
+781100 6867400 108
+828900 6873800 195.5
+772600 6899900 120
+758100 6874700 211.5
+757200 6849500 155
+820400 6886500 186
+753600 6893800 172
+819000 6874900 185
+773900 6875100 173
+779800 6876700 89
+766100 6906000 143.5
+831400 6869700 183
+754400 6887200 143.5
+764800 6839100 85.5
+754700 6859400 179
+742600 6846100 178
+828700 6847900 123
+753900 6872700 186.5
+758300 6898200 180
+842600 6894600 198.5
+764100 6886100 164.5
+750500 6861400 182
+839400 6872500 176
+756000 6909400 156
+753500 6912900 118.5
+819500 6856200 151.5
+815600 6885200 165
+752000 6852300 195
+757100 6854400 181
+794500 6885800 113.5
+771200 6916700 89.5
+748500 6828200 98
+762700 6906300 143
+771800 6871000 218
+764600 6901800 174.5
+764100 6843800 96
+759900 6904800 147
+836000 6900000 153.5
+767600 6911300 147
+833500 6836600 134
+811400 6854500 135.5
+822100 6846700 116.5
+838600 6860400 157.5
+745500 6872300 178
+775000 6860000 148
+819200 6869100 160
+782600 6865900 115.5
+753600 6868000 220.5
+805200 6867500 115
+791400 6858700 136.5
+764400 6865300 200
+759200 6869700 201.5
+757000 6844900 120
+756400 6892600 165
+831400 6855900 114
+818200 6857900 162
+770800 6861000 183
+733500 6850300 180
+788100 6885800 104
+758300 6888600 175
+840400 6861900 158
+825900 6857500 158
+766800 6889000 180
+812300 6829300 143
+743400 6857400 197
+802900 6854300 163
+743400 6860700 177
+812800 6855600 144.5
+778400 6887400 179
+789800 6890600 152
+804400 6838500 173.5
+786500 6897800 102.5
+786200 6883500 97
+766300 6903300 173
+736600 6854400 174
+781900 6853400 153.5
+756300 6851200 177.5
+815800 6835200 144
+801500 6843300 184.5
+828700 6904400 156.5
+747200 6870200 208
+831300 6881900 177
+831300 6847900 134
+755300 6835300 96
+833500 6887400 161
+752300 6844500 155.5
+790100 6910700 107.5
+779900 6902900 84.5
+769300 6845200 113.5
+749600 6906900 124
+768900 6887600 171
+778100 6850200 154
+815200 6840400 155.5
+739800 6853000 186.5
+783800 6908600 185.5
+755800 6912600 117.5
+823600 6906500 156.5
+807600 6896500 139
+846800 6874000 172
+764800 6900200 184.5
+752700 6842600 155
+831000 6835400 132
+838100 6877400 166.5
+785200 6913300 113
+774100 6881100 154
+801100 6909100 142
+743700 6839800 190
+821800 6890300 170
+838600 6844300 152.5
+761300 6903100 148.5
+762800 6903200 171.5
+767700 6902100 156
+811800 6893300 162.5
+791100 6872600 106
+734000 6842100 181
+810900 6833900 162.5
+842300 6810300 259.5
+892200 6767300 378
+872100 6823800 356.5
+841100 6780200 251.5
+886500 6745600 317
+895400 6736600 313.5
+886600 6757500 375
+885400 6802500 375
+899000 6747600 299
+848100 6786400 321.5
+895400 6738900 305
+887600 6781800 391.5
+851100 6806000 317
+863600 6740100 458.5
+846400 6801400 312.5
+894200 6780200 380.5
+877900 6746500 403.5
+904000 6759200 351.5
+879200 6742000 321.5
+887000 6773900 352
+880700 6743700 323.5
+902500 6772600 386
+883000 6740300 316.5
+868100 6817300 316.5
+853900 6833500 231
+836500 6819500 163
+908600 6755600 301.5
+844400 6795100 300.5
+897600 6755200 295
+875300 6800000 321.5
+849400 6803200 331.5
+871700 6775400 373
+855300 6735700 416.5
+884700 6764300 407
+876800 6817000 365
+829900 6775500 293
+882400 6754200 386.5
+888300 6788900 409
+848300 6810100 284
+827100 6816200 141
+873400 6802000 327.5
+852100 6750000 371.5
+850300 6751900 360.5
+901600 6759900 337
+858200 6753400 400.5
+875900 6728300 291
+859600 6809200 258
+836300 6813900 187
+866300 6750900 435.5
+857800 6821400 249
+880700 6746100 375
+861300 6765900 374.5
+875600 6760400 388.5
+874900 6783400 377
+880600 6800600 375.5
+853400 6804800 308.5
+840400 6836800 153
+892400 6791300 398
+842700 6772100 286
+864700 6787600 326
+883600 6788800 422
+886900 6780300 396.5
+836900 6838200 147
+840700 6777500 276.5
+881500 6783700 410.5
+881500 6739700 318
+905200 6765100 344.5
+832000 6808800 180
+846300 6843000 181.5
+873300 6732000 318
+873900 6739900 369.5
+863500 6810600 287
+871700 6731100 344
+850700 6835900 193
+858100 6817900 265.5
+895800 6742400 318.5
+845700 6820800 200.5
+899900 6760500 334.5
+833200 6817000 153.5
+886600 6786100 395
+854900 6739000 426.5
+853200 6775200 308.5
+850200 6810400 282
+880900 6769800 414
+902500 6772000 373
+844500 6803300 304
+852700 6823400 258.5
+882400 6773000 415.5
+857900 6823400 251.5
+896800 6782900 375
+837800 6824500 157
+910100 6758300 293
+871600 6742800 370.5
+851200 6815100 295.5
+896200 6791300 399
+854600 6758200 353.5
+878400 6737300 331.5
+853500 6793100 328
+843900 6823900 188
+863000 6758600 405
+869100 6821400 341
+873900 6811300 353.5
+850200 6836000 181
+883200 6756300 397
+824600 6818500 137
+889900 6760300 317.5
+857800 6822300 249
+869700 6814700 324
+859600 6784800 286.5
+899000 6792000 409.5
+869700 6754000 410
+888500 6758000 311
+845100 6815900 222.5
+882800 6743200 310
+866900 6803000 304.5
+879800 6781200 392
+856900 6762500 366
+868600 6750100 416
+866000 6815600 307.5
+872100 6743500 380.5
+864900 6773300 343
+866600 6826000 326.5
+877600 6749400 410
+883100 6779900 427.5
+891600 6792100 323.5
+855200 6783800 318
+911600 6763900 315.5
+838800 6783200 272.5
+882300 6760200 409.5
+852100 6746200 395
+897700 6735600 305.5
+866900 6793300 328.5
+897000 6752000 277
+865800 6779500 367
+842500 6826900 180
+870900 6778600 386.5
+839400 6780400 282.5
+860100 6774400 340
+884400 6748900 344
+846200 6743100 377
+857000 6823000 243.5
+857700 6795600 257.5
+855500 6793700 312.5
+847100 6788900 343
+859000 6808500 289.5
+884000 6796300 414
+882400 6798200 365
+861100 6755900 390
+846100 6790800 323.5
+878100 6761100 408
+870600 6796100 305.5
+833800 6808800 207
+860600 6819400 272.5
+842300 6807500 262
+870700 6760700 370
+891300 6786200 369.5
+874400 6813400 378
+875000 6768400 392
+838500 6766400 287.5
+883600 6807500 395.5
+895300 6750700 279.5
+885300 6754100 368.5
+849200 6752700 353
+879100 6751100 385.5
+876600 6731900 311.5
+859900 6788400 283.5
+885100 6774300 376.5
+849600 6775000 302
+858800 6786000 285.5
+899300 6736500 289.5
+890600 6777200 372
+876200 6755900 374.5
+870600 6768200 381
+848100 6825600 212.5
+870700 6763500 380.5
+884500 6735200 302
+837600 6808800 241
+904100 6769100 377
+893200 6786800 415
+866800 6770100 351
+840000 6760200 297
+868800 6769200 366.5
+851200 6808800 311.5
+887700 6737200 313.5
+873100 6743300 351
+864800 6756500 417
+889000 6737400 316.5
+850000 6762800 331.5
+868700 6798600 298.5
+850400 6819600 252.5
+852300 6799600 338
+879700 6752300 370
+884800 6801400 376.5
+867600 6731100 377
+902500 6753900 328.5
+876400 6801000 340
+851600 6800800 332.5
+856200 6749400 395
+854200 6810900 311
+845000 6765700 283.5
+859000 6791200 301.5
+839700 6830600 151
+873900 6776100 407.5
+905000 6751000 291
+874800 6772500 384.5
+850200 6824600 232.5
+837800 6839700 132.5
+869000 6819700 344.5
+890900 6739000 313
+894700 6745600 310.5
+853200 6830200 214
+825600 6822900 131.5
+844500 6759000 330
+872100 6733500 346.5
+850400 6821200 248.5
+896700 6784500 375
+859100 6810900 280
+891300 6787900 399.5
+840200 6833100 157
+891000 6741600 317.5
+869900 6772900 364.5
+834300 6841100 127.5
+885900 6760800 403
+874700 6787800 346.5
+837600 6833900 148.5
+866000 6734400 390.5
+840900 6829600 168
+876000 6734500 311
+874400 6814800 373
+897200 6770700 365
+871500 6808300 325
+856100 6756300 374
+869200 6756700 376
+875300 6785900 367
+863300 6753200 423.5
+840000 6793100 317
+864500 6748000 468
+854500 6812200 301
+854400 6748800 376.5
+877800 6802800 360
+860600 6732900 409.5
+897100 6764700 373.5
+847400 6764800 298
+845400 6841000 170
+859100 6781100 331.5
+883700 6736300 303.5
+858400 6795300 306
+830800 6821200 140
+849300 6739600 407.5
+879000 6799500 352.5
+843500 6777400 270.5
+886300 6769500 383
+897500 6795100 388.5
+854800 6790600 298.5
+845000 6797300 294
+868000 6773700 360.5
+861500 6813400 282
+838000 6784700 263
+881800 6756400 386.5
+891700 6760700 334
+866500 6742900 431.5
+847300 6781500 301
+845300 6823000 201
+844800 6802000 294.5
+839800 6815100 184
+897100 6786100 378.5
+887300 6802700 370
+833900 6771700 281.5
+835900 6803700 268
+870600 6746500 395.5
+855100 6827100 222
+862800 6776600 331
+896000 6768000 357
+881400 6766600 436.5
+864000 6760800 394
+880100 6784500 401
+858900 6758400 391
+853500 6771000 336
+890500 6785200 361.5
+862800 6775200 341
+890000 6789700 391
+849800 6828600 214
+889400 6787500 401
+874900 6805500 339
+863900 6766700 381.5
+847600 6811100 265
+899300 6794800 405
+872000 6758400 382.5
+839900 6842400 155
+879100 6758600 380.5
+858300 6807000 293.5
+875600 6745600 391.5
+858200 6819700 254.5
+878700 6810400 379.5
+865000 6763100 398.5
+873100 6797200 309.5
+878800 6764200 427
+866700 6809100 305
+875300 6757400 373.5
+847900 6822700 223
+870700 6820600 335
+838400 6799200 306.5
+847300 6820800 220
+844900 6817300 195.5
+878100 6808600 381
+895900 6758300 331
+848100 6816500 257
+834500 6825800 151
+868000 6811700 308
+831700 6824600 142
+825400 6824900 137.5
+867600 6824100 334
+856900 6796800 306.5
+876700 6805800 393
+858500 6798500 310.5
+890900 6752100 329.5
+860400 6818200 275
+845200 6819200 208
+845200 6821400 192
+851500 6780300 324
+853500 6790100 322
+843800 6805300 272
+868500 6756200 393
+839700 6837300 141
+868200 6789500 328.5
+891000 6762600 352
+903700 6751500 281
+893200 6748700 302.5
+882900 6753100 385
+873000 6746300 390
+861600 6780800 329.5
+853400 6817300 281
+832000 6770800 280.5
+867400 6758500 390.5
+844800 6818200 196.5
+894200 6761400 330.5
+830300 6820300 146
+857700 6739900 419.5
+895300 6754200 294.5
+863500 6804800 298
+874400 6753900 401
+850200 6736600 432
+883800 6738700 300.5
+881700 6747500 372.5
+843600 6839300 164
+859300 6813700 275
+854200 6802900 306.5
+881400 6779900 402
+885100 6776300 403
+857200 6792000 271.5
+842200 6812200 223
+887100 6750000 334.5
+850200 6833600 197
+871100 6799000 294.5
+865700 6741100 399.5
+865900 6738800 417
+881500 6777700 411
+861900 6823900 283
+913900 6762400 284.5
+893000 6775900 379.5
+883400 6764100 422
+884600 6785700 421
+898400 6738300 302
+899600 6741900 328
+888600 6761100 381
+892200 6789500 403
+907900 6757500 324.5
+873000 6729800 288.5
+890100 6793000 392
+854400 6745000 414.5
+876600 6768700 405.5
+843600 6814500 219.5
+848400 6787800 329.5
+896800 6792900 396
+888100 6784300 372
+847300 6777500 288.5
+862600 6785200 352
+851500 6790900 342.5
+855200 6829200 235.5
+899900 6751800 300.5
+856000 6799600 303
+841900 6787000 276.5
+841700 6782600 277
+857400 6827500 258
+859100 6802000 291.5
+850100 6799300 327.5
+882600 6790800 384.5
+868600 6741500 391
+869700 6791200 324
+901400 6755500 333
+862500 6792000 303.5
+899500 6761600 347.5
+870100 6744100 389.5
+858300 6815900 264.5
+876400 6778900 382.5
+876500 6819800 373
+875300 6781500 385.5
+874100 6750500 424.5
+853500 6780400 298
+884700 6780300 437
+880200 6752200 376.5
+869800 6799800 296.5
+864200 6816000 296
+868900 6744800 411
+844700 6779500 283
+877200 6744100 361.5
+895200 6799300 372.5
+862600 6734800 427
+871000 6726000 301
+893600 6796500 375
+832700 6778900 277.5
+900300 6738300 299.5
+847200 6744100 394.5
+870400 6737300 391
+858200 6734500 405
+833000 6774900 277.5
+861400 6736600 458.5
+852100 6783000 325.5
+882600 6749600 358
+845200 6812400 243
+841500 6819700 184.5
+876900 6792500 354
+895400 6788600 411
+891200 6776200 368
+901700 6751500 293.5
+879600 6787900 384.5
+848900 6736000 429
+856400 6747000 393
+872600 6821500 355
+863700 6793400 326.5
+865300 6820000 312
+886500 6778000 394.5
+901000 6736600 300
+423100 6754100 62.5
+441000 6806400 225.5
+401900 6789100 139.5
+415600 6774400 82
+427300 6749700 55
+404700 6757100 57.5
+427400 6745100 50
+433100 6774500 80
+456500 6828100 194.5
+460100 6820600 277.5
+396300 6751500 64
+418200 6788600 100.5
+406400 6826700 180
+433000 6813800 125.5
+406900 6823900 194.5
+400600 6799800 168.5
+447900 6818500 210
+419800 6801500 154.5
+410500 6820200 214.5
+401300 6804700 166
+450000 6814200 237
+451900 6809500 226.5
+463200 6805200 173.5
+473600 6820700 260
+385500 6752700 85.5
+415900 6796400 120.5
+408300 6799000 160.5
+427900 6794500 118.5
+397700 6762700 70.5
+402000 6827500 161.5
+445100 6828000 139.5
+418000 6797700 138
+436100 6818700 191
+420300 6798700 119.5
+401000 6782300 163.5
+449400 6793900 228
+414500 6756000 69.5
+454500 6797200 285.5
+403000 6769700 80.5
+434700 6767200 87.5
+415000 6759000 79
+424100 6793700 102
+397800 6756900 74
+431800 6793100 111
+404500 6786500 126
+403100 6822200 193.5
+447300 6775900 88.5
+413800 6752500 69.5
+398400 6770500 87
+400500 6787000 130.5
+429300 6825600 127.5
+432600 6786200 95
+391600 6761300 82
+454900 6790400 227.5
+408100 6767800 77
+434500 6763300 105
+436300 6791200 105
+454600 6802200 248.5
+414300 6811600 187.5
+409700 6789200 149.5
+436200 6805600 131.5
+412700 6769500 92
+442600 6787100 105.5
+463400 6822500 295
+460900 6795200 240
+405500 6780200 140.5
+410600 6784700 124
+409000 6748600 61
+421700 6767900 70
+417900 6784500 102
+467000 6812300 223
+457300 6782600 200
+442800 6824000 187
+409600 6761000 78
+468300 6817900 291.5
+450000 6769900 80
+405800 6783500 141.5
+392800 6771400 80
+457100 6810000 196.5
+434900 6803500 121.5
+450500 6782800 153
+419600 6817600 163.5
+457800 6802100 236
+432800 6747900 68
+415800 6817100 197
+407500 6762700 71.5
+434100 6779300 99
+444700 6760000 54
+404900 6761500 63.5
+441300 6765200 64.5
+445000 6764600 62.5
+425800 6823300 153
+427900 6761800 88.5
+471400 6818600 286
+424400 6776800 73
+434400 6747200 61.5
+426500 6773600 72
+443600 6761600 63.5
+408000 6818500 205
+429900 6758000 84
+390700 6764500 80.5
+401900 6749900 66
+447700 6814700 229.5
+388100 6751200 85.5
+430600 6767300 91
+428200 6812600 144
+442800 6756600 64.5
+448100 6825300 147.5
+411600 6775900 96.5
+411100 6751200 58
+404000 6814400 188
+446400 6758300 48.5
+461100 6808400 208
+410200 6772900 96.5
+405500 6751200 56.5
+455900 6822400 174
+448500 6780500 102.5
+436700 6800700 138
+450300 6800100 246
+440000 6757200 79
+407000 6780500 130
+421000 6788000 92.5
+429300 6808000 135.5
+386500 6756100 93
+411400 6805800 151
+408500 6806900 153.5
+461800 6794900 211.5
+429000 6782200 91.5
+446000 6770200 79.5
+453100 6818300 192
+392900 6762900 76.5
+450300 6825000 155.5
+400600 6818800 187.5
+423500 6786800 98
+414400 6760800 80
+431300 6748300 57.5
+412500 6798600 130
+430300 6804100 120.5
+393800 6769200 79
+410200 6764900 82.5
+424800 6748100 51
+458200 6815700 275.5
+455300 6786900 221.5
+438000 6793700 111
+442500 6784300 112.5
+415200 6781100 105.5
+451300 6767700 74
+430200 6756600 75.5
+416100 6765100 74
+424300 6753200 54.5
+440000 6772500 85
+436300 6795200 124
+414300 6825700 195.5
+457300 6813700 275.5
+416900 6825100 180
+438400 6789200 98.5
+431400 6817500 128.5
+434700 6811500 121
+450700 6804300 209.5
+456700 6825400 173.5
+405000 6792300 155.5
+449600 6772000 85.5
+421500 6750700 55
+449500 6820600 182
+417500 6749700 64.5
+432100 6806400 120.5
+464700 6800700 184.5
+445500 6807600 196
+470600 6815400 189
+430900 6803100 109
+463300 6831700 282.5
+444800 6787000 105.5
+411000 6816300 212
+418000 6819200 177.5
+461200 6793200 218.5
+418700 6822400 185
+445000 6793400 111
+439800 6824500 158
+395200 6768000 77.5
+425500 6764400 72.5
+401300 6753600 67.5
+442400 6749000 61.5
+422700 6797800 100.5
+408600 6787300 128.5
+433400 6789000 95
+446400 6800400 201.5
+414400 6823200 196
+441800 6804600 172
+422500 6762100 60
+442800 6781400 112
+453400 6826900 175
+447100 6773000 86.5
+419200 6776000 77.5
+439200 6814900 207.5
+441500 6821000 184
+395700 6753600 79.5
+404900 6774700 97
+400000 6778200 129.5
+426500 6786600 112
+438500 6776500 91
+387600 6762300 90.5
+436900 6768800 75
+437600 6763900 80
+443400 6769800 79
+428800 6802000 114.5
+402500 6760900 64.5
+419800 6759100 65.5
+426300 6814700 155
+440600 6827100 160
+436800 6758500 93
+399200 6753700 74.5
+398800 6797100 139.5
+464300 6824900 253.5
+434900 6751500 76.5
+433800 6771200 87.5
+408400 6754200 60
+431000 6751500 62.5
+448000 6809400 238
+459100 6805600 211
+453200 6789100 206
+415000 6820000 198
+422600 6792200 95
+426400 6820800 144
+443900 6816300 237.5
+441000 6776900 96.5
+429600 6779200 77.5
+434600 6815500 128.5
+412300 6761100 73.5
+422800 6810800 170.5
+452100 6777500 156.5
+449200 6765500 64
+400000 6823100 172
+426100 6757900 61.5
+447100 6789400 141
+424400 6781300 80
+418800 6792900 103.5
+441600 6789600 89.5
+404800 6817000 188.5
+426200 6807500 158
+397800 6793000 138
+440700 6800900 147
+429200 6791000 125.5
+402300 6774600 103.5
+400800 6757100 63
+415900 6806900 167.5
+439600 6813200 203
+392000 6753500 81
+435700 6787500 99
+390700 6757000 90.5
+419300 6781400 82
+410800 6794100 141
+427600 6769000 75
+459100 6825500 220.5
+439400 6767700 69
+431300 6799600 119.5
+438100 6783400 105.5
+399800 6809300 197
+421000 6763700 69.5
+417800 6771700 72.5
+423100 6772700 70.5
+465800 6804000 163
+993800 6841300 484.5
+943300 6823500 292.5
+929800 6862000 287.5
+904500 6912600 281
+959300 6827400 270.5
+906400 6926400 337.5
+947000 6825900 327.5
+955900 6834600 245
+919100 6907500 230
+902600 6915500 301.5
+919100 6812900 419
+978900 6826800 322
+940800 6838400 283
+929000 6865400 286
+983300 6839100 295
+912800 6896300 253
+910900 6857000 240.5
+902400 6833400 329
+976200 6822400 319.5
+903400 6935900 333
+878800 6931100 255.5
+931700 6827700 259
+936400 6847600 217
+901600 6908600 259
+936400 6850700 307.5
+909200 6885100 241
+934600 6819200 302
+913400 6816600 379.5
+947800 6824100 278
+905100 6830900 349.5
+951400 6857100 239
+949800 6820400 301.5
+915500 6852700 220.5
+915100 6861500 263
+912400 6835500 259
+940000 6819800 328
+967100 6837200 262.5
+904700 6867000 266
+926400 6830100 273.5
+980700 6835800 281.5
+991900 6835900 490.5
+935300 6854500 280
+921400 6818300 389
+914500 6904700 214
+918400 6822100 389.5
+924300 6833100 348.5
+927800 6815200 371.5
+931800 6831500 282.5
+921200 6831700 368.5
+993200 6833300 515
+958100 6835400 257.5
+906500 6862300 250.5
+971800 6847400 263
+907300 6903500 213
+939800 6832900 299
+962100 6855100 268
+922300 6849000 293
+941600 6871900 224
+958600 6827900 250.5
+928200 6865900 277.5
+986300 6834900 297.5
+901700 6939000 351.5
+954900 6827700 258
+930300 6865600 293.5
+969900 6828200 281.5
+936600 6822400 300
+900700 6926700 305.5
+914300 6875400 313.5
+911900 6887000 267
+908600 6856100 231
+981700 6819300 319
+908700 6864100 267.5
+904000 6917100 313
+948900 6853100 271.5
+986500 6833200 311
+905300 6874000 229.5
+909100 6846000 298.5
+921400 6871000 284.5
+940100 6873000 228.5
+919200 6814800 444.5
+910000 6828800 303
+973100 6846100 271
+908300 6936400 360
+907600 6843900 319
+903900 6849800 302.5
+992500 6836100 482.5
+923900 6818800 391.5
+934400 6850300 285.5
+881500 6935400 274.5
+903100 6853300 309.5
+931300 6839200 316.5
+980300 6845000 306.5
+901200 6941500 329
+908400 6862700 245
+902600 6940800 323
+939700 6849500 257.5
+951600 6839800 267
+924500 6815200 414.5
+983000 6832600 306
+931800 6815100 307
+917900 6847700 263
+933800 6843100 317
+938400 6837000 282.5
+919800 6863900 255
+954600 6840900 282.5
+914800 6831700 320
+909500 6918900 307.5
+939600 6836600 289
+909800 6830800 341
+954800 6848900 269.5
+912200 6861300 239.5
+929800 6826800 286
+916400 6901100 255
+949300 6828700 310
+989900 6841100 324.5
+984400 6824500 402.5
+914600 6840200 272.5
+940400 6821800 320
+938000 6844300 226.5
+902900 6919700 319.5
+912500 6920400 306
+907900 6883000 231
+943300 6841800 246.5
+944100 6842200 260
+936000 6845800 218.5
+956400 6821700 285
+934900 6859500 313.5
+925600 6821600 296.5
+906300 6900200 206
+921000 6821300 345
+927700 6822700 313
+896700 6930000 315.5
+930400 6832200 262.5
+910100 6900800 207
+923400 6869100 255
+900200 6929500 318
+963600 6822100 288
+949900 6833900 235.5
+915500 6899700 263.5
+986500 6839800 314
+966000 6832800 257.5
+976800 6836300 271
+925200 6864300 242
+909300 6882800 243
+926100 6817300 435
+932500 6854900 270.5
+934900 6871300 198
+958500 6839700 258
+944300 6833500 296.5
+909800 6899300 210.5
+978100 6829900 285.5
+975100 6833200 279.5
+905400 6863700 262
+927800 6859700 271.5
+963700 6826300 291.5
+919600 6875700 278
+927000 6874600 266.5
+903700 6930900 339.5
+925800 6835900 313
+945700 6829000 325
+977800 6840500 272.5
+950800 6821900 302
+908500 6921200 346
+906900 6892400 214.5
+928000 6830500 273.5
+905100 6846300 313.5
+950900 6846600 264.5
+939300 6853900 278
+921600 6883300 262.5
+907900 6873100 268
+919200 6826300 364
+946100 6847100 234
+981800 6825300 330
+924500 6840100 281.5
+922700 6870900 243.5
+956700 6851900 273.5
+916200 6864800 267
+957000 6847800 272
+907200 6828800 349
+938900 6848100 255.5
+954200 6820000 306
+945800 6837600 269
+912300 6934000 375.5
+903300 6845800 290.5
+940800 6854600 262.5
+910700 6927900 374.5
+946700 6833500 272
+980100 6841400 300
+984800 6835200 297.5
+984100 6830300 299
+937000 6854900 299.5
+922600 6822500 342
+948700 6842200 263.5
+936400 6870400 259.5
+941500 6865100 208.5
+953900 6822200 313
+912400 6880300 257
+922400 6826100 355.5
+962200 6823900 282
+915700 6883000 263.5
+950700 6843000 260
+928200 6836400 317.5
+959400 6849300 281
+951100 6855200 255
+929900 6855700 274.5
+952300 6827600 289.5
+919000 6852000 222.5
+909900 6876500 274.5
+959700 6847200 251.5
+908900 6878700 244
+984300 6841800 314.5
+904500 6864900 265.5
+929700 6819400 335
+917800 6874500 289
+923800 6878300 285
+950400 6840800 265
+935700 6874500 225
+926400 6877200 286.5
+910700 6881800 258.5
+919300 6879500 281.5
+949300 6850300 261
+987500 6829300 404
+912300 6869000 287.5
+970900 6836300 272.5
+895800 6935000 308
+938500 6823400 307.5
+975400 6842400 280
+934900 6863800 317
+906100 6917800 315.5
+943700 6849200 252.5
+898700 6935000 317.5
+970500 6823500 310
+911300 6915100 260.5
+914900 6857600 261.5
+983700 6837200 287.5
+918800 6861900 262
+920300 6820500 382.5
+957900 6821600 310.5
+933700 6837400 268.5
+941600 6869000 212.5
+904700 6869500 257
+899800 6923900 280
+938000 6853000 263
+907300 6831100 346
+901000 6920800 296
+937900 6865200 294.5
+908200 6875400 234.5
+899900 6939100 323
+902100 6913100 281.5
+959900 6823300 304
+942500 6862500 207
+912200 6911600 249.5
+977000 6828600 300.5
+942800 6826400 299.5
+935900 6849300 267.5
+950900 6826400 301.5
+901500 6899600 206
+946200 6854400 247
+899500 6904700 237.5
+928600 6834100 251.5
+969000 6849500 252.5
+898800 6926400 291.5
+934300 6848300 270.5
+933500 6863600 288
+908700 6850600 308.5
+939700 6860900 307
+933500 6870700 202.5
+931800 6871500 202.5
+989400 6833700 341
+916400 6815900 409
+917000 6835400 289.5
+920700 6852900 240.5
+980500 6830700 290
+940600 6817700 322
+985600 6827300 397.5
+963500 6852500 270.5
+880800 6929500 258.5
+936000 6840900 243.5
+959900 6821700 303.5
+895200 6937200 346
+925100 6825100 305
+950300 6839000 268.5
+891700 6936000 338.5
+945700 6834100 271
+915800 6907900 226.5
+908300 6839900 316.5
+911500 6863900 267
+954300 6825200 296
+938400 6839500 274
+959800 6852900 275
+919400 6829400 365.5
+959800 6843600 259.5
+913900 6843000 256.5
+896800 6927400 281.5
+911300 6878400 256
+980500 6821100 344
+908700 6912200 251
+975200 6830600 304.5
+907300 6897700 204
+894400 6940600 310
+952700 6850700 273
+951300 6833800 250
+928500 6867900 286.5
+905700 6825600 356.5
+927400 6862000 257.5
+991300 6831300 499
+939500 6857400 310
+909300 6838500 309
+930800 6859200 288.5
+890800 6937500 369
+915900 6860200 269.5
+900500 6933700 336
+923900 6820200 315.5
+898600 6923700 283
+978900 6832500 279.5
+927200 6840500 317
+956500 6819400 347.5
+943000 6833300 307.5
+926900 6819800 345
+957500 6844700 245.5
+911900 6903000 209
+917100 6871100 327.5
+969000 6840800 267.5
+975100 6846400 260
+877000 6935700 249
+918400 6902100 278.5
+944200 6827100 312
+912500 6900700 209
+976300 6823000 311
+957600 6842700 259.5
+945400 6861200 219
+946900 6819700 315
+931300 6873200 206.5
+882500 6927500 255
+915800 6842100 278
+936300 6827400 265
+904600 6940700 336.5
+944100 6827900 291.5
+909100 6933000 396
+908800 6867700 294
+895200 6929100 275
+917600 6822900 360.5
+901600 6937000 330
+912700 6832600 274.5
+944500 6861800 218.5
+965900 6831700 279
+917200 6883800 273.5
+901600 6931000 336
+910800 6934300 385.5
+996300 6827900 527.5
+910400 6855600 236.5
+938700 6862000 314
+907900 6915300 281
+919300 6849800 228
+963100 6849700 271
+905400 6919100 335.5
+914000 6897800 242
+989200 6832000 365.5
+972700 6825700 302
+956800 6845100 270
+920400 6858900 270.5
+910500 6913200 254.5
+991100 6838500 333
+908300 6900200 205.5
+974900 6833900 261.5
+982400 6830100 292.5
+930600 6834000 274.5
+919300 6834600 325
+910200 6834600 337
+977100 6830600 286
+941800 6830600 285
+934400 6817400 283.5
+976200 6831900 276
+965400 6838200 254.5
+927100 6867300 279
+926300 6812800 403
+956700 6823700 306
+929800 6856500 271.5
+941100 6855500 309.5
+969200 6837700 275
+926600 6870100 229
+908100 6841800 316.5
+986700 6827800 361
+972300 6842900 273.5
+931700 6817800 285
+908200 6887700 232
+914100 6845000 248
+948500 6856300 242.5
+954000 6833900 246.5
+921800 6874700 276
+933500 6829200 271.5
+923000 6867700 267.5
+960100 6842900 268
+898000 6937000 309.5
+919200 6844000 273.5
+980300 6819900 333
+903000 6924600 309.5
+948000 6829300 307.5
+986600 6837000 287
+891800 6939900 315
+963200 6839200 258.5
+895600 6933600 312.5
+960300 6836200 247.5
+885700 6937600 313
+953500 6838900 274
+901600 6895000 204.5
+916400 6882600 274.5
+933000 6840400 328.5
+912100 6883300 264
+924500 6841500 307.5
+923900 6877400 283.5
+982500 6841000 316
+893500 6934400 284
+978600 6838800 268.5
+907500 6861700 241
+935100 6834600 290.5
+905500 6908800 243.5
+928300 6838400 314
+918100 6854800 237
+938500 6863100 307.5
+937700 6828500 302
+891700 6941600 308
+915600 6895400 282
+980900 6843900 325
+909600 6926000 339
+937800 6872700 233.5
+976900 6835100 263.5
+899600 6937100 310.5
+941300 6823900 315.5
+888600 6930600 296
+924700 6831600 344.5
+907900 6908800 223
+903700 6898800 201.5
+913200 6867100 268
+936100 6816400 299
+882000 6934400 278.5
+923800 6871500 277
+915800 6856500 254.5
+943100 6822400 306
+885500 6931700 274.5
+981000 6838300 290.5
+947700 6826100 335.5
+975300 6837900 264.5
+932000 6823400 286.5
+923600 6836200 346.5
+910600 6907200 222.5
+928100 6825200 279
+932700 6852800 275
+941300 6866900 208.5
+909000 6930300 390
+936600 6825600 283.5
+921200 6863500 239
+951000 6818200 302
+911700 6924400 361.5
+926400 6815900 410
+965000 6848500 262.5
+926600 6815300 418
+913500 6917800 282.5
+919700 6810500 400
+973800 6835900 252
+945300 6823100 290
+960200 6839100 235.5
+913700 6862800 262.5
+914000 6909400 248.5
+936100 6861900 332.5
+913300 6837600 246
+929600 6812700 305
+911800 6909500 237
+909700 6849000 302
+946400 6858400 228
+940000 6826900 294
+931100 6830300 268
+915600 6913800 266
+975700 6826600 293.5
+918700 6883600 273.5
+917000 6868300 291.5
+955600 6831400 255.5
+901100 6911400 261.5
+965700 6850400 261.5
+929200 6827500 276
+908900 6837000 330.5
+944400 6851000 255
+986000 6831200 315
+937700 6816700 332.5
+933600 6829600 302.5
+973500 6839400 276
+941100 6829800 286
+935200 6843900 235.5
+930700 6816300 297.5
+943200 6845700 239.5
+910900 6890200 249.5
+958200 6837900 269
+906900 6889500 217
+934800 6823400 276.5
+906000 6872500 249.5
+951700 6824500 301.5
+933700 6825700 266
+947600 6822500 306.5
+937000 6849900 281
+940200 6851200 243.5
+908800 6851900 262
+932700 6850400 277
+909200 6894800 221
+933200 6844200 308
+926600 6823800 290.5
+911600 6930000 393
+918000 6816000 424
+916900 6905400 221.5
+975900 6839700 269.5
+903400 6899500 201
+928700 6839600 288.5
+922600 6813700 416
+1002200 6831500 480.5
+942200 6852700 248.5
+949700 6832000 259
+946800 6841300 261.5
+934300 6822600 283
+958500 6843300 252
+920000 6825300 357.5
+928700 6862600 278.5
+884500 6933600 274.5
+917700 6883800 274
+926500 6826500 282
+932400 6837100 280.5
+904700 6895800 202.5
+912900 6845500 300
+966900 6848100 250.5
+967600 6829200 274
+930200 6841100 333
+949900 6848600 255
+932200 6846100 302.5
+925700 6871700 292
+903800 6903800 215
+937200 6859900 334.5
+933000 6873600 207.5
+901500 6834800 324.5
+913300 6891200 265.5
+911700 6855600 233.5
+921100 6862800 258.5
+910700 6892600 230
+911700 6852900 228
+927700 6818400 415
+936500 6820100 301.5
+929000 6823600 297
+942300 6820400 308
+968000 6830400 263
+922100 6850400 253.5
+900500 6918100 298.5
+906300 6849200 316.5
+972900 6827200 294
+938800 6871300 208.5
+979100 6843100 304.5
+901900 6927100 323.5
+906900 6907200 219
+880500 6932400 256
+925100 6854400 263.5
+953300 6843800 263.5
+898900 6917200 279.5
+947700 6845400 266
+909700 6915300 269
+901900 6904700 236
+921100 6880200 265.5
+922300 6877000 273.5
+923600 6858800 252
+972600 6837000 265
+945000 6824500 319.5
+918000 6906700 228.5
+896400 6938900 331
+904500 6933800 359
+890900 6933600 296.5
+929200 6821900 313
+939800 6839800 248
+911900 6839400 233
+954600 6831100 250
+913900 6829200 344
+922600 6815800 402
+924900 6812400 356
+913900 6905300 216.5
+981800 6826900 325
+909300 6847500 298
+932300 6859600 298
+990600 6825900 435.5
+949200 6847300 243
+942000 6836900 293
+910300 6922800 358
+932000 6847500 292
+962000 6847100 260
+945500 6830600 296.5
+955400 6855200 257
+896500 6925300 278.5
+940500 6844500 231.5
+961400 6831300 262
+905200 6922400 337.5
+973600 6833000 287.5
+900000 6838000 334
+855200 6910100 268
+849000 6857800 167
+857900 6928300 183.5
+891900 6860700 306
+893600 6864900 307
+894900 6911700 242.5
+893700 6849000 297.5
+895300 6900100 204
+869000 6933800 242.5
+858500 6922900 226
+868900 6936800 233
+869300 6908400 217.5
+848500 6845000 194.5
+866300 6865800 289
+899200 6892200 213
+896100 6866700 308
+898900 6829000 339.5
+872600 6860700 323
+869800 6833800 300.5
+881300 6857500 302
+876600 6823900 359
+887000 6922600 243.5
+869700 6932200 239.5
+880300 6911400 255.5
+885000 6869800 281.5
+864400 6837500 259
+875200 6848900 321
+884400 6874700 251
+860300 6857000 246.5
+895800 6871700 312
+851800 6919100 235.5
+882100 6864900 286
+858600 6917300 236
+882500 6830500 339.5
+876600 6913200 276
+892800 6827400 360.5
+893900 6889000 224.5
+878100 6939200 263.5
+849400 6851200 194
+888900 6858900 302
+890300 6848100 300
+860500 6876400 277.5
+873100 6933400 275.5
+864200 6871000 280
+844600 6894200 184.5
+902400 6864000 249
+869300 6847200 288.5
+899400 6863700 235.5
+877000 6888400 280
+867100 6861500 330
+870500 6921800 288.5
+858300 6920800 222.5
+870200 6908700 249.5
+853400 6844900 213
+871900 6836100 308
+865200 6904400 234
+898900 6830500 318.5
+877900 6936800 249.5
+885100 6826600 357.5
+890800 6830900 355
+879800 6820400 364
+860100 6887000 263.5
+881600 6832800 333
+849900 6861300 171
+866100 6892400 283.5
+868600 6855900 318
+882000 6898700 299
+869400 6906600 259
+900000 6892500 209
+872100 6859700 337
+889000 6900700 211
+864700 6885300 301
+897600 6873600 306
+897600 6900000 208
+878600 6882700 238.5
+843900 6895400 208.5
+889300 6891700 309.5
+861000 6841500 259
+851100 6851800 202.5
+874800 6940900 275
+871200 6929600 233.5
+887600 6843200 322.5
+866100 6906100 236
+850000 6843200 197.5
+866300 6912100 280.5
+865600 6838300 281
+880900 6927300 244
+848800 6839200 199
+892900 6927000 262.5
+856100 6860300 226
+861600 6884000 275
+880300 6880900 262.5
+884300 6861200 285.5
+905600 6891200 207.5
+871300 6918900 293.5
+875200 6862600 310
+891100 6923000 259.5
+852300 6865000 197.5
+856600 6920300 238.5
+848900 6901600 210.5
+880200 6922700 210
+875700 6875600 293
+863800 6854400 275
+850500 6880400 204.5
+875900 6935700 262
+882300 6848200 336
+890000 6915500 231
+873200 6840100 288
+887200 6879300 287
+876200 6886100 260
+857200 6875100 232
+842900 6898100 205
+897200 6834200 318
+873700 6937200 250.5
+865400 6888100 286.5
+857600 6922400 238
+886000 6847800 336
+891700 6895400 224
+856200 6856600 221
+892200 6912000 233
+882700 6908300 232.5
+870300 6929700 228.5
+892800 6910700 230.5
+891600 6898200 210.5
+873800 6898200 262
+897700 6904100 220
+893400 6822800 374.5
+871500 6891900 267.5
+904000 6868900 234
+898200 6894300 211
+890500 6854700 303.5
+869200 6865000 305
+862400 6908200 237.5
+896900 6832600 323.5
+857700 6911100 256
+873800 6829700 339.5
+884000 6872300 302.5
+885000 6841200 343.5
+879000 6869100 292.5
+894800 6901700 207.5
+855900 6868400 205.5
+878500 6881100 278
+875400 6854200 322.5
+879500 6858900 306.5
+859700 6870000 265
+857300 6925600 244.5
+890700 6918700 247.5
+858400 6934500 233
+906100 6885600 220.5
+871500 6865900 291.5
+874100 6825300 348.5
+894100 6835200 330.5
+877400 6902200 308.5
+885900 6861300 290
+882200 6824000 345.5
+889600 6893300 233.5
+896500 6836800 307
+881600 6842800 336.5
+854700 6872600 216
+879500 6913000 281
+855100 6886600 245
+886400 6900100 220
+898600 6887700 215.5
+851400 6916700 241
+871800 6864700 309.5
+871200 6910700 274.5
+886200 6865900 296.5
+846600 6908800 180.5
+873200 6903800 274.5
+846300 6888300 188
+859800 6845600 266.5
+855100 6888400 246.5
+878200 6884500 281.5
+899500 6885600 222
+895100 6884000 314
+879600 6916500 283.5
+906900 6877300 242.5
+856300 6883800 241.5
+876800 6882600 261.5
+882100 6900600 297
+851500 6847900 207
+902500 6868000 233
+888300 6835800 338.5
+870800 6869100 297
+858600 6833300 268.5
+876400 6867400 302
+847900 6863700 171.5
+873600 6900000 283.5
+874800 6914500 286.5
+862800 6857300 276
+862400 6921100 269
+857300 6939300 239
+885100 6898500 239.5
+887800 6840600 341
+894600 6893300 215.5
+857600 6930800 187
+867700 6903700 247
+843600 6857600 155.5
+896700 6912900 263
+856100 6928000 250
+899000 6899700 210.5
+881900 6922100 228.5
+859700 6919500 227
+893000 6853000 296
+872400 6917400 294.5
+858900 6926000 233
+852100 6846400 209
+861100 6903200 258
+851400 6910600 225
+884100 6828600 335
+879700 6906900 296.5
+861800 6925700 255.5
+893300 6902500 207.5
+890400 6889600 296
+896800 6829800 330.5
+879700 6847900 332.5
+897200 6892500 216.5
+897900 6855700 316.5
+873200 6831800 322.5
+855600 6843300 222
+894800 6830500 342
+841000 6857500 128.5
+882300 6882800 287.5
+898100 6842200 317.5
+861900 6901400 265.5
+892700 6846300 302.5
+871000 6941800 256.5
+883700 6920200 231.5
+878100 6835700 321
+866000 6850200 276
+903500 6888800 216
+894500 6895900 215.5
+855400 6878000 216
+858800 6835300 264.5
+856300 6936900 190
+888800 6876300 315
+895900 6905500 231
+870900 6880000 282
+859100 6879800 252
+897400 6884700 225.5
+878200 6896300 295.5
+872900 6945300 262
+876800 6894600 279.5
+894900 6892500 222
+898900 6828700 293.5
+883800 6877800 284.5
+848300 6867500 180
+863000 6898600 287.5
+875800 6888400 264.5
+850200 6897700 217.5
+880100 6904100 302.5
+900000 6846500 304.5
+880000 6827500 350
+860700 6931500 220.5
+892700 6823500 366
+893300 6875100 316
+879900 6890100 303.5
+867500 6863500 320.5
+867700 6859400 330.5
+845500 6862400 162
+870000 6943900 279
+846500 6907200 198
+898700 6823900 337
+840500 6860100 131
+898900 6898700 210.5
+894900 6923000 278.5
+898800 6848100 292.5
+885500 6896000 289
+862400 6934400 232
+874700 6906900 294.5
+853800 6929800 245.5
+864000 6849600 274
+871200 6842700 291.5
+863400 6838700 252.5
+889800 6906900 211.5
+865700 6833300 290
+849800 6913800 209.5
+879200 6861100 312.5
+894700 6866800 308.5
+853400 6930800 241
+869200 6922800 289.5
+853200 6932300 210
+861700 6941000 224
+853700 6879700 203
+856600 6940700 243.5
+861000 6940000 225
+878100 6841300 318
+866300 6939600 257
+858600 6909800 256.5
+899500 6913700 277
+876700 6837100 316.5
+857500 6843900 242.5
+863800 6844300 292
+899200 6841100 272.5
+852300 6912900 235.5
+889700 6837900 334.5
+867000 6887600 279
+868400 6874000 281.5
+851100 6883300 223.5
+864200 6896100 290
+886000 6832200 350
+900800 6830200 324.5
+859300 6854600 251
+866800 6897900 263
+876400 6914600 273.5
+884100 6896900 302.5
+881600 6903100 288.5
+870200 6938900 255
+842500 6865600 161
+891800 6840600 307.5
+885100 6902700 230.5
+875000 6939100 266
+899400 6869100 301
+884200 6907700 224
+843100 6868700 171.5
+868200 6910600 258.5
+858100 6892800 252.5
+858900 6889100 258
+876500 6925900 233.5
+872600 6873400 297
+875100 6895100 247
+891300 6921200 249.5
+851900 6895700 237.5
+851200 6891600 233
+898000 6832100 317
+856800 6934600 204
+874100 6892100 256.5
+883000 6866100 264
+860800 6941900 254
+866400 6935200 232.5
+892700 6886100 306.5
+847800 6908400 186.5
+888200 6904700 216.5
+875200 6924300 213
+893000 6859200 303.5
+873900 6921600 205
+863100 6923700 273
+858700 6906900 253
+874400 6918600 275
+872200 6903400 239
+855600 6852200 239
+843600 6856400 158
+864300 6873100 278.5
+864900 6916000 276.5
+862600 6914300 237
+850600 6848400 199
+897600 6890200 214
+877500 6851900 326
+886900 6857600 298.5
+853800 6944200 257.5
+878500 6924100 220.5
+872800 6928300 234
+862200 6860400 263.5
+853900 6917200 262.5
+901200 6866200 237.5
+867600 6849100 278.5
+885100 6886400 319.5
+888000 6906900 216
+891700 6855800 301
+880600 6877900 268.5
+871000 6845700 301.5
+883000 6876100 269.5
+895000 6858900 304
+892100 6904700 216
+867300 6923800 285
+887200 6924800 267.5
+867400 6828300 327
+871400 6938100 256.5
+860000 6852900 254
+887200 6917800 226
+874000 6848800 311.5
+853600 6836500 210
+858400 6842300 235.5
+900600 6825500 342.5
+867200 6883300 293
+863100 6841700 272.5
+867900 6854100 298.5
+882900 6905200 240.5
+857200 6836000 248.5
+869200 6838100 308
+899500 6895100 213
+885600 6900200 229
+860300 6924200 253.5
+875900 6839000 315
+875100 6840000 296.5
+864100 6863500 279.5
+887100 6858700 278
+880000 6908700 290.5
+891700 6873600 315
+862800 6911800 228
+889500 6888100 318.5
+855600 6913100 241.5
+881400 6834100 331.5
+883400 6924700 241.5
+852300 6867100 198.5
+871900 6905000 260
+903900 6892200 208
+892400 6819800 375.5
+871600 6899400 256.5
+894300 6885500 307.5
+856900 6839300 254
+885400 6858700 275
+854100 6847700 231.5
+856100 6902900 249
+889100 6880300 317.5
+887300 6908100 221
+869200 6848300 288
+864500 6889400 276
+867800 6879500 306
+892200 6891700 223
+881900 6886500 310.5
+856000 6893700 242
+897600 6837000 309
+858900 6865200 242.5
+875300 6909200 302.5
+862500 6851400 262
+876500 6873700 296.5
+865200 6850600 267
+899300 6825900 322
+854100 6882000 249.5
+851000 6902400 237
+886400 6895200 289.5
+856300 6884900 236
+884200 6870500 275.5
+890100 6886100 328.5
+846300 6891900 200.5
+891800 6920900 258.5
+879400 6879600 278.5
+890700 6884400 336.5
+863100 6881600 283.5
+899200 6843500 287
+849000 6852800 191.5
+873000 6943400 255.5
+873400 6841500 301.5
+874500 6844900 314.5
+886900 6893700 306
+883500 6844800 359.5
+870500 6886800 281
+882400 6873100 285
+875500 6942900 278
+872400 6841100 287.5
+850600 6907500 208
+873700 6916800 285.5
+898500 6861700 241
+886200 6868500 301.5
+845900 6860500 158
+859900 6895300 262.5
+883000 6864600 289
+850200 6860000 174
+847300 6855500 176
+844600 6866800 165.5
+851900 6857700 204
+871300 6867500 299.5
+876000 6857300 335.5
+853200 6923900 286.5
+895900 6882800 317.5
+893800 6917700 271.5
+895800 6891100 216
+876900 6933200 265
+897900 6879100 314
+869000 6870200 292
+895300 6820500 342
+866800 6909400 233.5
+854000 6942400 254.5
+900600 6822700 337.5
+856200 6938200 218.5
+880100 6840700 331
+848900 6854700 177
+870900 6852700 305.5
+881600 6839600 339
+891800 6887500 299.5
+870700 6920700 294.5
+902400 6873700 225.5
+885600 6818600 371.5
+885700 6882800 307
+865900 6843300 304.5
+865100 6834900 276.5
+863600 6937700 231.5
+849900 6905500 197
+873800 6863600 304
+874900 6859200 317
+865400 6872000 272.5
+848300 6905100 204
+899000 6839000 317
+883600 6853000 306.5
+874800 6881000 274.5
+850900 6877400 186
+852700 6939900 217
+867300 6938000 249.5
+878100 6930900 255
+862300 6916700 280.5
+893700 6913700 246
+854100 6920700 250.5
+877100 6905000 317.5
+862200 6895000 276.5
+857400 6895600 248
+867400 6876500 290
+895900 6914200 246
+892600 6916400 240.5
+308900 6747700 41
+314400 6776000 132
+312600 6728700 35
+255400 6797700 100.5
+293800 6734200 65.5
+225400 6802000 233
+284500 6746700 105.5
+264000 6766700 111
+279200 6746200 83.5
+244500 6782100 96.5
+298300 6739900 49
+264300 6737100 8.5
+218100 6764400 39.5
+256100 6768300 92
+315600 6731100 31.5
+303000 6744100 51.5
+251500 6746700 21.5
+306100 6770900 92
+280000 6737600 28
+274600 6753300 98.5
+291000 6743100 77.5
+220200 6762600 34
+247200 6737900 15.5
+292900 6750700 64
+261200 6738000 15
+315800 6753000 51
+289700 6776100 79
+275600 6740600 54.5
+248000 6782000 106.5
+266200 6730000 21
+297900 6722700 26
+238200 6744900 18
+239700 6792700 164
+243600 6738100 22.5
+265700 6787500 115
+232300 6795000 199.5
+248800 6797800 168
+276200 6780700 84.5
+229200 6786200 126
+291900 6777600 59.5
+295800 6764500 51
+260900 6727300 21
+288100 6752300 66.5
+232600 6774000 88.5
+281600 6758400 72.5
+265600 6773700 103
+317700 6750800 44
+220800 6785500 97.5
+256300 6791000 120
+223400 6757600 23
+233300 6755800 20.5
+294800 6765600 66
+253400 6735600 9.5
+302000 6754500 53.5
+254100 6788300 115
+316000 6758700 58
+205400 6793000 153.5
+240700 6705900 36.5
+316900 6742200 25
+223700 6785400 101
+227300 6753400 17.5
+245200 6756200 33
+256800 6785200 88.5
+321100 6759200 51
+253600 6773200 92
+266800 6755600 95.5
+301000 6790100 82.5
+209100 6802700 192
+306700 6788900 88.5
+279200 6767000 124
+288300 6761300 85.5
+287100 6765900 102.5
+276500 6774600 119
+291700 6768600 76
+268800 6769000 117
+292300 6782200 73.5
+225200 6755200 12
+308800 6764200 84.5
+238400 6792400 149
+278400 6763700 96
+309600 6750700 51.5
+255700 6740900 21
+224100 6753200 7
+297400 6759200 52.5
+307100 6740700 66
+230800 6715200 29
+253900 6750500 46.5
+272400 6764900 103
+267900 6744100 28
+212000 6796900 148
+263000 6741100 30.5
+299800 6729100 41.5
+300000 6773300 81.5
+284800 6774400 94.5
+269400 6740000 10.5
+241900 6758200 40
+276700 6788600 101.5
+294700 6758800 62
+223100 6769700 54.5
+298700 6779200 81
+278900 6769700 106.5
+225800 6764500 43
+280600 6728100 10
+306000 6780800 112
+225600 6759400 25.5
+230500 6763500 41
+227200 6789800 148
+315500 6748800 44.5
+283800 6738400 40
+239800 6766100 66.5
+312500 6786500 99.5
+255100 6758300 99.5
+303200 6738900 46
+304400 6749400 46.5
+260000 6744800 30.5
+287400 6791900 106
+268200 6751000 88.5
+297600 6753500 53
+272800 6772100 117
+277100 6734900 21
+226500 6793000 189
+282500 6731700 28.5
+251200 6715800 21
+302600 6764900 71
+257400 6799600 122.5
+257300 6732900 18
+306500 6734800 43.5
+218500 6756900 27
+301500 6726500 29
+254600 6778800 92.5
+302900 6728100 35.5
+282300 6745300 81
+274000 6777900 101.5
+253600 6743500 21
+294000 6722900 22
+227900 6771700 85.5
+268400 6755400 98.5
+300000 6762000 52.5
+305100 6775200 131
+221800 6753400 19.5
+292900 6765600 69.5
+257200 6737300 13
+315900 6774600 101.5
+236700 6761900 43.5
+271600 6779600 95
+235300 6753800 10
+310800 6765300 95.5
+305000 6759600 56
+241100 6739700 16.5
+235000 6746900 8.5
+295000 6767300 59.5
+260100 6782700 87.5
+262300 6790300 108
+263800 6798400 135
+286200 6776300 62.5
+302000 6757200 52
+227300 6776100 88.5
+267400 6796300 118
+276500 6748900 83
+249500 6737800 13
+275600 6729100 8.5
+233000 6708800 29
+262200 6795000 116.5
+317900 6754900 28.5
+284100 6781500 74.5
+256200 6744700 28
+294400 6776000 56.5
+287300 6729000 14.5
+231700 6782600 110
+223100 6792800 143
+217200 6798200 198
+242000 6796400 185.5
+268900 6792900 114
+238600 6788000 140
+262500 6756000 97.5
+271900 6789900 105
+212700 6786600 120
+214700 6763300 35
+249800 6792800 147.5
+292000 6770800 55
+239800 6780600 108.5
+253500 6803800 171
+244800 6802400 203
+253400 6747400 29.5
+297300 6772800 62.5
+271700 6736000 18.5
+282100 6767900 109
+238900 6731300 13
+223900 6751800 5
+303000 6781500 93.5
+231700 6767800 56.5
+260100 6767600 97.5
+228600 6796500 208
+317700 6768400 86.5
+297300 6789200 89.5
+216700 6790200 127.5
+236600 6798400 205.5
+256500 6709800 11
+299400 6793700 97
+242200 6773900 98.5
+246400 6787500 127.5
+278500 6776900 82.5
+251600 6766800 82
+290200 6780400 78.5
+264900 6749200 42
+306600 6751500 52.5
+250900 6752600 33
+309400 6757700 64.5
+297900 6746500 57
+300000 6746800 51
+290200 6735400 47
+295700 6726700 31
+297500 6785100 80.5
+235700 6712100 29
+271000 6734600 8.5
+250300 6758800 81.5
+299800 6766900 92.5
+309000 6789700 73.5
+294100 6796200 138
+274000 6757400 98
+221500 6767600 37
+231600 6751600 12.5
+288600 6786900 86.5
+215800 6746300 24
+264200 6770100 111
+309000 6744600 45
+288100 6723400 19
+237500 6748700 16.5
+250500 6769900 89.5
+287400 6756700 64
+244600 6745300 29
+257000 6754600 52.5
+273600 6738700 11
+293100 6756300 53.5
+239600 6727100 16.5
+285400 6740300 73
+286700 6749000 76.5
+288500 6771600 92.5
+315400 6738700 41
+309500 6761700 64
+242700 6752300 21
+314300 6745800 30.5
+281300 6751600 93
+249600 6741200 22
+270200 6747400 74
+242600 6801000 225.5
+279400 6783700 81.5
+236800 6757000 26.5
+270600 6786200 95.5
+265400 6781500 96.5
+249000 6775700 89
+316500 6734300 40.5
+200800 6801900 183
+311900 6769400 92
+288100 6731300 32.5
+259900 6775700 83.5
+233100 6758800 35
+265600 6762500 104
+233100 6789300 140
+297700 6733800 46
+312600 6739000 44.5
+948300 6859300 244
+994000 6864800 256.5
+968100 6857700 229.5
+945200 6862500 242.5
+941300 6865600 207
+921700 6904600 303
+1006300 6854700 313.5
+981700 6871200 250.5
+986800 6904300 312.5
+1019600 6903000 298.5
+994000 6858400 280
+946100 6888700 276
+992300 6897000 253
+1002400 6899500 263.5
+1009500 6856400 291
+971400 6864700 267
+940600 6933200 215.5
+994100 6851500 298
+1002100 6853700 310.5
+971100 6871200 294
+977600 6853200 258
+940000 6934900 211
+957500 6863700 266
+1000400 6846900 361
+983300 6858800 262
+948700 6870600 244
+1017800 6900100 305
+1012800 6860400 292
+959300 6909400 296
+988000 6893300 253.5
+1007800 6899100 310.5
+979900 6861700 233
+956500 6907800 254
+975600 6869700 264.5
+946900 6860100 242
+980000 6892100 272
+968800 6854600 233
+931500 6923700 196.5
+999500 6842200 589.5
+987000 6876400 231
+987200 6845200 313
+930100 6933300 224.5
+926400 6885500 276
+950100 6921500 262
+984100 6844400 319
+939800 6880500 277.5
+942600 6882800 274
+930100 6889200 184
+959200 6896900 319
+939000 6887500 242
+949700 6889500 276
+932300 6906900 160.5
+938900 6917800 214.5
+986300 6907200 229.5
+1003000 6848900 360.5
+988100 6844400 319.5
+966300 6875400 263
+977400 6874800 252
+949200 6933300 316
+961100 6912400 345
+961600 6914200 301.5
+934300 6907700 191
+978800 6869900 251.5
+951500 6877400 249
+950100 6924300 270
+959300 6912300 281.5
+941300 6932100 222.5
+947900 6934600 308
+931600 6922400 182
+933400 6904300 184
+1015500 6860400 292
+948200 6884600 266
+1005500 6859800 308
+920200 6906200 252
+969800 6878500 265.5
+981300 6900600 270
+957300 6923100 237.5
+986100 6886300 234
+1030500 6884500 331.5
+1004100 6894700 283.5
+950100 6858900 239.5
+1008100 6893600 316
+975500 6873700 276
+995000 6888300 235.5
+959200 6873600 279
+962200 6872800 272
+983000 6880800 233.5
+952200 6873000 250.5
+935400 6927800 192.5
+936100 6897800 214.5
+962300 6895200 337
+982200 6903300 258.5
+1011300 6896900 336.5
+962400 6901800 312.5
+937700 6879100 270.5
+1023600 6906000 297.5
+998600 6902400 242
+959700 6924400 242.5
+930700 6884600 184
+914400 6924300 334.5
+955000 6873000 268
+921300 6903100 311
+1008100 6858900 304
+949500 6869500 247
+954600 6903800 283.5
+938800 6893100 231.5
+1013300 6855000 334
+1002900 6891800 267.5
+985600 6872400 238.5
+1004200 6860800 302
+958500 6880600 261.5
+944400 6875800 303.5
+1008000 6854400 304
+947300 6878500 257
+1014500 6892400 310
+958200 6923000 228
+1025500 6898600 330.5
+993900 6853200 291
+952300 6898300 276
+926700 6918000 192.5
+965400 6914100 284.5
+963800 6892400 355.5
+960300 6863100 268.5
+1025800 6903000 314.5
+922300 6915200 280.5
+978700 6879700 258
+996600 6848800 301.5
+988000 6901500 305.5
+943800 6921500 259.5
+937900 6926500 227
+926300 6911800 258.5
+991600 6879900 229.5
+950000 6912400 261.5
+951100 6931800 341
+958600 6914700 263.5
+934600 6934700 198
+1005500 6889300 295
+927200 6933700 297.5
+951100 6888000 271.5
+966600 6901400 277.5
+942800 6907800 278.5
+950500 6916600 246.5
+1011400 6864000 264
+935500 6881100 227
+938500 6930800 164
+966800 6882300 291
+936900 6904400 197
+950100 6861000 259
+953600 6932200 346
+1015200 6885800 309.5
+936200 6902000 211
+998500 6860300 280.5
+1017300 6881900 322.5
+956100 6929500 310.5
+995400 6866400 267
+945300 6929700 257.5
+925900 6907100 297.5
+929900 6895900 237.5
+937000 6917300 201.5
+951300 6883800 247
+1006600 6868200 296.5
+935500 6921100 180.5
+944700 6880900 274.5
+952700 6919900 251
+935600 6884200 209
+928700 6911300 261.5
+977300 6872100 284.5
+924700 6917900 235
+943100 6868300 229.5
+938600 6923100 231.5
+957100 6916000 251
+957800 6867000 280
+933500 6909600 168
+948700 6904200 281
+930600 6911600 158
+929500 6916000 170
+940300 6909200 249.5
+959700 6894900 309
+962000 6879900 265
+985800 6909300 244
+970300 6872000 280
+937700 6897800 216
+925300 6893400 255
+984200 6905700 290
+973200 6895400 274.5
+979600 6876700 270.5
+964100 6915100 303
+989800 6882800 236
+926500 6899900 281
+927400 6904000 270
+939000 6899300 243
+941700 6890200 240
+925000 6904000 284.5
+923400 6910900 247.5
+1011700 6891200 318
+962800 6908800 282
+929900 6899200 194
+991400 6848500 306
+1019300 6898100 319.5
+978000 6880300 253
+957700 6901700 323.5
+1004800 6895300 313.5
+927000 6894100 180.5
+964900 6883900 277.5
+916400 6926700 354
+989000 6849900 292.5
+932500 6901200 164
+1021700 6898900 326.5
+999900 6852600 291.5
+942700 6904000 288.5
+957600 6905200 307
+959400 6859400 255
+977100 6900200 273
+926000 6893900 196
+956500 6879400 291.5
+958700 6899400 330
+987900 6888900 241
+956900 6865600 283.5
+991400 6852500 297
+966200 6888600 294
+1017800 6891400 330.5
+1000800 6848800 325.5
+938300 6882700 252.5
+955800 6897900 320
+937300 6885100 240.5
+931500 6938200 250.5
+980100 6871900 243
+989100 6903600 295.5
+949700 6880200 249.5
+945100 6863600 230.5
+931100 6918900 181
+971300 6874000 258
+966700 6856400 231
+972200 6901800 260
+953900 6923400 257.5
+962500 6868300 257
+987400 6898900 303.5
+939200 6929800 178
+961800 6897700 348
+991400 6905100 279.5
+961000 6918100 279.5
+935500 6890900 212.5
+957100 6880400 245
+1002800 6851300 326
+991100 6856100 285.5
+993900 6862100 258.5
+960800 6875300 304
+937700 6890400 218
+925000 6894000 263
+986100 6881700 230
+940200 6884700 268.5
+926500 6901400 282
+921900 6900600 303.5
+944000 6866400 223.5
+981300 6867800 234.5
+965100 6873600 240.5
+989000 6896900 271
+982500 6883400 233
+980100 6884300 276
+969100 6875500 256
+936800 6936600 211.5
+915300 6892000 273.5
+944100 6885900 250.5
+935700 6897000 216
+1017200 6888000 330
+993000 6863400 253.5
+925300 6928100 301
+931900 6895800 209
+914100 6935300 354.5
+935800 6905600 206.5
+975100 6862300 226.5
+947600 6892500 268.5
+969700 6860900 220.5
+972900 6865400 271
+1010500 6863400 266
+960200 6882400 285
+1007700 6862200 294
+996200 6862500 277.5
+981000 6884900 240.5
+939400 6896300 234
+922800 6884500 269.5
+1000900 6860800 297
+932800 6888100 196
+931300 6881000 204.5
+954100 6876900 271.5
+944400 6888800 257.5
+923700 6881600 278
+974600 6869100 274.5
+945100 6875200 322
+958900 6867800 271.5
+946900 6871100 304
+944900 6871600 297
+968400 6872100 269.5
+975700 6898400 281.5
+920900 6925200 366.5
+1001100 6900900 237
+945600 6920800 267
+986400 6858100 270
+919200 6888000 274
+945100 6918500 265
+974700 6866200 269
+943500 6894700 260.5
+924900 6889000 239.5
+1007000 6848700 382
+911500 6936700 362
+1007400 6850000 355.5
+925400 6911300 245.5
+954500 6874400 254
+940500 6876900 254
+962400 6916300 279.5
+922600 6918800 260
+971100 6853300 247.5
+991800 6851100 288.5
+972600 6849900 251.5
+953100 6928700 301
+946500 6898900 255.5
+931200 6908700 169
+945200 6896400 250
+956000 6878900 268.5
+994200 6848500 300.5
+940200 6930700 186
+926200 6915500 265
+998800 6895700 229
+980300 6845700 287
+958200 6896000 306.5
+955700 6885400 263.5
+1005700 6890700 280.5
+1020100 6904300 298.5
+989900 6886300 238.5
+981000 6908200 251.5
+976000 6860400 226.5
+965900 6871800 241.5
+994900 6892100 247
+925900 6895500 263.5
+938000 6900400 245.5
+989200 6854900 280.5
+972600 6892300 278
+950300 6900400 247
+992000 6900500 292.5
+924600 6890800 254.5
+951200 6904400 251
+994900 6868100 272
+1010400 6864900 259.5
+935500 6925500 199
+961500 6900600 369
+960000 6890600 304.5
+955400 6910400 264.5
+937000 6938700 225
+915800 6918700 278.5
+976300 6882100 252.5
+931400 6930800 212.5
+989700 6878500 232.5
+917400 6925100 337.5
+954500 6893800 262.5
+943500 6873500 285.5
+932600 6915600 193
+943300 6915900 260
+945200 6892400 250.5
+941600 6925200 238.5
+992500 6858000 281.5
+987600 6897100 282.5
+979200 6873900 261.5
+932700 6913600 192
+1018600 6890500 347.5
+917600 6921500 296
+1000000 6895500 252
+941700 6894500 261.5
+976400 6886300 295
+1005100 6898700 282
+930200 6922200 285
+941600 6876000 261
+967700 6890300 301
+1018500 6885300 329.5
+989600 6892500 250.5
+998000 6855900 284.5
+963500 6866700 257
+991900 6849700 299
+967500 6852600 252.5
+964700 6861500 261.5
+957600 6891700 265
+1007800 6860500 305.5
+1028400 6889200 317
+956600 6924300 260.5
+983700 6856500 271
+982000 6879700 238
+949900 6872400 302
+929900 6937900 264
+985700 6863200 252.5
+941200 6879100 269.5
+947300 6881600 272.5
+948500 6908100 281
+927300 6894900 262.5
+939700 6921400 225.5
+981300 6881500 235
+947600 6913900 280.5
+954700 6925500 264
+995600 6849700 294.5
+977300 6896300 312.5
+982700 6847400 287.5
+970500 6856500 232.5
+995100 6845000 324
+928800 6895100 240
+948500 6865200 256
+977200 6889400 283.5
+981400 6895300 281
+946500 6865300 233.5
+979600 6897200 304
+1012900 6895100 314
+966700 6868700 266.5
+988800 6904900 325.5
+979200 6865000 226
+959800 6880300 293
+931200 6883400 201
+1018600 6895200 320
+939600 6894900 226.5
+983900 6887500 245
+964200 6884400 284
+968100 6903800 241.5
+919800 6928100 366.5
+930700 6886200 203
+961700 6858900 257.5
+976900 6877400 226.5
+960200 6920200 254
+957400 6919500 232
+913700 6928200 378.5
+930600 6910700 181.5
+1015500 6901400 309
+935200 6913400 195
+978900 6859100 231.5
+956800 6874300 289.5
+944600 6932300 252.5
+961700 6914900 298.5
+943200 6899200 256.5
+989200 6906400 288.5
+963200 6874200 278.5
+1018500 6882700 343
+944700 6934100 255
+953500 6909700 228.5
+941900 6891500 242.5
+927700 6920600 171.5
+949000 6918600 249.5
+962900 6910500 280.5
+946500 6919800 289
+967800 6867400 273.5
+987200 6890800 248.5
+980200 6855500 259.5
+936300 6909000 215.5
+971700 6876600 255.5
+950200 6907500 267.5
+990600 6897000 265
+921700 6910200 249
+953000 6897500 269.5
+991300 6902300 276.5
+1012500 6856700 301
+958400 6872900 286.5
+986100 6875500 232.5
+949500 6875000 297
+970900 6902700 247.5
+999200 6869000 280.5
+963100 6888400 321
+1011300 6854000 353
+984300 6895200 261.5
+994700 6846800 310.5
+973100 6863300 225
+978500 6898700 282
+1028300 6900600 339.5
+992100 6844100 331.5
+945000 6873000 325.5
+951500 6882200 237.5
+984000 6901200 303
+955400 6913600 248
+1010400 6860500 298
+1034100 6885600 357.5
+981200 6892700 266.5
+938800 6897700 218.5
+926200 6902500 268.5
+950800 6885500 249
+993700 6902700 273
+1006300 6860900 304
+1026800 6903600 317
+962500 6877500 272
+975900 6888300 289.5
+952600 6910300 228.5
+1025700 6900500 320.5
+1001700 6852100 310.5
+953400 6900300 287
+949300 6927400 303
+952700 6906400 220
+974200 6853100 250
+935500 6900200 192.5
+948600 6895300 257
+964100 6913300 297
+934200 6902100 182.5
+956800 6860200 251.5
+1025200 6885100 317.5
+1023300 6892600 340.5
+963800 6881900 280.5
+970100 6893600 316.5
+971700 6883300 280
+928100 6888800 263
+989700 6898300 313.5
+930300 6906000 182.5
+965800 6867300 274
+989500 6888300 240.5
+951900 6868500 298.5
+948800 6868200 253.5
+995300 6863200 277
+1011100 6898600 330
+957900 6866000 280.5
+976300 6884900 286.5
+985800 6893900 258
+957600 6883800 285
+978400 6848200 258
+1021200 6891300 347
+936400 6900100 220
+1008300 6885100 300
+982600 6869000 253.5
+1004700 6856700 296.5
+989100 6869500 246.5
+923300 6887400 252
+980300 6869100 251.5
+965600 6896800 319.5
+954100 6895000 270.5
+963800 6904900 284
+980800 6902300 259
+992800 6893700 242
+980100 6899300 269.5
+967600 6879700 287.5
+936900 6888700 211.5
+965800 6893200 349.5
+1000000 6844700 324.5
+1005600 6862300 306
+966800 6862900 266
+964500 6903100 308.5
+1003500 6861000 302
+934300 6883300 209
+982400 6877200 246
+1021700 6895600 343
+963300 6856000 241
+929900 6876400 213.5
+989000 6875500 241
+918900 6931200 361.5
+935500 6918900 191
+954000 6870100 294
+989300 6846900 315
+1009200 6861900 271
+1006100 6866100 297
+960500 6867200 236
+952700 6879200 247.5
+995300 6860300 275
+940800 6900500 271.5
+925300 6910000 272.5
+939100 6903100 231
+955800 6890300 265.5
+960300 6905700 309.5
+991700 6846700 319
+982000 6897500 270
+965000 6886800 270.5
+970700 6895700 299
+959000 6874900 301
+979200 6887800 282
+1000300 6854900 286.5
+1005800 6864100 316
+948200 6921500 269
+918300 6892800 275.5
+965100 6860400 253
+971000 6888700 283
+1001600 6894600 244
+973800 6858100 231.5
+930900 6887200 182.5
+982000 6865700 234.5
+953700 6881100 263.5
+937100 6922800 205.5
+1005500 6847300 638.5
+1008500 6858200 315
+942900 6917200 237.5
+949900 6885600 261.5
+1022600 6902000 314
+960200 6902300 337
+921700 6920100 284.5
+983600 6879900 244
+939700 6881700 276.5
+1029100 6898500 354
+974600 6878200 243.5
+941100 6898000 250.5
+965900 6904000 272.5
+1010800 6890300 313.5
+942800 6893900 251.5
+951600 6880400 245.5
+927900 6896800 268
+952100 6892000 286.5
+1020300 6887100 339
+947600 6886500 266.5
+965600 6853900 249.5
+928900 6927500 201
+1002100 6837700 560.5
+998300 6864300 289.5
+996900 6897700 242.5
+943100 6927200 243
+962800 6865500 264
+1011300 6857600 290.5
+919000 6898300 300
+993800 6845100 328
+1012400 6862400 258
+996200 6840300 362.5
+943600 6911900 253.5
+933400 6933400 199.5
+951800 6871100 263.5
+990800 6850300 287.5
+957300 6910300 268.5
+931700 6917000 179
+954100 6859700 254
+964300 6880200 271.5
+952200 6865500 289.5
+959100 6885800 272
+997100 6894000 246
+1020400 6884200 346
+994600 6884900 234
+930400 6913400 183
+959300 6890300 266
+964800 6871700 257.5
+997700 6851500 288.5
+980400 6888100 257.5
+1011900 6847700 590.5
+927400 6912500 189
+1009400 6851100 363
+920100 6911900 253.5
+997600 6846800 326
+1015000 6898900 315
+935600 6879500 233
+990200 6890000 247
+970700 6880800 264
+1035000 6893800 341
+973600 6882000 266
+955900 6893900 267
+987800 6881300 229.5
+976700 6891000 273.5
+948000 6917400 279.5
+974300 6888400 283.5
+933100 6878200 208
+961700 6890700 310
+1003700 6888100 267
+942400 6887800 247.5
+935800 6876300 234
+954700 6883300 264
+947400 6872800 312
+975300 6863600 226
+987600 6879400 235.5
+954000 6914700 235.5
+914400 6934500 373
+926800 6882100 279
+941400 6919900 238
+982000 6874600 242
+943600 6869200 227.5
+951200 6873700 294
+928500 6903800 216.5
+982300 6860700 242.5
+969000 6861900 254
+1001800 6858000 280
+926100 6905700 272.5
+932100 6882000 192
+936500 6884100 230.5
+940600 6916000 237
+977800 6867600 242.5
+983600 6872400 233.5
+1006000 6853500 324.5
+961000 6871300 258
+971800 6859100 232.5
+943700 6932200 241
+960200 6870500 274.5
+937500 6932000 182.5
+966900 6911700 250.5
+937400 6919600 210
+950200 6868200 262
+1009200 6865200 277
+923400 6931400 361.5
+934800 6910000 199
+946100 6887300 229
+921000 6919700 281
+952300 6912600 227.5
+1001700 6845200 620.5
+960500 6881800 275.5
+951400 6902000 252.5
+948700 6911200 265
+918800 6903300 264
+995900 6854100 279
+922800 6928400 370.5
+963300 6899500 323
+954500 6912500 246
+945400 6901600 257
+923500 6888400 265.5
+985400 6904200 302.5
+984000 6899100 300.5
+932100 6936200 238
+946600 6932400 323
+984500 6868300 247.5
+930200 6893500 177.5
+927700 6898100 273
+951400 6906200 262.5
+969200 6891800 316.5
+933500 6887000 203.5
+924900 6892600 260
+923700 6886000 264.5
+995600 6870100 254
+925900 6881100 291.5
+940700 6893900 251.5
+953200 6926400 280.5
+921500 6922000 313
+973500 6893300 295
+921200 6894300 273
+925500 6931100 299
+942700 6933200 230
+964900 6908800 264
+924700 6895900 265.5
+941400 6929000 213.5
+933700 6897400 218.5
+940300 6905500 268.5
+1027500 6896600 330.5
+964300 6876500 286.5
+953600 6908200 246.5
+969300 6906900 266
+983700 6892400 266
+967500 6886800 282
+1005900 6886500 320.5
+974300 6889800 286
+919800 6917200 285
+941900 6874500 251.5
+948700 6878100 259.5
+956400 6915100 239
+941000 6912900 247
+769100 6672000 437
+735500 6643300 242.5
+738900 6667300 324
+742700 6677900 280
+716600 6678400 270
+717000 6700900 271.5
+748600 6665600 263
+747000 6696100 219
+749500 6656500 259.5
+712200 6704600 266.5
+776300 6642400 531
+711400 6642700 229
+777600 6661000 629.5
+744300 6646900 239.5
+759600 6629600 236.5
+770700 6695400 444
+721100 6663800 291.5
+730900 6691200 296
+733600 6698900 249
+757100 6643000 234
+770900 6663100 496
+705000 6692900 197.5
+727300 6628100 224
+709000 6632300 226
+730200 6700300 235
+782700 6691400 533.5
+749400 6690900 195
+708700 6685200 209.5
+748500 6675200 270.5
+761800 6688100 414
+720200 6690400 304
+738500 6650900 256.5
+738800 6655400 257.5
+726400 6694200 289.5
+743900 6681100 260.5
+727600 6680100 294.5
+781500 6682700 582
+694700 6708000 182.5
+749300 6684700 217
+744400 6690700 245.5
+731000 6669200 346
+714500 6684700 269
+765500 6693000 457
+707100 6653400 201
+733200 6668700 338
+753900 6664200 256
+737500 6703500 184.5
+719000 6682000 277.5
+715500 6692900 282.5
+751600 6669600 280
+762900 6626300 270.5
+743100 6667500 268.5
+754700 6661900 262
+704000 6668100 192.5
+753200 6695600 270.5
+754900 6635500 232
+726900 6623900 234
+732500 6626600 224.5
+727300 6635600 216.5
+734600 6697000 255
+717200 6661600 223.5
+739500 6673500 322
+698800 6695800 181.5
+700200 6698200 206
+719900 6647600 219
+771700 6640500 379.5
+737000 6622700 222
+717500 6646800 206.5
+738000 6645700 239
+770700 6663100 482.5
+752700 6692500 250.5
+748700 6659500 254
+764700 6699600 277.5
+706700 6639600 184.5
+756100 6676900 283.5
+757900 6646200 234.5
+712100 6699800 222.5
+769800 6629900 353
+712500 6709500 286
+705200 6681800 217.5
+749200 6686900 210.5
+734600 6637900 225.5
+735900 6685000 264.5
+768800 6693600 417.5
+705400 6684800 178
+724100 6630100 236
+762200 6670500 380
+715300 6671200 264
+764000 6628100 323
+701700 6694100 179
+743400 6640900 228.5
+764800 6671900 393
+762100 6635800 278.5
+759400 6661200 273
+699500 6682600 168
+734200 6687800 252
+749100 6641100 222
+755900 6690500 277
+737100 6686800 266.5
+767400 6664500 406.5
+738000 6682300 273
+757200 6682500 300
+753000 6677200 251.5
+777600 6679900 584
+760000 6665300 304.5
+711200 6665700 263.5
+754100 6638800 226
+734500 6657300 331
+724400 6637400 211
+741400 6686700 274
+714300 6621900 207.5
+764800 6678900 402.5
+705600 6630600 222.5
+704700 6706000 261.5
+714100 6625900 222
+731400 6685800 272
+699300 6693600 181.5
+727800 6682800 305.5
+742700 6685100 268.5
+717100 6676600 267.5
+741800 6690000 308
+764100 6663400 358.5
+761100 6663500 331
+776800 6667800 603.5
+702900 6664500 198.5
+766300 6635800 290
+727900 6641000 232
+715500 6662400 228.5
+735200 6636600 213
+746800 6671500 273.5
+734300 6677000 310.5
+757700 6665700 294.5
+713800 6639400 213.5
+782500 6686200 575.5
+731100 6705200 225
+730000 6630700 215.5
+781800 6641300 409.5
+749800 6661500 253
+739100 6706800 211.5
+765800 6681400 424
+737300 6689700 250
+778400 6651200 632
+733600 6707700 221.5
+705600 6714300 225.5
+737000 6681400 297
+736300 6666300 333.5
+706300 6672800 212
+707200 6660800 216.5
+764100 6634800 295.5
+787300 6675200 550.5
+751700 6630200 225
+745400 6664800 261.5
+789100 6678400 556.5
+768200 6658300 487
+755700 6693500 291
+724900 6640300 214.5
+694500 6701200 195
+764000 6645400 388.5
+717200 6683200 303
+753600 6644800 235.5
+710100 6711000 266.5
+762000 6694800 349.5
+737000 6627700 218.5
+695000 6715100 190
+709400 6696700 216.5
+695000 6705200 176.5
+729300 6673500 310
+756800 6699500 267
+733400 6692000 237.5
+748200 6699200 235.5
+691100 6713600 159
+749900 6648200 239.5
+757000 6689100 232
+717100 6687000 292
+747900 6629900 221
+721000 6672900 277
+697000 6689800 217.5
+717600 6668900 266
+726500 6687300 310.5
+745700 6702200 230.5
+700200 6705000 235.5
+737300 6699800 196
+719300 6701700 289.5
+710700 6691300 269.5
+744100 6704100 210
+745000 6687000 233
+730100 6677700 305
+768200 6652100 399
+743700 6697500 248.5
+750700 6696000 245.5
+738800 6712200 175.5
+716700 6653400 207.5
+751600 6690900 217
+744700 6652300 260
+721200 6696600 307
+756100 6654700 250.5
+740500 6658500 282.5
+765500 6631700 288.5
+691500 6691200 182
+714100 6650200 223
+753000 6668600 314
+743900 6684900 267.5
+726000 6699400 252.5
+745100 6700000 228
+748800 6701700 258.5
+713700 6678200 259
+719300 6707100 271
+750500 6698200 270
+724500 6669000 323.5
+773000 6650300 566.5
+759700 6675200 327.5
+729800 6639600 239
+720700 6652100 234.5
+711300 6650000 223
+697000 6701300 196.5
+777000 6671200 537.5
+702600 6671200 186.5
+738600 6697600 253
+783300 6671300 639.5
+704200 6709000 248
+717500 6631700 224.5
+726400 6661700 337
+751300 6643600 229.5
+759400 6697700 305
+741100 6705600 188
+741900 6634100 212.5
+706300 6645300 215.5
+711100 6656900 220.5
+730900 6682800 291
+729200 6695500 282
+739900 6684100 257
+737100 6662100 302.5
+725400 6651800 253
+720100 6639000 212
+737300 6695500 242.5
+722000 6658600 243
+750000 6692300 205.5
+739800 6691300 292.5
+776200 6638500 360
+758800 6691700 326.5
+723800 6682600 289.5
+764100 6658500 342
+771900 6667200 526
+730700 6703700 231.5
+746900 6694500 187.5
+752800 6656500 238.5
+745300 6694300 242
+705500 6679400 182.5
+737800 6679000 305.5
+742300 6692700 308
+696800 6686900 193.5
+701400 6675200 184
+729700 6660400 294.5
+729800 6655500 300
+711900 6654700 202.5
+748900 6684200 226
+730100 6688300 303.5
+762300 6681700 338.5
+744700 6696500 263.5
+733700 6682400 263
+730400 6686300 304.5
+771600 6676600 496
+732400 6697500 272
+732100 6662400 349
+702200 6682600 171.5
+732300 6679600 329.5
+739400 6685500 257.5
+739000 6637900 234.5
+738000 6649400 244.5
+776800 6687800 508
+764800 6647200 427.5
+743400 6701300 215
+707700 6663800 231
+766300 6666600 431
+714800 6665300 241.5
+718900 6694100 280
+728800 6652100 277.5
+735000 6671100 322.5
+736800 6654400 257.5
+707800 6669900 260
+761600 6654400 325
+747400 6681200 245.5
+714200 6656100 208.5
+745600 6632200 216.5
+699100 6715700 207
+773500 6656600 626.5
+725400 6657300 257
+706500 6649300 219
+731100 6708900 232
+723100 6643500 232
+744300 6655400 265.5
+751700 6684300 228.5
+730400 6647400 266
+770700 6685000 519.5
+706400 6657600 171.5
+768900 6632600 330
+731900 6645900 259
+742900 6629200 208
+741300 6706600 199.5
+713900 6682800 269.5
+734100 6703200 201.5
+706000 6710000 254.5
+718400 6625400 236
+754700 6676100 307
+764900 6639400 378.5
+725100 6675000 302
+705800 6676200 252.5
+706400 6634500 208.5
+752200 6698400 282
+739700 6712700 189.5
+774000 6632600 382
+723200 6662100 302.5
+742000 7011800 111.5
+667600 7093800 15.5
+660200 7097100 11.5
+733500 6992900 154.5
+732100 7024800 43.5
+753900 7021200 133
+662700 7070200 49.5
+658400 7081900 32
+713900 7017500 54.5
+774400 7011300 178
+724400 6994900 138
+773300 7018600 159
+718600 7012000 60
+766600 7012100 170.5
+708000 7032200 22
+769300 7003500 175.5
+767000 7009100 181.5
+719200 7013500 54.5
+743300 6994800 152
+671500 7086800 12
+742000 7039200 31
+749400 7003300 154.5
+644400 7082100 37
+784400 7003000 214.5
+747100 7036000 24
+727200 7000200 116.5
+734300 7013400 79.5
+692900 7051700 29.5
+767300 7004400 178.5
+712800 7065800 34.5
+714500 7039800 32.5
+723000 7015000 58
+736500 7018400 73
+708900 6995300 116
+675000 7073000 57
+746600 7009500 147
+733200 7006200 107
+729800 7012300 77.5
+725200 7011500 65
+715100 7067200 29
+710200 7058400 32.5
+766300 6993200 199.5
+703400 7075100 35
+734600 7025400 51
+725500 7030300 55.5
+708500 7073000 35.5
+746100 7027400 68.5
+692800 7046300 25
+762000 7005500 161.5
+778900 6988400 235.5
+775600 6991500 210.5
+745300 7038400 16
+748800 6997600 162
+672000 7073600 43
+729300 6999300 130.5
+715400 7048200 44
+704100 7059400 31
+732300 7045300 39.5
+719100 7021100 51
+730300 7030200 34
+716300 7017800 46
+746000 7010600 140
+741800 7018000 97
+725300 7024200 35
+709500 7051100 40
+695300 7068300 17
+689600 7053500 32.5
+732800 7030400 36.5
+763000 7016100 143
+756900 7022500 132
+699100 7046100 31
+704700 7064300 19.5
+738600 7021900 67.5
+751100 7024400 120
+730000 6994300 144.5
+659800 7077600 40
+727200 7011100 74.5
+778100 7015900 195.5
+647500 7081900 43
+772400 7011900 176
+780600 7009300 209.5
+728700 7028300 45.5
+670500 7079300 37.5
+757900 7021300 144
+747100 7023600 86.5
+748500 7019300 107
+652100 7081700 26.5
+655500 7070600 45.5
+662200 7061800 26
+742700 7001800 122
+714900 7063300 30
+776700 7015900 186
+707600 7060600 34.5
+717200 7020900 53.5
+716600 7026100 42
+680300 7074100 89
+703100 7054200 37.5
+724100 6996800 118.5
+704200 7027500 30
+723900 7023600 42
+732200 7015000 66
+726700 6994100 141
+713800 7051300 29
+721700 7023200 50
+748300 7014700 138.5
+693300 7058600 26.5
+708000 7029500 30
+733100 7045600 29.5
+664200 7090800 14
+710300 7042700 44
+641100 7097300 3.5
+773300 7014000 172.5
+728600 7014300 74
+715000 7022900 57
+717900 7025800 48.5
+732500 7002800 116.5
+704300 7047300 48
+771800 7019800 144.5
+745900 7014200 127.5
+660500 7106600 11.5
+718800 7052400 47.5
+731100 7024500 49.5
+686300 7048500 26
+711400 7017600 56
+701000 7057200 33
+765400 7000700 174
+746000 6997400 150
+713900 7021200 60.5
+741600 7005600 139.5
+747600 7025500 83
+727500 7036000 17.5
+720600 7014300 56
+723200 7034800 17.5
+659500 7093400 15.5
+727800 7037600 17
+724800 7007800 81
+701000 7030900 37.5
+741100 7037500 21
+656900 7093400 18
+736500 7005000 107.5
+741100 7021800 77.5
+697000 7047000 27.5
+745000 7019700 98.5
+717100 6999600 104
+714700 7007000 64.5
+711100 7021500 60
+661600 7093400 15.5
+738700 7000900 120.5
+654500 7098200 3
+777500 7002700 195.5
+661000 7097400 7.5
+724500 7000700 106.5
+708800 7076300 35.5
+707300 7042500 69.5
+706700 7024400 44
+776800 7012500 185
+689700 7056600 25
+778400 7013600 198.5
+735600 7009800 100.5
+705200 7025600 36
+723800 7042200 27
+713000 7004500 69.5
+707500 7035900 22.5
+643500 7094800 5
+661600 7077000 54
+744100 7006000 143.5
+738200 7039900 27.5
+745300 6994000 146
+665800 7066400 42
+728700 6997700 133.5
+718300 7031400 21.5
+729700 7017900 58
+727600 7020900 53
+743100 7034700 19
+737400 7029200 36.5
+725200 7022500 49
+717900 7056800 36.5
+768900 7013400 180.5
+705000 7062000 27
+671500 7075800 45
+720700 7046800 38.5
+724900 7043600 26
+707600 7020300 51.5
+658400 7090800 22.5
+712000 7052300 30.5
+651000 7082700 38
+773000 7016200 159.5
+664300 7097900 13
+757600 7009300 145.5
+705300 7020200 51.5
+759600 7024900 137.5
+645100 7100100 12.5
+654500 7082700 42.5
+662500 7087500 19
+768500 7019000 148.5
+715200 7063900 29.5
+709200 7049400 34
+700000 7068400 16.5
+652400 7097300 2.5
+698100 7063500 28.5
+746500 7039200 17.5
+676700 7062700 16.5
+733800 7030500 40.5
+776800 7018200 176
+768700 7007700 192.5
+774400 7002600 186.5
+705600 7074900 29.5
+739500 7030400 55
+748100 7022200 101.5
+777000 7022000 158.5
+643800 7084500 3
+712100 7028800 29.5
+778100 7009000 202
+708000 7057500 38
+751700 7000800 164.5
+721400 7041800 33
+767500 7002500 176.5
+765900 7012600 160.5
+718500 7019200 47.5
+708200 7047200 35.5
+721000 7016700 53
+678200 7071600 85
+752600 7020500 135.5
+727900 7006700 102
+715800 7010800 65
+759300 7009400 145.5
+720700 7043700 34.5
+706000 7045500 43
+772000 7023600 137.5
+772300 6991400 202
+697300 7055100 23
+697500 7049900 22.5
+780200 6994100 229.5
+696400 7070800 15.5
+730300 7010600 83.5
+666100 7073500 40.5
+693800 7046400 26.5
+647100 7077700 35.5
+672000 7070700 39.5
+670600 7070600 26.5
+667300 7069800 41.5
+742600 7032400 42
+690800 7051000 25
+747400 7015300 125.5
+709000 7023500 56.5
+746000 7030000 57.5
+720100 7002900 96
+714500 7057100 35
+722300 7000400 105
+718100 7023900 61
+721800 7003400 99
+700100 7055100 29
+688800 7048300 25.5
+782100 7017000 186
+712400 7047700 40
+703100 7032500 31
+732200 7028600 75.5
+738400 7033500 25.5
+764700 7015300 148
+649300 7077200 14
+761100 7008400 151.5
+666800 7106300 12.5
+711200 6993500 113.5
+739800 7036500 29
+693600 7066000 16
+740400 7040400 32
+713400 7059700 23
+707900 7054800 46.5
+668100 7089600 13
+741100 7026800 72.5
+773000 7009900 180
+696500 7048800 23.5
+739100 7014700 89.5
+697300 7060800 41.5
+731700 7015900 65.5
+734600 7023600 57
+638600 7099300 12.5
+766000 7017000 153.5
+732600 7042600 26
+715000 7001900 86.5
+712000 7010400 65.5
+715200 7015100 53
+738000 7011700 108.5
+661400 7072600 45.5
+759700 7012200 138
+701200 7053300 27.5
+696600 7072300 15.5
+746300 7005100 153
+746000 7006700 152.5
+762300 7008300 159
+786200 6996700 211.5
+703100 7062600 19
+742300 6999400 135
+707300 7038000 38
+702600 7043100 46.5
+709300 7001400 90
+702900 7019900 55
+761100 7021600 147.5
+694100 7056400 32.5
+769300 7009700 192.5
+671600 7092100 12.5
+660200 7062900 42.5
+694300 7050100 21
+756000 7024300 120.5
+696900 7058700 36.5
+749800 7016700 121
+697100 7057400 31
+717400 7029000 27
+747500 7033300 71
+770800 7024400 149
+722400 7033600 18
+699200 7048100 26.5
+747000 7007400 149.5
+713800 7058100 28.5
+674800 7077600 95
+769400 7020300 144.5
+709800 7040400 36.5
+743000 7025900 93.5
+713800 7013000 64.5
+724700 7019500 51.5
+692100 7054200 34.5
+720500 7019500 45
+722200 7010400 66.5
+674500 7060800 15.5
+656700 7088100 23.5
+709900 7019500 43.5
+711300 7069500 36.5
+690600 7052700 32.5
+738700 7002400 111.5
+717800 7044600 43
+748500 7024700 98
+729500 7003100 120.5
+760500 7014300 144
+712700 7010400 68.5
+666800 7108500 14.5
+711200 7072200 36
+771700 7025300 137
+778600 7022400 161.5
+717400 7037600 23
+714600 7055300 38.5
+785500 7000200 199.5
+724800 7037500 17
+657500 7079000 34
+652500 7085700 27
+667500 7078100 49.5
+712000 7032500 23
+663800 7078300 104
+657200 7103400 3
+751200 7011400 149.5
+726700 6998600 124.5
+696600 7062000 29.5
+730600 7007600 96
+695200 7048000 25
+727400 7004500 103.5
+670800 7098300 9.5
+657800 7066300 46.5
+726200 7007500 89.5
+764900 7011000 167.5
+663700 7103000 4
+778600 7003100 196
+642600 7089200 3
+705000 7022500 48
+663700 7080500 77
+718000 7000900 103.5
+661200 7081000 34
+709000 7006200 77.5
+658200 7070800 49.5
+733200 7041800 20.5
+721400 7029800 31.5
+708400 7002900 87.5
+753400 7023200 113.5
+749000 7020900 109.5
+772600 7007600 199
+723000 7005700 77.5
+779000 6996100 210.5
+745400 7000300 150
+782300 7011900 198.5
+722400 7029500 32.5
+652900 7078800 26
+715300 7018600 51
+715800 7061100 35
+710900 7064200 34
+742300 7028300 68.5
+668500 7075700 43
+735900 7030500 56.5
+647000 7084600 27
+695100 7058300 32.5
+651300 7090200 8
+690900 7048700 22.5
+699300 7063600 28
+700500 7073800 17.5
+738800 7028000 49.5
+715400 7031100 21.5
+645200 7089800 2
+678200 7078200 90.5
+706200 7056400 42.5
+703900 7042400 56
+663000 7077000 66
+747200 7012600 139.5
+658500 7096500 5.5
+706600 7067200 35.5
+705800 7049200 43.5
+713500 7056500 31.5
+668300 7082800 23
+731300 7029100 34.5
+661500 7068000 55.5
+772400 7021600 136.5
+650100 7095500 4
+744000 7021000 93
+657800 7080200 40.5
+734800 7028100 43.5
+656200 7104800 8.5
+737700 7016800 75.5
+780300 7007100 210.5
+728000 7022700 53.5
+721600 7008500 66.5
+716400 7014600 52
+741400 7009200 127
+722500 7018300 49.5
+710600 7025600 49.5
+733100 7002800 121.5
+713200 7053500 37
+770900 7017900 155.5
+752800 7026900 97
+784300 6996800 211
+724400 7026400 41
+771000 6997500 191.5
+744400 7032500 33.5
+734000 7019000 60
+719000 7010500 57.5
+726800 7003600 108
+655400 7095400 14
+733800 6996800 132
+713000 7036600 27.5
+719600 7016700 52.5
+716300 7062700 33
+716300 7049600 48
+734800 7007000 96.5
+704600 7007300 74.5
+721600 7026300 51
+766500 6995800 182.5
+730400 7039000 26.5
+705600 7030300 27
+736900 7039800 27
+701000 7003400 99.5
+689200 7064300 16
+717400 7042000 35.5
+709600 6997800 104.5
+720400 7040300 24.5
+691900 7057600 26
+711700 7005600 72
+760600 6999700 176.5
+658900 7068600 53
+660500 7084400 18.5
+715900 7010000 54.5
+727900 7030900 75
+637300 7100600 6.5
+732500 7021100 57.5
+731700 6998900 135.5
+688600 7067400 16.5
+679700 7060200 15.5
+678400 7076300 97
+718500 7050400 52.5
+722700 7036800 17.5
+734100 7043100 20.5
+758400 7025700 120
+784400 7019000 177
+701200 7046600 44.5
+744100 7014400 108
+773400 7005500 198
+715300 7013600 60
+730700 7045100 27.5
+765700 7008600 168.5
+740900 7023800 74
+758000 7011900 148.5
+758200 7005600 161
+711000 6995500 113
+709700 7035500 30.5
+665200 7076600 62
+732000 7023200 49
+702400 7004700 83.5
+673900 7070100 39
+691500 7065600 15.5
+737600 7012800 96
+709200 7063500 32.5
+695100 7057300 32.5
+688000 7051600 30.5
+709900 7067400 42.5
+774600 7026200 130.5
+702100 7050100 33
+761700 7017700 146.5
+741500 7011100 110.5
+650300 7085200 31.5
+740200 7020700 79.5
+734400 7010300 87.5
+720100 7006300 81
+676000 7068800 39.5
+723900 7030100 30.5
+711100 7034400 19.5
+723600 7038700 18.5
+664100 7107700 13.5
+712400 7002600 89
+701700 7061400 25.5
+736700 7021100 86.5
+681200 7071300 50
+711700 7018300 46.5
+716900 7059500 35
+713000 7022700 67
+698900 7049700 25
+774300 7021900 144
+754400 7004400 158
+738100 6995400 131
+716800 7008700 71
+698900 7058800 30.5
+763600 6993900 194.5
+706800 7063700 33.5
+715400 7028100 27
+667500 7060600 16.5
+713300 7029900 29
+680400 7060800 15.5
+764800 7019100 151.5
+715300 7052400 41
+744900 7024000 85
+772400 7000000 198.5
+737000 7024300 61.5
+733700 7001000 128
+721200 7014100 54
+674800 7066500 17.5
+722600 7011600 60.5
+704800 7028400 32.5
+767300 7027300 140
+728200 7025700 70.5
+721500 6992800 130
+658900 7100000 6.5
+710300 7028300 31
+753000 7025400 98
+733500 6997500 138.5
+705600 7039500 56.5
+712300 7045900 45
+711900 7054500 38.5
+723500 7037600 18.5
+650700 7080800 22.5
+691100 7061300 17.5
+739100 7015700 86.5
+713300 7062100 36
+717300 7052000 51.5
+667100 7087900 15
+771600 7002900 185
+692600 7064000 17.5
+723800 7004400 103
+663500 7064300 41
+737800 7026100 62
+707800 7045400 44
+705500 7053100 43.5
+734600 7032500 70.5
+717300 7065000 26.5
+703300 7031600 33.5
+699100 7056900 26
+757000 7006900 149
+704400 7033400 30.5
+740900 7004900 121.5
+758700 7000900 168
+723300 6994400 131
+720100 7034500 18
+650900 7102100 8.5
+660900 7102700 5
+669200 7095900 10
+738100 7017300 77
+756900 7020100 139
+711500 7012600 69.5
+731400 7025600 39
+714400 7027900 38
+722600 7020700 65.5
+756200 7019000 138
+680100 7065100 17
+728000 7041600 20.5
+757400 7002000 163
+777000 6995800 206
+754900 6998200 177.5
+660500 7079100 52.5
+705200 7055700 44
+729500 7009500 89
+703400 7065400 19.5
+739400 7009200 123
+646200 7097400 4
+695900 7059700 33.5
+665300 7092600 16.5
+665500 7082600 31.5
+720000 7028900 32
+775900 7009300 196
+655300 7100500 3
+725900 7039000 18
+765500 7023100 145.5
+727000 7016900 62.5
+745500 7017000 110
+714000 6993200 111.5
+699700 7065000 23
+712000 7027000 42
+737100 7042000 26.5
+702200 7039700 62.5
+742300 7015600 98
+764700 7004100 173
+735600 7018700 66
+684300 7067100 16
+750500 7019400 126
+715800 7003200 85
+778800 7012500 196.5
+668400 7102200 1
+737800 6997700 125
+714200 6995900 102
+714600 7042500 42
+703900 7053000 37.5
+705600 7071200 34.5
+700100 7051800 25
+703900 7035300 25
+729600 7026000 37
+773400 7008400 196
+711400 7007700 80.5
+652800 7092600 22
+709100 7028300 32
+659900 7088000 20
+716500 7032900 18
+648900 7091400 5.5
+734600 6998300 135
+718400 7055400 46.5
+764200 6998200 175.5
+769200 7026700 140
+772400 7027400 112.5
+754800 7025900 104
+703300 7044100 53
+774300 7020800 155.5
+760500 7018000 149.5
+772400 7013900 163.5
+687600 7055400 29.5
+717000 7013900 61.5
+714800 6995800 106
+743500 7010300 127.5
+766300 7003200 165.5
+731000 7004300 104
+761800 7013300 148
+719200 7000200 100.5
+695700 7053000 29
+718300 7005600 90
+711900 7024500 53.5
+773500 6994600 190.5
+757000 6996200 188.5
+736000 7032100 26
+760200 7003600 164.5
+774500 7013400 173
+653700 7089100 20
+632100 6917000 156
+680700 6942500 77.5
+639900 6935600 143
+645400 6942200 136.5
+694200 6910900 111.5
+627900 6914700 188
+703000 6920800 100
+646800 6900400 86.5
+614400 6912600 100.5
+691600 6931000 51.5
+691100 6909500 88.5
+673100 6899500 81
+693900 6909400 95
+631000 6901200 115.5
+630200 6915200 188.5
+701400 6918700 94.5
+622800 6912100 141.5
+661200 6925800 113.5
+640800 6930700 114
+699200 6897100 119
+627000 6956300 154.5
+640100 6955500 121
+635500 6947900 145.5
+678700 6945800 115
+658500 6939300 119
+630900 6945500 164.5
+625400 6921600 164
+664300 6917000 96
+693700 6951200 86.5
+674700 6924000 93.5
+688400 6899600 107.5
+638700 6924700 83.5
+639200 6902400 99.5
+634800 6909300 164
+661700 6941700 122.5
+666100 6900000 63
+657700 6943700 123
+694000 6890300 113.5
+620500 6904500 100
+660400 6934800 126
+613700 6960900 193
+638900 6917700 113.5
+643600 6943600 149
+688900 6927000 86
+614000 6952600 207
+704300 6940500 46.5
+664100 6942100 110
+659900 6913200 75
+682800 6942200 95
+695600 6939400 102.5
+621800 6920500 192.5
+666400 6944000 98
+610800 6953300 206
+630100 6947900 164.5
+616800 6937000 163.5
+645600 6923700 77
+641500 6916700 104
+618400 6922600 188.5
+607900 6905300 89
+667600 6922100 111.5
+657200 6916300 104.5
+649100 6915800 84.5
+653100 6902800 98
+672300 6920500 83.5
+692100 6929500 46
+610900 6956000 196
+696800 6895200 113.5
+665200 6908600 66.5
+669900 6919900 73.5
+662600 6945600 110
+689900 6928400 85
+614800 6925800 161
+613700 6957600 195.5
+694400 6934500 110
+630800 6909100 154.5
+640200 6940300 157
+645700 6928200 104.5
+611600 6948500 193
+619900 6933700 176
+697600 6922100 79
+660600 6916600 101.5
+617200 6929800 129.5
+616700 6937800 156
+678400 6887800 103
+619900 6916800 162.5
+690700 6900900 120
+643500 6920900 92
+677400 6910200 92
+616100 6912200 104.5
+686800 6936300 109.5
+702000 6909400 139.5
+632700 6904600 112
+687100 6923900 82.5
+682000 6930100 76
+696100 6938400 91.5
+682000 6888600 108
+641400 6920400 98.5
+616700 6950300 189.5
+645000 6949600 144
+653300 6943600 136
+635500 6923100 107
+693000 6916500 88
+693200 6941000 104
+626100 6940200 139
+691200 6910300 95.5
+611500 6961500 167.5
+616600 6898900 158
+690100 6950700 84
+678800 6920800 88.5
+697800 6932900 41.5
+698800 6894700 109.5
+647500 6934500 127
+617000 6914000 120.5
+663700 6915800 85.5
+703500 6939300 48
+671600 6902300 87
+617700 6915800 136
+689500 6906500 89
+667700 6943400 96
+643500 6955200 136.5
+689000 6890000 124.5
+643800 6946600 149.5
+623100 6917700 195
+612000 6959600 186.5
+673000 6941000 96.5
+706400 6920900 91
+704700 6944100 107.5
+608200 6950900 217.5
+610800 6913600 87.5
+700600 6949400 77
+687400 6888900 114
+683700 6930900 67
+682200 6932900 89
+623800 6948800 180.5
+693300 6942900 105
+644800 6953500 122
+644400 6908000 160
+693100 6893600 127.5
+689800 6910400 94
+645200 6896600 86
+682100 6939200 93
+700700 6932200 96
+662400 6919600 105.5
+685100 6934800 75.5
+633500 6920800 114.5
+637000 6946400 165.5
+626600 6907600 117
+607600 6926500 149.5
+615000 6945000 169
+665000 6911200 68
+629400 6908500 130.5
+666700 6926900 127.5
+650200 6941500 146.5
+638800 6910300 174
+638500 6943600 173
+661200 6908500 63.5
+634500 6954000 152.5
+698500 6891200 111.5
+642400 6900100 102.5
+626100 6949400 178.5
+610600 6917800 128
+619600 6950300 191
+633600 6916100 159
+683800 6933700 93
+680300 6945100 95.5
+676400 6932600 87
+698000 6945700 58
+631800 6922200 128
+627700 6937400 131
+705600 6893000 97
+631300 6950600 149
+650500 6913100 80
+673800 6911400 126
+682700 6895700 103
+619100 6908100 100.5
+676800 6937900 96
+701200 6900200 116.5
+614500 6938500 169.5
+642900 6939300 141.5
+619400 6937200 140
+707200 6936900 101
+623500 6952400 190.5
+645500 6914300 90.5
+631100 6911900 176
+622600 6957100 162.5
+684200 6913200 83
+628000 6900400 149
+645200 6932200 131
+614900 6905500 104.5
+685700 6911300 83.5
+615000 6910700 85
+637000 6904400 128
+664200 6902700 93.5
+611300 6902300 139
+655800 6911200 78.5
+655300 6945300 121.5
+668800 6894800 78
+662100 6928900 119.5
+684800 6889700 112.5
+663400 6930200 125.5
+694000 6890200 112
+680200 6904000 109.5
+654400 6906900 87
+634900 6906700 127.5
+610100 6947400 198
+633600 6943000 156.5
+636000 6900700 105
+653200 6908400 90.5
+608700 6959300 177
+706300 6945300 122.5
+640700 6901800 89.5
+705000 6952500 82
+611700 6924700 156
+617000 6939500 150
+622500 6932500 168
+636200 6939900 154
+621800 6915300 163.5
+688800 6895900 116
+613800 6944000 176.5
+676900 6916200 55.5
+626000 6906500 103
+684800 6938500 125.5
+638100 6915600 154.5
+633800 6935900 142
+703200 6954000 80
+676600 6941300 93
+648100 6916700 91
+629600 6939200 138.5
+658700 6930400 123
+645200 6917800 91
+628700 6954700 156
+650000 6934600 126.5
+687600 6927700 88
+627500 6909500 144
+701800 6895300 103
+680800 6911500 80
+669400 6924200 114.5
+700500 6920800 90
+689700 6932700 86.5
+677400 6908500 136.5
+610200 6936400 168.5
+651700 6910800 74.5
+620000 6897900 91.5
+625000 6905500 94
+643000 6899500 102
+663000 6900100 50.5
+668900 6935800 101.5
+701700 6890100 107
+648900 6923600 72.5
+655800 6907700 71
+630000 6925600 120
+618000 6931400 160
+692600 6934100 97
+642800 6933100 137
+696500 6931100 42.5
+679500 6917500 78.5
+683700 6921100 78
+663900 6912600 79
+609700 6936400 149
+643100 6928800 108
+697100 6943800 100
+658600 6905500 56.5
+658800 6934200 129
+627100 6919400 161.5
+704500 6895100 99
+652500 6932100 130
+666400 6925600 130.5
+669900 6900900 93.5
+648800 6943300 129
+624000 6932400 131.5
+658400 6927700 110
+670200 6940300 110.5
+624400 6944800 150.5
+641600 6949200 149
+650100 6908600 80.5
+612600 6932600 143
+626200 6927800 128
+634600 6934100 129
+637600 6921300 100
+667800 6945000 81
+687300 6934400 83.5
+608400 6921500 134.5
+664400 6892600 85.5
+638600 6951700 123.5
+613600 6933800 170.5
+607100 6945500 189.5
+653400 6916300 105.5
+695500 6948800 66
+673700 6906200 148
+673900 6916000 44.5
+622200 6950600 181
+638800 6914200 152.5
+698500 6926100 93.5
+655300 6920500 107.5
+700600 6930100 94
+666900 6917300 95
+670700 6890400 131.5
+650900 6922900 105
+641700 6925400 82.5
+642400 6903300 114
+688700 6934000 109
+708100 6940900 51.5
+691900 6943100 102.5
+673000 6918000 83
+678100 6919200 64
+658100 6941200 124
+640800 6944400 168
+627400 6946200 174.5
+640800 6907300 142
+693000 6939600 114
+680800 6927200 70
+622500 6936200 130
+697000 6899500 134.5
+608500 6940200 165
+693800 6946000 111
+618300 6948200 179.5
+665200 6943500 108.5
+623600 6922600 132
+699600 6888500 110
+705000 6952800 79.5
+643600 6936000 130.5
+625100 6913600 173.5
+668500 6928700 105.5
+686800 6906600 86.5
+676300 6929400 74
+653800 6908200 67.5
+690900 6933100 104.5
+629300 6903600 99
+641800 6914500 142.5
+661600 6893700 78.5
+629300 6921700 95
+661800 6928100 129
+669300 6931500 93.5
+690100 6929800 89
+642400 6936800 135
+680900 6892300 112
+678800 6926500 73.5
+699900 6942400 94.5
+704500 6921700 94
+703600 6943200 107
+630400 6930000 104.5
+632500 6907500 132.5
+671200 6915900 42
+704600 6956300 76.5
+663900 6927800 131
+611000 6941700 171.5
+627800 6927900 131
+707200 6931800 119.5
+662500 6923200 107
+640800 6922600 79
+635300 6911200 187
+680300 6897100 107
+652200 6912900 78.5
+627900 6926000 109.5
+677900 6939400 97
+667300 6913400 47
+643000 6918700 97
+630500 6924300 119.5
+673200 6938600 100.5
+613800 6907400 100.5
+630500 6955700 147.5
+634500 6912600 191
+621600 6924400 155
+671700 6928200 77.5
+621800 6953800 191.5
+697500 6904800 105.5
+665600 6913300 74.5
+700300 6952500 89.5
+683900 6909100 95.5
+669400 6933600 96.5
+693800 6954800 88.5
+657400 6947800 140
+613700 6905300 104
+609600 6957300 185.5
+681400 6918700 76
+657900 6950200 116
+662300 6906600 77.5
+641700 6910200 176.5
+624900 6930000 170.5
+637800 6948600 148
+673600 6932400 77.5
+666200 6899500 51.5
+617700 6925300 160.5
+620000 6911900 121
+692400 6947600 92
+691800 6903900 106
+610100 6950100 214.5
+632500 6953700 148.5
+698600 6916800 99.5
+705600 6923800 90.5
+621300 6906800 84.5
+696700 6889500 108.5
+696700 6901800 131
+667400 6903400 104
+657400 6898800 62.5
+682900 6919300 71
+620400 6928300 126.5
+703700 6950700 76.5
+707700 6896700 106.5
+677800 6891800 96.5
+626300 6911700 158.5
+656100 6901600 74.5
+671200 6911400 76.5
+611500 6922000 146.5
+686000 6902100 104
+708000 6954600 108
+685600 6904800 121.5
+609400 6904500 105.5
+612700 6950900 204.5
+651100 6929100 106
+679200 6906700 100
+621600 6911400 112.5
+615600 6924200 184
+685500 6924000 58.5
+696500 6935000 44
+656300 6914600 89
+707400 6948700 124
+708400 6942700 47.5
+656400 6906300 78.5
+700200 6923900 88
+625200 6901400 111.5
+643600 6941100 151.5
+626100 6931100 151.5
+615400 6960000 189.5
+653200 6896400 63.5
+647600 6908900 122.5
+690200 6887000 110
+686200 6893600 103
+697200 6949700 73
+613200 6940000 166
+667300 6930200 103
+701800 6935000 94.5
+618500 6899500 104
+623100 6909200 112.5
+661200 6910200 72.5
+702000 6922200 82
+639200 6907000 138
+653600 6950100 90
+705100 6935700 100
+692900 6931300 37
+642800 6908300 159.5
+677600 6896100 92
+669600 6889400 117.5
+686600 6947000 87
+671300 6928700 81
+663900 6932000 125
+647900 6902900 129.5
+695000 6906600 94
+701200 6946900 114.5
+694200 6950100 75
+638200 6933600 124
+704300 6948300 116
+657900 6902100 81
+618300 6945700 164
+659100 6931700 126.5
+708100 6944400 97
+676900 6922400 84
+678000 6901100 115.5
+615600 6932500 155.5
+641600 6942900 155.5
+676900 6896900 92.5
+620100 6930300 152
+636300 6917100 127
+675900 6902600 85
+710100 6926800 99
+648200 6927700 99
+684500 6917400 42
+674000 6904100 84.5
+614800 6948800 188
+663500 6914500 93
+618500 6912200 104.5
+697900 6955000 81.5
+697000 6946300 69
+654100 6900900 73
+653800 6924600 95
+704500 6918500 105
+645200 6903700 120.5
+640700 6947800 166
+622800 6905700 90
+667900 6939400 122.5
+626700 6899100 151.5
+635600 6929700 108.5
+680500 6912300 77.5
+669200 6937600 117
+678000 6912000 75
+664500 6918900 108
+643700 6917000 86.5
+625100 6934800 124.5
+702600 6941200 46.5
+665200 6924100 114.5
+659100 6918100 97.5
+660200 6939000 122.5
+646300 6915200 82
+683100 6901300 117
+651300 6945100 131
+636900 6931800 116
+700200 6907100 106
+672500 6916000 38.5
+689200 6908100 81
+686900 6930200 73.5
+649600 6904200 120.5
+680400 6921200 104
+666000 6892100 96.5
+672200 6933800 79.5
+616000 6905500 106.5
+695600 6924100 71.5
+624900 6946700 166.5
+637700 6937200 143
+691200 6955600 91
+685600 6941200 133
+684000 6935900 114
+627300 6944800 173.5
+608000 6901100 106
+614300 6915700 134.5
+676000 6897900 91
+697400 6943100 97
+691100 6926600 71.5
+687800 6942100 126
+682100 6929300 73
+620200 6955800 175.5
+609100 6942700 184
+632100 6952600 147
+683800 6898800 122.5
+683700 6943600 103.5
+610000 6951100 218.5
+646600 6939500 148.5
+699300 6945700 69.5
+688700 6943300 91.5
+626800 6951500 167.5
+628400 6943200 163
+670600 6912900 35.5
+661600 6912900 74.5
+636300 6912200 197
+615500 6951800 202
+704400 6896900 107
+636500 6950800 132
+697300 6939700 65.5
+653600 6938800 134
+660400 6946200 121
+651100 6914600 83.5
+698600 6951300 83.5
+621800 6946800 166
+616700 6946300 172.5
+681600 6937900 84
+660700 6947800 122
+650300 6938300 151
+625100 6938200 139
+666300 6933100 99.5
+628300 6902300 108
+650600 6901900 100.5
+678800 6942100 90.5
+687000 6925200 66.5
+691600 6940700 115
+623300 6903200 100
+697400 6941500 99
+696800 6897600 122
+660200 6919100 99
+624500 6910600 134.5
+663900 6935300 111.5
+693800 6899700 127
+618600 6925000 157
+699500 6909500 111.5
+633800 6926500 113.5
+659200 6895200 66.5
+628400 6932500 107.5
+655700 6940800 136
+650400 6933100 126.5
+661100 6914700 88.5
+641900 6951300 137.5
+659400 6914600 79.5
+633700 6911800 188
+662700 6910000 71.5
+698700 6947300 65.5
+636800 6935000 139
+627200 6950300 159
+618100 6937900 142.5
+677100 6943800 105.5
+608500 6907500 91
+696300 6942300 110
+695000 6921400 82.5
+699600 6939800 45.5
+699100 6940600 40
+639500 6928900 94.5
+702500 6917000 103.5
+659500 6936800 111.5
+669800 6907000 137
+682400 6939800 112.5
+681300 6887500 105
+675000 6937400 104
+622100 6943200 146.5
+685800 6931500 101
+677800 6929400 72
+705500 6925000 103
+618500 6954700 188.5
+706100 6943300 94
+655600 6946800 115
+654600 6933400 142.5
+648900 6948400 118
+651500 6924300 87.5
+674100 6925200 93.5
+651000 6917700 102
+653800 6948500 112.5
+669500 6920300 93
+614800 6899200 153.5
+671400 6936000 93.5
+646100 6945600 133.5
+674700 6919300 88
+704500 6890700 104
+702200 6904100 119
+647900 6897800 65
+676800 6927700 78
+644500 6951400 134
+660600 6923400 96
+654400 6935500 142.5
+639600 6948600 150.5
+676800 6906400 113.5
+685500 6944700 81
+628500 6916700 191
+705400 6948600 124.5
+630600 6931600 106.5
+687400 6950700 86.5
+686500 6929100 93
+666100 6911600 67.5
+648800 6931300 113
+665900 6945700 94.5
+628000 6923400 97.5
+686600 6910600 81.5
+685400 6949100 90
+614200 6910100 99
+680700 6916500 75
+668800 6910500 68
+618300 6943000 176
+620100 6941100 163.5
+659700 6910900 72
+700300 6892300 107
+683200 6911900 78.5
+620000 6945400 158
+645300 6911500 137.5
+689400 6904100 90
+628100 6942000 167.5
+690400 6952800 86
+703300 6900300 124.5
+640500 6932700 136
+638300 6930400 116
+651100 6952200 98.5
+617700 6902900 109
+611800 6940700 170
+675500 6933000 91.5
+648600 6899800 87
+623400 6951000 195.5
+644400 6902000 95
+627200 6953700 153
+659100 6906400 68
+618800 6935300 161.5
+636100 6942000 162
+612500 6900200 145
+616700 6956300 205
+698500 6904100 94.5
+655300 6929800 121.5
+650900 6936100 136
+671400 6944400 84.5
+665300 6939300 107
+690600 6896000 120
+658800 6949000 126.5
+647100 6951000 122
+633700 6950700 139
+610300 6943300 173
+624400 6942300 146
+667100 6894900 68.5
+658600 6921400 80
+633300 6945800 146.5
+656200 6943800 120
+659700 6902500 75
+648600 6945600 117
+669900 6943000 92
+631700 6940100 143.5
+622000 6900100 97.5
+639700 6939000 143.5
+660700 6898700 73.5
+611600 6927800 152
+682800 6935300 80.5
+657400 6925200 92.5
+663300 6925600 116
+703200 6888800 93.5
+623100 6935400 133
+632000 6938100 157.5
+703400 6923700 88
+620100 6936500 135.5
+657300 6920100 105
+627200 6934100 118
+609000 6944600 179.5
+677000 6889500 97.5
+705200 6928600 113
+419200 6856300 295.5
+517300 6852800 257.5
+429500 6860100 217.5
+491500 6837600 245.5
+475000 6847800 210.5
+485800 6845900 175
+498900 6826800 165.5
+466000 6839800 257
+507000 6836600 203
+500400 6839200 211
+438300 6842800 214.5
+509100 6864900 240
+531500 6834600 236.5
+528500 6798500 140
+487300 6848000 202.5
+497000 6864700 194.5
+522400 6857000 262
+515100 6839900 218.5
+511300 6837500 210
+494500 6864000 197.5
+513400 6830900 216.5
+428900 6850100 256
+490400 6850800 212.5
+518500 6841700 257
+446600 6848900 267
+468200 6826100 312.5
+443000 6862400 185
+537800 6825500 202
+459200 6850000 225.5
+477900 6820400 171
+511000 6849100 268.5
+539600 6811600 159.5
+463800 6839100 276.5
+463200 6860300 195
+476400 6840500 277.5
+533800 6824100 198
+453600 6849600 221
+447800 6829000 168
+479700 6844800 215.5
+426700 6827100 151.5
+532300 6803800 142
+443300 6831500 188
+455500 6850200 235.5
+495300 6871000 166.5
+450000 6827700 153
+483100 6860900 137.5
+434700 6833800 150
+503600 6823600 154
+504800 6824500 169
+510900 6842800 243
+499700 6873400 171.5
+478400 6857600 198
+460800 6848500 215.5
+461700 6836200 278.5
+456200 6839200 252.5
+439100 6859700 220
+527800 6855900 222.5
+450300 6839900 247.5
+534900 6841200 222.5
+437700 6863200 159.5
+446700 6830700 158
+519600 6851700 238.5
+485900 6826500 246.5
+482100 6841200 254
+509100 6822000 184
+475700 6816900 171.5
+525000 6811300 203
+538900 6833800 239.5
+515900 6800300 143
+543700 6816700 193
+445900 6829600 143.5
+515800 6850900 243.5
+478400 6829400 335
+506500 6847800 273.5
+419400 6831300 185.5
+473800 6847400 193.5
+518400 6837800 245.5
+472400 6842900 220
+521100 6844100 253.5
+490400 6873100 174.5
+476700 6865500 116.5
+421100 6853700 255
+474500 6821700 270
+438500 6827200 144.5
+530800 6818100 185.5
+487600 6838400 207.5
+526600 6822900 188
+495400 6823900 145.5
+483600 6820400 159.5
+512800 6822500 189
+523100 6835600 261
+509200 6843000 247
+518600 6818600 166
+531600 6840900 223.5
+469100 6849500 176
+532100 6838800 257.5
+485300 6861700 116.5
+436000 6862500 149.5
+521500 6815300 213
+519700 6834300 232.5
+490500 6859900 185
+455300 6852900 230
+524400 6859600 256.5
+506700 6842400 241.5
+433700 6861400 179
+484100 6835000 294.5
+534700 6831500 208
+451100 6862300 157
+520400 6810700 199.5
+533000 6807400 149.5
+424900 6835400 157
+433300 6832700 192
+534000 6809300 151.5
+435500 6826700 142
+498100 6832400 188
+522000 6825000 184.5
+423900 6860400 219
+438600 6833100 146
+500300 6847900 252.5
+514000 6862300 242.5
+518000 6832600 232.5
+524100 6819200 197
+484800 6841700 214
+448800 6854500 225
+498800 6855500 244.5
+520500 6861500 273
+435800 6860000 168
+493600 6842700 195
+467200 6858800 211
+523500 6822400 168.5
+479600 6825700 293
+516900 6840200 236
+449600 6866800 141
+519600 6822700 167
+525100 6806000 162
+431600 6838400 186.5
+421500 6858300 283.5
+449900 6863800 135
+522300 6800500 147
+528200 6832700 214
+530300 6832000 209.5
+482900 6850900 177
+437600 6855700 229
+502500 6859800 245
+432000 6856900 248.5
+514900 6836300 215
+504600 6854800 262
+465100 6856400 188
+453700 6846400 228
+520000 6847400 263
+482300 6844400 196
+510700 6862600 258
+537400 6839700 222
+489900 6853200 194
+489400 6841100 190
+449800 6860400 149.5
+456600 6865600 132
+474000 6813200 154
+443100 6853200 220.5
+483300 6837500 235
+530400 6843600 238
+495600 6825800 149
+516600 6811200 178
+429600 6853900 273.5
+495600 6842200 201
+496300 6860600 232.5
+503300 6843000 243.5
+529900 6818200 180
+448200 6841300 249.5
+497700 6845700 221
+482300 6864400 114
+529800 6805800 152.5
+429500 6864600 172.5
+452100 6865300 120
+480400 6863700 108
+508900 6808100 110.5
+480300 6866300 89
+453000 6843400 259
+447400 6867600 146
+505300 6839700 225.5
+444800 6855200 238.5
+492400 6826700 160.5
+444600 6859100 218.5
+522000 6849400 249.5
+524000 6864600 234.5
+506600 6831100 181
+501300 6853300 246.5
+545200 6828900 245
+525300 6800600 157
+495400 6853300 225
+454600 6862000 158
+528300 6847500 234
+451800 6858700 200
+435900 6832900 177.5
+494600 6857900 203
+437500 6858200 224
+490900 6857000 171
+508100 6874400 193.5
+490500 6825400 153
+483700 6868800 167
+487300 6855000 169.5
+484600 6858700 154.5
+517300 6863000 266
+469700 6861600 227
+530500 6850800 232
+422600 6830900 175
+443000 6829100 129
+496200 6862300 209.5
+500100 6830500 175
+506300 6820800 151
+524700 6847500 241.5
+547500 6826900 213.5
+507700 6834000 189.5
+457200 6845900 236.5
+440900 6846100 249.5
+471100 6856300 205.5
+425900 6848600 212
+480500 6853800 190
+462100 6862400 160
+484600 6854500 202.5
+514600 6826200 222
+445400 6844100 277
+475800 6830600 322.5
+432400 6844400 204
+448100 6836500 219
+521500 6837600 274
+500100 6841400 202.5
+461400 6856400 181
+433100 6851800 255.5
+433200 6848200 246.5
+423200 6825200 171
+526800 6817900 182.5
+473100 6864100 161
+547300 6823800 213.5
+470900 6836200 282.5
+516900 6848400 257.5
+469500 6859100 215
+440900 6849700 244.5
+507700 6862200 259.5
+432300 6827700 181
+472100 6845800 183
+510800 6805100 100.5
+437700 6836200 222
+480700 6848700 185
+467700 6824100 301
+496800 6849500 226
+499000 6836900 206.5
+510300 6837500 201.5
+479200 6863700 121
+529900 6800900 139
+457700 6834800 257.5
+509200 6868900 226.5
+471500 6828900 292
+533800 6852700 204.5
+494200 6830300 175.5
+530100 6852700 219.5
+487600 6872900 179.5
+535200 6816600 181
+474900 6841700 228.5
+468500 6831900 317.5
+515800 6823100 189
+540900 6821800 190
+433000 6855300 243.5
+508300 6832400 185
+454500 6856400 211.5
+460400 6853700 188
+447500 6855100 236.5
+512500 6810900 167.5
+539400 6813100 169.5
+426800 6844900 223.5
+518400 6821500 168.5
+521800 6805300 154.5
+502500 6871500 203.5
+540800 6811100 163.5
+460500 6858700 176
+494700 6873400 164
+447800 6861200 158
+518000 6799200 153
+515800 6843300 263
+429400 6840100 170.5
+472300 6831900 319
+500700 6858400 237
+502600 6846100 242
+478000 6853600 190
+503700 6833600 187
+427200 6833800 186.5
+507800 6814900 169.5
+425600 6857900 231.5
+474600 6825400 262
+432100 6862800 161
+508000 6872700 198.5
+518200 6826500 215
+474300 6857500 202
+450000 6856000 206.5
+544500 6813400 198.5
+495800 6838200 202
+492700 6854900 206.5
+518900 6827200 217.5
+481200 6821800 154
+533900 6844600 211
+508000 6828900 176
+447800 6863500 165.5
+488700 6828600 236
+455900 6863600 139.5
+476100 6828100 287.5
+482300 6822900 182.5
+481200 6861200 164.5
+494000 6845100 208.5
+459800 6847900 223
+479500 6823100 258.5
+501500 6858200 247.5
+442700 6848600 253
+444200 6863900 164.5
+511400 6833800 194
+476300 6850800 165
+426400 6852900 267
+499200 6851500 243.5
+468400 6843500 198.5
+482700 6817700 162
+490300 6829600 242
+501900 6836000 195
+474200 6851400 170
+465500 6854200 191
+423800 6837200 143.5
+439700 6854000 225.5
+473500 6828500 255.5
+465000 6846800 206.5
+494200 6833100 190.5
+459900 6839400 259.5
+523200 6802000 157
+438300 6840200 226.5
+465100 6862200 199.5
+517900 6832200 230.5
+508400 6827300 179.5
+427600 6837800 125
+503700 6829500 176.5
+542400 6830700 250.5
+493100 6823400 146
+469800 6854400 198
+438700 6829600 140.5
+479900 6814900 162.5
+520900 6865000 231.5
+439800 6866200 143.5
+530200 6837000 266
+510700 6858400 274
+500500 6834800 173.5
+502200 6851700 244
+525400 6829900 214
+501400 6856100 244.5
+500000 6869000 190.5
+451700 6854700 213.5
+516300 6805600 135
+487400 6859700 120.5
+467400 6840600 226
+456300 6831900 218
+470000 6839000 241.5
+530000 6825000 187.5
+487400 6860000 122.5
+436400 6847700 225
+491300 6863700 220
+513400 6865200 227
+500300 6862500 223
+478300 6860700 181
+531500 6804500 157.5
+471400 6863600 199.5
+519400 6811200 196
+458900 6860500 155.5
+474200 6855300 170.5
+529400 6857000 215
+480700 6818700 145.5
+468000 6834300 300.5
+484900 6818300 139.5
+470300 6833600 333
+510500 6827900 183.5
+504900 6869300 226
+454500 6835100 223.5
+441200 6833600 203.5
+522300 6829200 234
+500100 6875300 166
+475300 6836000 315
+488200 6846000 176.5
+438400 6846400 216
+514100 6853000 270.5
+482200 6867400 118
+425400 6839900 169
+479300 6834000 330.5
+525200 6825900 199.5
+500700 6865400 206
+500900 6828000 174.5
+496900 6856600 221.5
+449800 6847100 274.5
+513200 6819900 179.5
+510700 6813000 174
+503700 6862800 246.5
+531500 6848700 218
+513600 6857600 276.5
+471800 6824400 278
+519100 6849500 253
+507300 6810800 137
+526800 6834800 242
+496800 6830300 173.5
+509600 6818400 185
+428500 6862500 170
+418400 6825800 187
+446900 6858600 198.5
+516700 6865600 223.5
+512300 6827000 194
+455300 6859500 165.5
+518100 6811800 183
+430100 6861500 178.5
+528300 6811300 180.5
+451500 6830200 180
+502000 6838000 210
+489800 6864200 188.5
+454800 6842800 253
+522200 6852700 246
+530400 6823000 182
+523500 6846000 244.5
+469900 6851400 181.5
+481300 6853400 169
+530100 6819500 173.5
+471300 6858700 187
+480500 6837100 302.5
+466100 6849600 176.5
+524600 6819800 177
+537300 6815900 172.5
+525600 6854300 236
+524300 6833700 229.5
+526600 6814600 201.5
+492500 6867100 199.5
+503600 6826000 154.5
+490600 6833800 214
+513800 6809200 134.5
+523400 6808700 168.5
+489400 6823200 147.5
+532300 6799200 148
+503700 6874400 177.5
+444600 6866700 157.5
+507900 6852100 277
+504700 6826700 150
+482400 6851000 162.5
+453400 6828500 172.5
+477700 6845500 212.5
+518700 6816400 192.5
+462700 6848500 201.5
+471800 6849100 163.5
+459400 6842000 252.5
+486900 6864900 162
+504800 6856100 263.5
+478800 6815300 150
+512800 6835100 210.5
+458200 6858300 176
+486300 6833000 295
+486800 6866900 185.5
+452500 6837700 225.5
+495500 6848800 215.5
+537400 6809200 173
+485700 6870900 197
+510700 6810100 118
+472700 6861800 211.5
+503300 6850700 270.5
+507400 6858500 283
+507800 6839400 206.5
+478200 6866000 115.5
+519100 6807700 159.5
+470200 6850900 165.5
+448400 6833700 193.5
+545000 6821100 183.5
+534400 6812500 166.5
+522100 6820700 158
+487600 6819500 138.5
+532900 6794100 180
+493100 6869600 174
+514900 6816600 190.5
+457900 6855500 205.5
+534000 6816300 173
+467400 6836200 245.5
+489800 6869700 204.5
+439800 6851500 224.5
+436300 6851300 260
+495400 6868400 186.5
+431300 6834900 195.5
+525500 6808700 163.5
+499500 6871100 181.5
+465800 6851400 187.5
+497300 6868000 181.5
+514400 6860600 247
+493700 6862200 199
+521800 6835000 263
+463000 6853600 184.5
+435600 6857400 204.5
+503500 6849100 258
+470200 6847900 196
+452300 6849600 225.5
+528800 6841400 255.5
+520900 6843300 251
+514100 6841800 234.5
+534000 6827900 193.5
+472600 6852500 170.5
+487100 6825900 172.5
+486300 6822100 156
+483800 6846500 176
+424200 6853100 251
+525100 6839300 270.5
+463600 6842600 256.5
+706100 7012500 61
+657400 7019500 114.5
+622600 7083200 90.5
+682500 7011500 97.5
+658700 7050900 67
+611400 7056000 134
+686500 7030600 97.5
+698600 7017800 54
+631400 7031100 28.5
+628400 7042200 107
+696300 7012400 76.5
+660300 7021300 122
+659000 7020500 119
+695100 7026100 52
+626000 7035000 64
+617900 7041600 53
+638300 7074400 101.5
+637800 7028100 85.5
+680800 7006000 130
+693500 7005400 102.5
+689800 7002900 111
+641000 7015600 91
+668800 7006100 142
+711600 7014700 62
+671500 7050300 22
+677500 7023400 81.5
+694900 6995700 125
+681700 7032600 109.5
+674600 7004700 139.5
+644800 7028200 109
+698000 7000900 110
+647000 7039000 100.5
+610800 7076400 55
+612700 7030800 37.5
+669800 7051700 30.5
+631600 7071200 147
+616800 7032400 65.5
+630600 7083300 15
+608400 7080600 34
+661900 7005000 112
+678900 7031200 115.5
+624900 7090600 3
+621600 7036900 55.5
+696700 7016600 67
+614500 7040500 38
+688700 7014900 84.5
+618900 7042700 70
+679800 7008700 119.5
+664600 7041800 87.5
+685600 7009500 97.5
+648800 7032000 125
+646400 7067000 59
+605200 7037900 28
+672700 7008400 153.5
+688900 7028800 68
+635600 7070500 119
+658900 7031600 135
+612300 7061500 59.5
+654200 7042400 148.5
+605800 7055100 121
+682800 7028700 112.5
+647200 7016500 104
+667700 7058400 17
+684700 7046200 30
+628600 7062300 151
+676200 7050000 20.5
+652200 7028800 139
+634400 7066200 105
+659100 7051900 58.5
+683700 7062300 16
+685800 7028600 115.5
+692100 7041800 31
+634200 7062300 132
+681700 7039500 64
+622800 7060600 173
+646900 7041500 98
+695700 7016600 67
+669000 7047100 49
+624400 7065800 139.5
+639300 7043100 129.5
+651900 7037400 120.5
+622200 7042200 80
+654600 7057400 40
+690400 7033900 47
+625400 7085500 19.5
+703500 7026400 32
+604600 7038500 26
+670100 7021300 109.5
+698800 7025300 56.5
+664300 7015900 153.5
+615500 7055200 122
+698800 7009000 82
+651000 7033200 108
+707800 7005200 81
+620300 7044600 79.5
+654400 7047600 132
+664300 7012400 150.5
+701500 6996700 122.5
+622600 7081700 112.5
+697500 6996400 122.5
+633300 7080400 43.5
+613000 7051600 80.5
+666400 7012800 159
+639600 7041100 126
+700900 6998300 111
+638000 7041000 121
+611300 7063700 55
+665700 7038400 101
+698100 6995400 113
+647000 7036300 108.5
+697000 7011200 88.5
+639100 7039300 109
+644100 7068300 72.5
+619300 7039300 51
+681800 7024100 75
+649500 7063900 52.5
+694800 7010500 89
+651800 7019200 107.5
+671300 7009600 157.5
+606600 7064300 68.5
+609800 7085300 105.5
+602700 7065800 58
+699800 7012700 74
+609500 7082300 54
+627700 7054500 133.5
+643600 7077800 36
+687400 7001900 115
+692200 7044400 31
+668500 7012300 160
+663000 7036100 122.5
+682200 7002900 118
+675500 7027800 111
+612300 7035000 49.5
+628900 7057700 146
+626900 7033600 68
+617500 7053400 98.5
+666000 7033300 164
+608500 7038300 42.5
+620400 7053300 114
+626300 7073900 128
+704200 7016000 47.5
+620600 7057600 151
+635200 7080500 55
+681700 7046000 25
+651800 7022500 120
+672800 7058500 16
+687000 7043200 36
+651400 7049200 141.5
+656100 7022400 128
+640700 7050100 130.5
+693000 7001400 112.5
+638500 7046700 127.5
+624400 7057100 147.5
+635800 7029200 78
+687800 7004700 107.5
+610200 7052300 74.5
+675400 7016100 118
+620000 7026600 54.5
+636700 7094000 3
+699500 7041300 28
+666400 7009000 141.5
+642000 7044400 129.5
+641500 7053200 115
+635900 7042500 122
+676000 7045300 28
+641800 7048500 132
+635200 7087400 12.5
+676400 7019700 102.5
+682100 7046900 27
+649300 7023300 124.5
+635900 7072800 135.5
+632000 7030100 78
+644900 7062300 82.5
+658100 7024800 135.5
+605900 7075400 62
+659200 7022100 118
+610900 7079400 48.5
+690300 7015600 83
+626100 7095200 7
+684400 7003600 120
+684200 7036100 56
+693500 7013400 77.5
+698400 7029800 45
+654400 7018400 113.5
+670500 7025100 113.5
+683100 6994700 134
+645400 7031100 119.5
+629000 7077800 105
+621800 7067500 71.5
+679100 7010700 124.5
+653600 7051200 92
+633900 7018100 69
+660800 7051700 50.5
+657000 7004500 104.5
+651100 7022100 112
+611000 7043900 39.5
+662600 7045800 112.5
+696400 7029300 50
+646800 7027800 123
+625100 7040200 77
+678100 7028200 106
+682800 7011300 100.5
+658000 7039700 133.5
+703700 7009100 72.5
+696400 7035900 44
+673900 7013800 126.5
+648100 7042400 119
+687500 6998500 116
+691900 7025800 73
+663400 7006400 119
+617500 7089200 32
+623900 7048500 139
+654800 7014000 136.5
+616600 7040700 42
+703100 7022700 55
+659600 7035200 150.5
+650200 7035200 96.5
+674100 7030700 132
+652300 7039100 126
+675700 7023400 89
+627300 7084800 39.5
+678100 7002000 112
+672400 7013100 132
+623900 7086200 17.5
+638600 7025900 84
+643000 7038800 86
+702900 7016200 57
+692000 7000300 118
+654200 7025400 141
+654700 7027700 139.5
+666400 7004200 124.5
+620600 7086300 83
+705200 7010700 67
+627900 7082900 24.5
+667100 7027500 114.5
+654800 7053000 79
+614300 7050600 88.5
+659100 7046900 88.5
+663800 7057200 19
+649900 7039900 107
+621500 7031200 73.5
+675000 7038800 116
+630500 7037200 76.5
+660500 7030500 137
+607000 7074200 57.5
+700600 7016500 64.5
+624700 7050100 173.5
+605600 7081800 62.5
+676700 7036000 130
+647700 7072700 13.5
+628200 7032000 72.5
+611100 7061000 105.5
+648300 7057000 91.5
+624600 7061600 188
+604000 7032100 27
+675100 7034000 147.5
+636100 7033700 76
+620000 7037400 47
+693300 7038600 32
+673900 7028200 106
+603200 7036400 25.5
+648000 7030800 139
+691600 7040700 32.5
+673600 7044100 46
+605700 7088500 79
+661600 7008500 137
+660600 7025200 138
+629900 7081900 87
+648500 7044700 140.5
+628500 7027500 98
+696000 7023800 56
+646000 7073400 23.5
+657700 7016800 131.5
+609900 7039400 41
+628600 7026300 71
+662400 7013200 140
+637500 7083900 49
+609200 7040900 41.5
+646400 7063600 68.5
+641500 7023300 82.5
+630400 7077800 109
+638900 7051700 85
+644300 7065400 102
+604800 7050300 87.5
+608000 7047700 53.5
+683900 7007200 118
+630000 7068100 154.5
+627000 7071900 144
+641200 7051600 126
+674000 7022300 98
+674200 7007600 144
+607800 7085700 87.5
+673900 7003100 135
+639700 7048800 122
+684300 6997000 114.5
+689500 7006500 104
+689700 7044100 25
+645100 7049600 166.5
+685900 7045700 34.5
+628900 7073400 126.5
+652200 7059900 59.5
+624000 7070400 152
+645700 7041900 117
+622500 7076100 135
+693100 7032900 46.5
+611300 7087200 124
+640100 7079200 48.5
+601600 7053000 89
+656200 7028200 139.5
+634600 7067400 110
+664500 7046800 68.5
+654500 7066400 44
+601800 7043000 24
+642900 7070000 93
+601400 7040700 22
+602600 7066800 56
+634700 7040900 108
+655300 7047700 136
+666000 7006300 133
+676300 7052600 18.5
+640200 7024900 89.5
+620700 7064400 139.5
+684300 7021300 75.5
+621700 7069100 113.5
+671700 7046900 38.5
+662200 7049200 65.5
+673500 7011000 132
+660900 7003500 103
+657100 7027400 148.5
+635700 7082400 24.5
+671500 7035700 131.5
+656000 7034800 144
+685700 7005800 108
+605700 7077000 64
+644200 7058100 87
+649300 7054700 83.5
+669700 7030800 133
+706600 6999100 98.5
+698900 7002600 101
+630100 7053700 132.5
+688100 7061700 18
+643300 7042300 107
+664600 7008500 138
+691300 6997500 119
+702800 7021300 53.5
+694800 7032600 53.5
+657900 7054700 41
+668400 7037800 121.5
+670800 7041200 77
+690800 7029500 62.5
+704600 6996600 112
+698600 6998600 112.5
+656900 7063800 29
+690900 7022700 73.5
+658500 7049500 75.5
+629200 7091400 3
+644000 7034400 107.5
+616100 7083200 98.5
+661800 7042900 114
+628700 7076500 106.5
+638200 7094800 5
+644000 7072200 56
+651000 7030500 115.5
+645600 7021700 97
+631200 7024400 94
+617500 7064000 125
+693600 7009300 100.5
+688200 7014100 84.5
+647400 7034000 126.5
+632700 7098400 7
+617100 7039200 45
+635800 7056700 115
+637200 7059300 114
+673200 7052100 31.5
+676500 7018700 99
+674400 7045100 38.5
+663800 7024500 127.5
+624900 7075200 89
+642000 7062000 96.5
+670900 7054100 26.5
+612400 7095200 75.5
+690200 7035800 40.5
+634700 7029300 80.5
+691000 7037000 33
+696800 7004500 101
+623600 7035300 58.5
+622400 7052900 132
+681900 7043500 36.5
+654200 7037100 142.5
+676200 7042500 49.5
+685600 7012700 84
+692200 7027800 60.5
+683800 7032800 98
+651100 7026600 130
+616700 7047400 94
+666600 7024200 125.5
+609700 7054500 95.5
+652100 7045400 153
+673200 7021700 101.5
+647100 7045400 156.5
+695000 7036700 32.5
+692100 7017300 72
+624900 7077000 114
+669500 7019500 116
+664600 7045100 68
+692200 7029800 56
+603200 7062800 56
+672600 7031500 137
+621400 7092600 3.5
+643800 7038200 84.5
+669500 7059000 16
+668400 7025600 118.5
+672900 7048500 35.5
+636600 7022900 108
+638000 7030300 92
+669100 7014200 151
+632300 7044500 132.5
+619400 7064800 135.5
+623300 7072000 134
+664400 7036700 131.5
+635000 7092900 3
+655600 7043500 141.5
+650800 7061100 49
+603400 7086400 48.5
+647100 7049500 165
+643800 7075900 36.5
+700700 7013800 63
+639600 7059900 132.5
+615300 7073100 56
+651700 7064900 41.5
+629900 7028100 95
+649200 7066700 54.5
+624400 7082900 47.5
+613000 7042600 51
+677200 7047000 30
+618000 7028500 54.5
+682800 7048000 25
+655400 7051000 85.5
+619500 7079000 140
+693700 7015100 75
+680500 7020500 85.5
+615200 7071100 76.5
+675500 7009200 139.5
+631500 7064600 135
+656900 7048300 91.5
+689500 7037900 36
+636000 7056400 129
+600700 7081700 57
+661600 7054800 26
+643300 7027400 92
+613100 7091700 74
+655700 7037600 142.5
+659900 7052800 35.5
+616800 7078700 112
+681500 7053600 18
+650700 7071200 32
+654900 7026600 145.5
+631400 7032000 69.5
+633100 7035500 88
+693900 7021400 70.5
+672100 7049500 33
+686800 7011700 88.5
+619400 7095200 9
+626600 7044400 116
+608000 7062400 60.5
+641500 7041700 115.5
+659300 7015600 142.5
+660200 7027600 139.5
+662100 7023800 123
+633200 7058600 138.5
+632000 7018800 77
+642300 7060400 105.5
+609500 7044500 35.5
+651900 7055300 68
+652600 7057800 59.5
+627900 7020500 64.5
+665800 7054600 18.5
+638100 7079300 52
+663800 7029000 127.5
+601800 7075700 35.5
+669000 7055500 18
+602000 7070700 55
+679600 7013600 110.5
+603400 7047600 40
+691700 7031700 61
+701000 7043000 31
+700000 7019500 55.5
+658100 7043100 126
+677500 7012400 116.5
+644800 7018000 113.5
+629900 7031100 77.5
+680800 7011900 107
+645200 7034900 118.5
+632900 7073200 163.5
+653200 7034000 121
+708800 7016900 54.5
+687400 7007000 96
+696900 7017300 56.5
+635500 7019200 83
+643100 7017700 110
+640100 7013600 80
+619800 7047900 111.5
+702900 7012000 69
+627000 7050800 156.5
+666400 7020000 126.5
+615500 7047100 71
+658400 7041200 126.5
+607600 7052200 84
+670900 7045000 46.5
+640900 7036300 83
+663200 7052000 53
+613600 7049100 67
+633300 7023400 93
+610000 7048400 48
+604300 7068200 77.5
+662100 7014500 148.5
+674400 7048100 28.5
+606300 7059900 97.5
+662200 7021600 138.5
+635900 7084200 11
+628700 7072000 147
+684100 7009300 109.5
+634200 7025600 106
+649200 7020100 103.5
+661500 7058600 30
+628100 7050400 154.5
+622100 7050000 136.5
+658900 7006800 136.5
+665100 7022300 132.5
+688600 7000700 117
+599500 7048200 21.5
+656300 7030200 122.5
+631200 7087000 14
+684800 7025300 89.5
+609700 7050300 69.5
+652600 7031500 115.5
+636100 7047800 144.5
+620800 7071200 129.5
+615400 7093900 26.5
+674600 7014300 117.5
+664100 7022700 133.5
+656200 7025000 136.5
+630900 7094300 3
+660800 7037600 138.5
+679100 7004700 129.5
+611100 7042000 26
+680500 7045600 28.5
+606600 7068900 77.5
+627600 7041700 83.5
+670500 7039500 136
+638100 7066300 92
+614400 7086800 72
+618400 7087900 43
+679500 7032800 132.5
+670200 7035300 126
+652800 7069400 46.5
+640600 7085100 32.5
+701300 7035600 32.5
+645200 7025300 102
+673500 7015800 126
+624500 7067900 139
+632800 7079300 98
+704600 7037800 43
+691500 6998900 122.5
+685100 7052400 22.5
+632400 7030900 75
+697000 7044000 29.5
+624100 7046800 129
+677300 7044600 31
+628600 7035900 67.5
+685300 7040100 52.5
+671000 7002600 134.5
+661000 7045300 99
+672300 7046500 36
+618600 7068200 80.5
+618100 7072800 123
+617900 7061600 165
+672600 7028300 102
+650600 7025900 139
+690600 7046900 22
+640000 7028700 76
+623100 7075700 137.5
+701600 7026600 36.5
+654800 7024200 140.5
+657300 7060400 32
+610000 7058600 101.5
+599100 7068700 29.5
+609700 7046600 47
+631200 7034800 108
+639200 7089600 3.5
+623300 7038500 59.5
+679100 7055000 17.5
+641600 7033700 104
+618100 7090800 30.5
+687500 7028800 100
+617000 7057800 139
+696000 7019500 69
+608300 7073600 62
+648800 7061300 63
+643600 7032600 108
+689300 7026800 86
+671800 7028400 109
+690800 7016600 78.5
+656700 7055900 41
+702700 7001500 102
+676600 7030700 130.5
+681300 7049600 19.5
+677700 7058400 16.5
+642500 7067800 82
+637500 7045100 135
+682800 7018000 81.5
+607800 7029100 25.5
+627900 7084700 9.5
+672900 7039800 91
+671100 7016600 125
+642000 7056600 108
+628400 7063400 153
+607600 7077200 55.5
+687200 7016600 83
+678300 7045000 30
+692400 7019100 82.5
+680400 7038300 65
+670500 7042100 66
+667800 7042700 68
+680500 7043600 29.5
+699100 7037600 29
+612500 7082100 79.5
+633500 7032300 55
+643800 7014700 104.5
+624800 7027400 78.5
+647100 7054500 119.5
+693400 7042000 33.5
+688200 7004000 111.5
+663800 7033800 133.5
+617200 7091800 30
+648500 7038100 99
+683800 7059000 17.5
+613600 7047700 58.5
+650500 7075400 17.5
+678700 7024100 82.5
+617700 7076100 121
+630500 7043400 120.5
+688300 7022800 75
+684100 7022800 77
+662400 7017500 150.5
+672200 7023200 106.5
+670600 7045700 43
+638900 7054600 123.5
+689800 7009800 93
+707000 7018800 47
+641900 7077200 36
+674200 7034600 159
+609300 7035800 43
+667900 7021600 119.5
+691100 7003500 107.5
+632100 7026700 97
+682800 7034600 77.5
+639600 7032900 90
+670100 7011500 151.5
+634900 7016200 61
+685700 7003100 116.5
+685400 7015300 85
+702400 7037900 26
+632800 7039200 93.5
+639500 7018600 95.5
+663200 7025600 129.5
+637700 7042900 133.5
+635900 7031700 70
+686800 7012800 82
+626500 7081400 102.5
+641000 7063800 91
+650500 7013200 125.5
+701900 7023300 51
+637500 7034800 73
+644400 7039600 91
+659900 7008500 148.5
+656500 7045900 145.5
+660900 7019500 133.5
+658400 7052800 63
+695200 6997600 123
+668000 7031000 138
+630800 7021600 77.5
+653300 7055600 61.5
+693100 6998100 123
+658000 7022900 122
+686900 7019800 78
+707000 7015300 50.5
+684900 6998300 110
+708300 7008900 90
+617100 7081800 118.5
+667700 7016900 134
+645700 7075400 36
+628900 7054400 132
+695300 7008100 91
+647300 7028700 130
+668400 7007500 149
+668600 7035700 127
+657200 7057900 33.5
+690800 6992500 130
+688100 7034700 52
+613600 7045300 42
+645500 7068500 68
+641600 7078000 48
+613300 7070700 71.5
+601700 7055500 82
+656800 7033400 138
+641400 7047700 124.5
+600500 7068300 49
+704200 7012600 61
+605700 7063300 37.5
+677800 7015000 103
+622300 7045800 97
+619500 7072600 133.5
+667300 7046700 58.5
+639000 7071100 106.5
+612100 7041400 22.5
+634200 7054400 131.5
+637400 7050300 125
+618700 7070200 87.5
+607200 7056900 123
+657900 7004100 106
+644400 7045800 143.5
+608500 7071300 73.5
+696200 7040100 30
+691400 7011300 89
+650500 7042100 126
+625300 7042500 89
+673100 7042900 56.5
+699600 7035800 36
+695300 7002400 113
+605100 7040700 32
+697600 7001600 114
+654100 7041100 148
+680900 7008500 118
+609500 7042800 30
+657800 7056400 38
+668800 7017600 128.5
+669000 7028400 115
+669500 7033600 125.5
+685900 7022800 76.5
+606000 7027700 22
+689000 7021700 74
+603800 7034700 27.5
+659400 7002700 99
+693600 7028200 50.5
+697200 7021700 57
+611900 7039500 35
+628900 7032800 50
+642900 7023000 92
+603300 7074900 55.5
+625000 7022700 56.5
+602100 7084800 61.5
+663800 7008000 133
+626300 7053600 140.5
+692400 6995700 129.5
+674400 7025700 110
+633400 7092500 3
+629500 7024400 78.5
+623000 7025400 54.5
+629600 7020300 62.5
+605800 7079200 48
+613500 7078500 66
+609200 7088100 98
+634200 7084500 29
+639800 7072800 80
+657400 7045600 139
+619800 7030500 58.5
+620000 7033900 61.5
+624700 7039100 65
+672200 7033400 144.5
+614000 7067600 66
+635900 7078500 78.5
+653400 7063900 46.5
+696900 7006600 91.5
+605100 7041900 33
+693700 7035600 34.5
+688000 7045900 25.5
+627900 7046100 142
+604800 7059700 99
+646800 7025000 110.5
+631800 7041500 123.5
+644300 7019300 120.5
+654500 7031000 117
+686600 7035900 48.5
+609300 7031900 31
+704000 7023800 45
+693700 7031700 55.5
+647100 7021000 97.5
+639400 7061900 94.5
+707400 7014400 59
+664200 7020300 138
+693800 7036800 32.5
+637900 7021400 100.5
+695100 6999100 115.5
+636800 7015100 81.5
+680000 7041800 50
+670600 7031100 135
+700200 7008500 78
+669500 7009800 160
+699500 6996300 113.5
+667100 7030100 131.5
+640500 7068700 73.5
+631600 7067800 137
+702500 7017300 58.5
+604400 7065200 79
+609400 7092000 77
+679600 7053800 17.5
+637800 7068000 84
+610300 7072700 65.5
+616700 7055900 113
+653600 7068400 45
+645700 7053200 132.5
+649200 7025300 135
+638900 7065500 92
+598900 7065400 48
+679000 7025200 87.5
+659200 7044400 103
+663000 7039900 118
+669700 7049500 44
+694700 7023200 56.5
+604900 7030800 30
+665100 7048200 60
+706200 7001400 99.5
+684400 7012500 90.5
+640600 7031900 90.5
+686500 7000900 122
+613600 7088900 76.5
+671100 7022600 102.5
+684400 7054100 18.5
+635800 7075200 108
+655400 7055400 58
+674500 7017900 115.5
+643500 7023100 92.5
+646100 7071300 41
+612200 7072600 55
+659300 7029100 134
+688100 7037100 49
+648800 7069200 50
+657100 7042100 116.5
+601600 7080100 38.5
+647500 7060200 73.5
+690500 7041800 43
+699600 7021200 56
+614000 7045300 61
+681300 7014300 95.5
+650200 7027700 127
+687900 7043300 38
+623100 7064600 144.5
+663300 7031000 142
+653500 7049900 111
+673300 7045000 40.5
+683600 7025800 95.5
+667100 7039500 83
+679300 7036500 114.5
+684900 7018400 84.5
+631600 7052300 139.5
+599800 7035400 15
+653800 7047900 144
+639300 7034900 71
+603600 7058800 79.5
+615400 7062300 123
+603200 7070700 95.5
+685000 7049300 26.5
+649800 7051500 120
+631200 7063200 147
+601400 7032800 16.5
+655100 7056600 48
+612300 7066100 62
+615400 7030500 53.5
+654700 7020200 129.5
+677500 7038600 64.5
+680200 7016500 89.5
+609700 7029300 27.5
+614200 7084100 95
+640800 7019800 123
+689300 7000600 122.5
+682800 7019500 80.5
+652900 7018700 110.5
+705100 7016900 54
+672500 7019800 111.5
+656600 7015800 134
+622700 7073300 139.5
+673600 7005600 150
+683100 7023300 79
+650600 7034400 107
+670800 7028200 115.5
+640900 7071200 93.5
+639900 7053200 96.5
+660500 7033800 136.5
+637500 7037800 89.5
+663300 7043400 77.5
+621400 7077000 140.5
+641300 7031000 103.5
+692600 7022200 57
+643800 7029300 99.5
+687900 6541200 587
+692000 6518500 1083.5
+718600 6519000 454
+733200 6514200 492
+730300 6517400 428.5
+667700 6537600 695.5
+711800 6484300 712.5
+744900 6508200 591.5
+723400 6516600 394
+719300 6522100 335.5
+692000 6547600 545
+720000 6541100 330
+739000 6494700 735.5
+715300 6515800 428
+743600 6503800 777
+664000 6518900 722.5
+677700 6548700 686
+670300 6518900 763.5
+726300 6522900 387.5
+724200 6510600 578.5
+692000 6496900 1378
+747900 6488800 1047.5
+731800 6500300 620.5
+716200 6501700 402.5
+702500 6489700 801
+748000 6513900 686
+771600 6492500 1164.5
+714200 6479100 645.5
+664000 6494800 682
+675700 6492800 1205
+769900 6488200 1061.5
+721600 6495900 494.5
+703600 6493200 727
+722600 6533600 310.5
+701000 6520300 972.5
+704100 6525200 604
+713800 6548000 443.5
+678400 6480000 957
+719900 6501500 584
+695900 6501100 1116
+677100 6521200 768.5
+694900 6544000 561
+674500 6507400 886
+703900 6533300 549
+737600 6508600 558
+717900 6545200 349
+757900 6494700 939.5
+710800 6538600 337
+695500 6540200 753.5
+754000 6531300 755
+701600 6494000 815
+747600 6524900 765
+708200 6495900 658
+706700 6520000 461.5
+730700 6519900 393.5
+709900 6509700 509.5
+749300 6497500 937
+664300 6514800 727
+675700 6554300 650.5
+692700 6509300 976
+690100 6569400 505.5
+769100 6482000 981.5
+743700 6524600 562
+709700 6507900 438.5
+710000 6498800 594
+746600 6530300 607.5
+719400 6493900 460
+721300 6536000 311.5
+664300 6502000 716.5
+658600 6522600 764
+709600 6530200 416.5
+719700 6537600 314.5
+702400 6484400 1040.5
+762300 6492600 998.5
+710100 6491900 714
+773800 6485600 1132
+708700 6501300 639.5
+696500 6548600 556.5
+741500 6513000 449
+758800 6476300 802.5
+723200 6547300 355
+701300 6550800 574
+712900 6487600 599
+679400 6499900 1172
+717000 6548400 391
+738500 6536700 537.5
+687200 6562300 546
+725300 6490700 428.5
+734100 6547800 314.5
+737300 6532700 344.5
+689100 6511900 894.5
+666400 6512400 782.5
+665700 6488000 712.5
+716900 6479500 624
+719800 6548900 377
+664000 6523100 764.5
+706600 6527900 428.5
+723000 6544500 324
+708500 6540000 422.5
+707400 6510300 624.5
+717400 6512000 433
+729100 6535100 320
+707400 6532700 382
+682400 6508900 1119.5
+675400 6543800 687.5
+704900 6514800 616
+739700 6500400 756.5
+715000 6519100 411
+717100 6537500 321.5
+721000 6508300 559
+705200 6519300 483.5
+686200 6555200 633.5
+723600 6496900 545.5
+724100 6518400 394
+718900 6512300 486
+690500 6507800 1046.5
+706300 6530800 432.5
+737000 6483600 864.5
+723100 6490400 412.5
+724600 6519800 327.5
+723800 6492600 449
+679200 6505700 1161.5
+746000 6532200 723.5
+659300 6528400 762
+724100 6494800 457.5
+713100 6511600 413
+685500 6536200 593
+684500 6560600 619
+681100 6566000 541.5
+688400 6525900 709
+756900 6486900 786
+723400 6486200 439.5
+721800 6486500 478
+699400 6476700 1176
+680300 6564600 577
+753200 6506900 730.5
+732600 6481600 650
+736700 6540200 427.5
+706100 6525600 485.5
+734400 6509000 539
+717300 6533100 320.5
+691500 6550100 538
+710300 6486600 714.5
+682200 6551400 697
+713000 6522200 324
+729000 6494700 542.5
+717100 6529900 320
+741300 6493900 944
+714300 6549500 461
+707200 6506700 675
+674800 6529900 640
+706000 6488700 937
+747300 6510200 587
+718800 6498500 480.5
+703900 6518400 680.5
+679400 6550200 692
+749600 6508600 522.5
+694800 6490400 1265
+756000 6515300 943
+681600 6518900 867
+717400 6510400 553.5
+711400 6489800 749
+725600 6505700 645.5
+720600 6485500 438.5
+714500 6538100 324.5
+707700 6483100 962.5
+704000 6521800 588
+746700 6520800 689
+733500 6511600 576
+742500 6528700 538
+748700 6534100 937
+728600 6483800 664
+663100 6530400 703.5
+668900 6486100 799
+739200 6512300 440
+764600 6486200 989
+714000 6488500 523.5
+718400 6507900 557.5
+687700 6509300 1144.5
+708800 6536700 369.5
+736600 6513800 497
+717100 6540400 334
+693700 6504700 1243
+711200 6494500 535.5
+726100 6516800 345
+740600 6522100 358.5
+753900 6498500 768.5
+726300 6513700 454
+713500 6495900 533
+717200 6489600 507.5
+727400 6501300 522.5
+706600 6551000 491
+670600 6495700 854
+671000 6505000 806.5
+714000 6498600 503
+714800 6509400 411.5
+711100 6544800 433
+719000 6481000 603.5
+710100 6543700 392.5
+729500 6525400 369
+707800 6525800 419
+703800 6502400 761
+686000 6547700 566
+748200 6478800 993
+752200 6477500 826.5
+749700 6504000 736.5
+664900 6491900 694
+681800 6543700 608
+689700 6516200 833
+748100 6517500 482
+720400 6478400 539.5
+739200 6544500 426
+707500 6547300 453
+745900 6544000 682
+681800 6485000 1357.5
+735800 6500300 675.5
+703300 6470300 1168.5
+678000 6533200 613.5
+727800 6519800 356
+726100 6486200 543
+707300 6538900 391
+762900 6478700 973
+745900 6491000 1069
+668500 6533500 676
+727400 6546500 351
+701200 6525700 814
+673300 6511100 868.5
+682700 6533700 646.5
+693000 6531800 884.5
+694400 6482500 1099
+673400 6530900 627.5
+758100 6502100 1061.5
+720100 6528000 344.5
+656000 6523600 772
+685300 6531200 650.5
+707700 6487000 964.5
+727800 6491600 531
+684800 6509500 1025.5
+685200 6564400 624.5
+734700 6524400 378
+726100 6529300 331
+678300 6555900 670.5
+674800 6517900 884.5
+719200 6504900 568.5
+730400 6513600 498
+716600 6551300 396
+711200 6525100 332
+719700 6515800 391.5
+705600 6539600 559.5
+697900 6506700 881
+732200 6489700 638
+686300 6514100 799.5
+752500 6525600 864.5
+726600 6481400 561.5
+685100 6543700 566
+672900 6514700 882
+715700 6493900 505.5
+729900 6532800 350
+708700 6532700 409.5
+726900 6487200 577.5
+707200 6537300 400
+703400 6494500 711.5
+708600 6516800 405
+691400 6565200 487.5
+703500 6549700 537.5
+699000 6485500 934
+717000 6482000 544
+724000 6540500 344.5
+769300 6484400 1035.5
+666100 6528200 696
+736000 6482300 874.5
+749300 6528900 911
+735300 6486200 796.5
+687800 6522100 769
+691500 6555200 565.5
+693900 6476600 1226.5
+665600 6557600 476
+752300 6520800 943.5
+700000 6534200 730
+722300 6519000 450
+730200 6506000 624
+733100 6496600 642
+717200 6486800 489.5
+660600 6499100 662
+671600 6552400 611.5
+692600 6512900 992
+711600 6502500 562
+710400 6494400 621
+729400 6479500 611
+714400 6484500 581.5
+722300 6479700 447.5
+713900 6527800 318.5
+695500 6550500 502
+692600 6556000 510
+749600 6483600 887.5
+676300 6556700 560.5
+751500 6512500 693.5
+671800 6543000 655
+713300 6504100 468
+730200 6538600 344.5
+753000 6502200 690.5
+691600 6527800 899
+751600 6496200 984
+686500 6478800 1117.5
+755900 6512700 1049
+760600 6482500 795
+667100 6525700 690
+733400 6483500 686.5
+759400 6499300 663.5
+678000 6485600 989.5
+706400 6516900 455.5
+695600 6497100 1142.5
+714800 6535400 324
+679300 6513400 906
+708400 6504600 639
+718700 6484300 470.5
+723500 6529300 315
+768300 6477400 959
+763800 6489800 1051.5
+733200 6520500 378.5
+702900 6530100 695
+744700 6495900 986
+710500 6549000 487.5
+727100 6542600 353.5
+705400 6555600 405
+687200 6551900 622
+754200 6491400 869.5
+668700 6500100 769
+712700 6494000 505
+733500 6538300 291
+714600 6513700 364.5
+697700 6554500 499.5
+721700 6516900 448
+670200 6547900 632.5
+713400 6539900 332
+725600 6535800 333
+671500 6556200 501
+755100 6505800 924.5
+698000 6492400 964.5
+712200 6536500 334.5
+725700 6479500 464
+689100 6520700 817
+688300 6567000 561
+707700 6479700 807.5
+685100 6497500 1390
+705000 6535900 547.5
+692800 6563000 539.5
+732200 6544800 318
+734500 6541600 283.5
+722700 6492700 411.5
+712800 6499000 472.5
+741700 6509900 519
+762000 6499500 1103.5
+732000 6508800 625
+738900 6518200 424.5
+754400 6476800 767
+690700 6477200 1105
+675700 6500900 1019
+699400 6498700 810
+712300 6508600 484
+719800 6510200 576.5
+716400 6485200 532
+712400 6540800 339.5
+723300 6523500 342.5
+719000 6489100 471.5
+709800 6511200 546
+706800 6542400 528.5
+718800 6517300 458
+725700 6525400 340
+747600 6481900 990.5
+725600 6545600 356
+750800 6482200 832
+702800 6496800 667
+679300 6490300 1389
+726500 6492000 513.5
+699900 6543900 613.5
+714700 6486100 554.5
+755300 6532400 959
+676700 6561700 546.5
+705100 6546100 484
+735400 6535200 315.5
+735200 6490500 697.5
+741800 6517400 419.5
+713400 6490700 632.5
+701500 6513400 956
+731300 6485300 622.5
+733900 6505100 631
+714400 6524000 322.5
+679700 6498800 1110
+673800 6523800 738
+707000 6498500 676.5
+727900 6516700 397.5
+724900 6483700 547
+746800 6538000 771.5
+736800 6490300 842.5
+702600 6505300 723
+717900 6502700 498
+756700 6479600 745
+669100 6551800 527
+718000 6514300 350.5
+713000 6542000 354
+706100 6538900 520.5
+708300 6494600 702.5
+732700 6529100 340.5
+755200 6492400 818
+671500 6526800 649
+724400 6497100 523
+710900 6515200 433
+772000 6489400 1082
+725000 6488000 439
+686000 6526800 740
+663900 6487900 665
+728000 6510600 536.5
+716400 6498900 477
+733900 6516200 418
+761600 6485700 878
+715200 6507500 470
+760300 6483600 705
+715900 6502600 413
+714400 6503600 394.5
+722100 6505000 615.5
+729800 6544200 335.5
+723400 6499800 609.5
+715600 6547000 380
+740700 6491000 975.5
+730700 6494600 621
+750400 6500100 841.5
+711600 6495000 544.5
+708400 6538600 352.5
+700800 6556800 461
+694600 6553100 505.5
+702900 6553300 495
+741900 6480800 984
+740300 6542000 573.5
+689400 6532600 716.5
+671500 6549400 670
+694500 6559900 528.5
+730400 6550600 326.5
+687500 6537800 654.5
+738200 6525300 352
+672500 6535000 634.5
+666500 6517200 748.5
+704300 6523200 509.5
+708400 6507700 547
+771400 6484600 1018.5
+742300 6484500 997.5
+709900 6478300 762
+703400 6477300 965.5
+704400 6497500 685
+700800 6537400 654.5
+716700 6526600 339.5
+707800 6514400 614
+757900 6508600 1115
+695400 6494700 1028
+665600 6505400 784
+681700 6558100 650.5
+690500 6541100 576
+730800 6536300 313
+722300 6482900 438.5
+720200 6532300 324
+671300 6489100 866
+714600 6481500 648
+681300 6526900 748
+735200 6480300 833.5
+711400 6476700 733
+704200 6527500 469.5
+671100 6521300 734.5
+740100 6506000 635
+720300 6526200 331.5
+750000 6474500 936.5
+371300 6245800 374
+392000 6277100 121
+393900 6231100 899.5
+444600 6256400 312
+365000 6273700 81
+411800 6253000 212
+381300 6261500 127
+446800 6280400 189.5
+355400 6268300 99.5
+337300 6279700 25.5
+349200 6274800 33
+367400 6272400 89
+406900 6263800 139
+393200 6254900 152.5
+368300 6263100 74.5
+407900 6239900 295
+414200 6274600 152.5
+441700 6251600 333.5
+339600 6232000 672.5
+406200 6226400 1053.5
+392600 6267700 128.5
+407900 6233300 326
+407400 6269500 161.5
+418000 6252700 218.5
+425600 6262000 224.5
+417100 6247900 248.5
+334000 6270200 72
+431800 6240500 307.5
+372400 6263200 82
+359200 6242200 367
+402000 6268900 137.5
+413100 6257400 188.5
+374600 6269800 88.5
+354800 6238800 606.5
+434600 6270400 208
+399800 6276500 129
+403200 6279400 116.5
+390500 6280300 116
+421700 6219700 1119
+418600 6258800 206
+446300 6276000 210
+440300 6273400 212.5
+378200 6262700 117
+443300 6272200 212
+448500 6276300 197
+433700 6256200 289.5
+436400 6247200 299.5
+392400 6257400 141.5
+383400 6276500 88.5
+379800 6261100 115.5
+380800 6248100 277.5
+375900 6257400 106.5
+394600 6268700 118.5
+439400 6276600 201
+424300 6272100 176.5
+438200 6252200 313
+389800 6274000 106
+398200 6249000 200.5
+448500 6263200 268.5
+383600 6235900 451.5
+342700 6257800 477.5
+381600 6229600 876
+403800 6243100 213.5
+385700 6244600 342.5
+354200 6261500 98.5
+381600 6239200 241.5
+438200 6261200 273.5
+353900 6239500 283
+407500 6259900 138.5
+419000 6270500 167
+394300 6257200 182
+412000 6274900 147
+454200 6260600 265.5
+412500 6268100 188.5
+412200 6263800 188
+329700 6267000 53.5
+394700 6255700 181.5
+418600 6256300 161.5
+452100 6244100 383.5
+328400 6256700 454
+313000 6262700 54
+358600 6236300 476.5
+417200 6242000 293
+440700 6242700 353.5
+423100 6214100 1569.5
+440900 6246100 290.5
+442000 6276900 191
+369400 6248200 253
+446900 6269600 230.5
+356800 6236800 239.5
+419400 6279500 148.5
+377400 6221300 1170.5
+380300 6228600 852
+406200 6215000 1439
+405600 6236100 391
+444300 6278900 184
+406400 6223600 1091.5
+414300 6261300 185.5
+448300 6271700 225.5
+429500 6246000 286.5
+450200 6274400 199.5
+400400 6247200 211.5
+440100 6270300 223
+420200 6223300 1196.5
+419100 6267300 155.5
+423500 6266100 202
+378300 6255600 133
+346500 6240400 597.5
+442600 6262000 280
+371200 6262300 71
+422200 6229800 457
+399800 6235600 343
+377600 6241200 496.5
+416800 6272400 149
+435700 6279000 166.5
+384900 6248600 169
+422800 6269400 196.5
+431200 6271100 188
+342700 6273300 73
+437100 6273300 193
+428000 6276100 160
+382600 6237000 375.5
+383800 6277500 86
+406400 6262200 128
+414800 6277900 128.5
+421300 6254200 172.5
+334800 6271300 43.5
+409300 6258500 133.5
+386200 6254100 149
+383900 6262600 139
+359700 6258500 260
+445000 6263300 257.5
+437200 6235500 354
+435400 6274700 200.5
+415100 6248400 206
+448200 6260300 289
+450600 6273200 205.5
+424200 6263400 214
+452900 6273000 212
+390800 6270000 138.5
+445500 6268900 233
+417700 6256900 188
+426500 6250500 205
+442600 6254200 330.5
+424200 6276700 166.5
+377100 6250000 228.5
+427200 6268600 203
+432800 6248700 228
+350300 6240500 488
+398500 6247700 191.5
+406700 6239500 787
+361300 6253700 251
+369400 6258100 149
+423600 6234800 386.5
+454600 6258300 297.5
+402400 6245600 207
+404200 6266400 135.5
+436900 6277300 172
+434700 6248100 278.5
+361400 6241300 394.5
+443600 6236600 415
+397700 6269700 114
+387800 6264000 163.5
+425700 6265900 226.5
+375700 6244300 386
+428100 6259900 232.5
+351400 6258500 452
+407700 6274500 96
+404900 6217400 1067.5
+360100 6277100 88.5
+433400 6258500 272.5
+426400 6270100 190.5
+380000 6261800 61.5
+432000 6262400 244
+439800 6256500 305
+415000 6264600 206
+405800 6231500 668
+395700 6266400 148.5
+445600 6240000 379
+363700 6234600 850.5
+335000 6255700 350.5
+446400 6251000 354.5
+406700 6237700 240
+351200 6263400 308.5
+395300 6250400 186.5
+392600 6258400 163.5
+420900 6220400 1168.5
+370000 6252300 189.5
+423200 6252200 182.5
+426300 6248500 269.5
+370700 6257700 146
+365000 6247700 334
+442800 6243300 344.5
+370200 6241300 675.5
+361000 6238300 488.5
+384100 6226400 669.5
+433300 6242900 284.5
+399500 6261800 171.5
+432200 6239600 304
+443900 6250800 350.5
+430900 6246300 223
+421400 6216400 1586
+445400 6278200 194.5
+411000 6217900 1362
+421500 6217100 1247.5
+420300 6215800 1715.5
+418900 6223800 1148.5
+417500 6255700 135.5
+399500 6270400 119
+433700 6238500 310.5
+449200 6279400 193.5
+385700 6255800 147
+446400 6271100 219.5
+369200 6243000 334.5
+442500 6274800 202.5
+343200 6260900 200
+414800 6233900 348
+372200 6248200 215
+443400 6248400 351.5
+376400 6269100 92.5
+341000 6264400 91
+456000 6254300 300
+395000 6254200 193.5
+408300 6208000 1582
+416800 6275800 148.5
+372800 6256000 163.5
+400800 6272800 146
+421500 6226900 1178
+395900 6252900 195
+420000 6277500 159
+399600 6253000 223.5
+432800 6238900 325.5
+434500 6241300 315
+418700 6261500 211.5
+387500 6248300 267
+435100 6226600 411.5
+413500 6272200 114
+378200 6265300 87
+431900 6244500 261
+447200 6267900 241.5
+414100 6268400 182.5
+442600 6259700 292.5
+404100 6261600 167
+338000 6276200 27.5
+384500 6229200 410.5
+410600 6269500 176.5
+445700 6260100 271.5
+387100 6265400 156.5
+436300 6271100 209
+446300 6258200 289.5
+331400 6275200 42.5
+393300 6257700 174.5
+428500 6246900 262
+396400 6250800 171.5
+398500 6239800 425.5
+399300 6245700 232
+421000 6231100 452
+435600 6237700 249.5
+429000 6236000 348
+408900 6239500 292.5
+403000 6250000 232.5
+359800 6240600 287.5
+365000 6263800 124.5
+444700 6241400 365
+455400 6262900 262
+418400 6232200 428.5
+438700 6230900 379.5
+399600 6234400 412.5
+385100 6229300 496
+406900 6210800 1530.5
+382600 6259000 122.5
+441100 6265200 250.5
+401200 6223600 998
+431600 6267400 197.5
+450100 6268600 238.5
+376900 6266100 82
+435100 6232300 1051.5
+420900 6227500 889.5
+441700 6247100 333.5
+444700 6274900 209
+415600 6254500 204.5
+407000 6261100 121.5
+400200 6244900 228.5
+355600 6254700 509.5
+393600 6253700 149
+355300 6264100 242.5
+428800 6275500 168.5
+416400 6263100 208.5
+438800 6281200 173
+347200 6250500 498
+397300 6228900 1303.5
+438100 6267600 253.5
+435400 6254900 291
+366700 6260500 165.5
+446700 6236800 412.5
+435700 6243000 313
+355600 6239400 395
+435800 6265700 230.5
+340200 6229000 771
+385400 6257100 145.5
+438700 6237800 357.5
+404900 6277700 85
+376800 6272500 72.5
+406300 6230600 729.5
+385500 6231800 501
+413200 6259500 117
+411300 6242100 304.5
+448500 6254800 325
+431100 6231000 375
+441000 6263000 271
+443800 6277000 191.5
+376400 6271200 25.5
+416800 6278300 116
+385700 6220400 1090.5
+444900 6249600 363.5
+433100 6273500 201
+351400 6232800 814
+360600 6251500 343
+371500 6266600 90
+418700 6236400 321.5
+415100 6271000 117
+451100 6266800 246.5
+404000 6273000 155
+429200 6258700 244.5
+408600 6247000 241.5
+420700 6251100 231.5
+376700 6269900 96
+384900 6251600 161
+399600 6269000 68.5
+455800 6263800 256
+436500 6256300 271.5
+359100 6260900 201.5
+383400 6234600 518
+387500 6251400 215.5
+388200 6259700 129.5
+452100 6251000 337
+319000 6262800 440
+384700 6245700 265
+382300 6271400 115
+424100 6275600 172.5
+367400 6237400 707.5
+440800 6244200 331
+426200 6273700 177
+427600 6271800 189.5
+437000 6234300 308.5
+427800 6247800 258.5
+326800 6269400 36.5
+379300 6239800 670
+433500 6265300 217.5
+424900 6249000 262
+380800 6263600 124.5
+427000 6278100 153.5
+431600 6256000 275
+372900 6275400 30
+414900 6266800 190
+349600 6247200 455
+430500 6265900 201
+389500 6260500 157
+379300 6278200 79
+339500 6270000 65.5
+346800 6256100 220
+437200 6263000 251
+449100 6248300 380
+359900 6273000 91.5
+362800 6235100 857.5
+373400 6274300 29
+429300 6263000 234.5
+444600 6253900 338.5
+389600 6275700 97.5
+401600 6243900 202
+328200 6270600 40
+415600 6257800 195.5
+321800 6265200 41.5
+433200 6261000 252
+446500 6255400 305
+331500 6269800 49.5
+396600 6231800 420
+405700 6242000 263
+386500 6227500 825.5
+441800 6269500 235.5
+382900 6228100 652.5
+371800 6258000 100
+386000 6246100 203.5
+429000 6269900 196
+384100 6243900 327
+382800 6240200 362.5
+361100 6236900 497.5
+351900 6247500 496.5
+362200 6242900 370.5
+450100 6261100 283.5
+437800 6239700 330
+356500 6235500 797
+432000 6258800 268
+431100 6249000 219.5
+443800 6234300 397.5
+421900 6261600 164
+451600 6262800 271
+358900 6238600 335.5
+443500 6269900 223
+435300 6249600 250.5
+379900 6235800 737.5
+373700 6256900 90.5
+451900 6271800 215
+407400 6235200 248.5
+358400 6231900 783
+384800 6257800 135.5
+447300 6264500 256
+382000 6232000 608.5
+426700 6266700 216.5
+430100 6247600 211.5
+437400 6240800 325.5
+344000 6235100 753
+339300 6259200 391
+363800 6257000 183.5
+367100 6242100 461.5
+384500 6233700 494
+401800 6229400 743
+353400 6238000 711.5
+435700 6252900 297
+434700 6236700 323
+393000 6261400 164.5
+412400 6237900 343.5
+374700 6255500 149.5
+384400 6232200 309
+427100 6231400 407
+389000 6229500 519.5
+445700 6252800 334
+393300 6239500 484.5
+367200 6245700 377.5
+403100 6210700 1436.5
+334400 6275500 38
+398000 6250700 206
+384200 6258600 125
+368700 6259700 167.5
+420800 6229000 878
+422800 6228500 482.5
+417100 6232800 382.5
+440700 6259000 297.5
+427900 6248900 203.5
+438000 6250400 306
+411200 6238700 315.5
+404400 6215100 1460
+412000 6236400 288.5
+452500 6256100 302.5
+373500 6250500 182
+377200 6268000 99.5
+424700 6242500 332
+432200 6277100 190
+356200 6249000 494
+331100 6261500 118.5
+349300 6272000 67.5
+421000 6271200 185
+401300 6257800 195
+408100 6207700 1409
+455700 6257300 286
+339000 6265800 71.5
+410800 6259100 111.5
+325300 6260600 444
+410600 6261900 118.5
+340200 6262500 65
+400800 6267100 132
+390400 6251300 197.5
+412400 6253900 193.5
+349900 6257900 502.5
+344800 6274700 48
+402900 6241800 250.5
+390400 6258700 145.5
+439500 6230900 415.5
+425500 6271100 189.5
+388100 6274700 100.5
+367300 6264200 100
+442600 6280800 180
+339300 6274300 73
+395700 6279500 113.5
+374200 6252000 149.5
+407300 6278100 110
+406400 6241100 272
+395000 6272700 111.5
+358900 6246300 367.5
+430500 6272600 174
+442500 6241700 363.5
+388600 6267400 139
+438100 6239100 333
+439000 6278900 182.5
+391300 6257800 143
+408500 6259100 128
+394400 6252500 190.5
+432900 6268800 203
+383400 6264800 151
+341600 6262900 80
+399000 6246100 234
+358700 6257900 291.5
+409500 6267100 177.5
+448200 6266100 248.5
+429000 6267100 203
+322500 6265700 42
+430300 6244700 285.5
+452900 6252900 320.5
+387700 6240000 379
+435800 6258700 261.5
+393900 6246400 200.5
+424300 6250700 182
+382200 6254400 160
+443600 6265600 246.5
+439200 6246200 333.5
+451600 6259700 281.5
+406300 6217900 969.5
+419100 6273700 165
+382500 6242200 308.5
+421300 6267400 193
+409600 6253400 233
+387900 6261200 149
+364800 6234200 783
+434900 6261900 239
+315400 6259800 276
+353000 6275500 55.5
+373000 6260800 89.5
+384300 6262100 99
+411100 6257500 179
+426700 6240300 327.5
+400700 6248100 209.5
+409700 6276700 123.5
+374500 6272100 30
+396700 6267800 142
+418000 6262900 201.5
+452600 6269800 231
+421500 6274200 168
+421500 6224900 1219.5
+385100 6276800 90
+451000 6258500 298.5
+381300 6255100 156.5
+337100 6259500 201.5
+390700 6260000 148
+351000 6239500 713.5
+368900 6254500 190
+355400 6238700 238
+416500 6270900 125
+375700 6260600 125.5
+409300 6203600 1543.5
+385500 6252700 134.5
+363200 6242400 419
+364000 6278300 29
+406700 6257300 188.5
+372100 6268900 77
+419700 6247200 278
+431300 6242100 291
+435200 6239500 241.5
+456300 6241700 362.5
+504600 6247400 341
+483800 6228900 542.5
+475800 6229200 410
+469100 6221400 791.5
+484000 6239100 409
+469600 6247300 293
+463700 6252100 244.5
+463700 6250900 252.5
+456300 6223500 680
+483000 6222200 556.5
+476500 6221700 579
+492600 6220700 555.5
+457700 6228600 493.5
+456900 6271400 218.5
+481400 6226200 511
+468900 6234600 413.5
+481800 6194700 1447
+473200 6228800 458
+444800 6215300 1398.5
+478000 6249000 305.5
+487900 6206300 1321
+469100 6249000 296.5
+476200 6219900 1030.5
+475300 6240500 363
+449200 6215200 530
+460100 6267700 224.5
+456000 6219300 1447.5
+501500 6213500 789.5
+464400 6270500 203
+472500 6222200 670
+457800 6269000 227.5
+490200 6242200 311
+483400 6202500 1161.5
+480200 6247800 318.5
+486200 6202300 929.5
+495200 6216100 1002.5
+479800 6234100 451
+489400 6203100 1486.5
+458800 6273000 157.5
+487500 6194500 1623.5
+466000 6263600 197
+488100 6242900 376
+459400 6256700 278.5
+458400 6265300 242
+464000 6246300 278.5
+460100 6262800 195.5
+477800 6255500 294.5
+468200 6244700 360
+453100 6265300 251
+483200 6193800 2037.5
+459700 6252700 291
+453600 6203700 1434
+489600 6232700 504
+503300 6215900 604.5
+445400 6218600 705.5
+458000 6238100 373
+478800 6227800 435.5
+471600 6254900 242.5
+456500 6226100 457.5
+474900 6254200 282
+464800 6254900 230.5
+493900 6219200 809.5
+491100 6230300 527.5
+464800 6234000 415
+472900 6223900 559
+467400 6233600 448.5
+456100 6225000 527
+484900 6235100 454
+479800 6220000 548
+465200 6231600 482.5
+501400 6209700 1080.5
+471300 6233100 403.5
+484100 6204300 1207
+461500 6250800 253.5
+464700 6253400 239
+459600 6251400 293
+476100 6243800 250
+455700 6247500 333.5
+452400 6205500 1414.5
+485900 6203700 1402.5
+466600 6241100 367
+503700 6212700 795
+472300 6253000 252.5
+457200 6220900 1046.5
+466500 6265700 219
+449500 6220200 875.5
+468600 6264700 208
+491000 6220100 632
+494400 6216400 1186.5
+501500 6243300 352.5
+455500 6221800 670
+470400 6242100 349
+451500 6222900 772.5
+433800 6217700 1150.5
+455700 6224100 672.5
+494500 6245900 335.5
+446200 6217600 761
+464200 6230600 494
+446700 6245500 377.5
+463000 6233500 410.5
+440300 6209400 1933
+452800 6277300 197.5
+496700 6223500 503
+503300 6210400 1053.5
+442300 6213500 1009
+486500 6231600 525
+440800 6214300 1175.5
+502100 6214500 764
+448800 6213200 488
+484600 6232600 499
+463200 6236500 357.5
+495700 6238100 433
+470100 6243000 336
+457400 6202600 1876.5
+502500 6211600 785.5
+500800 6244500 349.5
+464800 6240800 373
+489300 6222000 592
+459000 6231200 453.5
+458900 6225900 546
+482800 6248100 317
+500400 6206400 1334
+464100 6235900 362
+473100 6225000 459.5
+449900 6216600 649
+488500 6223800 566.5
+468200 6235800 425
+452200 6222000 555
+459500 6247600 317.5
+486800 6223500 587
+484100 6218800 666
+482200 6195800 1028.5
+460100 6204200 2078.5
+455900 6202100 1379.5
+481500 6218400 1181.5
+479800 6225800 500.5
+474500 6220100 806.5
+480700 6224600 508.5
+482400 6200800 1788.5
+480400 6195400 1663.5
+479900 6254400 309
+502000 6211700 1030
+469400 6250200 285
+455500 6239000 394
+469500 6229200 480.5
+494600 6221400 531
+449100 6211700 576.5
+484900 6204500 848.5
+459900 6270900 163.5
+442100 6214500 1119
+482600 6194600 1067.5
+452400 6222800 477.5
+463800 6252600 240
+484100 6197700 1364
+470400 6234000 396
+482200 6199700 1205
+477300 6230100 404
+452700 6203000 1802.5
+484700 6202000 1141.5
+493400 6235400 479
+468400 6251200 281.5
+480300 6245900 354
+449300 6223800 978.5
+470200 6245100 326
+450300 6254500 318.5
+469800 6238700 337.5
+475200 6249000 268.5
+455900 6192000 2049.5
+483600 6244800 340
+463300 6235300 378
+503100 6244000 354
+474400 6237700 350.5
+459100 6261300 254.5
+502500 6209500 1082.5
+482700 6207300 1249
+463900 6263600 195.5
+468800 6255000 259
+457900 6203200 1900
+473100 6232100 390
+454500 6202000 892.5
+467200 6253200 234.5
+476300 6255100 263
+489300 6239200 405.5
+481900 6246100 353.5
+492900 6243300 379
+472000 6252000 260
+448000 6212400 916
+479900 6252100 325
+449200 6231000 466
+492500 6232300 491
+487000 6200400 1491.5
+502700 6213600 570.5
+457100 6234000 400
+449000 6224500 771
+464100 6242600 334.5
+458700 6223900 682.5
+470300 6232300 451
+483300 6200300 966
+461400 6225900 562
+456200 6229300 523
+480200 6194500 1379
+476100 6239800 360
+477600 6226500 410
+482600 6229300 513.5
+487000 6228500 544.5
+465200 6233300 460.5
+458200 6227500 462.5
+452800 6281900 180.5
+467700 6247100 325.5
+456300 6231100 506.5
+449300 6218100 499
+501800 6215300 779
+486300 6210700 1077
+475000 6222000 575.5
+506500 6209200 977
+482200 6193300 1665
+451200 6206000 1329.5
+492800 6250500 262
+446500 6214800 1406
+467200 6258000 217
+453800 6236300 443.5
+463600 6249500 260.5
+478800 6198400 1952
+465000 6261600 205
+491500 6238600 461.5
+500900 6242600 390.5
+450300 6210900 1470.5
+477300 6231500 412.5
+451900 6229700 507
+461100 6231000 478.5
+478100 6223400 468.5
+499700 6219700 599
+448500 6251900 338
+485900 6211000 1245
+479400 6218400 513
+473700 6239400 310
+460100 6221400 1027
+487900 6197100 1283.5
+484400 6242600 375.5
+488300 6194100 997
+455100 6273500 214
+462800 6255600 230
+500900 6208100 1144.5
+431900 6216600 1517.5
+497900 6222000 608.5
+505800 6211100 468.5
+478100 6192400 1924
+481100 6230000 453
+447200 6216400 506
+460100 6224400 628.5
+469200 6232000 450
+475300 6223600 464
+476800 6225100 452.5
+454400 6224900 649.5
+479000 6221800 510.5
+481200 6196000 1751.5
+481600 6231000 488.5
+486300 6219500 677
+455200 6272200 219.5
+450500 6217500 1040.5
+461400 6228900 492.5
+453300 6186100 2250
+501100 6212900 1085
+459200 6249700 309.5
+497600 6247100 317
+475100 6245300 260
+449000 6256800 310.5
+472800 6244100 279.5
+479700 6256300 275.5
+455800 6227300 505.5
+484000 6249300 311
+469100 6218500 1436.5
+487300 6193500 1980.5
+502700 6214500 611
+502800 6245800 349
+460700 6237400 353
+447700 6213900 876.5
+503800 6213800 707
+487500 6196200 1294
+485600 6216600 1233.5
+482200 6204700 1237.5
+493400 6222100 500
+458000 6232800 416
+486600 6250500 292
+475200 6242100 314.5
+477600 6233600 398
+485700 6246700 302
+463900 6232900 453.5
+481800 6243600 388
+491200 6227400 567.5
+460300 6244500 325.5
+478400 6218300 561.5
+464100 6238300 338.5
+483600 6196800 1205
+489100 6249700 302.5
+447500 6247100 375
+476700 6234300 397
+466300 6227400 538.5
+497000 6220700 527
+491700 6226000 567
+466100 6228500 505
+455300 6274900 207.5
+460100 6274300 187
+481000 6250000 340
+456700 6221400 697
+451300 6213200 992
+489100 6235700 445
+456000 6251500 312
+452100 6203600 1671.5
+469100 6258400 235.5
+504200 6215900 595
+462200 6241500 305
+498800 6209100 1394.5
+482500 6235900 446
+460100 6250000 258.5
+495600 6245000 375
+457600 6277300 192.5
+462700 6247800 270
+457000 6257800 269
+486500 6236100 449.5
+477700 6251800 313
+500500 6248800 331.5
+484100 6250800 326
+476100 6250300 290.5
+449000 6211100 712.5
+471700 6249400 285
+488900 6193400 1536
+465000 6252200 244
+457600 6235200 388.5
+467600 6243300 351.5
+504700 6216900 449.5
+493400 6246300 312
+461100 6258500 257.5
+493600 6245100 371.5
+495600 6240000 409
+469500 6240100 328
+446100 6227800 436.5
+468300 6236900 350.5
+466600 6225000 619.5
+464500 6229300 510.5
+453400 6222500 620.5
+471800 6225300 479
+446600 6219500 942.5
+475700 6245300 318
+486100 6221700 667.5
+505100 6210800 743
+467200 6263700 237.5
+469800 6217200 1688
+482600 6232300 460
+489200 6191600 1921.5
+450200 6213400 1535.5
+472100 6237900 318.5
+485600 6208600 1122.5
+479900 6240800 381.5
+488000 6192000 2043
+473500 6241100 287.5
+485200 6207100 1052.5
+491600 6241000 397.5
+469800 6240700 330.5
+481000 6239000 405
+462000 6238600 333
+495300 6240500 405
+463000 6265400 209.5
+501000 6239100 422
+476000 6237500 366
+482400 6254200 308.5
+469100 6252700 270
+499500 6245100 333.5
+497100 6235000 489
+487700 6246400 324.5
+459000 6229900 484
+478300 6246600 342
+461500 6224200 667
+494800 6223100 520.5
+457700 6232000 464.5
+455300 6280400 188.5
+463100 6260300 206.5
+453000 6221000 1012
+453100 6204000 1493
+450600 6215800 1174.5
+447700 6215600 496
+447500 6218800 629
+476000 6235600 380
+483200 6198800 1129.5
+448400 6232900 449
+488400 6194600 1045.5
+467600 6245300 339
+446700 6235900 436.5
+473000 6242300 280.5
+470800 6256900 254.5
+477500 6243400 327.5
+485500 6253000 294.5
+450100 6223900 924
+462000 6254300 238
+455300 6201900 1353.5
+469900 6225700 537.5
+487100 6244200 344.5
+465500 6226800 614.5
+499800 6222200 482.5
+443100 6213600 855
+491400 6223100 527
+484200 6199800 1269.5
+474000 6249100 258
+488900 6195800 1540.5
+489400 6218700 864
+473700 6191700 2075
+496500 6221500 677
+467700 6222500 1656
+453600 6230800 482.5
+485700 6210100 1279.5
+488100 6219600 667.5
+451700 6224300 496
+437600 6211600 1932
+500300 6209700 1067.5
+479500 6221600 505.5
+473900 6220900 647
+498200 6217900 863.5
+469800 6236400 358
+489500 6194200 1610.5
+454000 6249300 330
+478100 6219400 609
+474200 6222800 557
+457500 6225800 559
+465900 6235100 435.5
+468900 6225700 544
+478600 6225500 411.5
+480800 6194400 1939
+463300 6222000 857.5
+445500 6219300 1199
+487900 6218400 875.5
+483200 6197800 1143.5
+466700 6261200 207.5
+451900 6226500 651.5
+454400 6221300 739
+456600 6202700 1588.5
+445500 6203900 1901.5
+455600 6266500 238
+451300 6220400 582.5
+454100 6219800 980
+505600 6214100 668
+480200 6244100 393
+502000 6213100 541
+439400 6213500 1302
+491100 6244700 291
+473900 6250700 242
+496300 6249000 321
+504400 6249000 333
+493800 6237400 450.5
+466300 6248100 266
+471500 6223900 579.5
+497800 6249900 322.5
+496100 6243400 381.5
+494900 6241700 403
+498400 6242300 401
+466200 6246500 312
+449400 6229400 483.5
+475000 6252100 247
+469100 6219900 1191
+491500 6222200 573.5
+453300 6202300 749
+465900 6268200 198.5
+454500 6201600 1935.5
+487300 6202100 1262
+465800 6237100 403
+475500 6230300 385
+467700 6248300 293.5
+472300 6246900 291.5
+494700 6248200 293
+442700 6227700 917.5
+455300 6226800 500
+458700 6234000 397.5
+486400 6218700 847
+469300 6238000 372
+671600 6185500 249.5
+652000 6185800 898
+695300 6175700 26.5
+649700 6161200 1659.5
+649800 6172700 795
+627700 6158900 1871
+686700 6154000 235.5
+683900 6177100 81.5
+694500 6181300 14.5
+620400 6143500 2000
+661600 6170000 450
+668200 6182400 330
+617900 6149000 1618
+697300 6187200 5.5
+700500 6168700 14.5
+636100 6158600 1673
+632800 6165500 1615
+660600 6182400 478
+699300 6174200 9
+647500 6159400 1340.5
+675000 6176900 294.5
+631100 6163400 1830.5
+649100 6163200 610
+682900 6156800 139.5
+675600 6168900 277.5
+657800 6173900 633.5
+610600 6151700 1879
+659000 6176900 608.5
+656500 6187500 455
+688700 6151600 421.5
+677200 6176400 103
+661400 6186800 397.5
+659500 6190200 568
+681200 6177300 152.5
+648000 6165500 892.5
+669100 6172200 374
+617200 6147700 1542
+664300 6148800 958
+682600 6186700 199
+668900 6174600 278
+648900 6190500 639.5
+673200 6161400 520
+687000 6179300 62
+617400 6152800 1429.5
+627100 6156100 1491.5
+666200 6160900 1162.5
+702000 6160700 549.5
+628900 6170500 1859.5
+684400 6154500 699
+669800 6158300 850
+642900 6153300 2034.5
+655600 6179100 767.5
+668800 6159800 868.5
+647100 6168400 1073.5
+630100 6157300 1565
+646500 6155300 1661
+678900 6161100 342.5
+687800 6183900 66
+675000 6160500 395.5
+668200 6164500 791
+639900 6162000 1462
+669800 6150800 764
+698500 6171100 10.5
+684400 6183400 181.5
+657700 6184800 393.5
+691500 6167300 52.5
+649300 6188300 790.5
+658800 6168700 513.5
+689100 6170900 53.5
+652100 6168000 513.5
+627700 6172300 1857
+686000 6162600 122
+697600 6166700 32.5
+696400 6159000 646
+612600 6154500 2079.5
+616000 6146800 1689.5
+657000 6145000 1634
+624400 6153100 2148.5
+686400 6172500 79
+650000 6181500 1064.5
+708600 6157600 327.5
+696000 6172700 18.5
+699200 6186000 3.5
+678600 6175800 88.5
+654300 6181100 807
+660300 6184700 369
+668100 6142900 843.5
+693400 6192600 177
+624100 6156400 1788.5
+672700 6177200 202.5
+660400 6140100 1110.5
+684500 6164300 144.5
+665300 6152000 1533
+655800 6169300 430.5
+657800 6171500 406
+664000 6185300 349.5
+685400 6177900 64.5
+608500 6152300 1644.5
+676000 6152900 786
+651400 6162500 1468
+654200 6165200 1130
+642100 6163700 1366.5
+663400 6165700 834
+627600 6165600 1768
+696400 6184500 12.5
+669100 6162500 608
+689700 6185500 40.5
+689100 6162900 82.5
+673400 6173200 212.5
+655800 6182900 656.5
+679800 6184400 192
+696100 6170900 20
+613000 6148800 1182.5
+696800 6163700 27.5
+667800 6179800 341.5
+629200 6155100 2011
+652600 6170600 529.5
+603900 6161700 2192
+642900 6171300 1242.5
+713600 6149300 321.5
+693800 6164500 54.5
+620300 6149400 2104.5
+689000 6164600 84.5
+650100 6159200 1709
+710500 6153600 482.5
+679600 6162300 264.5
+612500 6151900 1347.5
+626200 6168700 2118
+698700 6180900 10
+661300 6171800 281.5
+657500 6182200 501.5
+646500 6174500 1508.5
+689700 6196700 404.5
+647600 6162700 800.5
+684300 6168000 105
+671600 6153900 781.5
+650700 6167800 710
+613800 6153700 2060.5
+627400 6155400 2035
+680000 6170300 160.5
+622900 6151000 2079.5
+667900 6185200 326
+603400 6159200 2116
+679500 6154300 773.5
+633000 6164000 1375
+644200 6163400 1120.5
+686000 6158200 209
+648800 6172500 738.5
+661000 6168800 606
+661500 6189200 408
+690300 6157500 522
+662400 6145700 1570.5
+693500 6182800 18
+664800 6181800 447
+674000 6164800 486.5
+693600 6160200 63
+692100 6163000 67.5
+668800 6185300 260
+700600 6178500 18.5
+640400 6159600 1650.5
+655200 6185900 680
+664000 6173200 471.5
+638300 6159900 1320.5
+661500 6178900 573
+679300 6168400 227.5
+702900 6187600 2
+632100 6167300 1807
+666100 6172300 386
+661700 6160000 1706
+653600 6191800 590.5
+657800 6166900 1408.5
+632500 6157200 1872.5
+691300 6153700 691
+660900 6162900 1094
+625800 6171100 1992.5
+701400 6180900 5
+617400 6156000 1753
+619000 6156100 1641
+620900 6151600 1695
+699500 6183900 4
+681200 6167700 165.5
+666700 6190300 480
+677400 6164000 306
+693200 6170800 39
+663400 6144300 942.5
+671100 6140900 765.5
+684800 6169700 93.5
+643700 6160000 1335
+677900 6177600 277
+673600 6183300 294.5
+694600 6167600 28
+652900 6164700 1619
+652500 6168800 522.5
+686500 6186400 242
+683000 6175800 67.5
+620500 6155800 1762
+655400 6171700 693.5
+641600 6169500 1608.5
+692100 6158400 533
+640700 6161400 841.5
+681900 6164700 141.5
+686800 6165400 89
+706600 6158400 327.5
+627600 6156900 1562
+679200 6190600 315.5
+697800 6161300 45
+681000 6169100 114
+694400 6158100 638
+663900 6177500 470.5
+614800 6146700 1677
+700200 6167400 16.5
+681900 6194300 347
+623900 6164700 2169.5
+668300 6168600 450
+673000 6158600 439.5
+675800 6172400 319
+696000 6169400 18.5
+672100 6172600 326.5
+675300 6185900 191.5
+680600 6158800 218.5
+686200 6174600 66
+691400 6177600 51.5
+659900 6168600 706.5
+638600 6162500 1354.5
+653400 6187800 571
+673000 6152900 800
+1008900 6882800 295.5
+1027000 6825300 447.5
+1047400 6837200 141.5
+1071400 6875900 123
+1047100 6848500 160.5
+1044600 6860900 169
+1027600 6846700 287.5
+1001800 6870000 298.5
+1067700 6882800 158.5
+1050300 6888900 364
+1030800 6818700 188.5
+1061500 6857000 126
+1011800 6819900 810
+1040800 6856900 200
+1020700 6850100 314
+1069800 6879200 156
+1066600 6864300 121.5
+1029400 6849500 305
+1045500 6829900 148
+1049600 6815700 155
+1039100 6850200 173
+1028000 6828900 621.5
+1045300 6826700 150.5
+1024000 6845800 454.5
+1033800 6825900 167
+1042000 6820500 156
+1010100 6871000 328.5
+1017800 6879100 316
+1067200 6866800 119
+1032200 6849300 276.5
+1045000 6867100 194
+1022900 6850100 293.5
+1038800 6872000 201
+1040200 6846700 165.5
+1032800 6863200 198
+1041400 6819100 157.5
+1053900 6861300 147
+1062700 6878400 149.5
+1038400 6808500 164
+1039000 6816300 159
+1032200 6864300 202
+1043900 6846900 163
+1024500 6816400 472.5
+1010100 6820300 585
+1001500 6864700 303.5
+1022300 6852300 277.5
+1034200 6834300 174
+1015900 6811900 559.5
+1074200 6878100 136
+1044400 6858900 146.5
+1018600 6875400 305
+1041000 6801600 170
+1026300 6855600 223
+1024800 6836900 472.5
+1031900 6854800 215.5
+1031100 6834400 272.5
+1028200 6878300 303
+1044800 6801600 168
+1019100 6854800 391
+1040200 6859600 202.5
+1014500 6830200 557.5
+996600 6879500 229
+1036900 6834700 167.5
+1049400 6876800 166.5
+1031400 6836400 268
+1036300 6878700 290.5
+1030800 6842800 210
+1037300 6843400 193
+1009600 6821600 530
+1023900 6835400 305.5
+1063800 6862700 123.5
+1026900 6818700 500
+1042600 6892000 332
+1031000 6845300 270
+1021200 6811900 285
+1027100 6840700 329.5
+1029100 6821300 573.5
+1029400 6839500 278
+1036800 6802700 168.5
+1038600 6843600 182
+1020600 6810300 396.5
+1059700 6890800 215
+1045700 6841200 146.5
+1042700 6803000 167
+1006300 6873300 299.5
+1061900 6881300 162
+1030400 6821600 205
+995900 6882200 242
+1012500 6827900 599.5
+1040800 6823100 154.5
+1038300 6874900 229
+991500 6877400 240.5
+1031200 6827400 364
+1016500 6833000 623.5
+1011500 6827900 604
+1011200 6870300 300
+1037200 6858800 203
+1027500 6807700 350
+1077400 6882600 139
+1017700 6814200 441.5
+1032700 6875400 212
+1036400 6813800 162.5
+1016100 6876600 321.5
+1069000 6884800 163
+1020600 6857900 320
+1024800 6853100 235.5
+1038200 6870400 200
+1044200 6861800 183.5
+1006600 6821200 636.5
+999400 6878900 273.5
+1008200 6868700 313.5
+1043200 6827400 151
+1057600 6889300 340.5
+1045500 6828700 148.5
+1039900 6882200 378.5
+1036400 6857500 214
+1054600 6884600 232.5
+1064800 6878400 146
+999700 6867600 284.5
+1029500 6850000 240
+1011400 6877200 309.5
+1023200 6865100 298.5
+1029100 6822900 414.5
+1024500 6847400 348.5
+1008800 6877900 299.5
+1037400 6856100 218
+1028900 6867700 249.5
+1012900 6871900 320
+1035800 6854300 229.5
+1043900 6848300 162
+1040500 6855500 206
+1005800 6877600 285
+1064900 6882000 157.5
+1014400 6823800 696
+1012700 6864600 281
+1030000 6831200 503
+1045200 6865000 189.5
+1034400 6866000 233
+1044400 6891400 361
+1018000 6811600 495
+1029100 6862100 217
+1071300 6887200 157
+1026200 6857200 198
+1034500 6853600 207
+1059200 6854700 128.5
+1045700 6809200 162.5
+1057300 6852700 128.5
+1042000 6850100 166.5
+1017300 6812400 445.5
+1020500 6877800 306.5
+998600 6887100 242.5
+1043500 6821500 154
+1055100 6878600 181
+1036800 6847300 177.5
+1001300 6874600 293
+1050000 6842000 141.5
+1031700 6872900 207
+1015700 6814400 552.5
+1045900 6849300 160.5
+1037600 6794600 177
+1057300 6882000 322.5
+1048000 6862900 177.5
+1025600 6872600 272.5
+1034300 6846700 184.5
+1042600 6855600 169
+1039900 6817700 158.5
+1032100 6846800 286
+1053300 6881800 176
+1054800 6865400 138.5
+1032800 6877400 301.5
+1056800 6862800 135
+1059400 6877700 162
+1002900 6871300 313.5
+1026700 6839300 241
+1032300 6857800 193
+1060400 6861800 124.5
+1065000 6886000 166
+1034600 6867400 237
+1023800 6831900 411
+1045700 6881900 225
+1027400 6852100 242.5
+1056400 6884400 188
+1072700 6874600 116
+1076900 6881300 124
+1040600 6865700 229
+1066700 6880200 151.5
+1057100 6864800 131.5
+1010800 6867200 297
+994600 6878900 235.5
+1053300 6859600 152.5
+1039200 6877200 219
+1064100 6870300 127
+1024800 6863600 203.5
+1031800 6876900 280
+1032400 6818300 172
+1013700 6876200 303
+1041500 6869000 211.5
+1013800 6815100 668.5
+1046900 6851200 156
+1017300 6832600 424
+1039200 6840900 182
+1033100 6861200 201
+1030000 6857000 213
+1051500 6857200 150.5
+1020100 6853500 267.5
+1068900 6888300 161
+1031600 6830200 255.5
+1049100 6829300 147.5
+1038000 6818700 157
+1062200 6888400 181.5
+1046700 6813800 158
+1070700 6872300 116
+1073500 6879700 143.5
+1061200 6886200 175.5
+1039600 6802300 169
+1052500 6883900 334
+1006400 6814200 636.5
+1038300 6845000 166
+1019900 6860600 309
+1028600 6819900 263.5
+1034200 6849400 228.5
+1028200 6855900 220.5
+1021800 6859400 200
+1043000 6834000 147
+1026900 6852600 237.5
+1034800 6796600 175
+1075200 6885000 148
+1042000 6856500 166
+995800 6877800 245
+1022300 6811300 266
+1047100 6817000 156.5
+1040300 6838700 178
+1039200 6847700 168
+1027600 6850400 245
+1039300 6856100 231.5
+1050100 6845400 141
+1027300 6854000 235
+1006700 6883800 295.5
+1038400 6838800 181.5
+1035800 6826200 156
+1027800 6832000 302
+1027300 6842800 357.5
+1007600 6873900 293
+1031100 6865500 208.5
+1038600 6888100 391
+1075800 6887700 146.5
+1007900 6875400 268.5
+1031200 6842000 244
+999000 6892500 243.5
+1042200 6836100 151.5
+1010400 6881200 310.5
+1004100 6880300 280
+1046000 6875000 197
+1034800 6863100 194
+1014400 6875900 318.5
+1059600 6883600 169
+1042900 6868000 195.5
+1049100 6883000 313.5
+996500 6872000 253
+1029100 6842100 219.5
+1028200 6859700 190
+1020300 6812900 393
+1046900 6868100 158.5
+1047500 6881400 201
+1028700 6840000 225
+1037600 6831500 165
+1015300 6865500 289.5
+1045400 6852600 161
+1019400 6836600 609
+1047200 6874200 186.5
+1015100 6831700 611
+1021900 6856100 214
+1012200 6823600 620
+1048400 6879900 202
+1049900 6844600 142.5
+1047400 6876000 187
+1073700 6882600 156.5
+1016800 6871000 306
+1038100 6868200 251.5
+1032000 6838500 263
+998300 6865700 283.5
+1069400 6874000 120
+1025900 6849000 271.5
+1003100 6881500 269.5
+1048400 6812500 160.5
+1018700 6813500 361.5
+1029200 6870100 220
+999800 6862900 292
+1005000 6869600 305.5
+1002200 6877800 288.5
+1041700 6880600 235.5
+1037100 6872300 197
+1012900 6811200 643
+1049500 6857600 160.5
+1023600 6870500 304.5
+1013100 6867700 286.5
+1029800 6857900 195.5
+1051000 6875800 161.5
+1054600 6890600 384.5
+1048900 6878900 187
+1049100 6847700 143
+1051300 6877200 155.5
+1042300 6838800 148
+1037900 6799600 173.5
+1044500 6831400 148
+1046100 6811300 160.5
+1045200 6844300 165
+1057100 6883300 172.5
+1039500 6799600 171
+1035800 6860800 188.5
+1036900 6852900 229.5
+1039400 6863900 207.5
+1042200 6854600 174.5
+1033000 6870100 211
+1070800 6881500 164.5
+998700 6872100 288.5
+1055500 6881300 181
+1051900 6854700 133.5
+1028700 6818500 235
+1041200 6860900 169
+1020300 6835800 293.5
+1042600 6887400 356
+1047900 6835300 142.5
+1078500 6887500 116.5
+1069300 6870500 117
+1023000 6867100 301
+1028000 6816300 253.5
+1030400 6804800 174.5
+1035300 6798600 173.5
+1038600 6867600 254
+1007300 6829500 695
+1024900 6850200 277.5
+1034200 6838600 164.5
+1036300 6849300 215.5
+1011700 6828100 564.5
+1061700 6883900 172.5
+1042700 6828800 151
+1047400 6877100 198.5
+1041900 6814300 160
+1043100 6872700 179.5
+1048000 6819500 153
+1024000 6877100 305
+1031500 6824100 196
+1016400 6811500 561.5
+1031900 6850700 257
+1037100 6814700 160
+1035200 6810800 164
+1044000 6842000 156.5
+1036300 6806100 166
+1032200 6860300 197
+992200 6879900 231.5
+1043900 6854300 167.5
+1040000 6822200 156
+1030400 6815800 235.5
+1067400 6869300 118.5
+1009400 6818200 576
+1011600 6821000 694.5
+1021700 6863600 297.5
+1050200 6846500 142
+1045700 6845100 168
+1039500 6820600 156
+1043400 6863300 194.5
+1026600 6836000 262.5
+1007300 6871200 300
+1019200 6833900 562
+1017700 6815800 688.5
+1026300 6870500 217
+1030900 6839500 262.5
+1041800 6824200 154
+1044700 6823700 152
+1035800 6841500 193
+1009400 6872800 296.5
+1039100 6796900 173.5
+1038700 6801800 170.5
+1041500 6804400 166
+1026900 6835300 257
+1019200 6830100 715
+1024200 6861200 200
+1027200 6813700 300
+1033800 6839500 209
+1028300 6853700 220.5
+1047500 6861300 177.5
+1034000 6864500 207.5
+1068700 6873100 116.5
+1039300 6870500 209.5
+1031200 6859300 186.5
+1027500 6810200 355.5
+1068200 6872000 127
+1042100 6863500 194
+1026400 6805900 352
+1011400 6875600 290
+1011900 6874400 307.5
+1020300 6820300 770.5
+1034700 6868800 219.5
+1071200 6867600 117.5
+1032400 6822700 190
+1027000 6879500 314
+1026200 6804000 348.5
+1049900 6880900 202
+1048300 6831300 145
+1046100 6858300 162.5
+1002000 6885600 265.5
+1045400 6876700 210
+1061300 6867500 128.5
+1032500 6866600 228
+1051900 6891400 386.5
+1037300 6864600 216
+1029900 6826300 247
+1051000 6861300 165
+1030700 6863600 224
+1068400 6882100 164
+1055400 6850600 131.5
+1031300 6843800 206
+1030100 6850700 231.5
+1045600 6831400 145.5
+1035400 6857700 186
+1019600 6812000 448.5
+1037300 6881100 357
+1040300 6805800 166.5
+1053200 6857000 141
+1028200 6873000 278
+1041700 6811500 161
+1029900 6871600 205
+1033100 6847700 265.5
+1018900 6849500 337.5
+1049900 6848900 141
+1046500 6884500 294
+1060700 6859000 125.5
+1014700 6880500 328
+1019800 6848700 345
+1033500 6855300 212.5
+1024200 6851800 281
+1051400 6868000 159
+1036100 6852300 226.5
+1038200 6871000 185.5
+1019700 6859300 306
+1033000 6865700 215.5
+1017700 6850400 432
+1020400 6861100 311
+1025200 6802500 443
+1040300 6832800 172
+1036000 6844300 196
+1036800 6846000 174.5
+1027600 6870300 210.5
+1060500 6890200 207.5
+1001700 6867500 288
+1036700 6839000 180
+1042600 6841800 161.5
+1007900 6819600 532.5
+1010800 6816500 744.5
+1022700 6812600 383.5
+1029000 6844600 288
+1043700 6847400 167
+1013200 6820600 825
+1042700 6852200 214
+1013400 6823800 722.5
+1022100 6848400 312.5
+1006400 6875000 256
+1046500 6846300 166
+1028600 6835800 288.5
+1060100 6866900 129.5
+1041700 6808100 163.5
+1035500 6801600 170.5
+1005700 6818200 616
+1039000 6835200 163.5
+1033700 6874400 207.5
+1006600 6879400 275.5
+1004100 6813200 674
+999100 6876900 276.5
+1017100 6844800 624
+1041100 6841200 167
+1033500 6809800 166.5
+1057200 6884900 192
+1034600 6832200 173.5
+1005600 6880600 275.5
+1041600 6877400 212
+1041100 6875900 207
+1019100 6807100 513.5
+1040200 6874200 209.5
+1032800 6839300 218
+1020200 6872900 304.5
+1038100 6860600 198
+1064300 6880500 155.5
+1004600 6874400 299.5
+1003700 6875800 299
+1027200 6814900 293
+1073100 6870300 116.5
+1039500 6867700 248
+1066000 6866800 120
+1011000 6825500 504.5
+1036300 6866700 233.5
+1027000 6826700 641
+1004800 6872600 330.5
+1045400 6838800 144.5
+1021700 6849700 289
+1032700 6820300 169.5
+1045500 6864000 183.5
+1073300 6886800 156.5
+1029800 6854500 228.5
+1020700 6855600 215.5
+1024500 6855000 228
+1034300 6823000 159.5
+1046400 6861100 178.5
+1043300 6864900 196.5
+1021600 6809500 537
+1025800 6816800 403.5
+1067700 6868500 118.5
+1028200 6851600 240.5
+1035600 6873900 219
+1034300 6794100 178.5
+1028000 6811800 413
+1030500 6852700 211
+1028900 6863800 240
+1058700 6891500 298.5
+1019700 6815000 587.5
+1039700 6797400 174
+1039500 6871000 182
+1023600 6873300 292
+1061400 6893300 330
+1042900 6815600 157.5
+1037300 6829200 154
+1051200 6882400 301.5
+1071100 6884100 170
+1065400 6881100 153.5
+1010700 6822400 558.5
+1056200 6887300 233.5
+1032300 6841200 230.5
+1020900 6726800 379.5
+1016100 6715100 540
+1017000 6753500 262
+1026000 6726000 397.5
+1031100 6745800 277
+1006500 6747100 364.5
+1024100 6784600 194.5
+1018700 6775700 535
+1019500 6729300 359
+1030800 6720800 442.5
+1020500 6742200 284
+1031000 6725300 451.5
+1029300 6725500 421
+1019800 6762900 231.5
+1011900 6726500 381
+1037700 6741700 238.5
+1010800 6748300 314.5
+1030000 6741500 272
+1037400 6749500 230
+1019900 6738900 323
+1016300 6732300 340
+1034900 6717100 452.5
+1040500 6769200 202.5
+1025500 6731400 369
+1033900 6730200 351.5
+1020100 6781700 438
+1018300 6733300 333
+1015400 6783200 470.5
+995500 6754900 882
+1037600 6732000 282.5
+1021100 6715400 665
+1017700 6770400 396.5
+1008300 6748300 359.5
+1010000 6775100 829
+1037400 6778300 196
+1002700 6758800 782.5
+1020200 6720100 530.5
+1011400 6729700 369
+1020600 6770700 587.5
+1037700 6756800 221
+1029900 6735000 357.5
+1013500 6719400 446
+1021000 6794400 278.5
+1002000 6732100 349.5
+1016700 6744700 288
+1006900 6751600 494.5
+1029400 6796400 175.5
+1037900 6744500 233.5
+1030600 6740600 295
+1013400 6762200 589
+1022000 6741500 325.5
+1016200 6739600 282
+1016900 6747400 276
+1030900 6727400 417
+1028900 6782800 188.5
+1019300 6793800 583
+1033200 6733600 333.5
+1017200 6738500 277.5
+995600 6761100 833.5
+1009900 6734700 306.5
+1009400 6749800 351.5
+1021300 6729100 364
+1011300 6736600 298
+1043100 6732900 241
+1019400 6801200 662
+1022200 6718400 579.5
+1010400 6768200 756.5
+1029900 6716400 599
+1006100 6734600 339.5
+1016200 6770800 504.5
+1007300 6733600 347
+1020000 6711100 630
+995000 6752800 787.5
+1015400 6758300 302
+1023500 6720200 544.5
+1003700 6774100 910.5
+1008200 6732000 345.5
+1026300 6718200 614
+1038800 6727200 327
+1024800 6793400 182
+1024100 6716800 639
+1018000 6786300 491.5
+1006700 6760500 951
+1039000 6763600 212
+1022200 6728100 374
+1028700 6780600 191.5
+1005200 6755600 763.5
+1028400 6778200 195
+1024300 6733700 336
+1013500 6796900 935.5
+1024300 6767800 206
+1018600 6759400 247
+1032900 6769600 206.5
+1023900 6798400 452.5
+1024700 6731600 354.5
+1024600 6752400 238.5
+1027400 6771000 202.5
+1013700 6737700 295
+1003900 6749300 539
+1040400 6736100 236.5
+1031600 6732300 379
+1017200 6730500 357.5
+1014500 6773500 537.5
+1024500 6729500 395
+1020700 6723700 411.5
+1021400 6720400 536.5
+1002500 6745500 380.5
+1009400 6729800 356
+1032600 6761400 220.5
+1016700 6713800 594.5
+1035900 6735600 274
+1001600 6751600 811
+1027500 6739700 330
+1042900 6730500 257.5
+1039800 6729300 295.5
+1008500 6742200 339
+1008800 6731000 349.5
+1026000 6756000 227.5
+1020400 6737000 314.5
+1031900 6716000 615.5
+997700 6760900 627.5
+1005600 6777100 789.5
+1005500 6781500 883.5
+1018600 6784900 529.5
+1012700 6738100 310.5
+1038400 6780900 189
+997800 6750100 654.5
+1027700 6755700 227
+1031200 6785900 186
+1043300 6774100 196.5
+1019300 6783400 514.5
+1025400 6751400 232.5
+1020400 6785900 261
+1034000 6727800 396
+1020500 6767500 217.5
+1035200 6720400 439
+1002100 6733400 359
+1022400 6724300 405
+1036100 6722700 444.5
+1024800 6719300 534.5
+1023800 6726400 387.5
+1030500 6790000 180.5
+1022300 6744200 287
+1024500 6754100 238.5
+1018100 6755900 254
+1019900 6745900 279.5
+1004700 6739100 355
+1003600 6741400 376
+1001200 6760100 870
+1022400 6777600 242.5
+1039600 6756500 214
+1028200 6713500 620.5
+997800 6762600 845.5
+1006900 6737900 330.5
+1009900 6728400 370
+1029200 6740800 301
+1035500 6728000 355
+1012300 6733000 339.5
+1006900 6740800 340
+1004500 6757100 769.5
+1032900 6789800 181.5
+1010400 6802300 768
+1032100 6776600 198
+1010600 6754900 615.5
+999500 6761500 834.5
+1009900 6791800 775
+1007900 6779300 567.5
+1022900 6733400 339.5
+995400 6771500 925
+1004400 6730500 358
+1017700 6764300 245.5
+1029600 6743900 294.5
+1026300 6734600 352
+1008300 6752700 477
+1005400 6731100 362.5
+1012400 6747400 300
+1040100 6727700 300.5
+1021000 6733300 332.5
+1018900 6779100 457.5
+1005300 6741100 361
+1019800 6790300 294.5
+1010900 6727200 378
+1004700 6733000 353.5
+1005600 6793800 937.5
+1032300 6734200 356.5
+1007700 6736400 328
+1032200 6729000 393.5
+1030500 6719300 459
+1027800 6733800 375
+1035400 6779300 194
+1019200 6718100 548
+1025600 6789600 183.5
+1026700 6769400 206
+1033600 6792400 180.5
+1028000 6774100 198
+1028300 6731000 384.5
+1037800 6789200 181.5
+1018800 6714900 611
+1024500 6725600 394
+1013200 6779100 602.5
+1020500 6776600 502.5
+1028800 6788300 183
+1015900 6767800 399
+1020200 6735500 330
+1030800 6778900 194
+1012600 6756700 693.5
+1012600 6754900 693.5
+1012400 6753400 317.5
+1008700 6734700 317.5
+1033900 6785700 187.5
+1020300 6795400 457
+1018600 6787200 435
+1024500 6801400 450.5
+1028700 6717400 601.5
+1020500 6765400 218.5
+1016800 6790600 580
+1030900 6735700 341
+1023500 6741700 330
+1018400 6737500 309.5
+1004300 6744700 360
+1026200 6738000 335.5
+1036700 6726200 373
+1013400 6804100 635
+1006900 6778200 826.5
+992200 6752400 862.5
+1023200 6800500 494
+1006500 6743100 338.5
+1036700 6723400 400
+1035100 6786500 185
+1039000 6786800 183
+1039800 6777100 194.5
+1034100 6726100 432
+1018400 6789200 537.5
+1004300 6777300 859.5
+999200 6759800 730
+996900 6759700 823.5
+1007100 6753100 625
+1020700 6797100 588.5
+1028800 6744600 307.5
+1021100 6792200 299.5
+1026300 6723000 410.5
+1023900 6799700 276
+1017200 6723500 408.5
+1034300 6737800 272.5
+1019000 6777600 583
+1012600 6725100 390.5
+1000400 6774800 917.5
+1003400 6775800 900.5
+1034700 6773400 202
+1025200 6766000 209.5
+1044200 6731200 250.5
+1025300 6764200 214
+995700 6751400 751.5
+1038000 6759900 217
+1014400 6782000 582
+1027000 6720600 507
+1028400 6737000 325
+1020200 6777400 285
+1010000 6740200 322.5
+1040600 6777900 192
+1013900 6723400 402.5
+1021600 6793000 227
+1025300 6760600 222
+1019800 6773600 519.5
+1001500 6759200 627
+1003300 6761500 966
+1009300 6740500 306.5
+1009700 6768100 894
+1018500 6717300 551.5
+1013200 6780900 624
+1011900 6743500 304.5
+1021600 6761900 226.5
+1027800 6772000 202
+1015900 6762400 830
+1009400 6788800 849
+997000 6750200 685
+1030100 6786600 184.5
+1038600 6746400 232.5
+1026800 6776600 196
+1032100 6721300 464.5
+1036300 6776500 197.5
+1037500 6752600 226
+1039700 6775300 197
+1006300 6750100 420.5
+1011000 6780100 655.5
+1026600 6796700 182.5
+1011900 6763800 608
+1010300 6764200 799.5
+1010000 6739300 318.5
+1010300 6729200 364.5
+1027100 6747700 288.5
+1012500 6766900 577.5
+1018800 6727700 375.5
+1031900 6766200 211.5
+1027100 6731500 379
+1038600 6766900 208
+995700 6760500 845
+999100 6749000 792.5
+1022100 6733600 331
+1020100 6740900 278.5
+1039600 6723500 374
+1014200 6740700 292
+1017600 6805500 582
+1001000 6747200 545
+994200 6752400 766.5
+1015200 6738500 304
+1038900 6778100 193
+1025700 6724500 398
+1027100 6784500 186
+1037400 6720100 449.5
+1011900 6787100 700
+1005000 6740000 358.5
+1010900 6778800 576
+1023900 6744700 296.5
+1008800 6778200 647
+1026800 6742300 329.5
+1038700 6773000 202.5
+1033400 6737100 290
+1016000 6767300 405.5
+1031600 6739000 289.5
+1014500 6760900 606.5
+1022100 6749700 251.5
+1027300 6752000 231
+1014700 6726300 398.5
+1021800 6737100 345.5
+1029600 6737000 325.5
+1016600 6742400 287
+1035400 6730900 315
+1005600 6780500 890
+1037500 6784800 185.5
+1023500 6736000 326
+1021500 6791400 268.5
+1019300 6760200 235.5
+1005900 6739200 338
+1023100 6727100 380
+1038900 6768400 205
+1027800 6722000 419
+1026900 6769900 205
+1005400 6737700 351.5
+1020400 6750800 249
+1002800 6731100 357.5
+1004600 6751100 648.5
+996900 6764000 854.5
+1029900 6747900 299
+1010600 6744800 314
+1012500 6740300 296.5
+1029300 6729800 397
+1023100 6732800 349.5
+1015100 6759700 594
+1021900 6757300 232.5
+1008200 6768800 874.5
+1030000 6787800 182.5
+1009200 6733600 325
+1020500 6748600 258
+1003400 6747200 399.5
+1011900 6736000 311
+1007200 6780700 715.5
+1027700 6753500 229
+1020700 6780100 477.5
+1010400 6766300 908
+1014400 6764700 437
+1033900 6763800 216
+1032800 6787400 184
+1034700 6734600 299.5
+1017000 6765900 398
+996200 6751700 817
+1033500 6783000 189
+1014600 6723100 405.5
+1017300 6720600 429
+1017700 6735500 339.5
+1029700 6720700 454.5
+1015900 6806700 570
+1011600 6793900 774
+1025000 6747600 283.5
+1032000 6737800 290.5
+995900 6766400 865.5
+1018700 6790400 441
+840600 6514300 208
+827200 6499400 369.5
+831400 6517800 414.5
+806300 6558200 726
+803400 6553100 610.5
+845500 6529800 265.5
+834200 6559900 208.5
+812700 6537000 514.5
+845800 6527700 263.5
+842100 6531100 289
+832600 6510100 382
+834200 6531700 242.5
+849000 6504200 274.5
+842800 6532400 239
+826000 6526500 323.5
+832100 6548500 215.5
+801400 6548900 517.5
+825400 6500900 545
+808900 6528200 729
+838100 6486400 303
+817600 6532600 359
+839500 6502600 198.5
+824900 6520200 502.5
+812700 6512800 520.5
+810200 6542900 731
+842900 6526600 262.5
+835200 6531000 283
+846700 6512600 200
+802000 6556400 648.5
+821600 6507900 682
+810800 6566800 752.5
+835700 6521600 253
+825200 6522500 503
+831300 6521000 355
+811400 6514300 575
+826000 6554300 449
+859000 6523900 200
+833100 6544800 193.5
+838400 6519800 247.5
+802400 6545400 517.5
+809400 6566900 601.5
+832000 6536200 266.5
+860700 6519400 235
+839100 6523300 252.5
+810600 6572200 675
+813900 6522200 655.5
+852100 6508900 234.5
+845700 6493500 229
+806400 6520200 579
+818800 6565500 669
+820100 6523200 431.5
+824500 6541500 539
+864300 6514600 238.5
+814400 6529900 570
+825300 6562100 548.5
+813300 6555300 648
+836400 6490900 435.5
+827100 6508100 598.5
+848100 6509400 208
+856900 6507200 292
+831400 6544700 236.5
+843400 6523300 220
+829000 6559100 246
+816500 6519100 598.5
+831100 6540900 260.5
+810700 6539500 639.5
+804800 6551100 621.5
+830300 6536400 354.5
+839800 6507100 255
+820200 6576500 486
+821900 6573500 534.5
+822900 6571300 606
+800500 6549100 467.5
+828800 6516700 532
+826000 6541800 326
+841900 6509800 213
+806400 6532900 651
+835500 6513800 258
+815600 6534800 486.5
+833100 6552800 205.5
+829100 6525700 402.5
+822100 6517100 588.5
+844200 6513800 187.5
+854600 6508000 252
+823800 6567400 692
+850800 6505000 279.5
+821200 6541400 536
+828900 6542500 254.5
+832300 6564900 215
+839500 6512200 236.5
+824000 6546400 581
+803000 6542300 602
+813500 6504700 554.5
+806700 6537100 674
+823700 6552700 518
+834200 6519000 264
+844600 6505400 238
+808600 6513900 552
+826100 6528900 255
+843800 6528900 235
+843100 6519400 237
+821100 6539500 400
+823100 6534000 308
+822600 6539900 505
+832900 6532100 245
+812500 6562100 706
+851300 6512600 226
+832800 6527600 292.5
+818400 6536600 472
+829700 6555700 223.5
+818000 6541400 501
+825400 6537500 345
+831700 6514900 301.5
+822800 6535500 290
+822900 6529200 328.5
+815400 6556700 640
+846000 6504000 277.5
+832200 6499900 276
+844600 6492400 340
+855700 6516600 235.5
+849600 6522600 179
+836200 6504700 250.5
+812500 6506600 633
+823800 6501300 672
+836400 6559500 178.5
+832000 6543200 250
+829600 6498900 275.5
+813200 6575600 607
+832900 6530100 246
+813800 6516500 537.5
+843000 6502200 284.5
+826900 6514100 515
+827700 6510500 548.5
+820400 6532400 342
+841900 6528800 333
+835100 6558000 197
+801600 6553400 526
+852900 6518000 220.5
+824500 6547500 550.5
+830400 6530000 258.5
+809700 6550500 671.5
+820400 6548600 606
+808100 6570600 541
+811200 6531600 601.5
+827200 6549300 475
+841300 6531700 304
+837500 6527900 439
+814100 6549700 578
+834000 6517600 259
+829100 6519700 533.5
+808000 6559800 745.5
+857900 6512100 253.5
+834600 6538000 171.5
+815300 6552500 618
+829400 6533700 326
+846100 6520200 177
+843200 6530700 231
+841900 6513200 193.5
+843200 6527900 218
+829700 6563900 450.5
+828200 6536100 333
+826800 6569100 569
+826000 6524200 460
+833300 6525200 296
+844500 6532700 258
+837100 6516700 246.5
+810300 6554900 698
+827300 6546000 304
+827800 6503700 603
+830300 6512300 433.5
+838100 6508100 235
+824600 6536600 340.5
+811900 6545700 604.5
+816100 6513400 595
+836600 6509800 267
+830800 6494700 297.5
+827500 6553300 267.5
+845300 6494300 334
+833800 6508000 295
+827400 6545100 300
+831800 6534600 287.5
+831900 6572000 436
+818900 6510600 704
+821400 6558200 600.5
+834100 6505900 282
+829300 6572700 479.5
+802800 6549200 570
+825200 6539100 419
+810600 6522300 663.5
+845500 6526700 253.5
+839700 6530100 440.5
+861800 6524500 208.5
+841100 6501900 217
+841500 6528100 328.5
+833100 6497600 250
+837700 6536400 181.5
+827000 6575600 541
+855600 6520500 211
+822200 6525300 518.5
+825500 6527500 258
+826700 6561100 524
+832600 6521600 301
+830800 6537600 326
+830900 6567200 367
+833800 6496200 381.5
+807200 6553700 689.5
+823100 6551900 545
+827200 6555600 427
+815900 6547600 592.5
+832600 6569500 365
+841200 6525500 402.5
+816900 6543800 516.5
+820800 6520900 459
+807000 6543700 653
+829200 6558200 335
+833200 6538800 262.5
+848700 6517300 202
+847300 6526300 247
+840900 6515900 206
+817000 6502700 724.5
+818500 6517700 448
+838100 6521000 242.5
+827700 6505100 565.5
+818800 6528700 454.5
+810700 6507300 585.5
+816800 6507200 691.5
+842100 6504900 219.5
+827500 6541000 285
+818400 6539400 505
+824100 6524600 289.5
+829000 6570600 436.5
+813500 6541300 631
+815600 6531600 436.5
+835100 6533700 194
+852200 6520700 205.5
+815500 6533900 484
+843400 6506100 202
+819300 6563100 635.5
+831300 6506100 427
+859100 6511600 270
+823800 6513300 670
+841100 6507000 217.5
+814400 6513100 448.5
+836200 6524400 307.5
+818000 6523900 620
+839700 6525000 381
+827600 6532200 266.5
+806600 6547400 617.5
+814800 6502700 616
+829500 6531200 291.5
+842700 6534700 234
+831800 6490900 497.5
+840900 6497300 346.5
+841400 6489400 340.5
+828500 6565900 506
+823000 6574100 565.5
+828300 6527700 301.5
+824300 6537700 409
+824700 6504700 784.5
+844700 6509800 194.5
+818000 6563100 666.5
+825800 6544400 518.5
+824800 6559000 482.5
+826400 6550300 338
+817200 6570000 719
+810400 6576200 506.5
+822600 6562800 578.5
+818800 6574700 562
+839800 6532900 303.5
+833000 6563000 213
+811100 6533900 543
+830300 6503500 379
+836200 6563400 178
+825900 6533200 276.5
+809200 6524700 695
+822900 6536900 358
+810700 6518000 624.5
+830600 6532100 315
+835000 6502200 257
+827800 6548700 353
+838700 6488100 285
+837900 6500600 259
+837500 6532100 356.5
+825000 6529300 339.5
+842400 6528600 207.5
+815000 6564300 746
+840200 6516500 246
+807900 6509800 541.5
+818700 6513200 640.5
+815000 6510300 678
+822400 6501200 729
+838800 6505200 229.5
+817100 6527500 623
+898300 6708600 208.5
+910400 6728500 232
+936800 6762300 287.5
+947300 6714300 290.5
+939500 6718000 329
+916300 6724100 231.5
+923500 6724900 235
+931100 6742800 289
+933500 6718800 382
+919400 6741800 296.5
+959300 6730200 302.5
+898600 6714700 218
+953400 6729200 337.5
+907300 6690600 243.5
+901500 6720800 231
+898300 6699400 227
+953600 6720500 330
+910400 6711900 230.5
+928900 6726600 295
+939700 6705300 254.5
+935000 6747100 237.5
+912800 6755200 253.5
+934700 6728400 324.5
+942900 6733300 341
+962300 6737200 318.5
+974200 6722900 432.5
+915600 6710500 257.5
+953300 6750300 286
+923900 6729400 226.5
+894400 6701400 220
+917000 6751200 287.5
+979800 6742300 608
+902600 6719300 219.5
+953900 6755700 350.5
+948500 6737600 350.5
+918200 6755500 247.5
+964000 6749600 418.5
+974100 6732000 411
+924700 6741800 294
+906000 6731400 253.5
+930600 6730900 260
+914500 6707600 242.5
+910200 6707000 227.5
+943700 6739200 313
+949100 6727500 361.5
+952900 6733000 320
+939600 6707000 278
+916800 6738400 285.5
+931400 6707100 324.5
+943700 6730300 311
+926300 6724700 238.5
+960600 6735500 297
+905200 6699700 268
+928100 6740800 231.5
+908700 6723900 211.5
+903000 6739900 317.5
+954700 6739800 368.5
+962100 6721500 287
+919300 6744400 261.5
+940600 6760800 283.5
+906500 6708800 220
+936300 6763800 288
+959800 6719700 321.5
+913200 6739200 275.5
+916200 6708600 307.5
+898200 6722900 234
+886800 6715400 251
+926600 6762800 286
+890800 6705200 218
+946400 6712500 277
+921900 6698500 237
+888800 6711700 222
+984900 6727000 386
+906100 6724800 223
+899500 6716800 222
+915100 6720300 231
+915800 6733500 277
+890600 6717900 253
+935700 6727100 333.5
+897000 6693500 228.5
+980000 6735100 397.5
+917600 6715900 232
+933300 6724700 360
+906300 6717400 219
+938100 6712200 309.5
+964200 6721000 328.5
+898300 6701500 221.5
+918000 6710900 305.5
+913800 6744000 299
+932900 6722100 370.5
+913200 6697300 310.5
+936900 6714600 319.5
+918800 6753300 252
+968200 6763900 689
+972400 6739600 555
+880000 6712000 233.5
+912500 6724500 230
+942200 6740900 318.5
+914300 6706400 306
+925800 6750200 246
+943400 6746900 273.5
+909800 6696400 292.5
+892300 6700500 217.5
+936800 6749800 263.5
+918600 6699200 296
+932200 6750000 276
+940900 6708300 262.5
+941200 6756100 264.5
+908000 6712400 226
+912000 6712200 242
+959800 6748000 327.5
+906300 6746400 291.5
+945900 6737900 303.5
+965800 6735800 313
+928300 6710000 333
+948400 6744300 329.5
+958700 6733100 317
+906400 6702700 235.5
+969000 6734800 318
+945400 6759900 266.5
+943200 6717300 322.5
+947300 6721600 338
+909100 6728700 228
+950400 6743200 354.5
+938600 6725400 353.5
+960900 6743900 320.5
+879600 6725900 286
+929000 6698400 262
+928300 6726900 235.5
+927500 6730000 238.5
+897000 6721400 229.5
+913300 6726600 230.5
+969600 6733600 354.5
+949200 6749400 279
+964600 6729300 299.5
+968500 6724500 345.5
+933600 6758600 283
+921100 6706500 343
+954300 6722900 305
+923400 6764500 266.5
+909100 6752200 273.5
+968300 6759800 582.5
+913600 6752900 264.5
+902700 6701800 227
+962100 6758000 544.5
+912100 6700400 312
+980900 6728500 430.5
+898600 6692100 260
+961300 6749300 379.5
+940900 6734200 298.5
+978500 6726500 417
+937200 6759600 289.5
+923000 6760500 237
+938800 6761400 281
+978300 6755700 818
+983300 6729200 437
+933900 6762100 284
+899700 6687600 206.5
+962600 6719000 329
+983700 6730400 401.5
+902400 6747400 305.5
+945600 6754300 285.5
+939100 6737900 285
+902600 6694600 261
+943100 6752000 260.5
+906600 6719900 218
+932800 6756300 291
+927600 6739400 241.5
+938800 6732000 258.5
+929100 6752200 278.5
+918000 6763800 289.5
+983200 6738400 439
+915600 6707300 320
+950700 6744900 355.5
+931300 6762600 295.5
+929000 6760300 309.5
+930400 6767000 322
+889400 6715100 229.5
+972500 6729800 433.5
+960300 6722200 292
+961300 6733600 305
+946900 6736700 290
+936900 6729400 294
+971700 6749000 607.5
+942100 6759900 294
+968400 6740700 413.5
+941200 6713000 306.5
+927900 6712700 342.5
+945400 6712400 278
+944300 6741300 300.5
+934800 6720200 387
+908300 6730000 233.5
+926400 6702200 284
+967900 6737900 334.5
+909500 6700500 282.5
+940300 6732300 302.5
+888800 6727000 293.5
+966500 6755100 462.5
+955600 6752200 362
+948500 6736700 345.5
+892800 6717800 228.5
+923000 6752900 259
+928500 6727500 239
+923000 6750600 245
+928100 6765500 247.5
+971300 6731100 378
+909400 6691400 256.5
+897800 6732900 298
+920700 6758500 266.5
+940200 6751000 260.5
+924600 6743100 286
+973100 6724300 423
+908500 6709800 229
+894100 6692200 214.5
+951300 6731700 330
+938600 6704100 248.5
+922900 6733800 279
+899000 6689100 244.5
+922100 6723000 242.5
+934300 6750300 263.5
+933800 6712200 318.5
+902700 6737800 348
+923500 6716100 236
+901800 6744900 344.5
+936200 6704200 275.5
+899200 6696400 236
+918500 6712000 262
+904700 6742000 329.5
+941300 6728600 287
+897500 6728400 288
+914200 6746200 268.5
+906200 6747000 305
+942100 6746200 323.5
+938400 6745800 279
+949200 6741200 371
+952100 6746600 285
+951100 6735900 348
+956700 6738300 308
+905500 6691200 253
+916900 6719200 235
+966300 6718800 417.5
+974900 6757500 638.5
+969500 6724400 371.5
+908100 6702600 238.5
+932700 6725700 365
+951600 6734500 341
+968800 6744900 516
+909000 6732500 238.5
+901600 6692000 252.5
+960700 6746200 333
+949000 6734300 328.5
+920000 6736900 296
+906600 6749600 286
+938200 6754600 277.5
+964600 6741700 329.5
+933100 6737000 289
+952200 6726800 360
+932500 6745400 270
+937700 6727700 332
+929200 6725000 298.5
+896800 6727400 261.5
+956600 6726800 330
+933100 6730200 296
+937400 6736000 284
+955800 6736400 346.5
+938700 6733300 284.5
+893900 6712800 221
+938500 6742200 337
+920800 6763000 267
+939200 6728400 313.5
+934600 6744200 315
+927100 6733500 234
+969900 6734500 314
+961200 6754200 447
+914500 6729800 232
+905500 6726500 224.5
+941500 6710100 264.5
+909100 6714400 234
+933200 6767800 359.5
+966100 6721500 391
+912000 6704400 289
+945500 6710700 272.5
+941400 6710700 289.5
+975000 6723900 442.5
+983200 6723400 401
+890300 6709600 217.5
+925900 6706200 304
+931500 6710100 324.5
+896000 6722500 232
+898000 6697800 226
+909600 6729200 244.5
+966900 6726000 361
+903900 6689900 236
+962000 6753200 390.5
+915800 6716000 236
+928900 6749000 248.5
+930200 6700100 272
+949300 6755800 322
+900400 6730500 290
+931500 6752900 296
+907000 6733800 270
+919800 6719100 237.5
+964600 6752900 433.5
+943900 6706700 252
+953800 6744900 357
+929500 6741800 240.5
+956700 6742700 308
+925200 6747200 251
+929400 6758200 295
+984200 6733400 428
+906600 6721000 226
+910600 6738500 270
+930600 6739400 280
+900100 6702500 225
+936000 6721600 365.5
+921800 6729700 224
+905000 6724800 231.5
+905400 6706300 217.5
+914500 6716900 240
+894400 6730200 303
+913800 6694600 275.5
+979900 6727700 405.5
+958100 6722300 287.5
+964600 6718600 399
+931000 6734500 257
+904100 6696500 269.5
+947900 6715300 291
+948200 6729000 363.5
+950500 6747200 276
+963700 6727700 318
+948000 6746600 330.5
+940000 6724300 358.5
+907900 6743900 320
+912500 6736400 257.5
+952900 6751600 327.5
+911800 6741500 289
+911300 6751000 278
+905300 6696600 280
+980500 6730100 413
+929500 6719500 356
+951500 6728500 363
+968800 6733600 334
+934600 6732700 239.5
+895300 6708100 218
+925500 6732700 263.5
+924000 6706000 326
+915300 6718700 222.5
+887500 6712500 223
+923100 6727700 231.5
+906900 6704100 218
+895500 6695900 218
+921200 6703200 292.5
+919200 6759000 281
+960900 6725800 312
+924500 6697300 258
+898900 6722000 223
+898800 6706400 216.5
+893700 6703700 200.5
+970600 6761000 591.5
+891800 6719700 236
+906100 6751400 295
+895300 6697400 218
+927600 6722700 297.5
+970700 6762600 628.5
+923600 6761800 261
+919500 6762200 268.5
+940600 6755200 264.5
+959600 6754700 408
+959000 6726700 314.5
+920100 6729900 231.5
+953700 6741200 375.5
+948000 6748400 267
+937900 6756900 274
+962700 6753900 456
+979100 6733400 409
+922700 6758600 279.5
+979600 6725600 413
+922700 6754900 276
+982700 6726400 430.5
+934600 6701700 245
+981300 6725100 392
+965100 6724200 320.5
+904800 6728300 233
+935700 6768600 367
+943500 6714500 298.5
+978500 6724500 421.5
+921800 6713900 312.5
+962300 6748800 376
+914400 6756900 295.5
+924200 6747500 246
+906800 6694000 283
+946100 6746400 324
+946300 6747900 274.5
+970300 6756400 520.5
+964800 6740000 318
+976000 6740400 511.5
+970200 6736600 382.5
+926700 6767500 339.5
+966600 6731400 324.5
+910400 6748000 298
+915100 6741600 280.5
+959400 6754100 367
+927200 6751700 285.5
+928300 6736400 271.5
+938000 6751000 262.5
+916300 6695300 285.5
+930000 6762300 310.5
+936400 6734500 256
+961900 6744600 369
+944400 6753700 269
+905500 6737900 340.5
+961700 6730200 300
+949600 6716400 300
+979400 6749200 785
+966700 6734300 312
+889500 6693400 212.5
+936200 6711200 304.5
+915700 6755000 269
+933200 6714000 342
+979700 6752100 825
+886100 6708100 221
+960600 6753500 367.5
+931900 6728900 319
+970400 6747200 507
+909800 6726600 222.5
+969600 6723000 386
+924800 6702200 279
+980300 6746700 849
+961800 6723300 282.5
+949100 6763000 388
+939800 6758200 265
+954000 6726400 334.5
+963900 6721800 297.5
+908900 6740500 303.5
+950800 6717500 328
+905400 6740400 340
+896100 6688000 235
+925400 6716300 331.5
+903600 6705600 221.5
+940200 6739800 286.5
+941500 6738800 278
+945900 6762600 291
+920600 6700800 295
+919400 6748400 247.5
+953400 6735400 351
+927100 6731900 235.5
+951500 6762500 324
+959100 6724100 289.5
+908200 6753200 298
+948400 6759700 288.5
+967200 6743900 332.5
+944600 6758900 273
+891800 6702300 206
+934300 6740400 309.5
+955600 6729500 343.5
+976600 6726900 433
+893900 6707500 212.5
+920000 6731400 270.5
+931900 6703900 297
+893500 6706200 214
+927800 6697500 268.5
+946200 6732400 324
+894300 6702400 217
+925400 6727800 239.5
+886800 6702700 216.5
+954900 6718900 284
+924400 6709900 364
+940500 6717300 286
+901900 6699000 238
+905400 6718700 222.5
+918400 6695100 240.5
+960600 6728700 329
+912300 6692700 268
+903300 6727900 234.5
+904600 6694000 259.5
+917400 6730600 233.5
+913300 6707100 231.5
+923400 6698300 248
+924900 6712500 340
+969900 6729400 373
+882600 6710000 233.5
+910700 6723700 214
+945100 6708500 271.5
+922000 6719400 238
+923500 6717500 238.5
+962000 6717600 364
+918600 6766300 288
+939400 6746200 311
+930100 6704100 292
+906400 6742500 310.5
+975500 6752400 656
+936800 6722900 367.5
+893900 6689700 239
+968100 6745300 396
+933100 6712800 342
+926700 6714600 332
+923600 6731200 229.5
+981200 6735600 422.5
+963200 6752500 415.5
+919500 6697000 239
+903300 6708900 210
+931500 6764700 260
+924000 6752200 263.5
+971700 6735500 447
+929900 6727000 307
+932200 6700300 248.5
+901400 6701100 235.5
+941900 6727000 323.5
+901400 6715000 220.5
+933200 6733800 263.5
+939200 6729400 296
+946400 6734200 324
+917000 6745500 266
+901100 6690700 237
+955800 6720800 273.5
+975900 6733400 464
+926300 6756700 291.5
+910900 6721800 228.5
+894200 6696000 207
+880100 6709600 227
+958300 6750700 326
+929500 6732800 255
+916100 6727900 230
+954900 6727100 335.5
+956300 6722500 313.5
+966500 6741300 318
+947400 6741100 314
+912000 6732700 244
+943100 6754600 263
+959300 6743500 316.5
+954200 6759400 422.5
+893900 6723000 235.5
+940100 6743300 338.5
+894700 6709500 216.5
+967100 6758800 510.5
+934300 6703600 275.5
+972300 6734700 416
+973900 6746000 618
+922600 6745500 265
+955000 6743200 308
+966700 6749700 431
+947800 6750200 277
+932900 6706200 284.5
+898300 6711300 217.5
+968700 6723100 338
+794500 6665300 446.5
+820300 6618000 359
+826400 6618200 341
+820500 6586600 421
+840500 6628100 189.5
+854500 6605000 183.5
+821900 6625400 370
+793100 6590800 315
+769600 6619900 334
+836400 6647600 214
+770900 6625100 338.5
+848000 6605200 218.5
+832000 6601800 342
+831700 6609100 246
+805400 6574800 551.5
+823200 6644800 386
+780300 6584100 279.5
+819500 6636600 284.5
+815600 6627500 368.5
+841100 6606300 311.5
+881000 6599100 320
+850100 6610600 191.5
+878100 6621300 202
+851800 6629900 196.5
+820000 6590300 447.5
+754100 6620400 235
+786800 6613800 322.5
+848800 6619700 175
+820000 6622500 334
+802600 6584900 426
+827900 6622100 317
+851600 6624200 184
+818000 6581900 429.5
+842600 6588500 226
+817200 6590200 417
+828600 6604200 242.5
+821300 6614100 333.5
+829000 6612900 227
+866300 6618400 191
+857100 6612200 193
+799000 6623800 356.5
+819600 6580200 422.5
+876100 6636700 195.5
+827900 6610500 264.5
+790700 6617100 324.5
+793900 6584800 341.5
+812000 6637600 424
+829800 6588600 447
+786100 6628000 368.5
+795500 6582100 376
+810700 6616600 403
+872100 6600500 200.5
+819200 6585200 409
+798200 6642100 476.5
+797400 6567700 363
+801500 6658100 330
+840800 6583900 238.5
+870900 6649300 179.5
+804900 6616700 325
+791400 6646000 385
+861600 6614300 188
+806700 6650800 458
+801500 6666200 441
+791700 6571500 417.5
+770700 6604200 294.5
+806500 6577700 487.5
+810400 6599100 397.5
+796900 6575700 398
+796400 6603600 359.5
+790600 6641400 349.5
+799600 6574200 435
+878300 6628400 196
+788400 6578400 414
+840900 6629900 181.5
+832600 6611700 238.5
+771400 6610300 330.5
+870200 6616400 190.5
+831800 6635900 280
+846500 6608600 245.5
+841100 6617800 254
+853300 6608500 192.5
+779100 6578000 271
+796200 6589900 327.5
+796500 6660800 422
+820000 6605200 302
+842800 6613600 329
+849600 6603600 174
+867300 6648300 184.5
+811800 6657400 419
+861500 6622000 196.5
+813000 6645900 470.5
+785200 6610300 309
+875100 6598200 208.5
+823000 6593200 428.5
+822300 6615300 338.5
+829300 6580500 502.5
+824700 6639700 352
+809500 6632500 328
+802600 6577500 529.5
+789000 6597500 273
+787800 6569000 372.5
+833400 6610400 243
+799900 6589800 349
+788600 6609000 301.5
+828600 6627100 329.5
+786300 6567800 374.5
+803800 6587800 412
+833100 6575800 372.5
+865800 6641600 187.5
+832400 6576600 385.5
+829800 6582900 495.5
+817900 6635800 312
+833900 6567000 215
+861900 6608400 189
+786900 6634500 312
+847800 6608000 190
+822600 6598000 390
+804700 6661400 391
+798800 6656700 341.5
+783200 6607000 291
+835000 6640400 249
+800900 6579500 415.5
+780400 6573200 329.5
+822800 6647600 391
+825200 6592300 361
+858900 6646600 185
+852100 6615600 192.5
+825600 6605300 304
+840200 6630900 189.5
+857300 6610300 184.5
+872200 6645100 195.5
+831500 6599000 362.5
+790300 6629900 402
+786700 6587900 308
+781600 6580600 294
+820400 6603100 298.5
+842200 6620000 196
+831000 6639100 298.5
+792700 6632800 465
+812100 6628600 324.5
+849500 6644000 174.5
+869100 6633800 200.5
+840300 6610000 354
+875100 6632900 194
+876800 6629800 195
+802000 6660600 400
+857100 6637200 198
+825600 6633900 395.5
+839500 6649100 209.5
+828600 6602800 236.5
+862100 6629300 201
+871200 6630500 196.5
+834200 6577100 315
+778000 6576000 279
+781500 6614700 297.5
+778000 6588500 242.5
+810900 6590000 461
+803500 6638400 427
+809800 6634400 416
+826100 6647000 395
+881900 6642600 202
+822400 6576700 481
+775200 6598500 264
+872000 6622300 193.5
+833800 6590100 412.5
+872900 6640700 199.5
+854500 6647600 189
+835300 6624900 203.5
+845900 6634200 192
+824300 6624600 362
+829600 6622500 251
+825400 6620100 364.5
+844400 6621800 183
+881300 6623900 203.5
+804700 6619400 300
+837300 6580400 244.5
+856700 6651400 189
+802500 6571300 521.5
+866700 6616400 187
+822400 6603400 307
+838100 6611600 344.5
+815500 6605400 353.5
+829200 6606400 230.5
+773900 6599900 281
+831000 6586300 371.5
+802700 6594400 342.5
+812900 6593700 455
+815400 6614100 413.5
+785900 6579600 337
+838800 6598500 310.5
+798200 6564600 450
+779800 6590700 258
+861400 6651900 184
+794800 6585800 335
+833400 6647100 258
+864200 6648100 184
+825700 6601300 332.5
+780200 6575500 287.5
+835100 6574000 230
+833400 6617500 202.5
+836300 6582900 293.5
+861200 6615900 190.5
+860500 6649200 184
+857600 6620500 197.5
+786600 6582500 301
+815900 6598300 340.5
+819200 6613800 336
+835200 6594000 385
+799700 6571800 425.5
+858600 6602400 193
+813100 6633800 349
+829200 6644300 324
+846500 6638500 182
+817400 6600500 344
+772400 6570200 305.5
+783200 6567800 335
+834200 6634600 233
+818200 6622400 341.5
+876100 6618700 194.5
+827700 6620300 316.5
+818100 6593400 401.5
+812100 6609000 375.5
+864700 6631400 199.5
+793400 6606700 289.5
+794300 6574200 423.5
+798100 6600000 364
+876700 6613800 200
+823100 6599500 305.5
+822200 6650500 410.5
+844100 6593700 210
+815200 6603600 369
+796600 6569200 349
+792900 6669200 478.5
+818300 6577300 478
+792300 6661700 486.5
+833100 6598500 420.5
+843500 6637100 181.5
+827800 6618700 326.5
+822800 6631100 377.5
+872000 6610400 193.5
+875200 6624700 194.5
+859200 6650800 180
+873500 6620100 193
+786700 6652200 503.5
+859800 6619000 195.5
+865100 6622500 196
+788000 6571400 436
+807400 6590200 433.5
+871200 6613100 193.5
+790200 6589100 301
+833300 6587800 408
+814100 6579700 542.5
+835100 6616300 208
+851700 6639100 185
+833100 6607800 259
+806100 6581400 517
+789800 6657600 448.5
+827200 6645300 308
+865800 6608600 197.5
+883100 6602100 417.5
+754800 6617100 231
+800800 6585200 365
+833100 6584100 317
+861900 6625600 198.5
+843400 6589900 226
+806100 6628900 355
+807400 6614500 384
+858200 6627300 197
+843500 6605200 269.5
+833600 6627000 203
+838100 6584800 306.5
+829600 6635700 273
+856700 6607700 186
+848200 6643700 190
+814700 6651600 400
+791200 6627000 409
+824300 6649000 393.5
+842100 6623000 196
+835500 6574900 228
+819800 6642200 348.5
+796600 6584000 381.5
+777900 6572200 286.5
+821000 6638600 311.5
+793300 6600200 280
+790700 6577300 421.5
+804300 6581900 426
+830800 6574600 471
+838800 6589900 255
+795600 6635500 495
+799600 6598100 325
+783800 6647600 557.5
+822500 6620100 301.5
+793500 6567900 333
+785900 6595200 269
+788100 6661600 495.5
+863200 6650600 183.5
+830700 6636600 305.5
+875800 6608400 197
+866600 6626900 199.5
+846700 6631800 185.5
+816200 6596300 351.5
+819000 6610300 293.5
+830400 6629700 306
+764200 6604700 277.5
+798900 6619200 341
+774400 6623500 389.5
+825600 6641900 280
+874200 6649200 182
+783400 6664700 571
+791600 6593800 290.5
+793100 6651500 331.5
+829200 6631800 364.5
+823900 6619300 340
+820200 6596100 357.5
+837200 6618000 195
+825400 6586800 470.5
+802200 6604100 373
+796900 6601900 358
+784700 6642700 364.5
+781700 6585200 284.5
+764900 6611300 315
+778700 6629400 362
+817800 6652200 400.5
+783300 6626800 367
+854900 6633900 204
+825400 6612700 311
+795400 6597400 306
+872200 6638900 201
+880300 6629500 197.5
+859300 6641300 185
+835300 6569400 231.5
+880200 6640600 199
+870200 6653200 186.5
+822100 6637200 357
+819900 6598400 289.5
+826900 6643100 315
+821100 6612000 297.5
+837000 6626000 192
+877500 6634500 194.5
+784000 6574200 367.5
+834300 6573200 338.5
+796100 6567800 347
+781700 6620900 362.5
+809300 6638800 427.5
+828200 6600200 259
+791700 6581200 385
+841000 6615100 335
+849200 6626500 184
+867600 6638700 197.5
+841000 6580200 257
+848800 6606700 189.5
+839900 6642200 207
+843000 6617500 274
+808500 6582100 555
+830800 6583500 312
+836500 6568000 183
+752200 6624900 236.5
+832000 6580200 415
+815800 6650000 408.5
+855500 6644500 184.5
+843600 6591500 210
+833700 6574200 347.5
+778400 6568700 299
+865200 6653100 184.5
+840900 6634300 182
+885200 6617700 205.5
+878200 6640600 197
+819500 6621000 335
+824400 6583500 521
+807900 6608400 383.5
+858300 6646700 176.5
+839800 6607800 328.5
+847100 6624200 175.5
+842100 6611000 332.5
+839300 6639800 190.5
+823300 6608900 327
+846700 6633300 196.5
+878900 6606700 206.5
+854400 6652700 190
+820100 6610100 276.5
+838100 6605100 345
+783600 6597600 268.5
+827400 6594100 400
+821600 6586600 403.5
+786200 6604400 286.5
+843600 6599000 254.5
+815100 6593000 391.5
+830600 6584600 371.5
+797900 6593500 313.5
+766300 6622000 312
+828800 6618600 279.5
+839000 6576100 175.5
+818000 6588000 420
+836200 6576200 236.5
+829400 6585800 431
+886300 6640000 204.5
+798100 6585200 378.5
+759700 6604500 259
+838900 6594700 331.5
+793800 6657800 387
+834200 6581700 296.5
+829500 6634200 330.5
+832100 6596000 432.5
+813900 6585700 510.5
+777700 6584100 248.5
+868000 6650700 177.5
+853200 6630000 199
+861500 6637400 193
+802400 6597800 354.5
+883000 6613700 204
+821900 6643400 310.5
+813700 6648900 408.5
+839800 6637100 187.5
+848400 6650700 192
+785000 6637600 366.5
+837000 6592000 272
+814200 6639000 387.5
+793700 6617600 309.5
+850300 6616600 190.5
+850900 6647000 188.5
+776200 6611000 305
+854400 6646000 175.5
+844600 6602100 247
+781200 6611800 292.5
+833500 6604300 381.5
+821700 6600200 284
+836200 6597600 392.5
+794000 6638100 445
+837600 6573400 199.5
+843400 6625200 189
+852400 6635300 195.5
+815600 6630000 350.5
+864300 6639200 189.5
+825800 6646400 309.5
+803300 6568300 502.5
+805900 6633200 411.5
+853300 6651100 187.5
+823400 6616700 347
+840700 6638700 184.5
+830200 6628700 264
+861100 6643800 185
+875500 6615200 192.5
+820000 6644300 366.5
+859800 6628800 200.5
+813100 6615600 460.5
+794700 6609800 301
+799000 6577200 387.5
+837200 6599500 386.5
+840900 6589500 229
+757000 6607900 259
+831400 6644700 313
+832500 6643100 300.5
+828500 6640100 332.5
+856800 6617400 196
+828100 6629300 353
+882500 6621500 207.5
+856700 6624900 195
+820600 6607300 302.5
+827000 6639000 372.5
+811500 6620900 359.5
+814300 6647400 413.5
+826600 6596400 364
+801400 6638600 460.5
+839300 6603200 350
+878200 6631700 197.5
+837300 6607200 308.5
+833000 6632800 314
+778700 6592600 252.5
+860000 6635000 199
+876300 6602500 204
+806200 6623600 338
+840600 6597600 324
+855300 6611100 194.5
+804900 6604800 351.5
+824200 6606800 287.5
+827600 6624300 330
+767500 6600900 274
+823900 6615600 341.5
+823300 6579900 536
+789200 6582700 315
+837700 6638600 193.5
+839400 6592300 263
+797000 6578400 433.5
+860200 6613000 187.5
+825100 6610400 305.5
+776100 6579300 277
+786900 6575900 444
+811200 6606000 400.5
+844400 6595600 186.5
+801800 6629300 469
+814700 6588500 414.5
+799900 6566600 429.5
+804800 6571200 487
+817300 6607700 331.5
+848200 6636700 193.5
+832800 6578900 369
+785900 6569800 388
+831100 6646800 274
+798700 6582300 413.5
+817900 6631500 309.5
+772700 6576300 290
+793000 6613400 308.5
+834300 6579400 255
+785000 6632700 364.5
+811600 6624700 342.5
+844100 6632300 183
+862800 6632600 201.5
+781200 6595500 253
+861700 6611400 188.5
+800400 6577500 386.5
+866600 6653100 185.5
+829700 6614100 241
+828400 6636100 375.5
+793400 6646200 466.5
+823000 6589300 364
+841500 6596000 309
+845200 6629600 183.5
+786900 6622100 318
+827300 6614000 291.5
+825400 6629800 389
+822200 6634600 340
+829600 6624900 307
+799500 6612500 342
+875300 6645800 196.5
+849700 6637500 190
+805700 6601600 361
+845100 6651400 200.5
+828000 6633400 349.5
+781500 6651200 643
+785000 6659100 607.5
+842200 6639800 196.5
+778300 6618600 374.5
+828300 6642200 377.5
+838500 6634300 189
+800600 6591200 320
+822800 6622500 335.5
+824500 6647300 321.5
+796700 6568900 343
+817700 6616800 361.5
+825200 6625800 354.5
+871000 6620100 190.5
+852800 6640400 183
+839000 6614900 329
+809900 6658400 356
+867800 6612800 191
+853800 6621300 194
+774400 6614500 328
+798800 6650900 461
+805200 6654800 418
+818600 6625700 374
+842100 6627000 188
+815000 6655700 394.5
+794600 6641000 459
+759200 6613600 274
+854000 6646000 176.5
+845700 6603100 245
+866700 6635400 198.5
+783500 6634000 366.5
+820500 6647900 438.5
+788200 6666100 542.5
+842800 6602800 297.5
+882600 6600800 403.5
+804200 6612900 336
+854900 6608300 185.5
+817600 6605700 304.5
+824400 6588900 396.5
+807400 6645800 524.5
+778800 6604200 287
+762500 6620500 329
+763500 6614300 357
+837700 6602400 353
+828800 6608800 257
+844300 6612000 237
+493800 6796800 73
+491100 6818700 145.5
+479500 6742100 74.5
+487500 6746500 74
+468400 6757100 56
+504400 6797500 79
+496100 6757700 79
+536600 6768500 134.5
+483800 6754000 75
+491800 6821100 144.5
+501100 6760100 100
+467800 6744900 67
+477100 6806700 141
+531200 6753100 111.5
+462200 6789100 204.5
+468600 6761400 64
+496400 6797800 83
+486700 6777700 88.5
+456100 6774800 143.5
+491000 6770800 86
+490400 6783600 68
+467500 6791600 187.5
+474000 6739600 67
+484700 6773500 93
+476000 6745500 80.5
+499600 6807700 129.5
+490200 6820300 144
+481600 6771600 92
+472000 6810200 164
+486500 6790500 79.5
+500600 6755600 121
+476400 6782000 126.5
+469400 6798500 183
+487600 6808900 116
+507900 6769200 94
+524400 6742800 104
+523900 6750600 116.5
+489900 6798900 76.5
+506300 6800400 90
+513400 6737300 90
+490900 6811200 167
+506600 6797800 75.5
+512100 6750200 116
+479000 6810300 157
+469700 6806800 163.5
+502400 6775100 61.5
+504700 6733000 76
+533200 6768300 151
+493400 6810200 160
+446900 6749500 37
+493100 6820000 144.5
+500200 6804800 119.5
+491400 6751800 79
+510900 6762100 117
+505100 6808700 138.5
+456100 6762700 67
+484400 6810700 164.5
+493400 6750400 71
+474200 6751600 62
+478100 6736000 57.5
+497300 6768700 88
+486300 6727000 74.5
+470200 6791800 203
+479900 6796400 127
+471100 6766900 71.5
+479700 6797400 127
+471100 6771800 86.5
+486100 6810000 120.5
+479200 6764500 72.5
+511600 6800100 123.5
+488100 6767000 60
+487000 6795600 80
+527500 6794400 137
+506300 6784600 108.5
+496200 6771700 81
+479000 6728400 63.5
+466500 6747600 58.5
+505300 6814400 177.5
+532100 6777600 128.5
+446500 6752800 61.5
+503900 6811000 153.5
+470900 6745500 71
+504800 6737800 101
+507300 6804100 112.5
+460600 6754100 46
+518800 6784400 117.5
+474100 6747000 72
+462200 6773400 113.5
+484200 6809300 143
+495300 6789400 92
+500700 6821600 164.5
+517700 6735500 93
+536300 6779900 186.5
+512900 6786600 131.5
+521700 6741600 101
+450700 6754100 46
+536500 6788400 190
+516800 6781700 95
+508900 6783400 115
+494300 6774000 92.5
+463700 6769700 89.5
+503900 6786200 102
+513600 6795800 135.5
+531200 6756500 114
+517100 6741000 94.5
+464000 6762600 68
+487800 6776800 71.5
+501200 6772500 89
+488600 6794000 83.5
+502100 6777300 63.5
+520200 6773700 124
+459400 6765800 81.5
+449600 6761100 61
+503000 6781900 99
+472500 6789800 187
+485500 6756700 53
+498300 6733300 78.5
+486400 6797800 78
+477300 6768000 83
+465600 6759000 59.5
+496600 6809000 154
+498300 6785400 81
+490400 6802300 99
+468100 6779200 135.5
+479200 6800800 130.5
+456600 6748500 44
+517700 6779200 90.5
+452800 6749600 44.5
+479400 6777300 113.5
+469200 6750400 49
+486500 6771300 89.5
+500400 6817600 249.5
+454600 6770000 77.5
+463000 6784700 145.5
+521400 6757200 129.5
+503900 6820800 155.5
+460200 6756600 46
+465900 6767600 86.5
+507700 6751700 127.5
+525400 6762200 154.5
+513800 6740900 95.5
+519000 6771400 118
+509700 6735800 83.5
+459400 6760800 55.5
+496600 6728300 72
+484000 6786300 117
+477700 6758600 54
+492300 6796400 70.5
+463900 6743100 62.5
+506700 6795300 77.5
+507800 6730400 94
+525200 6779200 136
+498400 6806300 137.5
+494500 6789800 79.5
+505200 6793400 82
+489400 6786300 75
+491100 6804000 113.5
+465600 6764600 74.5
+503200 6762800 103
+475400 6806300 137.5
+478600 6791200 111
+500000 6727000 90
+519500 6792800 129
+531700 6785900 176.5
+450800 6741800 46
+524500 6775200 142.5
+535600 6780300 174.5
+492100 6756700 52
+477100 6773200 97.5
+461400 6777500 130.5
+511900 6770500 121.5
+515300 6777200 97.5
+491100 6790500 77.5
+485900 6799300 88
+518100 6739300 91.5
+458400 6759200 52.5
+490200 6735800 77
+487000 6750400 76.5
+494500 6785700 77
+489100 6748600 81.5
+490700 6758600 60.5
+497200 6740400 99.5
+513400 6776400 102.5
+531400 6760200 125
+501000 6749900 133.5
+534500 6759900 117
+479100 6747500 74.5
+505000 6799100 87
+491600 6773300 77.5
+493100 6793400 61.5
+491700 6739200 80.5
+470500 6773300 87
+510600 6766800 111.5
+488400 6774400 85
+464900 6770800 88
+490500 6786700 70
+496000 6792400 63
+463000 6735500 47
+481700 6812300 168.5
+520500 6788500 123.5
+488800 6806300 114.5
+458700 6768000 87.5
+476100 6812300 170.5
+526400 6746800 110.5
+484700 6802400 82.5
+499400 6809300 169
+481400 6762900 55.5
+485500 6778000 89
+480900 6759100 53.5
+527900 6745900 103
+509200 6794900 102.5
+483200 6749600 81.5
+510300 6732400 87.5
+518600 6762300 150
+473500 6760000 56.5
+500000 6738700 111.5
+520200 6777100 105.5
+480700 6737800 68.5
+506100 6802700 93.5
+474300 6801300 118
+518000 6754600 122.5
+509100 6740000 96
+484400 6769800 90
+516100 6788400 138
+462000 6765900 86.5
+514400 6791800 140.5
+493000 6756700 71
+500700 6798100 93
+486300 6816700 139
+506400 6735700 87.5
+472800 6756800 53.5
+476900 6788300 124
+487400 6813400 155.5
+487400 6818600 143
+504100 6805100 111
+472200 6779300 128.5
+474700 6798200 159
+482800 6765800 72
+520200 6781000 94.5
+472800 6792600 185
+502700 6793900 68.5
+490600 6813600 197
+521200 6785900 107
+494500 6760400 63
+467900 6775400 116.5
+507100 6792600 89.5
+470400 6777800 117.5
+529900 6783500 152
+498200 6802300 114.5
+525200 6771800 144
+492500 6804900 109
+502200 6805800 128
+514700 6786200 131
+488900 6796400 74
+514600 6778800 93
+525700 6790000 112.5
+481200 6779300 118.5
+529400 6788000 136
+475500 6784600 138.5
+474400 6772800 92.5
+531300 6775600 153
+479100 6802100 92
+481600 6776300 88
+498700 6778600 89.5
+510800 6754700 113
+531700 6763000 137.5
+462400 6737000 60.5
+474900 6763000 70
+522900 6758300 136.5
+457700 6751500 54.5
+469700 6804200 129
+490500 6774600 66.5
+473800 6779900 112
+469300 6770300 87
+506600 6775200 83.5
+516400 6773700 105
+492100 6729400 69
+508700 6789600 122
+506400 6789200 107
+525000 6754600 126.5
+483500 6792200 97.5
+521600 6784500 104
+478800 6782400 124.5
+510700 6781500 107.5
+479100 6793000 132.5
+482600 6790800 94
+479200 6787900 116
+460900 6781800 174
+468400 6786700 131.5
+528400 6762200 142
+502100 6815000 239.5
+496900 6819900 215.5
+503200 6789200 103
+482000 6773500 99.5
+501600 6801800 108.5
+521200 6793900 149
+493900 6801200 97
+490800 6778800 82.5
+465700 6792400 203
+482800 6782900 122
+499400 6796400 70.5
+538200 6764500 124
+499300 6791500 93
+506900 6762100 110.5
+471100 6783100 136.5
+472000 6764100 67.5
+517200 6766500 137
+512300 6771900 115.5
+496000 6764000 56.5
+531700 6750600 109
+480600 6806600 128
+501000 6731200 64
+504000 6734300 71.5
+518800 6758600 133.5
+487300 6761900 47.5
+506400 6746500 127
+464700 6753800 42
+492700 6807900 134.5
+454300 6756600 48.5
+483700 6767600 75
+494800 6805100 113.5
+469300 6737800 63
+503400 6809400 145
+481300 6751500 75
+492900 6782500 73.5
+512200 6761700 134.5
+453100 6755300 49
+495100 6735800 77.5
+491300 6783000 62.5
+485900 6787300 93
+523200 6768400 143
+519100 6751800 114
+457500 6741900 47.5
+463300 6745600 51.5
+472400 6768900 84.5
+537700 6786500 197
+510300 6770900 108
+496300 6802300 107
+451100 6745900 40
+486300 6731000 61.5
+484400 6814600 162
+524500 6793700 126
+508900 6742400 108.5
+511800 6754700 122.5
+508800 6803800 86
+483600 6806900 112.5
+472100 6775500 120.5
+504200 6773100 92.5
+507800 6778400 96.5
+515000 6782100 109
+496000 6751100 115
+485200 6759300 54
+457400 6766600 79.5
+505300 6743100 119
+496000 6812100 213.5
+514600 6747900 102.5
+486900 6803600 93
+523600 6795400 122.5
+500000 6811900 234.5
+488300 6781400 98.5
+527800 6790600 137
+525900 6788400 104.5
+527200 6758100 135.5
+502700 6818500 166.5
+475900 6739200 65
+536000 6784200 191
+523600 6778400 138.5
+490000 6762200 47
+529200 6782000 134.5
+485400 6742400 69.5
+481100 6803300 95
+495900 6743400 107
+517600 6748800 105.5
+467700 6773500 99
+489600 6742600 76.5
+1004000 6472600 2482.5
+955500 6507300 1226
+959100 6480000 799.5
+926800 6514100 374
+962900 6466200 1571
+963500 6472200 1627
+990100 6464000 2244
+972200 6527800 1185.5
+943800 6489200 564.5
+989600 6503500 1855
+956900 6508400 453
+912100 6503000 515.5
+956400 6510300 1125.5
+929700 6520900 440
+986000 6503100 1812.5
+984700 6461500 1949.5
+916600 6508700 919.5
+973100 6494000 1109
+939000 6489500 392
+956200 6499800 894
+978000 6487500 2122
+975600 6490900 1036.5
+984300 6488200 1877
+959100 6478000 836
+908500 6496500 267.5
+938500 6497200 1148
+942500 6493100 533.5
+969900 6492400 1640
+953600 6505400 1181.5
+934600 6506900 1240.5
+922000 6515800 612.5
+948700 6497300 429
+918100 6496700 868
+959600 6482400 1715.5
+986400 6501600 1680.5
+966800 6466500 1763
+976900 6496100 1440.5
+936600 6501000 1036.5
+957600 6504000 1430
+930000 6516300 998
+957700 6509500 387.5
+913000 6509500 610
+925600 6507800 311.5
+918000 6502800 808
+963100 6473100 1645
+980600 6490500 1550.5
+950500 6499800 471
+957400 6489200 1547
+958200 6499300 1234
+920200 6489200 1100.5
+991100 6482700 2497
+958300 6478700 589.5
+974200 6481700 2102
+934700 6500800 825
+999200 6471500 2566
+952800 6471200 1931.5
+956300 6491000 1341.5
+915200 6487500 846.5
+992000 6464200 2300
+939400 6491600 311
+946600 6514600 1486.5
+914000 6495600 388.5
+958300 6510300 396
+923500 6498100 849
+943500 6516200 1036
+938100 6513400 1271.5
+977600 6462900 2109.5
+973000 6530500 1392
+940900 6510400 1356.5
+930900 6494500 928
+962800 6511500 992.5
+916700 6512500 890
+960600 6497000 1412
+914600 6515400 415
+956900 6461800 2240.5
+924800 6517800 534
+947400 6489800 1315.5
+947700 6491700 1148.5
+978700 6490000 798
+996100 6509700 1893
+969300 6457600 2099
+986700 6461300 1925.5
+914500 6500700 580
+964000 6514100 1179
+962200 6469700 844.5
+961600 6509100 1183.5
+916900 6527100 396
+929800 6505100 966
+957900 6499100 659
+920600 6531700 627
+922200 6513400 844
+937300 6487600 339
+977900 6495000 1047.5
+936100 6503600 1119
+917600 6519300 677
+974300 6520300 1453.5
+964100 6515300 596.5
+959700 6513800 1199.5
+921900 6500500 696.5
+923200 6483800 1227
+916000 6503200 765.5
+974000 6490300 1104
+938400 6493900 728
+933100 6495000 318.5
+917100 6498500 450
+931400 6499600 354
+957400 6501300 1333.5
+922100 6493100 1068
+993000 6501100 2439.5
+939900 6517600 999
+928700 6510800 885
+916600 6520800 440
+978100 6491900 1258
+958500 6476600 1291.5
+1006500 6473200 2499.5
+965600 6515600 867
+930400 6497200 586
+928400 6513400 939.5
+946100 6501600 1156
+940000 6506800 1458.5
+978700 6523200 1667.5
+917300 6507200 938.5
+933400 6519500 907
+946100 6512800 1308
+927800 6500500 402.5
+989100 6487200 2112.5
+912200 6501700 499
+956300 6485300 1280
+909000 6499100 289.5
+969400 6505000 1527.5
+911400 6497000 299.5
+916700 6493700 904
+1012800 6476900 2713.5
+939400 6494500 385
+932200 6501300 473.5
+932800 6498600 505
+920400 6535400 647
+971900 6529300 1560
+913100 6492800 413.5
+968000 6505600 1422.5
+945200 6488800 1347.5
+940100 6487800 514
+927600 6521600 574.5
+955900 6492400 1205
+984600 6501700 1592.5
+925700 6512300 279.5
+967700 6507300 1212.5
+944300 6520200 1219
+961900 6474600 1143
+919100 6525100 334
+933600 6503000 936.5
+928800 6525000 507
+942200 6487600 547
+918400 6523400 425
+962200 6517400 1086.5
+961900 6480200 1745.5
+918500 6517200 740.5
+927300 6499300 433
+923800 6526300 723
+910100 6500600 355.5
+949500 6500200 302.5
+991600 6503800 1702
+968700 6508900 1393
+941500 6516800 941.5
+988000 6504000 1552
+929300 6502200 422
+960700 6512200 381
+930600 6502200 765
+913800 6511700 485
+909000 6504700 484
+988500 6490600 2407.5
+967800 6512000 1391.5
+950900 6497700 669.5
+971000 6498500 1613
+972400 6486800 1745
+920900 6485100 1048.5
+984100 6462300 2165.5
+1002700 6506300 2309
+961800 6484500 1815
+928800 6509000 636
+945800 6493700 514
+925400 6487700 1344.5
+943700 6490100 562
+958100 6511400 1230
+920700 6539500 642
+913600 6507100 635
+947600 6497200 470
+944900 6495400 501.5
+919600 6497100 866
+914700 6509100 418
+969600 6496900 1455
+927100 6506200 475.5
+956100 6487200 1276
+952100 6493900 1201
+953800 6463200 2445.5
+940100 6493100 311
+956600 6494500 897.5
+964200 6518200 1082
+944600 6506200 1394
+971100 6535200 1806.5
+999700 6508700 1899.5
+962100 6463400 2029
+944000 6500100 921
+956700 6482200 823.5
+975600 6492000 894.5
+988300 6462500 2307
+940300 6489000 584.5
+969000 6519200 1432
+968600 6504300 1230.5
+993500 6465700 2360
+960000 6470000 1466.5
+932300 6521900 561
+919300 6521200 806.5
+937800 6513700 1064.5
+936900 6493500 689
+929900 6514900 959.5
+928200 6518000 436.5
+905300 6503600 348.5
+950300 6503400 1168
+908300 6506200 513.5
+929700 6500300 500
+921400 6528600 563.5
+924300 6503800 836
+974000 6495100 1358.5
+972000 6495400 805.5
+914100 6498700 474.5
+926900 6497300 902.5
+932000 6518100 967
+943800 6487300 1580
+958200 6512700 1306.5
+914500 6491700 522.5
+925800 6497300 925
+955400 6482200 1577
+914100 6504900 649
+985200 6489200 1667.5
+973200 6529400 1453.5
+930500 6524400 435.5
+924600 6524000 538
+911500 6515500 449.5
+1002000 6506500 2319
+935100 6496100 765
+978000 6519500 1782.5
+958700 6493700 1511
+916900 6487300 819
+930100 6519800 453.5
+915200 6505300 917
+957700 6476800 1592.5
+941300 6494000 345.5
+947500 6511400 1453.5
+967000 6467600 1688
+996200 6465300 2286
+922700 6509500 861
+946600 6510600 1441
+960700 6468900 1426
+948600 6495600 659
+970700 6501500 1438
+950500 6492300 1269.5
+964600 6468000 999
+945200 6496700 343.5
+990700 6505800 1868
+965800 6522800 1399
+993600 6508900 2283.5
+933700 6518600 1002.5
+959600 6479500 846
+960500 6508500 1295
+919400 6514000 869
+954100 6501000 647.5
+926300 6509600 308.5
+972100 6463000 1127.5
+916000 6490800 859.5
+976000 6493500 753.5
+957200 6466100 1677
+954500 6473000 1697
+970300 6466000 1739.5
+972600 6463700 1914
+917900 6528900 310.5
+1010800 6491200 2692
+964700 6519700 1217.5
+915300 6485700 411.5
+910200 6506000 628
+958700 6507000 1296
+970500 6523500 1200
+945100 6492200 554
+926000 6500000 360
+945000 6490800 421
+945400 6489700 626.5
+980800 6489200 1563
+950700 6495000 928.5
+984600 6503600 1766
+1016600 6482800 2700.5
+980500 6496700 1546
+933600 6497200 597.5
+980600 6499300 1405.5
+998600 6470000 2236.5
+961800 6473700 1572
+934300 6493300 679.5
+973400 6459900 2180
+944100 6514400 1264
+965400 6517000 655.5
+952900 6497000 900
+959000 6466200 1482
+913000 6499200 422.5
+1005600 6493500 2593.5
+948200 6498900 353
+941200 6496800 864
+937200 6556900 717
+931000 6554700 603
+978900 6592900 983
+930600 6538100 422
+923400 6551800 412
+925200 6560700 632
+955900 6557300 1198
+951200 6549300 1282.5
+947500 6563200 920
+979900 6553300 1566
+927500 6558900 756
+973400 6551900 1784.5
+959200 6563100 739.5
+989400 6531500 2439.5
+919000 6546300 351
+939400 6542200 607.5
+935900 6527400 486.5
+961500 6577100 1064.5
+940600 6542600 565.5
+992000 6595100 950
+964900 6582000 888
+956600 6577800 794
+959300 6528100 1413
+940000 6536800 735
+924800 6543200 598.5
+953900 6538700 1224.5
+983100 6568800 1360
+942600 6538100 672
+986500 6582200 1630
+935100 6543000 605.5
+984800 6573000 1608.5
+936200 6533600 627
+931000 6556700 625.5
+935700 6531900 510
+963100 6566500 1025
+928600 6529400 423
+939500 6559700 988
+960200 6524200 1139
+977300 6562700 1304.5
+980600 6535000 1756
+954800 6582200 499.5
+957800 6589200 411.5
+947800 6534000 836
+971200 6592300 525.5
+982200 6539400 1252
+955900 6571000 962.5
+962800 6550200 1499.5
+961400 6534600 1602
+933200 6554600 570.5
+933400 6559100 675.5
+929200 6560800 457.5
+948600 6530400 822
+972500 6557100 1281
+959500 6586900 548.5
+918800 6553100 406
+954900 6560100 682.5
+945300 6551400 701.5
+937900 6561600 566.5
+980700 6555700 1513
+926300 6559900 623.5
+971000 6582000 1155
+920800 6557400 431.5
+932700 6535000 534.5
+973500 6559900 904
+986000 6571200 1675
+932300 6552500 498
+926800 6540800 449
+1004100 6555900 2109
+954500 6557100 751
+923700 6555700 665
+932400 6547300 560
+945300 6555300 827
+942400 6549300 658
+975700 6595200 572
+965300 6539600 1803
+966100 6584200 1040
+927300 6544900 574
+936600 6548300 646.5
+979000 6595200 601
+959500 6579400 977.5
+942900 6524100 1211
+928400 6550500 514
+935500 6522900 892.5
+939700 6539800 435.5
+951100 6537300 1184
+983000 6573400 1308.5
+957800 6536800 1427
+984200 6594200 1367.5
+961200 6527600 1576
+981600 6577100 1487
+946300 6547100 641.5
+921000 6553700 436.5
+927600 6537600 404.5
+950300 6572100 476.5
+952000 6567300 459
+959700 6555200 1164.5
+928400 6542900 552.5
+949500 6547100 1125.5
+982500 6587100 1422.5
+937700 6559400 952.5
+955600 6590900 406.5
+979300 6558900 1020
+965500 6559400 1143.5
+953100 6588700 411.5
+960600 6564600 659
+962700 6558900 1152.5
+941100 6549600 676.5
+969300 6556400 1506.5
+924200 6552400 442.5
+955900 6576000 983
+967000 6565700 1179
+944700 6524800 1257
+980900 6561200 969.5
+935100 6538300 510.5
+979900 6542300 1550
+985600 6542700 1711
+960900 6539700 1367.5
+979800 6588700 1093.5
+962400 6545300 1387
+924900 6539300 660
+919600 6543900 593.5
+991400 6543800 1541
+926600 6529700 599
+945500 6530900 1050
+928900 6556200 800.5
+953500 6527800 1486.5
+966300 6587500 594
+976600 6555600 1431.5
+932100 6541100 524.5
+923600 6548000 460.5
+981500 6595700 808.5
+944500 6554200 714
+962600 6580800 886
+928800 6552600 725
+985600 6596400 686
+968300 6569400 1267
+967400 6591500 470
+967500 6578000 1205
+963400 6589600 421
+950200 6523200 1339.5
+943200 6543200 597
+979700 6580100 1265
+931400 6532900 446.5
+962900 6581600 527
+934000 6526400 550
+934300 6530900 521.5
+947400 6567300 837
+941400 6546700 721
+948800 6569300 626.5
+943500 6540300 785
+991000 6592400 1480
+943800 6545200 626.5
+926600 6550800 430.5
+949600 6535000 1187
+952300 6522200 1127
+942700 6565000 883.5
+973800 6586800 995
+939400 6521600 1050.5
+964200 6541600 1344
+956900 6523900 1258.5
+919000 6550600 398.5
+940600 6538500 462
+977500 6594700 571
+943500 6534300 863.5
+957400 6561700 455
+960600 6556700 966.5
+917500 6555800 429.5
+954200 6583700 470.5
+976700 6560400 933.5
+972700 6584400 1269.5
+957800 6567500 880
+956600 6519400 1384
+964100 6566400 983.5
+964900 6584000 609
+969600 6572600 1308
+925700 6539700 646
+963900 6587800 451.5
+931700 6529900 422
+929500 6541000 525
+982500 6591200 1520.5
+935800 6556200 632
+956200 6583100 603
+973900 6589900 655.5
+923200 6544700 749.5
+952300 6564600 621
+947300 6570000 408.5
+948600 6559700 819.5
+958900 6566000 623
+944600 6559200 1025
+995700 6581300 1741.5
+957400 6555800 1075
+955100 6567000 472.5
+925100 6545500 599.5
+981300 6543900 1632
+964400 6571600 1073
+928400 6533900 450.5
+934500 6562000 556
+929600 6534900 368
+964800 6565000 1107.5
+980600 6535000 1408.5
+944500 6526700 1140
+937600 6554700 712.5
+941800 6543300 648.5
+919800 6549400 394
+937300 6540400 529.5
+940300 6553000 878.5
+977900 6586600 1059.5
+978600 6578500 1246.5
+944400 6546800 620.5
+952800 6573500 496
+935700 6551800 551.5
+966300 6555600 1321.5
+973000 6591800 711
+952300 6561600 705.5
+982800 6571900 1586
+941800 6564300 916
+950200 6524700 1123
+983900 6561800 1373
+991400 6584300 1702.5
+934000 6539900 527
+961700 6571200 1040
+965300 6543800 1820.5
+971900 6579100 1473
+966000 6576200 1193.5
+961300 6580500 741.5
+946400 6536200 866
+930700 6551500 523.5
+965200 6574400 1165.5
+963800 6574700 1016.5
+947100 6542100 880.5
+949500 6571200 451.5
+978200 6589700 728
+999700 6543200 2901
+982700 6541400 723.5
+951000 6569000 486.5
+949700 6539800 1174
+931300 6560500 580
+943800 6566200 840.5
+957900 6564200 560
+938700 6556400 974
+968600 6585100 994.5
+970300 6560500 1146.5
+970800 6588000 926.5
+974400 6557000 1218.5
+972300 6593600 546.5
+969900 6557800 625
+974600 6591600 793
+987900 6560600 1668
+976400 6585800 1205
+956100 6568600 869.5
+971900 6565400 1291
+953800 6570500 939.5
+983900 6560400 1351.5
+932000 6549500 444.5
+950400 6557600 878.5
+947000 6544000 1071.5
+977000 6532700 1631
+956400 6585000 539
+933300 6536800 465
+953900 6590400 398.5
+935700 6536800 490
+958200 6534500 1504
+925800 6534900 679
+939700 6562700 685.5
+958500 6522000 1271
+947600 6526700 1252
+932800 6523700 572.5
+942900 6556600 1002
+948800 6525400 1045
+994400 6539300 2538
+970600 6589200 544.5
+935500 6544700 690
+930800 6526700 466
+962300 6562500 1226.5
+991800 6557600 1913
+987900 6539300 2689
+937700 6528100 1071
+982400 6584000 1334.5
+956000 6521700 1267.5
+934500 6528600 483
+978100 6582200 1263
+956000 6563000 456.5
+957200 6558100 534
+928500 6547800 528.5
+938000 6565100 481
+976600 6557500 833
+962400 6573300 1096.5
+937300 6525500 1022
+950900 6579800 432.5
+949300 6553700 774
+951400 6586100 405.5
+939400 6531400 1059
+948600 6571200 422
+949400 6531800 1380
+651900 6862400 0
+559000 6940300 105.5
+573300 6956500 143.5
+555800 6980400 51
+550800 6966100 87.5
+581700 6950800 179
+545900 6972900 55.5
+531400 6957700 111.5
+532000 6971900 65.5
+519200 6949100 126
+593400 6969000 192.5
+602400 6968600 186.5
+591400 6958200 161.5
+534500 6962400 110
+573000 6971000 101.5
+597000 6972900 153
+603400 6974100 159
+568400 6969800 86
+527700 6972800 45.5
+572000 6943700 143.5
+552500 6977900 35
+593900 6963600 173.5
+567100 6941900 115
+514700 6956300 111
+605500 6929800 150
+521000 6945700 111
+528200 6959800 125
+586400 6954100 166.5
+557400 6910400 39.5
+533400 6969300 89.5
+532500 6960400 92
+527300 6961500 95
+512400 6960300 80.5
+543000 6954600 150
+498200 6957300 57
+550200 6935500 66.5
+500100 6955900 61
+598300 6964800 201
+540200 6966900 110.5
+531500 6937300 73.5
+573600 6983300 93.5
+498400 6947400 69
+515100 6948600 110.5
+501400 6944100 83
+508100 6955100 111.5
+546000 6933800 61.5
+491300 6943400 52.5
+606600 6960100 182.5
+583200 6997000 51.5
+552400 6980600 43.5
+501300 6939800 70.5
+509400 6942900 121
+496100 6943800 65.5
+552200 6929000 68
+581300 6944100 190
+503700 6943100 86
+538500 6971100 75.5
+573600 6936000 144
+566700 6984000 48.5
+568500 6918700 98
+579800 6990500 55
+577600 6979700 97.5
+575100 6984100 120.5
+580000 6965600 124
+524300 6950200 135
+515500 6934900 58.5
+500000 6940500 57
+515400 6940600 98
+568100 6972700 77
+506300 6939200 70.5
+575000 6939100 145.5
+572000 6957900 134
+559300 6965100 116.5
+526300 6957700 116
+548500 6964800 116.5
+521000 6954600 128.5
+604400 6968500 172
+528800 6933300 65.5
+567100 6966600 111
+550800 6974300 46.5
+601200 6966200 199.5
+503400 6946600 102
+583400 6963900 138
+600000 6971400 187
+596900 6975200 156.5
+558000 6951100 159
+576800 6942200 166
+557100 6914600 19.5
+564800 6962300 109.5
+525100 6931700 19
+569900 6985900 55
+562900 6959300 126
+531000 6955500 105.5
+558700 6927400 18
+581100 6987700 67.5
+584000 6933300 122.5
+603500 6943400 163.5
+544000 6978000 34.5
+563300 6955100 137
+507200 6958500 107.5
+551500 6954800 135.5
+587000 6977700 156
+577700 6958100 165.5
+593200 6975600 141
+549600 6928300 34.5
+540900 6972200 77.5
+565900 6951200 151.5
+533600 6954300 111
+543700 6950300 145.5
+540400 6964200 114
+583700 6957600 163
+607500 6932000 108.5
+545600 6957200 153.5
+561600 6949600 147.5
+570800 6981900 64.5
+545100 6961200 132.5
+578300 6984400 118
+516200 6954900 114.5
+551100 6950400 163.5
+579300 6992100 53
+557300 6958100 149.5
+585100 6961600 142.5
+575900 6946200 167
+511200 6948200 118
+584600 6941500 183.5
+561300 6917500 65
+534500 6943800 94.5
+565100 6974600 110
+558600 6979300 51.5
+597300 6963200 213
+508700 6946800 110
+547600 6942400 99
+602000 6964100 190
+543700 6936600 78
+509700 6952800 115.5
+524000 6943100 102
+583500 6952000 210
+586700 6995500 71
+563400 6948500 139
+602800 6941400 149
+561200 6976400 57
+577400 6988800 81.5
+527700 6949500 134
+580600 6941800 157.5
+565900 6928800 78
+529500 6942400 86.5
+583300 6935800 129
+606800 6925700 143.5
+568300 6931200 103.5
+547900 6932300 12.5
+568500 6937600 130
+536700 6972700 52
+579900 6931500 112.5
+588300 6968800 155
+553200 6936500 72
+542100 6942100 106
+554900 6921600 60.5
+571500 6949600 154.5
+565200 6977400 65.5
+552600 6965900 85.5
+537900 6964700 106
+597600 6960300 195
+584400 6955600 162.5
+605500 6965800 165.5
+528700 6939500 125.5
+514400 6961600 77
+596600 6972000 167.5
+606500 6953600 204.5
+553200 6976800 40.5
+538000 6959600 132
+550600 6919600 51.5
+515500 6942200 88
+497900 6955300 79.5
+498400 6959900 51
+567800 6926300 97
+579300 6975800 111.5
+592200 6930200 154.5
+595900 6952400 180.5
+565400 6918800 67.5
+557700 6936100 75
+509800 6956800 106
+500300 6951700 106
+510100 6944900 102.5
+596200 6954900 177
+553500 6946200 122.5
+569800 6983600 78
+542700 6945500 95
+593300 6937700 162
+537600 6948700 120
+603100 6949900 217
+602600 6962000 209
+550400 6979700 29
+555200 6919400 70.5
+569400 6980500 68.5
+593000 6953600 151.5
+559900 6969300 103.5
+580900 6961700 143
+595500 6962300 179
+599300 6934800 156.5
+541400 6975000 54.5
+551100 6913700 79
+601600 6932900 159
+546800 6964700 117.5
+593300 6985500 136.5
+549700 6918800 67.5
+495700 6947800 84
+528100 6957500 127
+558600 6924700 34.5
+500800 6954700 78
+600300 6927900 164.5
+559900 6943500 118
+538400 6973500 72
+552300 6959300 118
+516500 6968500 59
+512000 6950800 115
+508600 6950800 120
+492400 6947800 52.5
+560900 6936500 104
+573100 6941900 154
+541500 6951500 141.5
+559100 6913800 39
+596800 6970600 171.5
+523900 6947200 140.5
+566800 6972300 91.5
+600000 6943000 151
+548300 6970800 81.5
+523200 6959000 104
+583700 6931300 107
+540200 6960300 120.5
+535200 6969600 85
+589200 6946000 177
+555100 6911400 67.5
+581000 6936800 142.5
+565100 6922600 81.5
+584800 6981300 131.5
+512900 6941700 97.5
+551500 6926300 60
+572300 6985700 64
+499300 6955300 89.5
+546700 6931200 22.5
+538000 6935100 27
+574700 6932100 160
+574700 6923300 144
+586300 6932000 120
+607000 6974500 133
+609000 6932200 137.5
+578100 6986600 95.5
+573100 6988200 64.5
+513300 6944700 88.5
+588400 6987000 124
+584900 6971500 133
+567200 6933200 109.5
+562800 6930700 111.5
+585000 6985700 98
+516200 6964100 70.5
+576400 6982900 120
+576400 6940000 155.5
+513000 6957700 108.5
+576900 6935100 124.5
+566200 6919800 93.5
+606500 6939500 157
+565800 6927700 79
+524300 6939100 89
+517600 6947200 104.5
+555800 6935900 100.5
+584800 6991200 78
+573800 6945600 154.5
+601500 6982300 129
+520700 6963300 79
+575600 6986700 118.5
+596400 6977800 151.5
+555700 6975000 49.5
+551900 6940300 79
+562900 6969700 81.5
+579100 6967700 116.5
+537200 6968500 96
+566000 6964700 118
+543900 6963800 125.5
+566500 6963300 116.5
+535800 6964200 99.5
+518800 6968800 68
+526400 6967800 93.5
+549000 6958900 143.5
+562900 6960700 117
+522000 6951000 136
+501700 6959200 64.5
+598900 6984200 114
+550400 6952000 153.5
+579800 6971000 141
+502100 6947600 102
+531400 6961400 89
+554700 6938400 95.5
+586200 6960600 104
+512600 6937200 63.5
+598100 6982800 135
+497000 6937700 44.5
+533500 6973700 40.5
+563900 6966500 102
+549600 6969700 98.5
+589900 6933800 138.5
+527200 6970100 66.5
+576200 6925000 143
+531700 6953900 108
+564300 6924100 74
+507500 6961300 84
+591900 6991300 76
+590200 6942600 168.5
+580000 6984200 95
+508200 6958000 100.5
+559600 6976400 50
+542500 6957600 154
+600800 6973500 175.5
+533800 6960200 88
+568600 6968200 102
+602900 6937800 135
+591300 6964700 167
+540900 6934300 59
+524400 6964200 103.5
+528400 6968300 61
+591700 6987100 104
+508900 6937100 82.5
+562300 6956700 130.5
+586100 6942400 200
+579600 6954900 192
+573300 6926900 119
+510000 6959600 99.5
+521700 6944200 105
+566300 6979700 52.5
+526100 6948700 138.5
+582100 6969600 148
+556700 6964200 102.5
+559300 6968200 117.5
+505700 6936400 54
+569100 6946000 135.5
+572200 6966700 136.5
+554600 6968300 80
+532100 6959400 87.5
+529900 6971400 51
+589100 6936500 151.5
+589000 6989600 95.5
+533000 6948500 134
+528700 6953700 136
+549300 6966700 87
+586000 6970800 122
+563300 6946100 122
+540300 6941400 74.5
+596700 6946400 182.5
+565400 6934900 136
+568200 6939800 134.5
+540000 6955300 132
+493900 6950000 56
+555600 6942300 115.5
+515400 6950300 120
+525600 6965900 109
+550500 6964300 97
+566300 6961700 135.5
+546400 6937300 66.5
+540900 6943900 82
+554700 6933900 94
+591200 6956000 140.5
+533800 6945300 107.5
+536100 6952600 139
+574100 6929200 131.5
+545800 6968300 84
+560700 6940300 110
+596000 6985500 118.5
+547900 6948400 123
+579400 6983500 125.5
+563800 6939600 121.5
+547300 6969400 81
+575200 6978900 89
+562300 6921500 45
+541400 6929400 40
+519200 6960700 88
+505500 6944200 106.5
+498300 6948300 75
+540700 6968900 93
+561800 6972400 68
+593500 6966800 171
+549800 6972000 83
+570200 6943700 137.5
+553700 6962100 108.5
+561300 6965800 106
+518000 6942600 76.5
+569100 6976000 68.5
+561200 6968400 94
+547500 6945600 119.5
+562200 6971900 72
+603600 6946300 190.5
+528700 6947700 141
+545200 6975600 56
+558600 6931800 69.5
+558100 6938100 101.5
+586400 6969000 147.5
+594800 6946900 147.5
+589200 6947400 176.5
+558100 6933100 74
+572000 6977100 102
+571100 6940200 145
+508600 6940100 89
+585000 6945000 214
+553300 6973500 49.5
+526900 6931500 60.5
+515800 6959100 83.5
+605700 6935600 126.5
+531100 6939100 77.5
+549300 6939700 70
+518900 6955500 105.5
+592500 6939000 155
+565700 6967900 109.5
+554300 6950100 131.5
+595400 6978100 141.5
+566900 6931500 98
+519400 6938900 67
+524000 6934900 69
+558800 6952100 155.5
+547200 6963400 125.5
+523800 6972300 45.5
+543600 6958800 143.5
+547200 6951200 151
+607500 6936400 140
+511700 6954800 108.5
+564500 6971100 96.5
+574000 6949800 166
+552600 6962800 104.5
+568200 6949000 152
+567900 6923900 118.5
+603700 6930800 165.5
+588500 6995000 74
+511200 6945600 106
+521500 6965000 92.5
+535500 6936700 27.5
+586600 6938500 156.5
+544500 6925700 28
+569500 6960700 120.5
+526600 6964400 84.5
+529100 6951700 133.5
+514200 6962900 73
+528100 6936400 116.5
+535600 6946500 118
+505600 6941200 92
+584200 6993600 71
+539500 6949400 128
+535300 6938700 58.5
+558500 6933900 88
+517000 6937600 66.5
+580400 6980600 119.5
+538600 6969100 95.5
+572100 6924700 113
+536800 6955900 111.5
+576800 6932300 135
+563400 6930000 118.5
+535000 6941900 75.5
+549800 6923400 57.5
+569600 6928300 113.5
+566300 6954900 149
+546000 6924400 30.5
+538300 6938700 62
+574600 6988500 64
+566700 6970800 105
+578400 6961000 165
+562400 6928700 77
+569500 6922400 114
+563400 6974900 66.5
+564200 6954400 140.5
+498300 6946200 67
+538700 6952700 135
+592300 6964000 172.5
+548700 6956900 154
+532100 6946500 134
+539900 6947500 99.5
+543000 6943000 109.5
+583000 6987900 86
+561200 6963500 107
+526900 6954900 126.5
+545300 6942600 90
+534900 6971700 55.5
+543200 6938400 90
+513300 6962600 69
+567400 6918100 100
+529100 6943700 117
+586500 6985000 99
+552800 6976100 41
+563700 6915100 44
+576000 6953900 159.5
+541700 6977200 39.5
+577100 6950300 158.5
+523000 6965700 95
+499300 6952500 101
+503800 6962000 54.5
+528000 6942200 113.5
+548000 6976200 38.5
+539300 6951500 142.5
+551400 6967700 80
+610000 6964300 159
+606300 6942200 157
+580700 6952600 184.5
+581300 6930100 108.5
+552600 6948900 134
+524300 6968700 88.5
+555600 6953800 138
+592000 6957400 168.5
+513300 6954000 114
+519700 6957400 100.5
+597300 6950300 191
+515100 6953300 123
+535800 6959800 115.5
+503300 6950000 115
+573100 6934000 150
+590700 6939600 159
+561100 6974700 57
+578700 6936100 128.5
+526300 6939700 128.5
+555800 6967200 84.5
+591600 6980500 129.5
+569900 6956100 132
+593300 6943100 157.5
+559200 6959800 128
+600500 6945700 183.5
+580500 6949000 172
+541900 6928200 41.5
+517000 6953600 118
+559000 6955000 155
+550000 6948000 120
+527100 6951300 131.5
+566700 6982000 87.5
+508800 6936100 62
+547100 6960600 139.5
+508600 6948900 119.5
+519800 6954700 126
+583400 6943800 185
+536700 6957900 119.5
+547800 6952000 161
+545200 6970300 72
+582900 6937900 136
+599600 6946900 187.5
+532200 6934800 62.5
+582400 6959900 156
+585300 6939800 170.5
+588600 6992500 91
+576800 6990700 48.5
+604400 6979600 128.5
+561300 6930900 107.5
+590300 6985400 136
+567900 6984900 51.5
+529200 6973000 48
+538400 6975200 41.5
+553100 6958100 114
+552300 6970400 63.5
+594300 6949000 163
+555900 6965500 97
+565500 6948600 143.5
+564100 6927000 79.5
+548000 6954100 161
+577800 6982600 140
+561900 6982000 47
+572500 6972700 86.5
+554300 6914400 66.5
+522000 6970000 52
+578400 6944800 179
+574600 6973600 112
+581300 6939000 148
+496500 6942200 48
+493300 6941200 53
+497000 6956100 57
+587000 6930700 126
+588700 6983800 116
+561300 6924900 25.5
+544600 6946900 105
+564300 6917300 44
+532900 6967900 85.5
+521900 6957800 100.5
+516900 6966900 90
+558000 6945200 150.5
+542700 6948400 116
+562600 6970900 75.5
+519900 6965400 100.5
+542900 6968400 88.5
+607900 6971300 143
+607000 6965600 159.5
+506800 6944800 112.5
+556800 6922500 55
+553000 6964100 115.5
+562500 6957800 128.5
+588700 6958000 154.5
+552200 6957200 124
+548300 6959700 137.5
+544500 6955200 158
+571400 6946600 166
+537200 6961400 122
+575800 6969200 114
+553500 6952300 143
+570500 6974900 75
+546400 6922600 65
+525800 6942600 127
+563200 6942900 120.5
+566300 6946800 136.5
+551900 6942900 108
+557400 6948100 168.5
+595700 6939500 149.5
+499000 6943900 57.5
+570500 6933900 128
+582700 6994400 51
+591900 6936900 152
+573800 6939500 152
+504300 6937400 54.5
+556400 6956300 137
+555300 6913000 25.5
+547900 6965700 102.5
+586000 6988700 107
+520700 6960300 95.5
+584600 6977400 160.5
+567700 6959800 121.5
+590000 6977300 148.5
+598400 6945700 160.5
+538500 6933700 68
+578300 6939000 136
+556000 6910800 39.5
+547200 6978800 27
+529900 6963500 83.5
+595000 6988800 85
+586900 6951600 167
+555800 6951900 157
+544300 6965600 107.5
+587500 6960500 149.5
+517700 6949700 126
+558100 6971800 90
+607400 6967300 150
+552300 6932900 67.5
+588600 6973600 160
+539600 6970900 80.5
+563800 6967500 95.5
+558500 6974000 83.5
+555100 6970800 63
+567100 6975600 61.5
+521700 6938500 66.5
+581800 6974400 124
+567400 6958100 119
+535000 6976200 40
+575100 6970100 106
+590100 6972500 167.5
+556200 6950700 168
+524000 6970200 65.5
+562300 6916000 42
+590200 6966700 160
+488700 6938000 50
+523200 6955200 114
+520300 6947400 135.5
+567700 6953400 150
+573500 6947200 169.5
+541900 6956400 148
+565100 6925100 113.5
+571600 6953800 134.5
+603200 6927500 165.5
+533000 6952200 118.5
+552200 6917800 63.5
+513900 6946700 110.5
+572400 6920100 118
+527000 6974700 40.5
+541600 6966300 108
+526400 6944300 144.5
+507600 6963400 53.5
+580700 6935000 120.5
+511100 6965200 62.5
+577000 6973900 145
+603600 6971100 165
+598700 6969900 180.5
+555500 6973100 61
+545200 6971500 61.5
+499600 6937500 51
+562700 6980200 50
+587400 6967100 153.5
+556700 6928500 70
+575500 6962200 163
+542100 6964900 121
+520700 6968300 78.5
+506200 6963200 48
+554800 6958400 125.5
+594800 6959700 190.5
+502300 6955000 81
+513800 6966800 62
+505400 6956600 86.5
+549000 6968200 110
+495000 6953000 68.5
+601000 6959100 211.5
+506400 6953600 97.5
+577500 6928200 123
+596300 6937500 152
+532500 6950000 123
+501900 6937300 53
+557100 6962400 115.5
+602600 6928500 205.5
+533400 6964300 87
+500900 6938900 66
+605500 6946300 198
+523000 6941000 91.5
+553100 6919900 29.5
+527500 6938400 107
+517900 6958100 96
+512000 6939600 119
+555000 6930700 85
+538200 6944700 85.5
+529900 6968000 68
+588400 6965700 161.5
+519700 6970400 48
+504700 6949200 120.5
+532500 6974300 41.5
+569200 6952000 160
+587300 6949500 176.5
+543100 6962100 129.5
+546300 6967200 104
+553800 6944500 118.5
+517100 6944400 85.5
+526000 6953100 125
+499500 6948900 96
+516900 6940500 73.5
+546900 6974400 44.5
+546300 6963400 134.5
+522100 6953200 126
+509500 6963500 57
+503900 6959000 60.5
+600000 6951400 194.5
+597600 6934700 180
+526300 6971000 69.5
+561300 6946900 149
+577300 6965300 157
+571800 6980100 74.5
+576100 6930300 150
+491400 6937100 52.5
+583700 6930200 106.5
+501600 6961000 49.5
+542600 6930300 35
+529200 6959300 113.5
+593800 6950600 154.5
+569000 6965200 109.5
+583000 6948100 199.5
+533900 6957700 97
+502500 6952800 115
+526400 6972600 54
+601400 6955900 219.5
+603600 6978400 143.5
+524100 6961300 102
+545000 6950600 146
+562500 6951600 161
+541800 6970600 83
+551100 6962600 104
+709500 6840600 135
+683900 6867600 73.5
+710600 6861200 133.5
+678400 6879200 95.5
+688400 6849000 113
+691000 6881900 99
+696900 6858300 101.5
+721000 6869700 155
+720800 6841100 157.5
+695800 6877000 73
+679300 6861800 90
+694100 6857700 91.5
+731400 6861400 149.5
+679400 6869600 85.5
+672300 6856700 98
+671000 6790600 108.5
+701100 6828300 121.5
+713600 6857600 115
+675400 6836500 91.5
+663500 6807600 95
+700500 6877700 80.5
+694800 6878100 82.5
+706900 6883000 136
+680300 6796800 97
+718700 6859900 167
+702100 6879400 83.5
+704000 6876900 112
+679600 6812100 71
+678400 6866800 102.5
+691700 6836800 100.5
+692600 6827700 108.5
+689600 6793500 110.5
+678700 6831300 82.5
+707600 6870900 100
+697500 6856300 92.5
+721700 6820400 108
+700100 6864700 156.5
+688200 6875100 110
+678300 6855200 115
+704200 6882100 107
+701000 6848400 110
+669400 6881700 112
+675800 6792400 92.5
+661100 6782100 98.5
+683400 6865400 79.5
+667400 6790900 110.5
+732200 6843800 178.5
+692500 6870000 94
+701700 6795300 130
+699100 6871400 129
+692700 6858500 90
+694800 6803900 90.5
+701200 6857300 100.5
+697600 6797800 119.5
+718000 6844600 155.5
+699800 6811000 90
+689200 6862500 94.5
+672200 6792600 109.5
+728800 6852800 157
+718400 6863800 128.5
+676900 6801700 68.5
+711900 6862900 146
+665400 6817700 72
+686300 6862600 100
+695800 6794800 132
+666700 6837000 86
+680500 6849000 100
+681200 6802300 65
+701600 6875400 80
+707700 6823500 127
+678000 6827800 72.5
+696300 6873000 91
+707500 6880000 153
+690000 6838300 99.5
+686000 6870000 63
+711800 6882100 164
+667100 6819800 64.5
+692300 6877600 115.5
+688600 6809700 93.5
+677200 6863300 69
+706000 6872000 102
+700300 6843400 109.5
+714700 6820000 104.5
+718900 6835700 156
+708900 6811000 86
+719200 6833200 125.5
+687000 6800100 79.5
+690700 6866600 90.5
+694800 6865700 123.5
+675200 6847300 100.5
+670200 6879900 104
+687400 6865200 85.5
+707000 6813100 83.5
+726300 6842300 151
+720200 6813100 88
+698200 6878600 82
+715500 6815400 54
+692700 6796100 117.5
+713000 6821000 100
+670100 6798300 101.5
+682600 6820800 69
+688800 6884200 93
+735000 6860400 181.5
+686600 6885700 101.5
+689600 6822600 113
+669900 6836300 88.5
+681100 6791600 100.5
+672100 6829700 87.5
+721400 6844000 158
+665100 6797700 112.5
+677600 6862300 75
+720100 6855000 137.5
+686000 6795200 108.5
+674600 6785100 105.5
+681100 6832800 91.5
+669600 6846400 81
+678400 6861600 109
+685800 6831700 87.5
+692600 6793000 118.5
+721800 6823500 116.5
+686900 6790400 125
+718200 6823800 105.5
+717100 6822000 98.5
+686200 6809600 64.5
+681700 6880900 140
+725500 6820300 108
+710000 6858000 111
+678500 6864300 74.5
+680900 6861700 107
+690200 6796400 115
+716900 6867200 122.5
+712600 6846400 135.5
+721100 6837400 163.5
+678100 6820800 65.5
+712100 6815500 91.5
+691900 6816000 108.5
+670600 6804900 119
+674300 6793800 94.5
+659900 6805300 118.5
+714800 6823300 119.5
+676200 6796100 90
+691000 6829000 100
+699700 6813800 109
+680600 6865200 81
+689600 6864900 82
+677100 6871700 83
+723000 6825500 116
+680100 6835600 93
+669700 6825300 59
+677600 6819300 64.5
+725700 6813900 67
+687700 6852100 118.5
+677900 6839500 77
+670800 6861500 72
+684000 6876000 105.5
+697600 6851700 118.5
+681000 6846100 92.5
+725900 6826400 132.5
+721700 6863900 133.5
+683400 6870200 61
+712700 6877100 126.5
+701500 6836500 116
+695800 6799000 112
+677300 6864700 78.5
+703200 6820700 133
+690400 6786300 124
+672800 6864800 53.5
+728900 6844100 172
+689000 6864700 93
+716700 6818000 85.5
+714000 6811000 89.5
+664400 6806400 94.5
+712800 6832500 145
+705400 6887800 108.5
+710800 6822700 121.5
+686200 6867000 76.5
+699100 6839200 109.5
+725800 6817000 59.5
+709500 6869700 117
+669900 6864400 71
+677700 6882100 129.5
+693200 6862100 101
+674400 6861200 71.5
+702800 6852000 107
+705900 6843200 118.5
+712400 6823500 118.5
+699200 6848400 123
+733900 6827000 136
+724500 6837400 165
+673000 6824000 65
+674400 6854600 105
+696900 6842600 95.5
+666600 6821900 62.5
+683100 6878100 117
+677900 6812100 96
+719400 6826200 112
+694300 6808200 65
+696400 6848500 120
+686200 6797000 103
+725300 6810800 107
+666600 6793000 125.5
+689700 6869700 90
+671000 6884900 124.5
+685800 6871400 68
+691800 6873300 73
+689600 6830200 100
+684200 6812000 69
+692800 6839400 95
+677300 6796500 95
+687200 6830800 93
+717100 6854800 130
+717700 6812700 68
+693900 6854400 107
+681300 6842000 90.5
+679300 6884700 122
+671400 6843700 75.5
+695400 6841700 95.5
+683700 6831800 91.5
+693100 6864600 110.5
+676400 6886300 124.5
+668500 6825100 60
+684800 6857300 123.5
+696400 6828100 111
+683200 6883400 125
+710800 6821000 106
+724600 6835400 162
+703500 6877800 121.5
+675500 6877100 79
+673400 6863900 45
+715500 6826200 111
+713100 6825200 129.5
+680500 6829200 72.5
+716300 6812600 93
+689700 6876200 128
+657800 6798700 96
+675200 6830200 82.5
+701200 6834100 118.5
+667000 6828500 61
+664900 6787300 101.5
+686000 6845700 103
+692500 6804800 83
+696100 6809200 84
+687800 6825600 101
+716500 6842800 153.5
+722700 6866700 159.5
+707900 6828400 143.5
+697800 6834100 117
+687000 6860800 132.5
+715900 6851000 131.5
+688500 6840900 91.5
+667800 6840300 67
+681900 6859800 128
+681000 6871100 63
+682700 6814600 73
+721100 6831500 132
+671000 6855400 100
+701600 6813500 98.5
+710900 6810900 84
+698000 6869100 144
+664500 6793300 125
+685200 6837300 90
+676700 6883900 132
+690500 6817900 105
+688900 6805500 81
+713500 6867400 126.5
+730900 6822000 115
+674400 6868700 94
+694200 6801300 110
+714900 6855500 118.5
+666400 6789200 105.5
+682600 6868700 57.5
+662800 6796200 124
+694800 6868900 115.5
+667200 6795600 115.5
+729000 6812700 101.5
+709600 6819800 103.5
+697000 6865100 141
+693900 6828600 107.5
+699500 6797900 124
+671100 6824500 57.5
+718500 6820100 106.5
+699300 6862600 138
+691100 6875400 83.5
+724600 6853200 149
+702200 6853900 110.5
+697000 6838700 100.5
+703700 6851000 117.5
+684100 6803800 73
+677700 6876100 87.5
+672200 6787500 109.5
+683600 6871800 67.5
+723100 6841200 153
+698300 6805300 89
+706100 6857300 111
+732300 6858900 178
+699700 6855600 110.5
+701400 6804900 93.5
+697100 6813200 110
+722400 6853600 147.5
+666700 6816500 96
+722900 6812000 97
+707000 6860100 116.5
+725400 6851400 154
+723400 6861900 143.5
+685300 6810800 76.5
+672800 6848100 89.5
+731300 6854400 155
+676500 6825200 66.5
+691100 6847600 108
+729700 6835100 155
+713400 6819800 95.5
+670600 6829600 74
+671000 6818600 84.5
+697300 6886600 114
+663700 6819500 62.5
+728600 6830900 134.5
+670800 6816200 84
+693200 6850400 115.5
+695200 6791900 127
+699700 6819000 124.5
+677700 6783200 91
+670400 6821600 76
+667300 6824600 59.5
+676400 6852200 108
+682900 6849000 101
+708600 6834800 138.5
+658200 6795500 94.5
+672800 6861700 73.5
+671400 6793900 101.5
+704900 6827700 132
+691300 6879800 123
+726500 6812400 104.5
+667800 6805100 99.5
+667800 6812600 96.5
+690800 6850500 114.5
+704700 6817000 108
+671000 6782500 98.5
+685900 6882100 133.5
+714800 6874100 124
+702100 6860300 137
+678100 6792400 93
+682500 6816300 72.5
+678100 6874100 73.5
+725300 6843800 162
+675700 6879000 83.5
+702800 6858100 109.5
+690300 6839300 90
+675100 6823200 67
+680300 6787000 96
+714500 6845000 143.5
+704900 6869800 124.5
+672700 6859600 89.5
+683400 6851600 109
+723900 6829800 134.5
+674500 6788400 109.5
+701400 6873100 77.5
+668300 6802100 124.5
+704100 6812100 91.5
+714100 6842000 145.5
+679200 6839800 82
+725100 6862600 143
+673100 6839500 73.5
+683400 6880000 143.5
+708900 6814200 92.5
+714300 6848400 143
+663200 6795100 124.5
+711100 6874900 124
+695500 6789800 127.5
+695300 6874400 76.5
+686200 6808200 71.5
+711600 6885000 139.5
+722100 6828800 127
+678300 6858000 105
+687700 6783500 98.5
+672300 6834500 88
+697900 6823400 120
+706600 6806600 78.5
+705800 6839500 127
+702400 6846300 109.5
+686200 6834600 96.5
+687700 6866500 66
+691200 6862300 89
+689800 6871200 63.5
+718400 6818500 67.5
+673500 6805300 102.5
+713200 6828200 128
+709500 6872100 115.5
+696400 6866200 145.5
+710800 6873400 118
+678800 6865000 80
+677800 6860200 96.5
+720900 6826600 122.5
+678300 6804600 89.5
+718800 6809300 100
+676900 6833000 88.5
+716200 6828900 127
+727700 6817300 61
+715400 6859500 133.5
+676100 6873900 61.5
+723600 6815400 60.5
+700100 6825100 120.5
+717600 6813400 55
+699500 6802000 125.5
+699100 6807100 77.5
+678000 6800600 70
+675500 6883500 130.5
+663200 6802200 97
+696600 6869200 132.5
+712100 6853000 130
+696000 6818200 112.5
+692400 6861300 90.5
+702300 6809500 58
+675500 6842800 81
+677600 6836300 92
+690400 6845300 99
+668000 6831600 62
+709400 6849000 132.5
+709200 6885600 130
+686600 6788800 110.5
+683900 6829600 81.5
+672800 6868300 92
+715500 6873700 129.5
+706500 6851500 123
+674800 6826700 69.5
+706400 6819000 121.5
+689200 6882800 106.5
+669200 6830700 74.5
+684300 6860600 128
+719900 6848200 164
+723500 6849100 156.5
+681800 6813900 94
+719800 6849600 157
+672800 6826400 58.5
+717300 6869200 154
+676000 6859700 99
+672600 6883100 106
+692800 6809600 96
+683100 6837500 84
+684600 6798100 78.5
+684700 6808600 67.5
+683400 6844400 91
+704000 6807300 54.5
+678000 6789200 92.5
+680900 6804200 92.5
+726400 6857400 181
+693900 6885000 101.5
+676700 6823400 61
+684900 6865800 86.5
+691400 6885200 100
+692600 6801700 99
+666400 6825900 61.5
+701600 6880600 90.5
+685400 6885600 101
+697300 6882600 103
+697500 6831500 117.5
+682600 6874600 92.5
+717900 6842100 156.5
+687400 6878700 128.5
+717500 6874400 122.5
+683400 6840100 83
+695000 6881700 103
+671900 6876100 79.5
+684500 6877900 108.5
+687300 6867900 56
+673700 6881700 94
+716200 6875400 120.5
+681500 6816900 78
+699300 6884300 119
+710200 6831000 144
+702800 6866700 157
+714300 6867200 124
+707900 6832000 135
+681900 6825400 88.5
+713700 6874800 109.5
+676400 6828900 66
+682600 6864500 83.5
+681300 6863900 83
+684400 6822500 85
+713300 6818600 89.5
+691900 6834100 111
+726800 6863900 153.5
+687500 6817100 94.5
+701600 6885800 100.5
+687400 6857100 124.5
+671200 6871500 93
+666400 6787700 103.5
+705500 6832600 125
+719100 6866400 131.5
+686800 6806000 74
+670900 6868700 91.5
+731500 6848500 172
+677700 6841300 92
+684200 6878700 113
+687900 6838300 98
+709000 6854500 115.5
+695300 6870900 92.5
+735200 6836300 166
+714300 6835000 144
+673900 6802200 99
+677300 6861100 82.5
+701300 6872400 110.5
+675000 6858800 101.5
+717100 6860800 153
+711100 6828700 130
+706600 6809800 67.5
+678300 6878000 90.5
+705300 6872800 108
+671700 6849400 95
+688700 6803000 99.5
+656800 6801900 97
+685300 6817800 80.5
+680600 6879000 101
+730000 6838800 165.5
+668000 6815300 77
+629100 6875800 104.5
+617200 6841600 169
+623100 6826100 129
+629700 6867800 120
+589100 6880600 145.5
+597900 6871900 145.5
+612700 6846000 162.5
+595900 6874600 116.5
+601500 6849900 140
+608900 6870800 100.5
+612300 6832600 155.5
+629700 6859700 105.5
+600900 6847800 144.5
+615800 6881500 85.5
+602200 6856800 141
+620000 6879000 67.5
+613800 6838800 158.5
+613300 6862800 144.5
+637700 6868000 39.5
+596600 6845300 154
+636400 6866300 36.5
+637400 6872100 39.5
+632300 6860500 137
+622500 6851900 132.5
+621000 6881100 82.5
+609200 6847500 149
+599500 6866600 96.5
+606100 6859600 125
+614400 6872200 75.5
+624700 6864200 135
+609500 6869600 98.5
+613900 6820400 149.5
+609900 6862900 131.5
+611400 6855700 134
+602600 6886800 27
+597600 6852200 118
+613700 6881900 127
+618400 6818000 152
+624500 6841900 144.5
+622900 6837900 143.5
+601700 6851500 140
+603000 6873900 113
+593700 6882600 77.5
+622800 6879900 114.5
+640500 6869800 42
+609600 6837800 151
+607400 6862300 117.5
+592600 6872600 135
+614800 6872200 63.5
+607700 6866300 145
+606000 6872500 94.5
+616600 6822000 156.5
+634700 6864700 65
+600000 6859000 137.5
+598500 6863900 118.5
+607300 6872300 82.5
+596100 6882700 72
+620100 6877600 35.5
+631500 6865600 121.5
+606300 6833000 143
+618500 6858400 112
+639200 6872000 42
+603100 6869400 107.5
+620600 6850200 138.5
+623700 6851400 170.5
+615000 6870500 74
+637100 6864500 26.5
+626500 6873100 94.5
+602700 6860400 136
+620800 6823800 134.5
+628000 6848400 132
+617000 6818700 151
+616500 6865300 84
+610500 6875400 39
+601000 6875900 101
+628900 6856200 155
+600800 6870700 120.5
+627200 6876100 98.5
+613500 6885100 147
+612200 6861700 129.5
+622700 6847300 138.5
+601700 6866700 88
+621000 6872800 107
+622100 6870400 119.5
+597700 6873600 123
+631800 6874000 25
+592000 6871100 131
+597700 6884000 64
+632300 6865100 101.5
+594900 6883200 65
+601800 6869500 113
+619200 6874400 105
+615700 6855100 89.5
+629600 6872400 30.5
+610100 6831600 149
+628200 6862600 134
+608700 6881500 131.5
+599600 6874700 95.5
+605900 6880900 82.5
+588800 6884300 101
+605600 6873400 75.5
+607800 6857300 149.5
+630000 6870300 94
+606900 6868600 134
+618700 6846900 148
+611000 6826000 145.5
+633500 6863400 113.5
+596100 6863300 128
+622700 6863300 107
+639800 6867900 40.5
+612300 6882900 127.5
+602800 6876400 77
+596500 6869900 134.5
+597100 6846200 155
+590700 6874100 147.5
+602500 6853400 138
+614000 6824700 148
+624900 6876000 43
+595600 6865600 130.5
+618100 6878600 86
+619200 6859800 113.5
+631100 6876100 92.5
+636900 6851800 125
+613200 6873500 79.5
+616300 6853700 128
+616200 6883500 115.5
+612500 6853700 140.5
+603400 6839700 146.5
+622600 6858000 132.5
+632600 6847500 138
+601100 6865200 99
+601000 6883400 40
+605600 6875700 65.5
+609600 6856800 142
+612900 6877600 104
+611200 6868500 111
+592200 6880500 88
+595800 6866600 126.5
+612400 6873800 86.5
+627700 6843400 133.5
+593900 6885500 57
+609400 6865100 145.5
+631900 6863600 121
+593900 6868000 132
+617100 6866700 80.5
+597900 6860200 132
+592000 6885700 76.5
+599900 6878600 80.5
+625600 6862000 100
+617700 6851300 137
+614400 6857900 86
+631100 6856000 136.5
+598700 6855600 111
+600100 6843400 155
+616500 6857900 82
+628300 6835800 134.5
+604600 6860700 131.5
+608600 6858700 137.5
+636400 6856400 141.5
+624100 6879100 104.5
+606800 6851500 146.5
+631900 6852700 138.5
+635700 6852900 136.5
+626000 6836200 135.5
+638200 6866000 40
+618100 6845000 148.5
+600200 6879900 43
+626600 6853400 158.5
+597200 6887200 68.5
+611500 6863500 142
+617200 6831200 146.5
+634900 6850000 146.5
+625600 6875200 94
+620800 6868800 168.5
+600500 6872400 120.5
+630100 6857500 134
+620900 6865300 114
+636100 6858200 145
+599600 6882700 49
+617300 6862400 86.5
+636900 6863100 94.5
+634700 6860000 146.5
+635200 6862600 101.5
+610500 6879400 116.5
+609800 6884800 137.5
+603500 6875000 98.5
+615600 6868300 102.5
+614600 6851300 138.5
+633700 6877800 38.5
+617500 6874400 99
+603300 6866600 108.5
+603000 6836800 143
+611400 6858500 96.5
+602700 6863200 110
+606100 6877500 29
+598800 6867900 121.5
+616800 6870400 119
+630100 6847800 122
+633300 6866700 64.5
+614200 6883600 123
+616200 6873800 79.5
+630200 6851300 157
+608200 6842700 155.5
+600400 6863000 118.5
+598500 6841500 147.5
+631400 6877900 93
+625400 6858300 144
+589400 6877800 136
+634500 6866700 60.5
+615700 6844400 167
+619400 6857700 132
+613200 6860700 126.5
+626800 6859300 118.5
+605800 6863400 110.5
+628900 6852700 160.5
+631000 6861100 137
+623400 6854300 137.5
+604100 6872100 84.5
+618400 6867900 119.5
+626100 6845700 122.5
+638800 6852300 128
+615500 6877600 101
+625700 6831400 119.5
+619100 6879300 68
+593200 6876100 121.5
+619000 6881200 74
+639200 6855900 134
+626600 6871500 75.5
+624900 6869400 119.5
+607500 6877800 77
+619300 6856500 119
+625000 6843500 133.5
+601300 6874700 115.5
+636000 6871100 45.5
+629200 6845700 123
+604100 6883100 80.5
+637300 6861500 125.5
+620500 6861800 94
+617600 6853600 121
+640400 6854000 140.5
+625200 6845300 131.5
+606600 6836300 141.5
+619500 6835200 147
+628100 6867400 118.5
+613100 6854700 124.5
+609100 6854300 152
+623800 6849800 148.5
+605900 6865400 122.5
+598200 6880800 69
+611600 6877300 72
+591300 6878100 124.5
+614600 6860600 120
+598500 6845800 159
+631700 6845500 117.5
+597300 6855400 108
+621800 6830700 133.5
+625300 6832200 124
+633200 6848900 125
+619600 6828500 152.5
+604200 6870500 91
+621900 6874600 75
+613800 6865100 122
+441000 6614700 189.5
+427400 6578900 24.5
+466600 6585000 124
+458100 6661800 61.5
+437600 6593400 53
+432700 6655400 117.5
+426500 6620900 212
+441300 6569000 76
+428000 6637200 194.5
+449400 6559400 102
+438000 6636200 177
+419800 6575500 20.5
+432100 6615000 173.5
+480500 6560700 152.5
+451800 6669400 60.5
+468300 6578300 145.5
+439200 6608400 138.5
+465400 6604000 151.5
+463100 6554600 116.5
+447000 6582600 87.5
+437400 6576400 45.5
+443800 6638500 161
+429000 6591600 62.5
+427200 6585600 19.5
+481500 6562800 149.5
+471000 6590600 121.5
+425400 6646600 193.5
+453400 6604300 162
+420700 6642200 180
+460700 6644700 93
+461600 6602100 170
+453700 6580900 131.5
+472700 6564100 154
+451800 6621600 149
+463000 6561300 108.5
+439100 6573700 54
+433600 6665200 129
+447700 6598500 119
+457300 6654700 82
+466800 6600200 158.5
+452600 6617100 165.5
+436500 6572100 65
+458200 6569500 111
+446600 6565700 50.5
+433700 6586400 39.5
+415100 6649400 181
+466700 6636600 109.5
+459200 6574500 145
+423400 6621100 190
+444400 6642100 134.5
+449400 6586200 114.5
+450300 6604300 142
+418800 6581900 19.5
+452700 6578600 111
+468400 6612800 178.5
+447800 6563700 60.5
+449600 6591100 92
+432100 6570300 63
+444500 6629500 197.5
+424000 6581100 16.5
+458600 6636900 118
+455900 6656500 79.5
+435600 6625400 205
+463300 6664400 74.5
+419500 6638000 179
+461700 6627500 133.5
+442000 6664000 112.5
+464000 6625900 159.5
+458200 6563000 96
+461200 6647400 83
+446400 6585500 100
+458300 6630200 124
+443100 6599600 102
+459100 6566000 105.5
+427200 6571300 53.5
+433300 6605100 88.5
+440400 6590100 61.5
+453600 6595300 83.5
+461100 6614700 216.5
+432400 6610900 140.5
+465300 6582800 139
+437000 6582000 35
+429900 6564400 59
+457400 6581600 149.5
+420700 6580400 15.5
+447300 6573300 70.5
+442800 6653400 133.5
+468500 6563400 149.5
+459000 6638400 116.5
+446100 6661600 87
+446400 6589800 81
+460500 6634100 122
+435500 6599700 67.5
+414200 6580500 15.5
+464000 6566300 135
+463000 6572000 150.5
+449700 6581900 111
+423900 6576300 31.5
+454100 6593400 94
+476600 6563600 152
+460900 6588600 122.5
+455700 6565600 84.5
+451000 6658200 84.5
+462200 6580900 155.5
+461000 6605300 169
+424300 6586600 40.5
+454100 6572600 93.5
+452500 6585400 137.5
+451600 6562400 80.5
+417000 6572700 26
+463100 6659200 75.5
+423700 6634600 174
+444000 6572300 67.5
+473000 6560900 145
+452500 6641700 127
+431200 6567400 51.5
+449700 6567500 56.5
+454400 6569800 87
+437100 6566600 74
+459100 6593500 109.5
+460900 6641000 103.5
+458200 6666100 56.5
+424800 6615100 161
+441000 6607800 168.5
+430600 6563200 54.5
+452000 6589200 102
+443700 6619300 190.5
+468000 6567100 157.5
+446900 6632700 180
+464800 6589500 108.5
+423300 6606900 88
+456300 6595100 118.5
+424000 6604400 74
+461200 6551700 120.5
+464900 6622000 163.5
+427600 6612600 110.5
+467000 6557300 126.5
+424100 6643800 198
+436200 6612700 177.5
+453900 6648300 100.5
+468900 6628800 141
+459700 6610500 196.5
+470100 6557100 143
+464900 6559900 114
+468800 6657200 65
+461600 6557800 120
+445400 6609000 166.5
+426000 6631100 189.5
+426000 6608600 104
+462900 6651900 88.5
+453300 6658900 77
+438400 6617900 203
+431000 6631200 198.5
+446900 6613200 191
+431300 6621000 178
+464500 6646700 105.5
+434300 6601500 90.5
+453100 6630800 141
+451300 6565300 72.5
+427700 6617200 187
+442000 6655900 113
+434200 6643600 167
+439900 6667200 108.5
+428700 6630400 190
+456100 6573900 116
+442200 6596100 81
+444600 6602500 139
+455100 6657100 77.5
+423900 6570000 33.5
+448400 6578300 78.5
+477000 6574300 135.5
+436400 6609800 122
+452400 6645100 128.5
+439300 6660300 112
+463400 6661700 75.5
+432600 6627400 188
+452800 6623000 151.5
+445900 6663700 77
+452500 6665500 58.5
+435600 6652900 132
+445000 6560800 73.5
+455700 6610500 192
+459400 6618000 211
+428400 6595900 56.5
+431100 6635600 192
+467700 6608900 175.5
+470000 6644000 84
+446800 6647600 156
+442000 6576300 58
+447900 6607000 169.5
+459400 6624300 147
+455600 6657700 82
+447900 6619800 166.5
+433300 6591800 42
+455100 6590900 119
+451600 6608200 174
+457200 6669400 52.5
+467000 6558400 126
+460000 6571900 120.5
+441900 6611800 168
+452200 6635900 147.5
+443400 6592500 57.5
+432400 6653900 135
+429000 6608700 102
+423600 6628000 202.5
+426800 6626500 196.5
+427000 6654800 152.5
+451500 6597500 118.5
+445400 6666100 85.5
+452400 6613500 185.5
+461300 6548300 106.5
+443600 6622300 181.5
+474800 6565800 144.5
+456900 6651900 84.5
+455100 6563100 86.5
+419100 6647000 181
+432000 6563000 74
+415500 6661100 148.5
+441400 6585100 66
+447200 6626400 182
+411000 6647900 174.5
+473100 6582100 128
+436100 6655400 121.5
+467500 6646900 91.5
+421700 6566600 35.5
+449800 6649700 129
+433100 6663100 124.5
+463000 6587300 134
+447400 6652500 135.5
+455000 6597500 125
+437600 6600700 78
+426200 6574400 36.5
+440200 6623500 207
+466000 6573600 159.5
+472100 6630800 128
+443200 6626300 202.5
+477800 6577900 135
+432700 6574100 43.5
+427100 6603300 85.5
+465300 6593000 130
+471100 6569400 146.5
+423700 6599800 47.5
+459900 6558800 118
+468900 6572700 144
+414800 6653700 165
+452200 6626300 151.5
+456100 6569300 93
+461900 6591900 107.5
+420300 6583700 14.5
+416000 6584000 18.5
+420900 6576800 16
+442100 6572600 65
+458000 6604500 183.5
+478400 6567100 140
+457100 6555500 129
+453000 6560900 101
+441600 6562800 71
+473900 6573000 139
+461400 6666000 47.5
+448800 6650600 130
+461100 6596100 151.5
+416700 6643200 169.5
+421700 6646500 174.5
+464000 6632100 132
+457000 6584800 154
+460600 6566700 127
+457700 6558500 122.5
+447500 6594000 86
+429500 6584000 16
+439600 6592600 61.5
+430900 6602700 80.5
+448600 6646200 139
+443500 6563000 61
+468700 6651100 60.5
+465700 6654700 90
+434300 6626600 195.5
+457400 6618300 188.5
+475600 6570800 141.5
+456000 6661300 63
+445500 6567900 62.5
+439900 6629600 187
+478000 6581100 132
+434700 6633100 192
+456800 6639700 133.5
+438300 6605300 116
+456900 6563800 82
+437800 6560500 66
+430500 6600200 77
+432800 6594700 41
+438900 6603900 119
+431200 6579700 30
+471700 6576100 131
+423600 6573600 49.5
+425900 6567600 34.5
+464000 6570000 160
+437900 6659600 97.5
+448900 6613000 175
+442400 6578700 51
+457600 6574000 130.5
+449000 6570500 74
+421600 6636400 187
+461900 6631400 144.5
+458400 6608700 186
+451200 6611600 187.5
+454500 6558600 112.5
+610400 6997800 61.5
+698300 6983000 90.5
+705400 6982900 103.5
+634500 6986000 53
+637100 7005100 118.5
+624400 6978000 89
+710600 6985000 112
+660600 6960900 77
+630900 6962800 129
+619700 7010400 55.5
+614400 6983500 97
+668800 6983800 73.5
+645300 7010200 78.5
+667200 7000700 130.5
+651000 6988900 110.5
+687100 6958900 90.5
+690300 6956800 88
+674600 6955600 78.5
+632300 6995600 78
+667900 6965300 84
+623300 7016000 54
+662100 6963500 70.5
+615900 7021900 48
+700200 6968500 73.5
+693400 6980700 69
+669300 6969800 72.5
+616300 6979100 127.5
+610400 7019700 24.5
+634000 6969800 126
+698900 6960000 64
+660500 6977900 36
+630000 7003800 93
+669100 6978000 64.5
+640600 6999900 112
+640900 6973300 91.5
+596200 7003400 52.5
+619000 6978700 110.5
+624300 6981800 59.5
+648100 7011800 101.5
+602600 7000800 64
+707100 6978900 95.5
+623400 7014900 65.5
+638400 7000900 92
+672000 6995900 120.5
+652800 7006700 102
+608300 7000600 44.5
+611800 6980800 118.5
+620500 7001100 49
+660100 7001000 104
+634100 6990900 55.5
+657800 7011100 122
+681900 6995600 132.5
+642600 6966500 92.5
+689000 6987900 94
+620100 6996800 54.5
+648100 6993200 107.5
+660700 6986400 82.5
+624600 7004400 58
+656400 6959500 114
+668200 6996000 125
+602700 7025100 15.5
+622800 6976700 117.5
+657500 6985400 80.5
+611400 6984800 107.5
+610400 7006600 33
+630100 7018700 53
+619300 6967800 180.5
+703600 6988400 132.5
+634100 6980800 83
+679500 6988900 94
+663800 6955000 96
+667700 6980400 69
+592300 7002300 43.5
+653700 6986300 105
+631800 6994700 71.5
+700700 6979500 81
+625000 6959900 147
+674000 6978700 62
+660000 6987000 79.5
+683200 6969500 98
+591900 6999700 89.5
+671100 6969200 72.5
+664300 6993100 108
+696300 6963800 64.5
+636500 6960600 120
+654700 6964800 76
+633600 6988000 43
+640600 6962000 91.5
+602700 6989900 94
+621000 6985700 77.5
+616800 7027800 41.5
+689900 6955100 90.5
+654200 6953200 110
+668000 6958100 78
+627500 7019700 52
+661800 6958600 79.5
+635700 6967500 102
+629800 6958800 154.5
+659000 6968400 72
+604700 6985100 142.5
+618200 7026600 40.5
+658500 6975800 69.5
+621400 7006500 50.5
+679700 6982400 77
+596600 7007700 24
+672100 6992100 100.5
+684800 6966000 83.5
+683000 6992500 126.5
+644200 6970500 78.5
+673500 6971500 74
+681800 6949400 98
+611100 7024600 35
+650000 7007500 106
+694400 6971800 68
+609900 6976800 125.5
+605900 7006800 23
+685900 6968500 92
+703200 6972500 76
+608800 6990500 105.5
+622000 7004000 48.5
+680700 6956400 80.5
+601000 7004300 39.5
+658100 6992200 115
+642400 6994900 83
+687400 6990600 125
+641700 7012100 69
+652600 7012800 127
+621900 6999600 66.5
+686800 6964100 76.5
+608300 6994500 85.5
+642900 6957200 132.5
+627100 7012700 82
+641100 7001700 121
+693800 6992500 132.5
+615400 6965300 202
+669800 6991900 104.5
+646500 7008800 86
+672100 6984900 73.5
+642900 6986000 57.5
+617900 6995700 54
+628800 7009400 107.5
+680300 6978100 62
+664100 6999600 123.5
+655500 7013200 143
+670700 6984400 73.5
+649100 6965600 97
+695400 6981500 82
+649400 6988600 117
+708300 6981900 102.5
+690600 6968000 85
+644900 7005300 119
+669400 6972400 74.5
+660400 6978300 59
+615100 6991800 72
+699400 6967200 69
+654000 6983800 86.5
+643600 6960300 115.5
+611500 6969300 183
+588900 7001400 53.5
+606100 6987100 113.5
+596100 7000100 83.5
+640100 7004000 126
+673300 6983600 82
+696800 6959900 65
+612100 6972400 164
+697900 6959100 60
+645200 6993400 95
+610400 6972900 139.5
+645500 6975900 53.5
+640600 6974900 95.5
+656300 6954700 126.5
+685300 6973800 76
+678800 6951400 94.5
+690300 6972500 73.5
+684300 6972400 87.5
+700600 6966300 69.5
+679400 6973600 71.5
+608700 7020800 20.5
+651700 6992600 120.5
+667800 6961300 81
+698500 6972900 67.5
+615800 7012200 46
+687200 6952000 79.5
+651700 6984800 100
+644800 7002500 132
+655900 6991300 118
+651700 6958800 97.5
+678300 6992600 116.5
+600800 6993800 106.5
+627700 6972400 113
+619400 6988700 78
+622900 7011700 61
+662400 6947700 103.5
+697400 6966200 68
+630600 6992100 60
+693500 6962100 69.5
+668900 6950000 84
+636300 6992300 60
+682500 6952800 85.5
+623900 6992900 54.5
+638500 6983200 59
+703000 6982300 96
+685200 6983100 76
+695800 6955800 76.5
+659100 6982400 68
+699000 6958500 66
+619700 6981900 88.5
+596400 6988500 72.5
+688900 6967800 85
+631000 6959300 158
+682100 6973700 69.5
+676200 6972300 77
+684900 6955700 81.5
+633600 6958500 129.5
+705200 6978300 96
+687300 6960300 87
+701000 6980900 94.5
+616200 6975000 152
+677900 6952800 79
+687100 6956200 90
+659200 6979200 58.5
+620900 6972400 134.5
+692400 6969500 78.5
+672600 6950000 94.5
+661900 6968100 71
+623100 6959400 153.5
+645500 6974800 66
+693400 6989500 130
+640600 6964400 97
+694600 6976900 64.5
+611700 6976100 136.5
+657700 6995300 114
+630500 6967500 140.5
+675900 6947700 102
+651700 6965500 102.5
+670000 6980300 69.5
+676100 6964100 91
+697000 6964000 65.5
+627800 6969400 148.5
+659200 6958000 108.5
+608200 6992600 103
+675000 6943600 104.5
+600700 6991600 77.5
+653300 6962400 91.5
+687700 6953800 82
+661200 6950600 115
+666700 6951500 83
+666100 6954300 76
+656500 6957000 121
+662800 6978100 56
+616600 7001400 39
+691800 6984300 94.5
+626600 6989200 52.5
+669500 7003800 133.5
+609500 6987100 111.5
+662600 6972700 83
+672500 6951500 99
+669400 6956200 76
+636000 6999900 90
+661400 6968400 70
+646200 6998500 122
+705000 6973700 79
+680600 6999600 109.5
+619200 6997700 48
+632400 7005900 103
+645200 6973600 73
+638800 6960500 114
+643700 6968800 79.5
+591700 6993500 65
+627500 6960100 137
+705700 6991600 125.5
+656200 6972000 66
+605900 6979500 116.5
+646600 6993200 100.5
+638900 6984200 54.5
+665500 6974300 76
+646000 6985100 69
+651600 6978400 49
+677400 6988000 80
+607800 7005100 30.5
+617200 6982300 93.5
+621100 6994000 55.5
+682400 6987400 102.5
+690900 6961900 74.5
+631700 6980800 76
+589100 6998400 63
+702700 6969300 81.5
+623500 7017800 58.5
+666100 6956900 74.5
+686800 6985000 82
+624000 6970100 152
+597200 6992700 100
+624800 6965400 148
+595200 6997400 104.5
+655500 6968000 71.5
+640800 6977400 87
+702800 6963800 69.5
+627900 7009700 96
+657600 6963700 93
+683800 6975100 68.5
+687200 6966600 84
+664900 6982000 72
+696500 6968300 67.5
+638100 7009500 106
+679000 6963400 95
+621500 6970400 161.5
+608300 6983100 139
+643700 6978200 72
+634800 6961400 119.5
+682300 6978000 64
+678900 6976500 62.5
+610600 7028600 34.5
+625900 6976200 107
+642400 7008400 98.5
+611800 6975200 137.5
+686000 6978800 73
+608300 6980500 160
+648000 7003700 133
+593700 6999500 93.5
+696000 6984800 91.5
+690200 6993800 133
+663400 7002500 115
+677900 6966600 82.5
+634600 7007300 121
+674500 6968700 75
+612400 7013300 31
+595500 6993400 92
+622800 6961400 159.5
+670800 6956800 79
+646200 6965900 108
+618600 6959400 169
+681400 6959200 94.5
+661400 6993200 108
+669000 6994200 112.5
+668700 6989400 102
+666100 6955200 75.5
+668200 6987300 89
+683800 6959800 90
+611200 6983000 113
+670200 7000700 138
+692600 6975300 66
+593000 6992000 60
+609200 6979700 157
+700700 6957500 72
+663300 6951700 88
+688700 6995600 125.5
+638500 6976300 85.5
+659800 6982500 77.5
+683200 6949600 90.5
+667900 7003600 125
+698800 6963700 64.5
+707000 6983000 104.5
+607400 6986200 118.5
+697500 6980500 80
+695000 6961000 67.5
+642100 6981200 64.5
+598000 7028000 15.5
+614000 6995400 63
+666800 6954300 78.5
+628000 6998200 93.5
+666700 6984000 69
+686200 6976300 67
+594200 7005700 31
+637300 7011200 94.5
+679400 6948600 102.5
+644800 7006500 105.5
+635100 7001600 94.5
+674800 6995100 103
+604900 7020200 7
+650700 6971200 75.5
+602000 7010900 22
+642200 6967500 84
+620000 7004200 46.5
+647400 6972100 88
+623900 7000500 83.5
+642600 6968800 83.5
+687000 6982600 70
+631200 6968700 129.5
+673500 6986200 73
+664900 6996300 136.5
+628400 7001800 79.5
+629500 6996400 76
+647000 7001300 131.5
+685900 6991900 140
+603000 6996800 84
+656600 6989500 104.5
+687200 6994500 129.5
+646900 6989400 95.5
+634600 6992000 65
+687300 6975100 77
+617500 6992900 59.5
+674500 6960700 78.5
+666600 6969100 72
+676300 6962500 99
+662900 6969200 68
+623300 6962500 151.5
+634300 6976600 89.5
+700700 6984400 102
+640400 7008700 108
+671700 6979300 71.5
+676200 6958200 98
+653000 6976700 53
+665800 6990300 99.5
+678600 6968400 88
+680700 6966700 86
+632000 6971100 104.5
+637800 6985600 60.5
+704800 6958700 66.5
+624100 6981100 83.5
+680700 6951900 91.5
+616500 7010600 58.5
+648600 6956000 122
+674900 6953100 86.5
+626400 7005700 74.5
+659600 6967500 71
+606800 7025100 17.5
+694300 6987400 115.5
+627300 6966300 149
+676500 6961100 101
+625600 7013700 69
+619200 7005600 43.5
+692300 6959700 77
+655000 7005200 99.5
+682300 7000200 107
+613900 6985900 95.5
+705300 6960800 70.5
+682100 6963400 92
+594200 7001700 65
+623000 6983500 74
+671600 6998000 125.5
+656200 6976500 46
+702400 6986900 121
+632900 6987300 57
+697400 6987900 107
+611500 6992600 86.5
+627900 6990900 52
+620200 7017700 50.5
+704300 6985800 119
+688000 6969200 86.5
+662800 6983800 91
+633300 6962600 116
+696500 6958100 66.5
+690400 6958700 89.5
+636000 6986600 47.5
+624700 6994400 60
+689200 6974000 74.5
+695100 6975300 67
+612600 6977800 155.5
+684200 6977800 69
+604200 7004200 38
+613300 6979800 137
+607900 6975200 125
+665500 6988400 94
+690300 6970600 85.5
+670100 6963800 94
+597900 7003400 42.5
+612900 6965400 164
+672000 6971900 72
+638200 6994900 76.5
+664600 6985400 104
+678700 6972300 88.5
+661000 7003400 106
+641200 6966100 88
+615300 6962900 203.5
+668800 6984700 73.5
+679200 6953300 86.5
+691800 6972200 78.5
+590800 7000100 92
+624200 6997600 71.5
+655500 6989400 114.5
+616700 6985500 82
+665600 6949000 82.5
+617300 6967200 191.5
+614400 7019900 37
+679000 6957400 81
+613300 6999600 44
+622700 7009400 71.5
+643300 6982400 48
+604500 7016400 3.5
+673500 6998100 137
+655600 6957200 104
+676700 6951900 86.5
+647800 7008700 90.5
+637300 6997700 82
+677700 6995200 112
+668200 6999600 141
+632000 7000100 97
+630400 6993400 60
+635800 7007900 112
+605200 6997100 74.5
+609600 6981100 133
+699000 6992900 111
+626900 6993900 58.5
+598000 6997500 96
+688600 6980400 83.5
+661900 6997200 126
+632800 6956800 135
+613500 6974400 135
+698800 6985000 112.5
+620200 6979800 90
+625100 7010000 73
+674900 6977100 62
+690300 6959400 84
+677100 6949000 97.5
+604200 6981400 111.5
+700300 6973200 73
+660900 6972000 91.5
+636900 7002400 109.5
+686300 6965900 80
+674100 6947900 100.5
+654100 6962100 93
+661800 6954400 97
+615300 7008900 56
+703000 6992900 115.5
+669000 6945300 78.5
+616100 7019400 46.5
+610800 6995900 89
+621200 7024100 39.5
+655500 6965100 75.5
+681100 6988800 101.5
+640200 7010600 73.5
+633700 6997200 90
+636300 6956700 144.5
+653700 6974800 43.5
+607900 6997200 72
+623500 6980300 83
+607200 6989800 99
+656100 6967100 73.5
+610300 7017100 24
+687200 6971200 77.5
+632400 6997600 84.5
+704500 6966100 72
+664600 6979000 67
+672900 6964200 88
+604900 6986400 124
+620000 6965100 180.5
+658300 6952200 128
+672800 6955200 78.5
+631600 7012600 92.5
+651400 7012400 116
+621200 6979200 89
+626700 7001100 73.5
+664400 6959400 74.5
+598700 7007700 29
+611900 7002100 39.5
+614300 7010700 43
+620300 6963400 186
+692100 6977600 67
+615500 6985100 88
+612000 7010000 37
+671800 6946800 84
+619800 7021800 58
+631700 6978900 78
+675500 6955700 76.5
+614200 6969100 155
+697000 6977600 66.5
+615100 7007000 52
+680600 6991700 124
+648100 6967900 102
+703000 6977100 92.5
+674800 6979000 68.5
+670300 6989300 89.5
+684200 6989800 116
+633900 7011200 97.5
+608800 6970900 145.5
+676600 6978600 62
+647400 6963500 120
+615600 6977400 131.5
+614800 6973700 139.5
+682600 6998800 110
+608600 7003100 36
+707200 6957600 78
+666500 6997300 135
+635000 6973600 99.5
+613000 7004200 34.5
+644600 6957400 144.5
+665200 6951000 86.5
+689600 6976000 71.5
+684700 6963400 85
+626800 6964600 142
+629600 6961300 131.5
+681100 6960900 97.5
+667300 6979800 65.5
+612000 7021000 32.5
+660900 6987700 85
+667000 6957100 76
+639500 7001900 110.5
+690400 6990100 118
+666600 6965500 96.5
+640200 6957100 123.5
+655900 6987900 95.5
+665000 6960400 70.5
+686900 6987900 110.5
+639000 7002900 120
+613800 6974900 143
+601100 7007300 24.5
+652700 6973800 65
+670100 6966100 78.5
+639300 6994600 73
+601300 6998400 81.5
+652000 7001100 115.5
+617000 6963100 188.5
+623300 6983100 45
+696000 6994000 125.5
+679200 6955100 79
+637000 6993500 64.5
+677500 6998000 106
+683300 6983500 80
+624100 6985700 65.5
+683100 6958500 88
+617400 6986500 103
+605300 6993900 88
+601500 6985700 122
+611700 6990000 95
+606800 6983400 151.5
+679200 6998000 113
+704400 6968700 81
+689000 6983200 71.5
+631000 6999000 100.5
+660100 6987800 87.5
+670700 6985200 70
+618600 6976300 123
+641100 6982100 56.5
+664300 6978000 63
+656400 6998600 131
+646000 7011600 109
+694400 6964400 73.5
+689600 6962700 75.5
+657400 6969700 63
+703600 6960300 65.5
+634700 6963100 115
+675400 6998400 109
+599300 7021700 19
+627500 6984600 87
+633500 7004600 116
+607700 7010300 21
+694900 6972800 67
+644400 6981600 43
+671400 7000300 145.5
+683700 6963200 89
+651300 7005000 98
+616100 6997400 45
+675500 6991700 93
+611500 6988000 102.5
+655700 7001000 125.5
+606000 7002000 46
+656700 6975600 45.5
+665100 7003200 122
+607800 6977500 119
+673100 6973700 88.5
+598900 7001200 62
+669600 6988100 89.5
+693600 6958100 79
+639900 6971500 88.5
+615200 6973300 141.5
+655800 7009400 111
+692900 6966600 77
+690200 6979400 76
+703600 6991700 123.5
+676200 6993900 104
+645500 6960400 127
+629500 7016300 73.5
+637400 7005800 117
+648000 6956700 128
+662700 6964100 72.5
+607400 7023200 17
+619700 7008400 53
+666600 6994700 119.5
+649500 6977200 60
+688200 6977500 70.5
+659900 6985400 76.5
+700800 6962500 64.5
+600000 6996800 104.5
+593800 6996800 114.5
+629500 6990600 51.5
+633800 7009300 108
+613100 6986700 103.5
+644700 6971700 70
+632100 6984700 60
+675600 6987100 77
+675000 6989300 81.5
+677400 6964600 95.5
+631100 6975000 91
+697000 6969500 71
+707600 6975900 83
+636700 6972600 102
+679700 6981600 58.5
+589500 6994900 60
+592400 7010200 7.5
+667800 6947500 78.5
+677700 6981100 67.5
+643200 7011900 78
+592200 6996600 89.5
+628900 7005300 96
+592800 6998800 97
+609000 6978500 157
+650700 6983400 82
+662400 7000100 113
+644800 6998900 105
+659800 6997400 120
+707100 6986500 109.5
+617500 6979900 98.5
+709300 6982800 115
+620800 6967900 175.5
+701400 6989800 134.5
+667500 6969900 73
+635100 7011400 98.5
+637400 6974000 108.5
+705700 6989000 128.5
+701300 6993100 117.5
+688500 6984000 77
+695000 6969300 71
+711500 6987100 123.5
+614500 6989200 81
+642300 6990600 85.5
+629300 6969500 138.5
+688000 6991700 121
+663400 6990000 86.5
+612800 6988000 96
+684600 6986900 92
+628100 6963500 137
+693800 6967000 72
+709200 6989900 123
+682900 6954900 78.5
+666100 6978600 67.5
+641500 6995200 87
+680100 6993600 138
+632000 6983400 68.5
+614600 6981200 113
+626700 6980000 99
+654200 6982700 86.5
+601600 6982700 96
+704700 6976500 85
+633300 7017600 58
+631900 7002200 90.5
+646100 6959500 136
+670900 6974800 68
+635800 6980300 81
+664900 6969400 68.5
+646800 6968500 94.5
+631600 7014400 70.5
+650900 6968900 83
+629400 6976500 84.5
+683200 6966200 85.5
+670200 6953900 90.5
+600800 7001500 62
+594300 6994700 105
+643900 6995600 96.5
+608000 7013800 16.5
+661000 7012600 134
+618100 6964600 197.5
+655400 6952800 128.5
+644600 6979900 49.5
+600200 6988600 80
+652400 6955800 107.5
+621600 6962400 160.5
+683200 6962000 89.5
+624800 6963400 146
+662400 6989700 90
+671600 6961700 96.5
+682600 6981100 66
+601700 7014000 8
+682300 6966100 90
+622800 7023400 56.5
+615500 6987700 103
+584500 6997700 49.5
+636200 6977700 84.5
+691300 6958100 86
+621300 6995600 57.5
+619900 6995400 46.5
+651400 6995200 131.5
+686700 6961800 83.5
+604700 6991200 97.5
+700500 6975500 79
+662600 6957300 83.5
+689900 6964200 75
+649700 6986000 91
+701800 6985400 112.5
+697900 6966800 63.5
+635800 6975300 103
+621600 6990700 76
+697500 6972000 66.5
+628100 6268900 207
+621700 6289100 290
+623400 6328000 270
+665100 6266000 571
+619300 6335700 325
+615500 6276400 284
+646200 6311100 354.5
+587200 6313300 181
+617500 6266200 198.5
+631400 6314700 219
+639500 6329200 368
+658500 6316200 364.5
+594900 6323600 288.5
+611300 6294900 196.5
+626400 6315800 206.5
+655600 6285000 531
+629700 6323600 311
+637300 6274400 222
+605000 6280100 228
+660400 6300500 678.5
+612600 6321100 230.5
+614000 6284000 227
+625600 6314800 147.5
+682200 6286300 940.5
+662700 6262400 654.5
+659100 6275200 747
+605400 6319200 319
+611500 6311900 196.5
+627800 6297600 230.5
+624500 6260400 461
+667900 6280600 855.5
+629400 6283700 204
+610300 6337100 295.5
+650600 6332000 479
+592100 6305800 176
+645700 6331800 512
+616100 6298700 234
+640500 6300700 319.5
+636500 6316900 244.5
+633300 6333900 310
+606600 6334300 368.5
+614200 6326000 253
+586600 6308300 169.5
+604400 6306800 190
+637900 6296900 281
+613100 6279700 271.5
+624400 6270300 207.5
+667800 6282500 903
+636400 6317600 249.5
+632900 6323800 268.5
+585100 6313400 179
+628200 6277300 213
+621900 6313600 151
+590000 6320000 191.5
+615400 6324500 272.5
+649300 6266100 694.5
+619900 6300800 228.5
+610400 6308100 152
+647000 6330000 477
+610600 6278200 251.5
+634900 6292400 256
+644300 6269500 251
+614400 6268300 257
+617100 6279900 253.5
+604600 6323500 277
+661300 6293400 598.5
+656600 6315100 384.5
+658800 6264800 533
+609600 6322200 220.5
+662400 6288400 637.5
+607400 6326400 288.5
+627200 6263400 496
+660700 6319200 378.5
+647700 6275200 343.5
+652900 6302300 534
+638200 6309300 274.5
+596700 6293300 180
+586900 6310400 177.5
+614700 6292900 257
+649200 6300600 472
+626700 6267700 204.5
+644100 6298800 379.5
+627600 6327000 287.5
+625500 6323300 296
+624400 6262000 492.5
+616100 6329900 239.5
+630600 6290000 262.5
+630600 6279300 188
+647500 6333000 504.5
+596700 6289100 196
+652300 6324700 411
+625300 6291400 283.5
+625100 6309800 218
+592900 6299700 172
+611000 6333800 319
+600100 6297000 115.5
+645700 6291500 420
+622000 6326000 288.5
+651800 6267000 365
+606400 6284400 220
+619100 6331800 303
+632300 6305700 258
+612400 6310700 149.5
+605400 6283100 237.5
+650200 6316600 341
+660800 6283400 766.5
+597500 6281700 206
+630300 6265500 495
+634800 6297800 257
+629900 6335000 342.5
+601300 6294600 151
+658000 6319800 366
+612700 6270800 251
+636100 6305600 268
+607400 6277100 224
+626700 6287200 261.5
+627800 6301100 230
+659500 6281300 645.5
+646600 6318500 290.5
+597900 6289400 199
+611200 6318800 252
+633300 6310700 245
+647400 6269100 277.5
+619800 6270300 203.5
+597400 6303400 173.5
+609700 6275100 239
+640000 6303900 313.5
+610000 6270600 251
+606900 6338400 252
+670800 6264100 652
+688200 6287400 874
+615600 6305500 242.5
+604400 6293200 162.5
+666200 6263500 641.5
+640000 6288200 316
+641800 6307600 306.5
+633400 6273200 224
+613700 6287100 140.5
+623600 6266100 216.5
+617900 6338700 238.5
+634500 6327600 294.5
+663800 6264000 632.5
+606800 6289700 156.5
+669300 6295500 723.5
+644700 6266300 536.5
+619700 6328600 258
+622600 6302800 226
+622700 6283300 214
+641600 6312200 306
+628200 6340400 343
+622800 6330900 268
+684300 6290300 928
+609300 6330100 376.5
+612000 6295300 206.5
+675200 6290000 936
+606200 6325300 329
+620600 6314700 177.5
+604000 6331100 373.5
+669000 6290700 795
+644200 6325100 377.5
+635700 6286800 247
+626500 6280600 170
+610000 6325600 242
+620200 6275300 259.5
+604800 6289600 189.5
+621500 6285100 224
+611300 6301200 239.5
+643800 6328300 443
+627600 6328800 271.5
+608600 6327600 343
+622100 6320000 245
+647400 6285200 446.5
+631900 6282900 193
+636000 6332500 321
+622100 6323000 274
+623800 6305800 199.5
+642200 6321100 358
+626800 6283600 237
+596500 6322400 249.5
+649000 6327200 446
+657300 6316200 451
+630000 6310600 228
+618100 6306200 244
+609900 6282800 239
+640700 6318400 264
+686000 6294800 961
+632000 6268300 521
+669900 6295600 738
+649500 6318700 318.5
+666400 6293200 689.5
+625400 6263900 243.5
+631200 6296000 249
+602000 6303900 126
+626000 6295900 235
+632600 6326400 292.5
+602000 6278500 207
+656500 6273800 682
+611000 6322800 236
+617400 6333100 261.5
+612500 6331500 258.5
+608200 6281400 256
+656600 6310200 500.5
+619000 6311500 170
+632100 6266300 507.5
+599200 6281500 208
+654100 6305700 532
+618500 6296300 249.5
+597900 6302900 121.5
+658700 6264300 705.5
+646800 6304200 436.5
+654500 6295900 571
+651900 6267400 451.5
+603300 6282200 226.5
+608100 6285500 210.5
+664500 6274000 662.5
+603900 6334900 285.5
+655000 6319700 362.5
+667500 6300800 762.5
+637600 6302000 302.5
+648600 6266800 501.5
+598300 6331700 291
+617100 6272600 231
+607100 6321700 229.5
+637400 6314700 241
+617400 6284300 237.5
+622000 6335200 341.5
+628300 6275700 204
+630300 6328500 273.5
+634100 6276200 205
+643400 6330500 454
+612900 6330200 245
+628400 6310300 223
+594200 6298100 145
+657700 6278900 583
+625200 6319700 251
+626300 6305200 220
+611600 6269300 264
+615700 6316400 196
+633300 6338500 324.5
+611100 6299700 219.5
+614700 6272400 212.5
+643700 6317500 272.5
+638900 6289100 302
+635000 6307900 275
+635800 6271200 257
+629000 6298600 220
+661700 6305900 670
+606000 6300700 205.5
+648800 6298600 425
+640400 6271400 600.5
+624400 6274000 257.5
+611000 6317800 231.5
+613600 6276600 264
+612800 6339700 205
+652400 6317800 320.5
+654800 6323000 417.5
+627600 6313600 209
+655200 6326700 491.5
+643700 6306400 364
+656500 6269600 569
+653500 6311100 435
+618800 6291400 293
+641500 6275600 225.5
+637900 6286900 268.5
+614400 6278300 277
+644900 6282200 429
+664900 6288700 726
+633400 6317500 228
+639700 6336400 405.5
+612900 6327100 233.5
+611900 6289800 183.5
+651400 6279300 504.5
+624600 6334800 351
+628600 6273400 192
+645400 6333900 430.5
+617500 6317800 214.5
+632600 6259300 735
+663600 6310100 565.5
+615100 6330300 231
+631100 6321100 238.5
+618500 6320700 235
+618800 6267500 197
+642700 6314800 265
+632500 6328100 284
+654800 6276500 559
+622900 6307800 199
+629000 6307200 239.5
+616300 6326300 245
+638600 6278800 259
+653700 6288400 471
+647500 6321400 378
+635800 6289600 244
+589200 6302600 169.5
+642800 6285300 305.5
+594600 6312700 209.5
+623900 6339600 320
+649900 6275300 490.5
+636700 6313000 261
+621700 6318200 199.5
+611400 6327700 239
+627700 6330600 313.5
+638500 6324000 320
+657900 6324500 449
+588800 6316600 180.5
+617300 6283700 213.5
+614500 6333200 239
+618600 6324000 258.5
+625400 6257400 531.5
+644100 6274600 260
+636300 6267100 596.5
+622300 6310400 201.5
+627700 6271400 194
+631100 6343300 363.5
+601400 6296700 183.5
+599700 6284100 222
+604300 6278100 219
+617900 6269600 197
+616700 6313300 136.5
+585100 6317600 180
+635800 6286700 253
+646100 6301200 392
+631600 6300900 249
+595000 6282700 200.5
+577800 6341400 154
+547600 6351300 164
+559000 6333700 77.5
+535300 6328100 108
+534600 6308000 154
+579200 6335800 115.5
+533800 6346400 148.5
+603700 6356900 307.5
+528000 6337300 59
+537500 6340400 129.5
+589400 6331700 182.5
+562000 6331200 87.5
+565500 6340900 146
+573600 6339600 148
+579800 6323100 168
+527600 6330300 128.5
+576800 6328900 135
+550100 6313000 155.5
+562500 6325100 90.5
+531600 6315400 209
+548300 6328600 79
+532100 6307200 149.5
+540900 6306000 197
+577500 6344700 170.5
+573900 6319700 156
+536500 6308900 129.5
+540600 6320700 142.5
+588500 6339500 161.5
+566600 6320200 93
+539800 6326500 120.5
+538400 6319100 158.5
+549100 6321000 117.5
+591700 6348000 219
+552500 6344800 148
+531700 6359700 163.5
+526900 6326500 134.5
+571400 6314400 139.5
+562700 6307300 130.5
+565600 6346900 173.5
+531100 6336800 121
+574500 6311400 93
+593100 6329400 236
+532400 6303400 150.5
+545600 6326200 102.5
+525500 6336900 105
+531200 6310700 189
+530800 6329000 131
+555100 6311800 129
+579300 6312500 145
+600400 6340000 252.5
+535900 6344900 136
+537300 6330900 69.5
+559200 6338100 139
+568900 6314600 97
+529400 6319700 181.5
+536200 6337600 126
+580100 6346600 210.5
+587700 6354900 247
+547600 6318600 128
+547700 6348700 145.5
+559400 6332300 84
+603700 6354900 299.5
+569400 6332000 139
+583000 6333400 146
+562900 6304700 151
+528400 6334200 107
+532500 6361600 183.5
+617600 6338900 263.5
+526900 6323100 151.5
+534200 6337200 119.5
+560800 6322300 96
+546700 6335800 129
+541800 6324300 125
+537700 6334400 125.5
+562900 6345000 179.5
+542000 6362100 213
+553800 6324600 87
+591100 6325800 173.5
+532100 6333100 61
+547500 6308800 180
+565600 6334800 140
+526700 6321100 145.5
+530500 6344600 137.5
+573000 6348000 177
+541100 6315500 159.5
+606400 6344800 271.5
+565500 6312300 124
+572400 6313000 95.5
+525100 6318400 164
+557100 6314200 93.5
+557100 6327800 94
+569000 6317500 144
+532500 6310900 194.5
+533100 6319800 180.5
+536000 6360200 185.5
+536600 6302400 201.5
+541200 6349200 140.5
+564200 6303400 159
+538000 6348300 160
+539300 6323500 131
+554800 6335700 115.5
+597200 6336700 217.5
+593700 6346100 243
+536100 6303900 169
+534600 6335600 67
+582200 6319400 168
+554700 6322300 88
+533500 6341700 130
+533100 6324600 155
+534700 6313700 184
+567900 6337300 143.5
+555300 6305100 139
+585300 6327000 162
+529500 6317200 197.5
+583000 6341400 151.5
+535800 6342600 124
+555500 6333400 81.5
+535700 6304900 189.5
+552900 6317800 125
+610200 6343700 266.5
+520800 6317800 151.5
+575800 6333600 92.5
+543700 6311400 164
+563400 6335100 143
+545000 6313300 151
+544400 6354600 197
+605500 6337500 268
+548300 6317600 130
+589500 6343100 187.5
+586400 6319600 190
+548900 6349500 160
+558100 6307600 128
+567400 6308200 137
+559500 6310500 118
+557900 6319200 107.5
+548700 6306600 184
+556400 6349200 173
+541500 6302800 220
+553900 6355900 179
+569200 6345200 162.5
+521500 6334500 121.5
+535900 6319200 172.5
+553500 6334800 76.5
+531800 6332300 109
+589100 6347600 160.5
+536200 6356900 169.5
+575400 6323900 164
+611500 6340500 245
+602900 6352700 300
+562800 6332200 81.5
+607400 6355900 341
+589100 6351200 234.5
+562000 6353400 201.5
+578300 6350000 217.5
+551500 6322500 119
+586300 6348300 160
+538300 6311400 174
+542800 6327500 102.5
+531200 6321000 175.5
+529600 6323500 167.5
+582600 6315600 165
+608700 6352500 327.5
+550500 6357400 190.5
+559200 6353600 183
+601800 6349300 277.5
+541600 6331400 73.5
+546500 6344900 134.5
+575700 6313200 138
+548600 6304200 195.5
+522400 6331500 148.5
+578300 6336300 144.5
+609200 6345100 327
+560900 6308600 124.5
+537000 6353600 174
+561300 6314200 120
+535500 6323200 133.5
+547800 6360800 212.5
+545000 6321700 131.5
+581600 6331800 143
+525800 6338600 55
+532600 6312700 194
+558600 6312000 96
+534500 6364900 166
+556400 6302100 132.5
+545500 6349800 152.5
+593600 6352900 256.5
+551300 6352500 184
+568100 6325600 139.5
+546700 6325200 106.5
+616200 6352500 379
+540600 6351400 171.5
+541000 6335000 128
+585300 6342600 148.5
+537200 6328400 103
+546000 6316500 136
+933300 6270600 421.5
+944500 6250400 502.5
+945900 6238800 433.5
+986700 6245700 195
+964600 6281400 372
+970700 6260500 340
+987700 6284500 460
+963300 6231900 300.5
+944800 6277400 520.5
+938100 6274300 332.5
+952700 6289000 646
+920500 6251700 829
+982500 6280700 473
+995200 6252300 266
+947300 6237100 191
+922600 6282500 471
+920300 6235400 127
+937000 6254200 683.5
+960900 6263900 283
+925600 6256400 540
+987100 6236600 264
+961200 6257500 365
+993500 6241900 162
+967500 6267000 259.5
+919400 6257600 497.5
+983200 6304700 1004
+945100 6229700 103
+998200 6268800 90
+928200 6228500 223
+939000 6268100 406.5
+954700 6229500 182
+942800 6231000 369
+941200 6247000 481
+931700 6230900 260
+956900 6279500 371.5
+931700 6265800 519.5
+965800 6273000 245.5
+1002900 6287500 338.5
+947100 6236200 360
+981700 6235000 247
+946400 6259700 523
+987600 6255500 282.5
+954400 6264500 283
+974600 6276500 446
+955800 6297900 808.5
+950800 6259000 448
+986600 6286500 704
+1012900 6284500 263.5
+949800 6282400 533.5
+960300 6286400 730.5
+977400 6267700 151.5
+934400 6292300 446.5
+989700 6303500 1232.5
+971900 6271800 206.5
+981600 6268900 179
+994500 6267200 240
+962200 6273900 225.5
+985700 6283500 435.5
+929000 6269000 466
+931100 6259000 525
+925500 6267400 574
+930200 6234200 441
+958800 6250000 300
+946200 6227600 136.5
+987800 6298800 1206.5
+972100 6233800 321
+994000 6288700 720
+921100 6271000 555.5
+961900 6250000 456
+950400 6226600 152.5
+943600 6281800 495.5
+1008400 6277100 240
+998100 6287500 424.5
+931300 6225700 176
+988000 6304100 1057
+957600 6269300 253
+977900 6264700 191.5
+947100 6252400 477
+939000 6282100 416
+980200 6277300 378
+933000 6280900 462.5
+930100 6281100 484
+943000 6277800 328
+1003900 6287200 254.5
+998300 6281200 321.5
+955500 6288900 706
+948900 6264900 340
+982000 6273400 186
+988600 6270200 284
+1002500 6266500 308
+949200 6270200 350
+932400 6247800 709.5
+941400 6253600 569
+923700 6248800 736.5
+944800 6271500 361.5
+947100 6287900 524.5
+981000 6285400 686
+964100 6289300 919
+949500 6242400 385.5
+986000 6247900 251.5
+957600 6255100 433.5
+999400 6295100 973.5
+982800 6296400 957
+950200 6232700 142.5
+998800 6287500 373.5
+974100 6232300 242.5
+961300 6279200 330.5
+958400 6302500 570.5
+991300 6243200 162
+952600 6295800 592
+949900 6253400 406
+986000 6272500 165
+938600 6229500 294.5
+981700 6240500 272
+954600 6248400 329.5
+927900 6237300 320
+936900 6286600 509.5
+924100 6236900 241.5
+943700 6243100 373
+978600 6283700 624.5
+961100 6302800 1021
+966700 6282300 631.5
+948100 6261100 478.5
+1005100 6265700 280
+968900 6243200 417
+953500 6254300 424.5
+981500 6252600 367
+990100 6240800 184.5
+950900 6249900 432
+968400 6260700 239.5
+992000 6299500 1307
+985100 6303100 1023
+949100 6294200 500.5
+952600 6268900 236.5
+927000 6281200 496
+966900 6252400 432
+954600 6275000 428
+936900 6260900 390
+995500 6248000 57.5
+955600 6241200 243.5
+938100 6235200 427
+947600 6234600 340.5
+938600 6224100 61.5
+925800 6237700 262
+924100 6230300 110.5
+973000 6284500 689.5
+934400 6226900 176
+992500 6298300 1302
+926600 6295800 352
+998900 6278000 308.5
+972500 6251800 410.5
+977300 6301800 950
+929800 6289900 401
+878900 6331300 548
+855600 6359200 249
+858700 6349900 241.5
+891400 6319000 655
+852100 6328700 69.5
+886500 6346600 1168
+874400 6307500 418
+843900 6347300 165.5
+895200 6310100 432
+874400 6338500 1075.5
+901900 6309900 670
+868700 6336900 291
+870500 6344000 685
+853700 6368100 201
+871100 6335900 271
+884800 6319100 561
+899300 6307500 699.5
+901000 6301600 711
+874900 6332300 314.5
+896200 6293200 264
+849300 6320100 23
+897400 6336800 847
+871400 6353500 347.5
+899800 6328700 959
+877400 6297700 360
+846700 6330300 75
+863900 6306300 124.5
+862500 6338100 243
+870000 6336100 286.5
+878300 6326400 559.5
+834100 6353300 47.5
+852700 6321700 70
+891200 6295800 261.5
+905300 6295100 365
+857000 6324800 32.5
+852900 6317700 70.5
+869900 6354600 560.5
+856400 6312600 86.5
+852000 6337000 65.5
+852400 6364100 144.5
+906800 6302100 694.5
+865100 6324200 149.5
+900500 6298500 316.5
+868000 6339800 444
+864100 6340800 328.5
+857800 6333600 72
+850200 6325100 64
+912100 6302000 536.5
+856300 6342200 101
+906200 6314000 558
+849800 6342300 76.5
+876200 6328200 527.5
+908800 6304800 642.5
+847900 6349400 168.5
+869900 6312800 343
+858600 6339700 161
+882800 6297700 413
+873100 6327000 262
+897700 6307200 817.5
+860300 6342600 392.5
+893200 6316700 715.5
+899600 6317100 676
+861600 6347300 319
+867600 6350100 322
+836800 6350300 125.5
+872700 6312700 365.5
+854900 6319400 75.5
+889800 6345200 938
+856300 6316200 82.5
+869900 6307400 366
+870800 6348800 336.5
+860800 6351600 266.5
+876700 6314900 375
+856700 6354300 245.5
+838100 6346300 132.5
+892800 6335400 1120.5
+898400 6296300 296.5
+864700 6315500 149
+880300 6309700 228
+840800 6343600 96
+890300 6298900 493.5
+868400 6353300 333
+877500 6306200 402.5
+858500 6367000 344
+902900 6316600 600
+885600 6305400 434
+891200 6306400 577.5
+894400 6300700 556.5
+888700 6298400 378
+864100 6330600 134
+850900 6333900 76.5
+873100 6345000 1134
+859400 6355500 275.5
+860300 6345800 265.5
+854500 6324600 31
+878100 6311600 230.5
+879900 6319500 522.5
+914100 6293100 421
+898400 6323600 1040.5
+869100 6317500 365.5
+872200 6324200 388
+862900 6319700 143
+870500 6330900 280.5
+899600 6312900 421.5
+870000 6322800 417
+847400 6345100 146.5
+868100 6306400 302.5
+862100 6335500 97
+870800 6316000 360
+903000 6300400 677.5
+889000 6332600 730.5
+907000 6292400 368.5
+916600 6296800 416
+839600 6355000 177
+862400 6356000 309.5
+860100 6328300 53
+879500 6335900 697.5
+869200 6322200 322
+884200 6314100 262
+844700 6339300 75.5
+845200 6318300 66
+894300 6339700 1107.5
+881800 6348500 1133
+865100 6340400 333.5
+904300 6300000 357
+893300 6306200 711.5
+855200 6318400 78.5
+877000 6309100 174
+854400 6350100 218.5
+901800 6291500 321.5
+872000 6307300 380
+860200 6316500 74.5
+865400 6343200 473
+882800 6306300 434.5
+908500 6299300 453
+852100 6344500 93.5
+892600 6311500 368.5
+850600 6351400 110.5
+886300 6297000 404
+865700 6351300 324.5
+896300 6300200 670
+834700 6357600 50.5
+840600 6335300 31.5
+860200 6332900 62
+867600 6348800 383
+866000 6338200 286.5
+871500 6337800 325.5
+880900 6316700 312.5
+889500 6314300 331
+869100 6325300 194.5
+866000 6302400 400.5
+390900 6657200 146.5
+412700 6586200 5
+371100 6664900 45
+388000 6594100 3.5
+328800 6625600 19
+361500 6654700 49
+364300 6602600 18.5
+415400 6592200 8
+336200 6622200 35.5
+412600 6599600 23.5
+411400 6614900 72.5
+388100 6634900 66
+418500 6623500 169.5
+352500 6610500 46.5
+386800 6610500 30
+417600 6619200 128
+372600 6603000 16
+363700 6611200 39.5
+393000 6632300 74.5
+377000 6660400 58.5
+400900 6597500 21.5
+362700 6643600 69
+406500 6618400 87
+350600 6627700 50.5
+345800 6606700 28.5
+398200 6610700 53
+406200 6598800 14
+403300 6600800 26.5
+356100 6639700 50
+365800 6600900 13.5
+409700 6631400 142.5
+373500 6658500 53
+412700 6592500 9.5
+404100 6658200 148.5
+357200 6658500 43.5
+328600 6660100 21
+346600 6626400 45
+364500 6657600 51
+406100 6652800 141
+362100 6640900 69.5
+387800 6648000 91
+391700 6616500 70.5
+397100 6614100 63
+344800 6643500 41.5
+360700 6608500 44
+373300 6611100 31
+337000 6611400 29.5
+401100 6647600 181.5
+336500 6632900 31.5
+410300 6625700 137
+363600 6653100 64
+362600 6605300 37
+401000 6596800 16
+332100 6637900 19.5
+396300 6588800 15.5
+412200 6605100 58.5
+376900 6612500 39
+314300 6644900 15
+339100 6618000 22.5
+370000 6613400 40
+355500 6635000 68.5
+368900 6647900 73
+412100 6609300 62.5
+392900 6662500 96.5
+344400 6620400 32.5
+380100 6619100 51
+325900 6636000 16
+352700 6604200 20
+342300 6615600 30
+347800 6629900 44.5
+358800 6592300 12.5
+398700 6634800 91
+383100 6615100 37.5
+372200 6598600 15
+390200 6619800 59.5
+403400 6592100 17
+380700 6645700 74.5
+376400 6652300 64
+345700 6646100 45.5
+367900 6644900 65.5
+346300 6614700 41
+385500 6653500 80
+376300 6669800 54.5
+367000 6654700 55.5
+412400 6644300 176
+365700 6618500 41.5
+404400 6605000 27
+386400 6599400 3
+354900 6618200 57.5
+320000 6664600 3
+408000 6603400 35
+325600 6638900 9.5
+376500 6609000 18
+373500 6592600 9
+347900 6617800 43
+383500 6641300 77.5
+375600 6648900 59.5
+414600 6624600 165
+347900 6644200 41
+333900 6617900 16
+392100 6660500 124.5
+373700 6606900 16.5
+403300 6654900 169
+334400 6615000 24.5
+420700 6616600 104.5
+369100 6590500 4
+395400 6617800 77.5
+416600 6594500 12
+400800 6620600 93
+407400 6638400 186
+377500 6639000 85.5
+359900 6633700 66
+417700 6609900 77.5
+365300 6635700 75
+328400 6649900 32.5
+339400 6631200 34
+407600 6595100 9.5
+406500 6628000 127.5
+398200 6594100 3.5
+331800 6627700 22.5
+322600 6651800 9
+326800 6630600 17.5
+400900 6612000 61
+326500 6658000 17.5
+318800 6653800 5.5
+338300 6638600 30
+389400 6614200 47.5
+405200 6607200 54.5
+332400 6654600 30
+350900 6600600 12
+385200 6641300 79
+407300 6653900 164
+396300 6658900 135
+402600 6615000 90.5
+331000 6640500 27.5
+379500 6609100 25
+395300 6639800 95
+380400 6603400 20.5
+299800 6666500 8.5
+418600 6595400 26
+386100 6635300 72
+403200 6620500 95
+355400 6601400 15
+333300 6610700 13
+381000 6623500 58
+400100 6615100 86.5
+409100 6623000 100
+422200 6612300 87.5
+355200 6624300 57
+361700 6628300 63
+411700 6620200 92.5
+375700 6621100 58
+405800 6644100 185.5
+322400 6633700 14
+371100 6652000 57.5
+361900 6599300 11.5
+388900 6608700 28
+342000 6653100 45.5
+404100 6599700 19.5
+421600 6613800 89
+406400 6633900 163
+342500 6639000 36
+375500 6604200 15
+415100 6618100 90
+402700 6611600 66
+398600 6593500 19.5
+326500 6644400 11.5
+330400 6623000 27.5
+374400 6645400 75
+367300 6604700 17.5
+319800 6656700 17.5
+343700 6623700 39
+381800 6647600 76
+387000 6659900 87
+412000 6594300 12.5
+416400 6601400 44
+381600 6614400 32
+390600 6628700 65
+357700 6647900 54.5
+399600 6662100 104
+331200 6633400 24.5
+412800 6633700 177
+369700 6619400 50.5
+337800 6651900 40.5
+332600 6626800 30.5
+398400 6654400 196.5
+397000 6623500 78.5
+322500 6636400 16.5
+417500 6588300 6.5
+376400 6606300 18
+339700 6626400 36.5
+356600 6663700 31
+416300 6590000 6
+366900 6610100 38
+391100 6596400 11.5
+348700 6600900 12.5
+403100 6649900 186
+395500 6595100 6
+347500 6641800 37.5
+356400 6611300 56
+414000 6623400 127
+291800 6638700 16
+355300 6630500 56
+378600 6662400 68.5
+337100 6646900 42
+316500 6658500 13
+420300 6620800 158.5
+403200 6628000 96
+372000 6628000 72
+363200 6619600 55.5
+400700 6624800 79.5
+394400 6649000 157
+409100 6646500 187
+415300 6639300 195
+401000 6609600 47
+395600 6630600 74
+400800 6631500 79.5
+375800 6617800 44.5
+397300 6608300 40.5
+391000 6604600 22.5
+355400 6606500 33
+407600 6611500 80
+405300 6596900 12
+405900 6626700 121
+416700 6632400 171
+370600 6641700 78.5
+367600 6590400 8.5
+369400 6597800 8
+357100 6602900 28.5
+372500 6661400 40
+381400 6658500 66
+409800 6605700 54.5
+349700 6622600 45.5
+408600 6589500 7
+386400 6594600 3.5
+381300 6665400 65.5
+302500 6665100 10
+408100 6606600 57.5
+342500 6630200 37.5
+407700 6617000 84.5
+359200 6620300 55
+393500 6610500 39.5
+369400 6603200 11.5
+377600 6596800 8.5
+383200 6595100 3
+390200 6639100 84
+384700 6606400 22
+388900 6653600 95.5
+396900 6600700 19.5
+319600 6647600 2
+396300 6643500 132
+394400 6603900 22.5
+419200 6613400 91
+387800 6665200 77.5
+301900 6668900 10
+367500 6617400 44
+418900 6603400 54.5
+417600 6598100 32
+398100 6636300 86
+385800 6644300 89.5
+400600 6640200 111
+348300 6636900 43
+358400 6616800 57
+376500 6626300 81.5
+423600 6591600 42.5
+377200 6671200 42
+349900 6647000 40.5
+381000 6633100 88
+384500 6629100 69
+417400 6628400 185
+354800 6645900 51
+400200 6605300 39
+393100 6613200 42.5
+381800 6612600 25
+371900 6638700 87.5
+309100 6649400 10.5
+370100 6660300 36
+306200 6662200 9
+310500 6655300 13
+404100 6644000 204.5
+370600 6632700 80
+331100 6630200 25.5
+529800 6611200 128
+502000 6608100 120
+472700 6675100 75.5
+495300 6605500 110.5
+478000 6627200 132.5
+528100 6618300 121.5
+488300 6587700 118.5
+484100 6595400 124.5
+486900 6641300 114.5
+485500 6586000 125.5
+484100 6602200 141.5
+501500 6555900 159
+472900 6634600 112.5
+511800 6596400 120
+487000 6583900 126
+533500 6617200 106
+499600 6587400 126.5
+478700 6649100 76.5
+532200 6601400 118
+498700 6634100 82
+528600 6642300 95
+483700 6633500 105.5
+524700 6652900 83
+470500 6622200 151
+473900 6666800 77.5
+480200 6619500 133
+525100 6648300 93.5
+506300 6596500 126
+512800 6642100 97.5
+482500 6626800 129
+521600 6568100 157
+518900 6572100 138
+477600 6636000 104
+499000 6568400 153.5
+472300 6628500 143.5
+502300 6596600 125
+528900 6566400 178.5
+513500 6610500 106.5
+517700 6658600 43
+536500 6594000 125
+490300 6662100 77.5
+518000 6655200 76.5
+490600 6627800 93.5
+515200 6631100 91
+529600 6628800 114.5
+493900 6621600 115
+485500 6656000 90
+486200 6559200 129.5
+549700 6598200 140
+476600 6673600 76.5
+525600 6600700 130.5
+486100 6563700 120
+491700 6647700 101
+490400 6651800 104
+494600 6629700 113.5
+470800 6672000 40
+484300 6583600 124.5
+507600 6648900 127
+476400 6646500 69.5
+494400 6559800 147.5
+521900 6578300 132
+480000 6646800 81.5
+491100 6611700 113
+486400 6561300 120
+499100 6620100 93.5
+510900 6613600 114
+481000 6609700 132
+529900 6641200 92.5
+472600 6638500 98.5
+475100 6600300 132
+492700 6659800 79.5
+479100 6596800 129
+497100 6614200 94.5
+553100 6602800 128
+499000 6624000 93
+544900 6607200 114.5
+529600 6603000 119.5
+498300 6648500 109
+491300 6564500 131
+506400 6640000 109
+504800 6587100 125
+469100 6667900 77
+520600 6583400 116
+508200 6632300 90
+488400 6570600 133
+503800 6625500 102
+511500 6615200 117.5
+475200 6628800 126.5
+533100 6634100 95.5
+483800 6638500 118
+482600 6566600 126
+478400 6669300 72.5
+496000 6612500 104.5
+490200 6606800 126
+501800 6604200 116
+497000 6572500 139
+494100 6583400 147
+487800 6626400 117.5
+520800 6596500 108
+531900 6583400 157
+500600 6589100 121.5
+478400 6632800 109.5
+495800 6591900 120
+544100 6598000 125
+483500 6619500 126
+511300 6590900 122
+488500 6656900 91.5
+490700 6560900 133
+536400 6609600 107
+496900 6556500 163
+485000 6635500 123.5
+485500 6660700 92
+490100 6646400 109.5
+515800 6619100 96.5
+502800 6638000 114.5
+505100 6572800 147.5
+499600 6563800 146.5
+501100 6589800 122
+500200 6560200 151
+483300 6663100 78
+534300 6601300 115.5
+514300 6623000 96
+469900 6660000 84
+506700 6607000 121.5
+479700 6657200 89
+478500 6660700 83.5
+520500 6621900 106.5
+473000 6656300 86
+473800 6610800 158.5
+514500 6648700 81
+516200 6587400 136
+558200 6590800 168.5
+483100 6581500 130
+522500 6587700 106.5
+536400 6583500 174.5
+506200 6571500 146
+503700 6629600 103.5
+530300 6565100 197.5
+502900 6616700 105
+519400 6644100 104
+476400 6650400 68.5
+520800 6628000 107.5
+473400 6603200 134
+492300 6578000 126.5
+535200 6622100 105.5
+501800 6576400 138
+546600 6588900 162
+480000 6669300 73
+489600 6586300 124.5
+483400 6569400 135
+495400 6597200 110
+523600 6585200 134
+470800 6657500 81
+525000 6631300 112.5
+466900 6669000 68.5
+499400 6583500 132
+509700 6578300 139.5
+488000 6619800 127
+526800 6569400 170.5
+517900 6651200 82
+483800 6574500 135.5
+484000 6623300 134
+508700 6651600 106
+480900 6621700 133
+527900 6636600 103
+484100 6650100 76
+502700 6647700 116.5
+493300 6656800 85
+540800 6607800 121.5
+476300 6617300 140
+503600 6633400 104.5
+514300 6606900 121
+501300 6622200 102
+553100 6590200 161.5
+475400 6657000 87.5
+515100 6593100 124
+527300 6608600 128
+521700 6572900 135
+519000 6560600 172
+489600 6629900 104
+489500 6624200 115.5
+496400 6609000 104
+510300 6644800 117
+486200 6669800 52
+526600 6613800 129
+512300 6652000 96.5
+477800 6624000 138.5
+478500 6641900 95
+489600 6633400 116
+524200 6617500 119
+530400 6575400 170.5
+496100 6646000 118.5
+518000 6633700 101.5
+469400 6603800 146.5
+493300 6644700 112
+488500 6615500 114
+536800 6588600 144.5
+505900 6610900 113.5
+504700 6601200 122
+515600 6595700 112.5
+496700 6578900 129.5
+518800 6637000 108
+513800 6619500 98
+512900 6638100 88
+498300 6601400 110
+536700 6626800 99.5
+489300 6564900 123.5
+514700 6644600 86
+509700 6571800 150.5
+489800 6557600 124.5
+467800 6661300 80.5
+512400 6560200 178.5
+538400 6623900 101
+473700 6588600 140.5
+484600 6644200 104.5
+486100 6581300 128.5
+475700 6631000 115
+475800 6610700 138
+487200 6623600 125.5
+486300 6632500 123.5
+500100 6650100 104.5
+493700 6612100 105.5
+467200 6667500 80
+468300 6663900 81
+537200 6609300 104.5
+543000 6583600 161
+492200 6607600 123.5
+486300 6595500 114.5
+536700 6613500 103
+472700 6595400 152.5
+522100 6592000 110.5
+487500 6599600 124.5
+482400 6597500 121
+525100 6579700 153
+494700 6572100 140.5
+546000 6594900 146.5
+555900 6592900 150
+493800 6594300 110
+481300 6571400 135
+494500 6617600 104
+470300 6646800 83
+508500 6566700 160
+488400 6652700 99
+482700 6627800 117
+496300 6638300 86
+498100 6598400 132
+509300 6609500 117
+478900 6607900 133
+487800 6650300 106
+528700 6593400 123.5
+476600 6622000 143
+493800 6602200 111.5
+486100 6611300 119.5
+535500 6606100 111.5
+509900 6600500 117
+480800 6653600 68.5
+494500 6640600 92
+540400 6602400 122
+490000 6595900 115
+507200 6584000 132
+500900 6643100 125.5
+493300 6565600 135.5
+472300 6672300 41.5
+516000 6614400 98.5
+506300 6614100 111.5
+505500 6627200 100
+512100 6633500 76
+492400 6641800 105.5
+524600 6655000 76.5
+471400 6659500 86.5
+481200 6663700 80
+512100 6627000 93
+513300 6604700 116
+525400 6591700 109
+519800 6610300 105
+518800 6603500 105.5
+492400 6629900 98
+499300 6638900 112.5
+518300 6628700 102
+496900 6604600 106.5
+499700 6630600 107.5
+568700 6568000 305.5
+520800 6518600 247.5
+550900 6564400 222
+534100 6565300 221.5
+552900 6499900 335
+567100 6552400 430
+543900 6541400 282
+553700 6515300 300.5
+531100 6517100 289.5
+542700 6508200 377
+539400 6525000 271
+573100 6565100 328
+530800 6527100 236
+561700 6558300 272.5
+582700 6502800 402
+550800 6530600 272.5
+567000 6518300 321.5
+569600 6534400 315.5
+569200 6491600 367
+541000 6513500 333
+578300 6496100 409.5
+547100 6505000 444.5
+594800 6501600 574.5
+575900 6533100 325.5
+609100 6514000 592.5
+568700 6511300 310.5
+613600 6510300 639.5
+562300 6524300 277
+534100 6565800 195.5
+524100 6523800 263
+588700 6531600 437
+557600 6520300 281.5
+586700 6503900 424.5
+592000 6514500 445
+537300 6534100 237
+552100 6570200 224
+576500 6584800 298.5
+570500 6573800 302
+593600 6522800 413
+563000 6505700 358
+544300 6510700 404
+553100 6534700 305.5
+570500 6524700 323.5
+530600 6532600 203.5
+580900 6521800 409.5
+579600 6509000 373
+567100 6539400 442
+581500 6513100 384.5
+537600 6514400 375.5
+585700 6512400 432
+561000 6550000 350.5
+577800 6503200 425.5
+575100 6521000 356.5
+576300 6563400 354.5
+566900 6560800 333.5
+538600 6558600 226.5
+565100 6527600 320
+555700 6537500 344
+541400 6524300 313
+559700 6492100 390.5
+534100 6517000 308
+557500 6563800 248.5
+571500 6581600 258
+520300 6515100 235.5
+581100 6558400 357.5
+551600 6513400 343
+570300 6520300 313
+532500 6507400 400.5
+554300 6561100 231
+577500 6512700 345.5
+544900 6566700 212
+572300 6511900 307
+554900 6571900 225.5
+553600 6507200 436
+548600 6572800 204.5
+574400 6581200 301.5
+575100 6524200 405.5
+573900 6506500 354.5
+525600 6514400 330
+538600 6572800 182
+609500 6519700 647.5
+562600 6523000 280.5
+566300 6585300 220.5
+552500 6526000 281.5
+543200 6517700 318.5
+578100 6517900 368
+563100 6586400 196.5
+534100 6552300 257
+561500 6488100 342
+582200 6554100 463.5
+548700 6545400 334
+558700 6570000 256.5
+553300 6573400 229
+556600 6506700 406
+571500 6549400 468
+561000 6541300 371
+562800 6512600 366
+546800 6551400 354
+553500 6550900 275.5
+560800 6503500 363
+554600 6529400 291
+578400 6554600 448.5
+544000 6576100 174.5
+553700 6553900 256.5
+556600 6583900 191.5
+561100 6514800 306.5
+548500 6562100 217
+567000 6507200 370.5
+586500 6499000 469
+537700 6505000 393
+554200 6496100 299.5
+602200 6516300 537
+559700 6560600 261
+562200 6545900 358.5
+578200 6528900 359.5
+558900 6510400 370.5
+565400 6571000 286.5
+528500 6505500 360.5
+581400 6545500 517
+555700 6546800 309.5
+539200 6553200 272.5
+579300 6536700 343.5
+548600 6531300 260.5
+545900 6532800 247.5
+574400 6545300 515
+529800 6520100 266
+553700 6517900 275.5
+540300 6532900 232
+550900 6520700 319
+566500 6545000 444
+599400 6507600 539.5
+585100 6547500 502.5
+591600 6513500 490
+559600 6584500 200
+541200 6533200 231.5
+542100 6549900 380
+541300 6521000 323
+555000 6555800 265
+550000 6510800 431.5
+584200 6535100 364
+581800 6551500 477.5
+583600 6540000 440.5
+562900 6501200 414
+535000 6533300 223.5
+592100 6535100 479.5
+558700 6547100 340
+532800 6514100 370
+574000 6557900 391.5
+596100 6504100 575
+565000 6577900 260.5
+545600 6528000 294.5
+595100 6526900 441
+561300 6520300 292.5
+555200 6523600 266.5
+589500 6504400 548
+544900 6564300 216
+576100 6541000 454.5
+582800 6527500 347
+588700 6519300 354
+542000 6551200 304.5
+565100 6535900 402.5
+526200 6520200 270
+571700 6502300 423.5
+569300 6583900 229
+572100 6583800 260
+582100 6522900 351.5
+563400 6532200 350
+574800 6575300 316.5
+577700 6549000 559.5
+542800 6571300 196
+563600 6552500 374
+565900 6518800 302
+587000 6508300 445
+530600 6503600 335
+556200 6515700 290.5
+558300 6537700 357
+586900 6521700 374.5
+550700 6581800 226
+603000 6520200 582
+586400 6541500 365.5
+594700 6508100 542.5
+599400 6521300 464
+555500 6579200 239
+555600 6540600 320
+568800 6528000 283
+561000 6554700 339
+549400 6559900 238
+574900 6530500 325
+551900 6548800 367.5
+597500 6512900 505
+542200 6565200 209.5
+569900 6530800 290
+604700 6524400 583
+573500 6514600 306
+547500 6538800 269.5
+587100 6517800 374.5
+561800 6564700 275
+599500 6525700 482.5
+532500 6559400 213.5
+589100 6526800 410
+556600 6514300 312.5
+1000600 6798800 795
+974600 6775600 607
+911300 6823600 346.5
+932200 6777300 370
+927700 6787300 343
+905100 6794600 404.5
+958500 6787900 402.5
+922800 6793700 375.5
+916000 6806200 322.5
+960500 6801600 338
+907300 6786800 389.5
+932000 6792200 337.5
+968600 6783400 571
+998000 6805500 414
+952100 6791700 405.5
+895600 6809500 366.5
+940100 6778700 405
+942700 6809700 340.5
+907900 6796500 377.5
+999400 6785200 1004
+901700 6796200 396
+910600 6786700 411.5
+940300 6796200 363.5
+959000 6794800 367.5
+982100 6775900 778.5
+996300 6799800 552
+976200 6796300 547
+949000 6781400 386
+937200 6778600 433.5
+922400 6798900 388.5
+948300 6776000 437
+951600 6788000 423.5
+953100 6783300 401.5
+977600 6786500 618.5
+915200 6769400 318
+962900 6798100 345
+981700 6789600 697.5
+928700 6798000 366
+902700 6821300 350
+904700 6822600 293
+997900 6819700 563.5
+934100 6792000 333.5
+963100 6818400 279
+965500 6790500 427
+965400 6784600 465
+975900 6793600 542
+914800 6795400 370
+996500 6827700 572.5
+982000 6802600 498.5
+907700 6798500 413.5
+970700 6802100 351
+897800 6819200 337.5
+980600 6791900 593
+923800 6808100 349.5
+1004700 6809700 599
+902800 6810400 355
+934500 6811500 285
+933500 6812400 303.5
+910000 6804100 393.5
+973600 6786500 608
+940100 6799200 355
+972200 6790900 516
+973500 6806000 420.5
+966600 6778200 499.5
+971700 6787600 532
+935200 6803200 332
+920700 6777500 315.5
+945300 6796200 371.5
+934600 6794200 324.5
+973500 6775700 579
+910500 6793400 383.5
+978200 6770000 654.5
+926700 6780400 305.5
+932800 6790000 334.5
+969000 6789000 501.5
+933100 6800800 311.5
+916800 6794600 388.5
+915500 6775400 307.5
+988000 6809000 479.5
+915900 6772700 284.5
+972800 6811700 343
+941400 6768600 336
+988900 6774400 971.5
+962200 6778800 488
+880500 6809600 402.5
+977000 6774100 628
+946600 6809300 327
+922500 6787700 375
+954200 6810900 341.5
+945500 6775200 351
+1001800 6807900 478
+903800 6781700 384.5
+917800 6770600 298
+973200 6816400 328
+956600 6773700 527
+940400 6815700 324
+914300 6800000 354.5
+944400 6807800 365
+910500 6824200 325.5
+960100 6764000 544.5
+932400 6802200 321
+900600 6785800 365
+914100 6807100 334
+892200 6818000 371.5
+1000700 6804500 484.5
+956900 6812500 352
+915100 6797800 362
+919100 6793100 389.5
+936000 6813100 289.5
+995700 6816000 535
+936600 6800000 320.5
+904200 6814600 344
+943800 6803700 366
+890100 6816100 398
+969100 6816600 289
+934500 6815600 277
+966700 6815500 290.5
+955400 6816400 322.5
+941400 6788500 369.5
+991900 6824600 565.5
+916400 6786800 421
+998400 6802300 543
+956500 6791500 403.5
+935300 6804900 333
+996800 6804000 416
+1000400 6803500 458.5
+955300 6794000 349.5
+940000 6802600 341.5
+968000 6788100 489.5
+953800 6800000 336.5
+977000 6762900 673.5
+981300 6767700 717.5
+933000 6794200 332.5
+904400 6798700 420
+909300 6772700 399.5
+943900 6793400 358.5
+920100 6801400 379.5
+964700 6803700 331
+994900 6804000 385
+943400 6789300 377
+991500 6790500 833
+908200 6800000 380.5
+962900 6786400 421.5
+947800 6810100 319
+905500 6813100 355.5
+926500 6796500 369.5
+928900 6785200 349
+935600 6800500 317
+942400 6805300 358
+915300 6807900 398
+981200 6801700 504
+909300 6809400 375
+907900 6811900 365
+983000 6759600 842
+983200 6783900 753.5
+1002500 6831300 574.5
+915900 6767300 317
+926900 6809900 305.5
+919900 6764300 272.5
+915300 6764800 313.5
+978900 6791000 607
+900900 6789500 351
+984600 6792900 621.5
+973300 6803000 399
+998200 6793300 910
+989600 6816000 463.5
+932700 6809800 304.5
+995900 6818100 433.5
+979900 6773800 716
+908400 6794700 344
+979400 6761200 678.5
+979100 6788300 699
+987300 6789800 770
+999400 6805200 443.5
+913600 6810300 391.5
+960000 6813100 344
+898500 6815400 344.5
+934200 6799000 307
+910900 6772300 374
+979300 6793700 573
+1000300 6810000 655
+906600 6819800 341.5
+917200 6769700 286.5
+968100 6797200 462.5
+910900 6770100 351.5
+997000 6807100 617.5
+914500 6815100 403.5
+915900 6781800 358.5
+958800 6801900 336.5
+947800 6798800 367.5
+931700 6788800 344.5
+965700 6785300 499.5
+992200 6782800 972
+905400 6790500 378.5
+991400 6812800 448
+910700 6818900 358
+995400 6811100 600
+927300 6789900 367.5
+1002300 6808600 522
+917700 6811300 386.5
+964400 6821300 294.5
+969700 6798000 456
+902700 6815600 358.5
+910300 6810600 377.5
+1002700 6806100 521
+900300 6807200 353.5
+956700 6797100 349
+969400 6819600 306
+917500 6805300 344.5
+951500 6807000 336.5
+926300 6799700 361.5
+928600 6805400 329
+977900 6792000 569.5
+928200 6812500 317
+981600 6795400 557
+929500 6808100 306.5
+978500 6803200 497.5
+931500 6806800 291.5
+939300 6801100 335
+937000 6767600 294.5
+978200 6799300 434
+941000 6812300 319.5
+993100 6794600 676
+945100 6804000 377
+917400 6813200 409.5
+1001400 6812100 634.5
+909700 6802500 357
+939200 6796100 332.5
+946100 6801100 391
+961800 6817900 308
+904100 6791000 378
+968900 6799900 351.5
+924900 6790000 396.5
+1001200 6816000 676
+950000 6791100 398.5
+902200 6804700 372
+973000 6794600 513.5
+949400 6803700 339
+946200 6811800 303.5
+903500 6802200 397
+947800 6767300 440.5
+947800 6797400 361
+950900 6806000 329
+1001300 6807100 467.5
+898300 6799000 374
+935400 6814700 288.5
+962400 6785600 428
+909100 6801600 367
+899400 6783900 372.5
+983600 6808100 489
+924400 6783500 341
+907800 6813200 372.5
+908500 6808100 387
+936000 6790100 342
+975400 6817200 381
+965200 6815600 291
+984200 6818600 444.5
+935200 6793600 335
+936800 6803100 354.5
+985800 6757800 890.5
+940000 6805200 363
+933500 6808200 301
+986400 6769500 849
+887000 6816700 384.5
+986200 6795300 593
+983500 6809400 432
+937800 6813100 323
+937800 6806100 333.5
+993700 6812100 491.5
+918500 6798700 379
+999000 6820200 652.5
+919400 6789200 409.5
+943800 6813000 321.5
+972000 6818700 327
+926400 6805800 334.5
+911100 6807200 363.5
+920500 6804900 362.5
+920200 6809200 346
+897100 6803900 346
+957700 6816000 337
+995500 6819300 572.5
+938400 6810900 325.5
+971700 6799500 428
+909100 6767100 344
+950400 6800000 343.5
+942500 6808900 341
+977000 6793200 557.5
+920800 6796500 400
+971300 6791600 485
+930300 6780900 318
+972800 6792100 530.5
+968600 6775400 594.5
+936700 6792500 340
+947900 6796400 357
+927500 6782100 303
+975200 6807600 420.5
+923600 6768100 309.5
+962100 6800800 341
+913300 6803000 334.5
+928500 6810700 301.5
+1004200 6807000 670
+933200 6807100 322.5
+907500 6823800 322
+979200 6775100 713
+965600 6812300 305.5
+906600 6798900 379
+955000 6806400 349
+987900 6760900 894.5
+955100 6801200 337.5
+988800 6781700 854.5
+905700 6793200 333.5
+931600 6798000 352.5
+923600 6791700 400.5
+980900 6772100 734.5
+938700 6768500 354
+944000 6794700 361.5
+892900 6810600 365.5
+996600 6798400 584
+947900 6791200 378.5
+936600 6809300 317.5
+898600 6797300 387
+934100 6797600 310.5
+965700 6767500 591
+926600 6807800 320.5
+967100 6800200 343.5
+913200 6771500 287
+916200 6812700 413
+994600 6818000 525
+900200 6798700 380.5
+891300 6805200 374.5
+950400 6793500 355
+897900 6813700 353.5
+913000 6778300 350.5
+997300 6794800 799.5
+908500 6792200 386.5
+918900 6806500 330
+967300 6822400 312
+936900 6768400 278
+957400 6804000 332
+977600 6797800 442
+976600 6812900 424
+993900 6800300 549.5
+936900 6814400 322
+942300 6795000 360.5
+945900 6802800 387
+932100 6804400 319.5
+914500 6803700 352
+982500 6763100 807.5
+929900 6793100 357
+999700 6819800 680
+943500 6807600 341
+955100 6798500 330.5
+964100 6814600 300.5
+895400 6813500 354.5
+941100 6810200 341.5
+1001000 6815900 628.5
+915300 6814300 392
+992800 6805500 600.5
+992800 6798000 544
+951000 6795700 347.5
+961000 6811800 331.5
+975100 6788300 577
+929500 6788400 364.5
+901300 6783400 368
+943400 6783100 371.5
+958900 6782500 463
+977300 6780400 641
+971200 6770500 634.5
+925500 6801900 347.5
+967600 6774600 570.5
+903100 6799200 394.5
+995700 6793200 799
+998700 6814500 634.5
+967800 6807000 310
+1003100 6802700 705
+989000 6767100 886
+958400 6768600 455.5
+921600 6769200 310
+981400 6794000 607.5
+998800 6829100 617.5
+985500 6789300 707.5
+981300 6760000 709
+1000500 6830000 592.5
+983500 6812100 420.5
+966500 6796900 410
+964400 6800700 338
+973800 6778700 617.5
+973200 6810300 410
+915200 6791100 383
+971700 6817300 319
+1001400 6805000 551
+941200 6806500 353
+893400 6806100 372.5
+943600 6799900 388
+903700 6823900 349.5
+967300 6805400 322
+979500 6798300 531.5
+884100 6810200 394.5
+933200 6798800 323.5
+930400 6799800 324
+951800 6802600 329.5
+915700 6798900 373
+971600 6772700 612.5
+977000 6799500 446
+930800 6795700 364
+924100 6795900 395.5
+910900 6796800 363.5
+927800 6803500 335.5
+955800 6791000 408
+985600 6814100 438
+956300 6783800 440
+937300 6775600 405.5
+924200 6780400 313.5
+906500 6781400 393
+902400 6779200 398.5
+929800 6805700 309.5
+940900 6774700 338.5
+902800 6794500 403.5
+916600 6782700 364
+941100 6777900 362.5
+926100 6778200 295
+960800 6797400 365.5
+982500 6796900 558
+988300 6792800 616.5
+924400 6800900 368
+925700 6811000 341
+999000 6817900 521
+976300 6794700 467.5
+921800 6805000 358.5
+962100 6814000 316
+884000 6812400 387
+969600 6802300 347
+912800 6789200 414.5
+956500 6808100 352.5
+1001600 6801500 717
+985500 6809800 410.5
+921200 6806900 340
+967200 6818200 288.5
+1000200 6817300 635
+968600 6803100 337.5
+974900 6794700 454.5
+1007600 6809900 649.5
+960900 6806000 340.5
+912600 6812200 394.5
+903600 6780900 395.5
+891000 6807900 368
+919100 6802800 363
+949000 6794000 367.5
+969200 6811300 310
+945600 6812600 314
+939500 6808700 342
+934200 6810100 313.5
+936800 6781800 378.5
+931300 6785600 363
+918700 6784600 374
+1004600 6803100 701
+930900 6789000 354
+971100 6805200 344.5
+989500 6801500 552
+970300 6808900 317
+955400 6804800 323.5
+922600 6779800 335
+969000 6791500 476.5
+936400 6785700 352.5
+923800 6788100 373
+997300 6812300 655
+924700 6805300 361.5
+912100 6806600 358.5
+902200 6803500 376.5
+900900 6803100 356.5
+960900 6794800 379
+960200 6799500 361
+927600 6798800 342.5
+911200 6799700 351.5
+899700 6809500 323.5
+953700 6777100 457
+911800 6776500 379
+942400 6801500 354
+919100 6809000 349
+921500 6774100 288.5
+915400 6781100 393
+962100 6811500 320.5
+945200 6805000 370.5
+942700 6817100 298
+938500 6791400 347.5
+978700 6782500 688.5
+893400 6812500 360.5
+906300 6812900 348
+953000 6804400 326.5
+945900 6789900 399
+971600 6815200 316
+906100 6804500 414
+923300 6810500 369
+926800 6802700 344.5
+917000 6766000 271
+967000 6791400 444
+897900 6820000 337.5
+910100 6782200 416
+903200 6788100 376.5
+919900 6785000 389.5
+897500 6780700 374.5
+943300 6771900 336.5
+926200 6774600 326
+988900 6810800 340
+908700 6806700 402.5
+973800 6792900 518
+899900 6816800 361
+934100 6787200 340.5
+973400 6764800 648.5
+899400 6820100 346.5
+972900 6788300 521.5
+965200 6796100 409.5
+907100 6777900 419.5
+997500 6822000 646.5
+914400 6780100 355
+766900 6755900 189
+698100 6785200 139.5
+750300 6727900 160.5
+708700 6728700 231
+717700 6794300 117
+739800 6792500 167
+765900 6730600 228
+729900 6784900 152
+724900 6744400 226
+760800 6773500 165
+772800 6751000 226
+717400 6768500 143.5
+708000 6759200 159.5
+790600 6751300 258.5
+749800 6735000 201.5
+780000 6753000 208
+768900 6745200 263
+742000 6755500 109
+787800 6738500 232.5
+729500 6751900 161
+703100 6751100 179.5
+791100 6747500 262
+696200 6733500 177
+769500 6701600 324
+792800 6734800 238
+745700 6740900 151
+737600 6791700 154
+771900 6737000 219.5
+702600 6728500 203
+748000 6734300 179
+748700 6738300 199.5
+717000 6795800 125
+757600 6706900 250.5
+744800 6792000 168.5
+719900 6749900 201.5
+778500 6699000 445.5
+713200 6723300 252
+709800 6737200 205
+744800 6724200 211
+727100 6748200 159
+761000 6710400 256.5
+750000 6726900 162.5
+752500 6782200 220.5
+725200 6734200 243.5
+722900 6786000 126
+719100 6796000 88
+736900 6739100 188.5
+705400 6790100 145.5
+757300 6702300 256
+731400 6744500 206
+727800 6761700 141.5
+707700 6802600 119
+719200 6790400 122.5
+726200 6790400 149
+766600 6744900 247
+722100 6720700 275
+752400 6740400 257.5
+773300 6753000 223
+748700 6742000 211.5
+719600 6784200 123.5
+726000 6711500 271.5
+774600 6733400 231.5
+738800 6728000 276.5
+772900 6718900 280
+724400 6728200 269
+715200 6802300 101
+711600 6745100 188.5
+766300 6713800 229.5
+752800 6770800 197.5
+729900 6787900 156
+756100 6752200 167.5
+719600 6787700 120.5
+735000 6725800 294.5
+770800 6756800 181.5
+735000 6723900 305.5
+760600 6749900 200
+771000 6744100 268
+787100 6742400 235.5
+709500 6802100 123
+776800 6718800 227
+728100 6731600 254
+743200 6750100 134.5
+745600 6735500 173
+761600 6762900 132
+724300 6745400 201
+756900 6709200 232.5
+728300 6777500 168.5
+755600 6724800 175
+784100 6745300 221.5
+722100 6775700 137
+763400 6715000 245.5
+777900 6716300 252
+729800 6736600 238.5
+735400 6757200 133.5
+730200 6805900 150.5
+741000 6781600 195.5
+758300 6719800 192
+700000 6731400 187.5
+715100 6798400 126
+747400 6733900 190.5
+777300 6708200 313
+740400 6738400 179.5
+756800 6740100 232
+763800 6708100 250
+779700 6714900 238.5
+778500 6702100 363.5
+757200 6752400 188.5
+729800 6799200 144.5
+786800 6760800 284
+770500 6755100 200
+747800 6722000 185.5
+754200 6713400 225.5
+742500 6770700 180.5
+739500 6753100 141.5
+718100 6759300 166
+738100 6755900 139
+725800 6759400 151
+759000 6762800 122
+779500 6703300 345.5
+767200 6717700 274.5
+712200 6804300 96
+724600 6767500 143
+725400 6786100 148.5
+719600 6724500 270.5
+785900 6717800 309
+726000 6740500 238.5
+781400 6745100 215
+723200 6747100 198.5
+706900 6774900 172.5
+723000 6727700 260
+722000 6737400 241.5
+724400 6757600 172.5
+757600 6704200 234
+721700 6790900 137
+735500 6736700 220.5
+762500 6743900 211
+779300 6719400 271.5
+724000 6761800 147
+719000 6791800 117
+780500 6730400 269.5
+713900 6785900 170.5
+755200 6729700 187.5
+761100 6701900 254.5
+753700 6763600 134
+760000 6769200 120.5
+722700 6805800 132.5
+703800 6800600 128
+752200 6776100 211.5
+760400 6764500 129
+749900 6706500 237.5
+772500 6721200 273
+732700 6783900 166.5
+764700 6710200 190.5
+775100 6703300 331.5
+751000 6755200 142.5
+753200 6729200 170.5
+722500 6778900 127
+737700 6742600 164.5
+705500 6796000 145.5
+756200 6707500 254.5
+719200 6778900 127
+743600 6785000 206.5
+743000 6765000 165.5
+776600 6741300 226.5
+714800 6724200 261.5
+717400 6749900 195.5
+709700 6759900 169
+751800 6731600 197.5
+741900 6757800 105.5
+728400 6785900 149
+768400 6710400 266
+713400 6800000 125.5
+726100 6750200 179
+739400 6793800 167
+699900 6789000 141
+770800 6712900 273.5
+702200 6785800 146
+738500 6758300 122.5
+716200 6775600 145.5
+705400 6742100 189
+739900 6761500 113.5
+761500 6755700 184
+725400 6765800 129.5
+756500 6755900 142.5
+784100 6714300 263
+729200 6794600 168.5
+707200 6754000 165.5
+778000 6754600 239
+765000 6755800 193
+724100 6731300 236
+747000 6770200 142.5
+742500 6723700 263
+792000 6730400 269
+711900 6789400 156.5
+796900 6747000 256
+741700 6714600 169.5
+721700 6782100 120
+723900 6805800 141
+764500 6746400 231
+743600 6733500 203.5
+691300 6738400 160.5
+759200 6771600 153.5
+738100 6777300 218
+768600 6739200 210.5
+791800 6759800 291
+754400 6751700 197.5
+755600 6770800 204
+713100 6769200 161.5
+739100 6758500 93.5
+730800 6753600 156.5
+713400 6764800 171.5
+735300 6760800 112.5
+774400 6740500 220.5
+753100 6756500 142.5
+738300 6768900 183
+770400 6737600 215
+759000 6718200 197.5
+783000 6739500 227
+746000 6766000 120.5
+746800 6755800 143
+741900 6751900 113
+745000 6737600 115
+792300 6742200 268
+724100 6794400 136.5
+716600 6791500 132.5
+781300 6750100 209
+761500 6730000 210.5
+751200 6722300 205.5
+703600 6748300 183
+784700 6751600 221
+778100 6733500 268.5
+779900 6712800 232.5
+765500 6749500 238
+764600 6714500 250
+724100 6771800 141
+718500 6763000 145.5
+774500 6715800 255
+719500 6713100 261.5
+712200 6768400 172.5
+710400 6785300 179.5
+727800 6743800 195.5
+778900 6725600 291
+771400 6755500 218.5
+738100 6805700 163.5
+757100 6722800 211
+746300 6787100 186
+764100 6736800 214.5
+709700 6757000 174.5
+780500 6757800 258
+731900 6785400 154
+762600 6721800 223
+777500 6737300 244.5
+765100 6761700 147.5
+715100 6785200 155.5
+788100 6749300 230
+782300 6713200 265.5
+749700 6729100 195.5
+706800 6737400 194.5
+699000 6721700 218
+764600 6741600 206.5
+783500 6710200 274
+718800 6739700 216
+713100 6757800 182
+744200 6730800 204
+792000 6737800 236
+705400 6726700 231
+781900 6742400 214.5
+782400 6720800 284.5
+722900 6781000 137
+719800 6792100 68
+745300 6771600 204
+736000 6753900 155.5
+744500 6712100 195.5
+749800 6769800 197
+717600 6760300 155.5
+775500 6721300 245
+795800 6746000 279
+750800 6751900 206
+715800 6742400 207
+757100 6763100 110
+719700 6795300 94.5
+757300 6749800 187
+770300 6757500 175.5
+733600 6752000 164
+760100 6704200 215
+781200 6706100 304.5
+719600 6777200 125
+747700 6745200 205
+736100 6762900 119
+760600 6707200 274.5
+703400 6754300 170
+768800 6757900 183
+748700 6750700 191.5
+723400 6769400 141.5
+726200 6726000 276.5
+785200 6759500 284
+776800 6714800 257.5
+735900 6766300 171.5
+713800 6781400 161
+705000 6779300 161
+734900 6747100 163.5
+717300 6772900 143
+744200 6792700 171
+706100 6802700 85.5
+773800 6722300 234.5
+738600 6762800 116
+747700 6714800 205
+732800 6765900 161.5
+710000 6805600 87.5
+785800 6731400 273.5
+768800 6715500 260
+736400 6728600 286
+758500 6756400 157.5
+752000 6715400 236.5
+788200 6740500 239.5
+735300 6731300 270.5
+784300 6719200 298.5
+773600 6709400 290.5
+788800 6757300 271
+749500 6725500 177.5
+759700 6715400 196
+767000 6698800 303.5
+773200 6725400 256
+724700 6717700 272.5
+749900 6755500 131.5
+758800 6714600 219
+771900 6716600 278.5
+764800 6725000 261
+762100 6705300 251
+783200 6746600 213.5
+720600 6717200 292.5
+740800 6730600 252.5
+743800 6735800 208.5
+737600 6723900 266.5
+786100 6736800 241.5
+748400 6718300 181.5
+704800 6804400 105
+740600 6714200 178.5
+723200 6783400 127
+710900 6772800 164.5
+783800 6756500 259
+736100 6781600 183
+730300 6724000 305
+731600 6716400 254.5
+766800 6715300 258.5
+732900 6754800 140.5
+740900 6727900 252.5
+730800 6775900 180.5
+748900 6709400 217
+717400 6784000 143.5
+775300 6696900 452
+707200 6793100 159
+778600 6743400 221.5
+744500 6776900 243
+757400 6776700 225.5
+713600 6780000 151
+722000 6770200 132
+762100 6768700 133.5
+727400 6745400 192.5
+785700 6755900 269
+726300 6747000 166.5
+732900 6798100 175
+707100 6786500 159
+745000 6756000 140
+744700 6758500 122
+720400 6807300 122
+738500 6786800 183
+732700 6792100 173
+796600 6745900 243
+717600 6755100 182.5
+764000 6711200 244.5
+727000 6761900 135.5
+792800 6732800 246.5
+746700 6761500 139.5
+721000 6788600 135
+732900 6787200 159.5
+751400 6724400 167.5
+741100 6735800 231.5
+713000 6733500 238.5
+706700 6782900 164
+696800 6738300 179.5
+780800 6733500 282.5
+743900 6713900 171
+736700 6760200 113.5
+759800 6713600 215.5
+735500 6788900 150.5
+719400 6804700 115
+721600 6763700 140
+742700 6761700 120
+754000 6746800 214
+732700 6757400 119.5
+770900 6753500 202.5
+740400 6717200 190
+759600 6746400 218.5
+753900 6716500 231.5
+779800 6709400 293.5
+755300 6738200 253.5
+710100 6782000 181
+713900 6716700 277
+736600 6713300 215
+708100 6780400 177
+774100 6728400 235
+725200 6754300 170
+709300 6777200 182.5
+756500 6741800 254
+766900 6740900 215
+762300 6760700 134
+790900 6737400 220.5
+722800 6798800 125.5
+729600 6764700 163
+708700 6792200 165
+781700 6711200 260.5
+719500 6732500 266.5
+741300 6792900 158.5
+730900 6739500 220
+747600 6783900 204.5
+777500 6731900 252.5
+703500 6793400 136.5
+751100 6748600 220
+731400 6729100 298.5
+768400 6748700 260.5
+717600 6718800 291.5
+742400 6744300 155
+707600 6746800 170
+739900 6745100 159
+732900 6761300 150
+740700 6798600 175
+705200 6755700 157
+765400 6753300 216
+711700 6794100 157
+767500 6750500 222.5
+755800 6725600 179
+766700 6735800 223.5
+726800 6757000 162.5
+782300 6726300 305.5
+717400 6801000 119
+768700 6718700 284
+725800 6766800 146
+707800 6748900 169
+780400 6719600 268
+711600 6751000 184.5
+740200 6746700 136
+763300 6758400 157
+709700 6746900 176.5
+718200 6797900 120.5
+728200 6791100 172.5
+726200 6752800 174.5
+797000 6742400 279.5
+754100 6767100 140.5
+735100 6786200 154.5
+789000 6722400 295.5
+758200 6766400 119
+787800 6719400 320.5
+778500 6719700 264
+725900 6724200 266.5
+1006900 6720900 419.5
+994800 6721800 359.5
+1002100 6736700 378
+987600 6739400 403.5
+988900 6733800 502
+1002400 6739300 383
+996800 6740300 452.5
+993000 6728900 373
+998000 6741600 442
+995100 6734600 360.5
+994500 6725300 377
+1000500 6727000 366.5
+995200 6736200 363
+1000500 6730900 351
+990600 6747700 803.5
+990100 6731300 384.5
+997200 6738600 386
+993000 6747300 806
+1000900 6740500 388.5
+989500 6727000 380.5
+993900 6736000 389
+997400 6729100 350.5
+995800 6737400 410
+998200 6730400 353
+990900 6736400 428
+991100 6742900 658
+994100 6730300 381
+989300 6724700 371.5
+998300 6731200 356
+1000900 6721900 375
+994500 6732700 366
+999900 6738300 367.5
+985600 6746900 866.5
+995900 6726700 350.5
+1000000 6736400 362.5
+983300 6743900 525.5
+996700 6725700 359
+987600 6735100 418
+994000 6737300 432
+997300 6719100 406
+982600 6744800 825
+1001000 6742300 387.5
+990200 6726100 374.5
+987100 6729600 391
+997200 6744700 726.5
+995700 6723700 366.5
+986600 6744900 626
+1000800 6719400 398
+988200 6736700 404
+1001400 6725500 378.5
+997900 6712500 580
+991600 6727900 363.5
+993900 6742700 657
+998800 6722900 376
+1006800 6726100 388.5
+992000 6733500 398.5
+1006700 6718800 448.5
+989200 6728800 368.5
+984900 6737400 428
+1009500 6720100 474.5
+995900 6740900 433.5
+1000100 6732700 353
+999200 6734900 363.5
+998300 6744000 424.5
+987600 6731300 388
+986600 6728200 396
+990500 6739400 437
+1000700 6733600 357
+988000 6745100 723
+998500 6727300 354.5
+1001600 6726800 371
+1005600 6727800 375
+986500 6732600 430
+986100 6730000 411
+988600 6743900 668
+997400 6742800 464
+1000300 6743300 397.5
+992100 6742900 649.5
+990600 6729600 373.5
+998300 6715300 494.5
+990400 6727700 354.5
+999300 6717200 443.5
+986400 6740800 498.5
+984200 6730600 412.5
+998400 6738700 372.5
+988400 6727800 382
+1000100 6721200 386.5
+995200 6737400 406
+1003600 6721300 383
+994800 6740700 438.5
+1000600 6713700 570
+987700 6740900 463
+1006100 6720200 436
+995500 6716900 475
+992100 6737000 414.5
+995100 6715400 501.5
+997000 6732000 353.5
+1004000 6729000 369.5
+997100 6736700 367.5
+1000300 6729200 356
+1008300 6723500 403.5
+999200 6726900 361
+637600 6838900 142.5
+663400 6844300 65.5
+641700 6828700 112.5
+644400 6844800 103.5
+629200 6805600 130.5
+654000 6808300 104
+631700 6815200 118
+659000 6837200 63.5
+650300 6829700 80.5
+648500 6810600 109
+627000 6825900 125
+635800 6800600 131
+656500 6843000 59.5
+640800 6808600 136
+658400 6829600 69.5
+654900 6839800 58
+653300 6828200 62
+661000 6809300 97
+633500 6807500 115.5
+650500 6848100 73.5
+652600 6814900 101
+638300 6805400 112
+644500 6829400 117.5
+656800 6839200 57
+638300 6844400 109.5
+644800 6846700 103
+644500 6832500 68
+652200 6818800 99.5
+650500 6841700 62.5
+645000 6801700 136
+665600 6843500 64.5
+659900 6832200 64.5
+646200 6840300 122
+631100 6832900 120
+656500 6830400 79.5
+659200 6830800 65
+650300 6819900 102
+645800 6850000 113
+647100 6819300 110
+660400 6846200 61
+659800 6814900 100.5
+647800 6838300 66.5
+656800 6821400 118.5
+648600 6837100 64.5
+648200 6841900 83
+643800 6842700 144
+623500 6814900 148
+662800 6834900 62.5
+626500 6813300 141
+654600 6825200 94.5
+653800 6810700 103
+642100 6824200 108.5
+660600 6811700 97.5
+637700 6829100 103
+650500 6835100 79.5
+642300 6821600 109.5
+662600 6825500 82
+662600 6830200 62.5
+657100 6844600 57.5
+659100 6824000 116.5
+656300 6835500 86.5
+653400 6804100 105
+640200 6821700 109.5
+622900 6817200 152
+637400 6808600 108.5
+662900 6832400 62
+646400 6837900 108
+652900 6836800 88.5
+639500 6827100 110.5
+667600 6842100 68
+658000 6818400 115
+665700 6841300 65.5
+647700 6816600 105.5
+627500 6822800 127.5
+636600 6842400 126
+653900 6815300 102
+632300 6802000 112
+630200 6817300 121.5
+640500 6825900 139
+643100 6849400 108
+654000 6841200 58
+646000 6814800 109
+638000 6815300 111
+635800 6841600 134
+637800 6805000 107
+642300 6850900 123
+649800 6817700 99
+621000 6819100 155.5
+661300 6817000 94.5
+658900 6825800 85
+633600 6836800 130.5
+625700 6801600 129.5
+661300 6834600 62
+630900 6829800 110.5
+645400 6811900 106.5
+643300 6808000 118
+640200 6844500 105.5
+663800 6837900 73
+655600 6827600 65
+646800 6848100 82.5
+651900 6820500 97.5
+662500 6846300 74
+653100 6845500 88
+645100 6833100 71.5
+635500 6831700 105.5
+636200 6844900 114.5
+625400 6805900 134.5
+651000 6845300 73.5
+648700 6840000 63
+643000 6809600 121.5
+646200 6830400 87
+649700 6845200 71.5
+649600 6805000 124.5
+648100 6824600 96
+662600 6819500 96
+637100 6825800 115
+645400 6831900 73
+664400 6843800 62
+636400 6817800 111.5
+662700 6823000 79
+638700 6842800 128.5
+655100 6845600 62
+645800 6835400 67
+659600 6838700 59
+637800 6835800 114.5
+636900 6806600 109
+657700 6833200 63.5
+652700 6821500 96.5
+635400 6836400 130
+644200 6840300 131.5
+637000 6811800 107
+646600 6845600 84
+643800 6806500 130
+626100 6819500 135.5
+636900 6832800 88
+625500 6809100 132
+643200 6838200 118.5
+629900 6842500 138
+629200 6820300 132
+635300 6833900 99.5
+646000 6824300 105.5
+661200 6837400 59
+646000 6837300 107
+635200 6807000 109.5
+638600 6823000 127
+638700 6840700 134.5
+652200 6840600 58.5
+654200 6843300 62
+630900 6814500 116.5
+641700 6848500 117
+627600 6809900 122
+652600 6830400 87.5
+659900 6845400 59.5
+646000 6843800 100.5
+629900 6838900 155.5
+623300 6822600 132
+649000 6834600 69
+632800 6820000 124.5
+650700 6840800 57.5
+635400 6828500 110.5
+654300 6835000 86
+662100 6829600 66
+629500 6826100 122.5
+646600 6802100 130.5
+650900 6827000 67
+632100 6826600 115
+636800 6846300 127
+644500 6819800 121
+639200 6848200 134.5
+642800 6831400 70.5
+639600 6816500 109.5
+653600 6806500 105.5
+662400 6835700 63.5
+654700 6806900 102
+642900 6826000 124.5
+637400 6806500 111.5
+651400 6824000 94
+638900 6829900 83
+635700 6847600 120.5
+646000 6828000 114.5
+645700 6824900 105.5
+648200 6829400 83
+635300 6824100 119.5
+650800 6837700 63.5
+640400 6832800 108
+652300 6841700 66
+628900 6830200 116
+642400 6832400 107
+646100 6806500 119
+626500 6816400 134.5
+654000 6813300 102
+661200 6815600 90.5
+631900 6838800 138.5
+631400 6841700 138.5
+648100 6844300 66.5
+639900 6829500 103
+646300 6865500 33
+647700 6855900 121
+646400 6868900 35.5
+644100 6865200 53.5
+645800 6855900 119.5
+644200 6856600 103.5
+639600 6859200 141.5
+646300 6858400 62
+637800 6860600 155
+640500 6864500 94
+648300 6850600 74
+645900 6853900 129
+647800 6866100 28.5
+644300 6859800 34
+647600 6868100 32.5
+645200 6869500 33.5
+647500 6854600 111
+640300 6860900 131
+650800 6871000 26.5
+645200 6866600 40.5
+650200 6857600 76
+646900 6851900 118.5
+649100 6867300 29
+647800 6858000 56.5
+640800 6858700 132
+643300 6863700 96
+642100 6858400 99
+647900 6853400 78
+640400 6856800 118
+644600 6867500 41.5
+649100 6870500 27
+641600 6865900 74.5
+642400 6861000 96
+648500 6857700 79.5
+649500 6855500 83
+649700 6853300 60
+657800 6870700 43
+657200 6863100 88
+655700 6870300 44.5
+664100 6867400 57
+665000 6871400 56
+664200 6865700 78.5
+659100 6862400 84.5
+665900 6868800 89.5
+662900 6870800 59
+657300 6872800 40
+669000 6868500 93.5
+652000 6874000 59.5
+665000 6866700 85
+652700 6870800 34.5
+657200 6864600 103
+666800 6867800 93.5
+667600 6860500 74.5
+658600 6865000 88.5
+654700 6868100 39.5
+659900 6865800 85.5
+665600 6873500 67.5
+658900 6867900 48
+653200 6874100 67
+669000 6873000 87.5
+668600 6870500 94
+668100 6866600 89.5
+651600 6870900 27.5
+656300 6865200 85.5
+654800 6873000 45
+656500 6866600 73
+664000 6862400 77
+662300 6863800 80.5
+651100 6867600 35
+668900 6862300 49
+662100 6867100 54.5
+649300 6873000 41
+665600 6862100 58
+659300 6869400 45
+660500 6871100 43
+666200 6864700 78.5
+661600 6861400 77.5
+668500 6847400 82.5
+651300 6853400 75.5
+662400 6849700 64.5
+657700 6855400 32
+668500 6856900 99.5
+656500 6852000 40
+657300 6860300 48
+650300 6851200 67
+666600 6858700 84.5
+652900 6856800 80
+664000 6850100 69.5
+668900 6854500 88
+666100 6854100 76
+651200 6856500 73.5
+667000 6848100 79.5
+665700 6846900 80.5
+663600 6860400 52.5
+660800 6849600 60
+662000 6859800 67.5
+650900 6854900 76.5
+663200 6855500 42.5
+652200 6850000 74
+655300 6851800 68.5
+664900 6852300 71.5
+666500 6844800 68
+658800 6861000 58
+656800 6858100 42.5
+658500 6857700 47
+664900 6860200 68
+662300 6852800 53
+661300 6858000 47
+657400 6847400 58.5
+666700 6853100 79
+651900 6857200 61.5
+653100 6855100 96
+655400 6854300 66.5
+652500 6852000 88.5
+665800 6855500 70.5
+667000 6844000 69.5
+664400 6857600 69
+655000 6857300 48
+658700 6856300 37.5
+655400 6849500 59.5
+656700 6848400 60.5
+659500 6848200 61.5
+660500 6854600 52.5
+648800 6884900 118
+631500 6884800 64.5
+610100 6894500 94.5
+603600 6898200 92
+631400 6882200 71
+667200 6882900 102.5
+647600 6879100 123.5
+659800 6883800 107.5
+653300 6881100 95
+631200 6879900 36.5
+623400 6883900 86
+619400 6888000 103.5
+641400 6887700 59
+660200 6888600 78.5
+629700 6879400 98
+658000 6885700 147.5
+628600 6894100 141
+604500 6892100 123.5
+635200 6893700 86
+611500 6895600 106
+661100 6888800 99
+630500 6897500 158
+666800 6888800 115
+627000 6896700 164.5
+627000 6886900 75
+622900 6893600 82
+617200 6882300 75
+668400 6885600 121
+650800 6881100 141
+658500 6875100 47
+650400 6876900 114.5
+650900 6895500 53.5
+667600 6881400 105.5
+627200 6887400 70.5
+648000 6878200 89.5
+634300 6883800 54.5
+635100 6894900 79.5
+615200 6892500 147
+619000 6892400 96.5
+631500 6891800 121
+629200 6882100 72
+602300 6894100 75.5
+663400 6886900 108
+622100 6890700 84.5
+631900 6888100 87
+600800 6890400 86
+622700 6883000 82
+652000 6876500 87
+625500 6881300 136.5
+668500 6888100 152
+652000 6879300 134
+616400 6896100 111
+635400 6898300 96
+638900 6877000 55.5
+653000 6892800 115
+647600 6890800 118
+659500 6888700 95.5
+648700 6878600 124
+602000 6887900 80.5
+658300 6892000 79.5
+653100 6886500 119
+645800 6877100 54
+639700 6886100 66
+652900 6877800 112.5
+611700 6889100 163
+630600 6892900 126
+663500 6884300 116.5
+661500 6881400 82.5
+620400 6893700 84
+637800 6880600 56.5
+643700 6876700 110.5
+663800 6882800 95.5
+620200 6890900 107.5
+618700 6895200 116.5
+659600 6876400 68
+607500 6899000 121.5
+639500 6895200 111.5
+606900 6888500 147
+652200 6889800 133
+655800 6891400 85.5
+664700 6878400 91.5
+629200 6886900 68
+639900 6875200 51.5
+614900 6889800 149
+650800 6875200 73.5
+642600 6869800 37
+627000 6882100 127.5
+643400 6896600 116
+647400 6874800 49
+649000 6895900 52.5
+639500 6892500 97.5
+622500 6896200 114.5
+654000 6892200 91
+625300 6897000 146
+643500 6880900 121.5
+642500 6882300 110
+621700 6887000 96
+625600 6888300 84
+647900 6893900 116.5
+632300 6895300 91.5
+603800 6901700 86
+606300 6885900 91
+641500 6875100 96
+637500 6893100 80
+633900 6888800 92
+611800 6893600 115.5
+648800 6882800 143
+632300 6899400 111
+645600 6874900 105.5
+666600 6884300 110.5
+654700 6880000 114
+608000 6885000 123.5
+646300 6879800 125
+634700 6886500 68
+644900 6879900 124
+652200 6884300 104.5
+654100 6887900 128.5
+638000 6894700 82.5
+624500 6889400 84
+644200 6893200 99.5
+627000 6880600 145
+646400 6884000 137.5
+604900 6895100 92
+645400 6884100 136.5
+661300 6878400 78
+635000 6883100 40
+649400 6886600 123
+651100 6893300 116
+647300 6888000 129.5
+646800 6895100 39.5
+643300 6890400 68
+656100 6874800 57
+652100 6875000 75.5
+641100 6877400 114.5
+628500 6891100 125.5
+603300 6888500 127.5
+606500 6894200 99.5
+657800 6890500 92
+610300 6886500 154
+617700 6887900 141.5
+636700 6889400 100.5
+627000 6891600 124
+617200 6885700 138
+610300 6897300 106.5
+604600 6900100 97
+647300 6877100 62
+640900 6888800 70
+649600 6886000 147
+642200 6890800 85
+599900 6887700 78
+644900 6872300 95
+644200 6878400 69
+655400 6878900 105.5
+633500 6880100 39
+662400 6878000 74
+616500 6889100 114
+654500 6877700 94
+622000 6885200 88.5
+648200 6892200 117
+657300 6881600 96.5
+640500 6885200 59
+641900 6886900 58.5
+648800 6876700 89.5
+613500 6892500 137.5
+616000 6890500 121.5
+623500 6892300 85.5
+641900 6883800 112.5
+658000 6880600 88.5
+657100 6887400 129
+655400 6886000 129
+640700 6879600 60
+656000 6883700 108
+660400 6885300 140.5
+649300 6874700 43
+608900 6892500 131.5
+625800 6894400 147
+646700 6892900 35
+657300 6876500 58
+659300 6886600 113
+628400 6884500 78
+651500 6883500 91
+605200 6885700 79.5
+644100 6885200 102
+610500 6889600 157.5
+664000 6888800 97.5
+1182500 6144400 1198.5
+1179100 6145800 1171
+1171100 6150500 809
+1192000 6137200 1454.5
+1190400 6131400 866
+1195200 6134300 1287
+1191900 6132400 778
+1186300 6132300 844.5
+1188400 6131600 887
+1177900 6137200 641
+1182000 6136400 761.5
+1179700 6133300 447.5
+1179600 6136100 560
+1163000 6131400 352.5
+1174300 6145900 663
+1168900 6151500 500
+1198400 6126500 1116
+1201600 6128200 1342.5
+1191500 6125400 712
+1183900 6129100 539
+1181500 6128000 439.5
+1179600 6125100 206
+1179800 6126900 224.5
+1175900 6131000 458.5
+1190500 6139100 1386
+1188700 6137900 1013
+1188700 6139400 1254.5
+1179300 6143500 672.5
+1181600 6141200 1112
+1201900 6119400 1326.5
+1191100 6118800 772.5
+1195500 6123700 943.5
+1193500 6123100 719.5
+1184400 6120900 574
+1188900 6122200 690
+1182400 6123200 444
+1182900 6124400 670
+1178200 6120600 438
+1183000 6120600 500.5
+1178300 6119000 438
+1181500 6122800 413.5
+1183500 6139000 1159.5
+1165600 6143200 666
+1212300 6116600 1364
+1210300 6114500 1245
+1211000 6112600 1276
+1206800 6113400 1108.5
+1208400 6113200 1126
+1195600 6115900 864.5
+1192600 6114000 673.5
+1190000 6117000 662.5
+1180900 6115800 359
+1176600 6114700 391
+1170500 6112300 393.5
+1164600 6152500 463.5
+1203900 6107000 661.5
+1209200 6109400 1257
+1205600 6109800 982
+1196900 6105000 815
+1199400 6107900 1036.5
+1202700 6107200 794
+1198900 6106800 805.5
+1200400 6107500 1104.5
+1191200 6109100 586
+1190600 6109700 276.5
+1183700 6109300 447.5
+1176400 6109000 393.5
+1230000 6103000 543.5
+1203700 6102100 970
+1199700 6102700 492
+1200000 6103900 631.5
+1198500 6101800 405.5
+1201200 6098500 809.5
+1197000 6104200 455
+1195700 6104300 580.5
+1191300 6099200 433
+1193000 6100200 433
+1194700 6100400 392
+1194000 6103200 529
+1186300 6099800 364
+1227600 6091600 722.5
+1211200 6093800 1134
+1214000 6092100 740
+1208000 6092200 973.5
+1208900 6092000 759
+1206300 6094100 1176.5
+1206000 6091900 769
+1197800 6094700 717.5
+1200300 6097700 763
+1191700 6097500 287
+1180600 6092200 324
+1226800 6085300 323
+1212300 6088900 631.5
+1210400 6086800 759
+1205200 6085200 299
+1205600 6085700 452
+1206000 6086700 634
+1204000 6089500 576.5
+1203100 6088000 479.5
+1208000 6085700 522.5
+1205900 6088000 492
+1200300 6085300 484
+1200500 6086400 552
+1194500 6091000 565.5
+1193200 6087000 527.5
+1192500 6089900 407
+1183200 6087600 326.5
+1212600 6084100 786.5
+1199500 6083500 331.5
+1201200 6079700 350.5
+1196400 6083100 336.5
+1192400 6082200 304.5
+1224400 6075300 658
+1206100 6078300 394
+1198700 6076600 660
+1197300 6072700 364.5
+1190700 6074800 316
+1193100 6076700 381
+1185400 6076400 221
+1217800 6069600 657.5
+1212800 6062900 683
+1206600 6063100 660.5
+1202700 6064900 594
+1216300 6051900 170
+1223300 6164200 1203
+1218700 6167700 909
+1223200 6165300 1112.5
+1218500 6165100 974.5
+1217700 6167100 931.5
+1223000 6169400 785.5
+1222800 6168400 779
+1223100 6168000 796.5
+1218600 6169100 715.5
+1214300 6164700 680
+1208000 6169600 485
+1207500 6166900 541.5
+1204900 6167700 1070
+1204700 6166000 1260
+1196500 6169400 1544.5
+1235500 6160500 565.5
+1235300 6158900 467
+1235400 6157000 147.5
+1235500 6159300 488
+1231600 6161200 884.5
+1224000 6162000 1107
+1224700 6162800 569.5
+1225900 6160700 699.5
+1227300 6162200 816.5
+1228200 6162600 832.5
+1229000 6160300 904.5
+1227200 6157200 933.5
+1226300 6159600 1143
+1226900 6158600 1070.5
+1227700 6160300 758
+1226600 6162700 543
+1225100 6162500 445
+1229100 6157800 663.5
+1224700 6161700 1066.5
+1223700 6162400 1061.5
+1218300 6163400 1062.5
+1218500 6160300 1174.5
+1218700 6161100 965.5
+1216800 6161900 705.5
+1214800 6162900 874.5
+1216100 6160600 1112.5
+1211800 6158300 937
+1210900 6161200 787
+1206400 6161100 1124.5
+1208100 6159800 1175.5
+1198200 6158500 1509.5
+1177500 6158200 1299
+1165300 6162200 858.5
+1234800 6152400 546.5
+1229800 6156700 514.5
+1232200 6154900 619.5
+1234500 6156800 551
+1230200 6151700 646
+1234400 6151200 546.5
+1234400 6154300 390
+1224900 6153300 1075.5
+1227400 6152500 680
+1229300 6152400 690
+1229300 6155900 793.5
+1228600 6156900 494
+1223900 6151200 712
+1217000 6155400 913.5
+1219700 6156600 1172
+1220000 6154400 1096.5
+1219000 6154700 760
+1220700 6154200 1182.5
+1220100 6153800 765
+1217500 6153300 492.5
+1215400 6154900 873.5
+1213100 6156400 951.5
+1207500 6153700 1462.5
+1193600 6155100 1671.5
+1195100 6154100 1552.5
+1195000 6157200 1761.5
+1196300 6156200 1232.5
+1229800 6147200 288.5
+1231000 6149500 571.5
+1226000 6145300 375.5
+1224200 6147200 500.5
+1224900 6149400 534.5
+1226400 6145500 379.5
+1226400 6150200 520
+1218800 6150000 552
+1219800 6148600 685.5
+1219700 6147000 675.5
+1222700 6147100 646
+1210800 6148700 444
+1210500 6147900 488.5
+1210000 6145700 1412
+1209700 6147200 1308.5
+1209900 6148200 1457.5
+1224800 6139600 392.5
+1218600 6138000 729.5
+1215000 6141400 844
+1216500 6139700 807.5
+1220400 6229500 281
+1210200 6139100 1395
+1211400 6138900 972
+1239100 6134900 51
+1231200 6133500 238
+1226200 6137100 417.5
+1214200 6131700 1232
+1221700 6127000 870.5
+1221900 6129000 546
+1231000 6123300 164.5
+1225600 6119400 780
+1224400 6122100 290
+1220000 6118800 1103
+1220900 6120900 1077.5
+1225700 6114600 516.5
+1220100 6112200 994.5
+1225500 6110300 1009
+1213200 6142100 812.5
+1226700 6224600 302
+1225700 6226600 207
+1219400 6226100 302
+1219600 6227700 281
+1223600 6227600 301
+1225300 6218700 534
+1219200 6218400 580
+1218600 6221800 418
+1223100 6220900 568
+1225600 6215500 632
+1226400 6212200 662
+1221000 6211100 722
+1217400 6214800 634
+1218300 6210800 662
+1229900 6207900 653
+1226700 6204500 599
+1221500 6206500 653
+1219200 6208100 420.5
+1228500 6199400 481.5
+1228800 6202000 492
+1226900 6200800 450
+1222700 6197800 473.5
+1221400 6198600 512.5
+1221300 6202400 560
+1226800 6191100 332.5
+1226000 6194500 360
+1221900 6192100 426
+1221400 6191300 479.5
+1216700 6196300 178
+1220300 6187400 289
+1217500 6186300 351.5
+1221500 6189000 415
+1222500 6185500 593
+1219500 6185000 675.5
+1214500 6187000 713
+1213700 6187700 434.5
+1216300 6185000 721.5
+1215200 6185300 827
+1206200 6185900 702
+1206900 6183900 827.5
+1202400 6184400 417.5
+1194200 6183900 405.5
+1196200 6184500 397
+1187200 6188900 75.5
+1184600 6184700 268
+1188700 6187100 204
+1184900 6183600 329.5
+1186700 6185400 298
+1184800 6186400 280.5
+1181200 6185400 134.5
+1224400 6181000 589
+1227300 6182100 343.5
+1228000 6183100 558.5
+1226400 6177400 214
+1222900 6180100 732.5
+1222200 6179500 638
+1219200 6179500 671.5
+1217900 6179500 619.5
+1216400 6178600 800
+1208300 6180700 885.5
+1197500 6177000 752.5
+1194800 6177600 1422.5
+1191400 6181100 690
+1193000 6178400 1289
+1192900 6182700 382
+1191800 6181600 576
+1193500 6182600 581.5
+1184300 6180500 486.5
+1186000 6178900 760
+1185100 6177100 1053.5
+1188800 6179600 794.5
+1187800 6178800 892.5
+1182800 6177500 410
+1182800 6181800 424.5
+1184000 6181600 444.5
+1179100 6182000 280.5
+1184100 6182700 163
+1172900 6180300 350
+1231100 6175500 155
+1232600 6170200 262.5
+1231100 6174600 308
+1232600 6173800 160
+1231500 6173700 320
+1229400 6171900 362.5
+1229600 6176500 220
+1223700 6170700 694
+1223500 6172700 578.5
+1227000 6171100 604
+1225800 6173400 618
+1229000 6174500 729
+1226900 6176500 357.5
+1227500 6171500 806
+1227600 6170500 355.5
+1219600 6172300 667
+1222700 6170300 847.5
+1220200 6174000 590
+1222500 6175800 543.5
+1222000 6171800 774.5
+1222600 6173100 618
+1216800 6171600 657
+1214900 6176400 737
+1202900 6173600 1132
+1202600 6175500 634
+1194000 6176600 1278.5
+1181500 6174300 1072
+1179900 6174400 300.5
+1237900 6165100 206.5
+1237700 6163900 461
+1233700 6167300 243.5
+1232400 6167900 600
+1233000 6166400 674.5
+1230300 6167900 518.5
+1235000 6166200 183
+1233800 6163500 687
+1223900 6167100 957
+1224300 6168100 472.5
+1227700 6167100 713.5
+1227200 6163800 753.5
+1227400 6165100 731
+1228900 6167300 369
+1224300 6164700 485.5
+1224300 6165700 681.5
+1227100 6167700 400
diff --git a/test/data/rgc-france-ign.xyz.README b/test/data/rgc-france-ign.xyz.README
new file mode 100644
index 0000000..899df0f
--- /dev/null
+++ b/test/data/rgc-france-ign.xyz.README
@@ -0,0 +1,7 @@
+http://professionnels.ign.fr/rgc
+
+From IGN RGC®,
+Open License etalab
+"La réutilisation du RGC® est gratuite pour tous les usages, y compris commerciaux, selon les termes de la "licence ouverte" version 1.0."
+
+
diff --git a/test/data/teapot.obj b/test/data/teapot.obj
new file mode 100644
index 0000000..c839837
--- /dev/null
+++ b/test/data/teapot.obj
@@ -0,0 +1,9965 @@
+v -3.000000 1.800000 0.000000
+v -2.991600 1.800000 -0.081000
+v -2.991600 1.800000 0.081000
+v -2.989450 1.666162 0.000000
+v -2.985000 1.921950 0.000000
+v -2.985000 1.921950 0.000000
+v -2.981175 1.667844 -0.081000
+v -2.981175 1.667844 0.081000
+v -2.976687 1.920243 -0.081000
+v -2.976687 1.920243 0.081000
+v -2.968800 1.800000 -0.144000
+v -2.968800 1.800000 0.144000
+v -2.958713 1.672406 -0.144000
+v -2.958713 1.672406 0.144000
+v -2.957600 1.534800 0.000000
+v -2.957600 1.534800 0.000000
+v -2.954122 1.915609 -0.144000
+v -2.954122 1.915609 0.144000
+v -2.949693 1.537790 -0.081000
+v -2.949693 1.537790 0.081000
+v -2.940000 2.019600 0.000000
+v -2.935200 1.800000 -0.189000
+v -2.935200 1.800000 0.189000
+v -2.931958 2.016526 0.081000
+v -2.931958 2.016526 -0.081000
+v -2.928230 1.545907 -0.144000
+v -2.928230 1.545907 0.144000
+v -2.925611 1.679131 -0.189000
+v -2.925611 1.679131 0.189000
+v -2.920870 1.908779 -0.189000
+v -2.920870 1.908779 0.189000
+v -2.910131 2.008181 -0.144000
+v -2.910131 2.008181 0.144000
+v -2.904150 1.406137 0.000000
+v -2.904150 1.406137 0.000000
+v -2.896846 1.410135 0.081000
+v -2.896846 1.410135 -0.081000
+v -2.896602 1.557869 -0.189000
+v -2.896602 1.557869 0.189000
+v -2.894400 1.800000 -0.216000
+v -2.894400 1.800000 0.216000
+v -2.885416 1.687296 -0.216000
+v -2.885416 1.687296 0.216000
+v -2.880491 1.900487 -0.216000
+v -2.880491 1.900487 0.216000
+v -2.877965 1.995883 -0.189000
+v -2.877965 1.995883 0.189000
+v -2.877022 1.420985 -0.144000
+v -2.877022 1.420985 0.144000
+v -2.865000 2.095650 0.000000
+v -2.858195 1.572394 0.216000
+v -2.858195 1.572394 -0.216000
+v -2.857432 2.091511 -0.081000
+v -2.857432 2.091511 0.081000
+v -2.850000 1.800000 -0.225000
+v -2.850000 1.800000 0.225000
+v -2.847806 1.436974 0.189000
+v -2.847806 1.436974 -0.189000
+v -2.841675 1.696181 0.225000
+v -2.841675 1.696181 -0.225000
+v -2.838906 1.980950 -0.216000
+v -2.838906 1.980950 0.216000
+v -2.836889 2.080276 -0.144000
+v -2.836889 2.080276 0.144000
+v -2.836550 1.891463 -0.225000
+v -2.836550 1.891463 0.225000
+v -2.828800 1.280400 0.000000
+v -2.822326 1.285171 -0.081000
+v -2.822326 1.285171 0.081000
+v -2.816400 1.588200 -0.225000
+v -2.816400 1.588200 0.225000
+v -2.812331 1.456390 0.216000
+v -2.812331 1.456390 -0.216000
+v -2.806615 2.063720 -0.189000
+v -2.806615 2.063720 0.189000
+v -2.805600 1.800000 -0.216000
+v -2.805600 1.800000 0.216000
+v -2.804755 1.298122 -0.144000
+v -2.804755 1.298122 0.144000
+v -2.797934 1.705067 -0.216000
+v -2.797934 1.705067 0.216000
+v -2.796400 1.964700 0.225000
+v -2.796400 1.964700 -0.225000
+v -2.792609 1.882438 -0.216000
+v -2.792609 1.882438 0.216000
+v -2.778861 1.317206 -0.189000
+v -2.778861 1.317206 0.189000
+v -2.774605 1.604006 0.216000
+v -2.774605 1.604006 -0.216000
+v -2.773725 1.477519 0.225000
+v -2.773725 1.477519 -0.225000
+v -2.769854 2.043616 -0.216000
+v -2.769854 2.043616 0.216000
+v -2.764800 1.800000 -0.189000
+v -2.764800 1.800000 0.189000
+v -2.760000 2.152800 0.000000
+v -2.760000 2.152800 0.000000
+v -2.757739 1.713232 -0.189000
+v -2.757739 1.713232 0.189000
+v -2.753894 1.948450 -0.216000
+v -2.753894 1.948450 0.216000
+v -2.753123 2.147861 -0.081000
+v -2.753123 2.147861 0.081000
+v -2.752230 1.874146 -0.189000
+v -2.752230 1.874146 0.189000
+v -2.747418 1.340381 -0.216000
+v -2.747418 1.340381 0.216000
+v -2.736198 1.618531 -0.189000
+v -2.736198 1.618531 0.189000
+v -2.735119 1.498648 0.216000
+v -2.735119 1.498648 -0.216000
+v -2.734458 2.134454 -0.144000
+v -2.734458 2.134454 0.144000
+v -2.731250 1.157813 0.000000
+v -2.731250 1.157813 0.000000
+v -2.731200 1.800000 -0.144000
+v -2.731200 1.800000 0.144000
+v -2.729850 2.021737 -0.225000
+v -2.729850 2.021737 0.225000
+v -2.725825 1.163194 0.081000
+v -2.725825 1.163194 -0.081000
+v -2.724637 1.719956 -0.144000
+v -2.724637 1.719956 0.144000
+v -2.718978 1.867316 -0.144000
+v -2.718978 1.867316 0.144000
+v -2.714835 1.933517 -0.189000
+v -2.714835 1.933517 0.189000
+v -2.713200 1.365600 -0.225000
+v -2.713200 1.365600 0.225000
+v -2.711100 1.177800 -0.144000
+v -2.711100 1.177800 0.144000
+v -2.708400 1.800000 -0.081000
+v -2.708400 1.800000 0.081000
+v -2.706950 2.114698 -0.189000
+v -2.706950 2.114698 0.189000
+v -2.704570 1.630493 -0.144000
+v -2.704570 1.630493 0.144000
+v -2.702175 1.724519 -0.081000
+v -2.702175 1.724519 0.081000
+v -2.700000 1.800000 0.000000
+v -2.699644 1.518063 0.189000
+v -2.699644 1.518063 -0.189000
+v -2.696413 1.862682 -0.081000
+v -2.696413 1.862682 0.081000
+v -2.693900 1.726200 0.000000
+v -2.689846 1.999859 -0.216000
+v -2.689846 1.999859 0.216000
+v -2.689400 1.199325 -0.189000
+v -2.689400 1.199325 0.189000
+v -2.688100 1.860975 0.000000
+v -2.688100 1.860975 0.000000
+v -2.683107 1.638610 -0.081000
+v -2.683107 1.638610 0.081000
+v -2.682669 1.921219 -0.144000
+v -2.682669 1.921219 0.144000
+v -2.678982 1.390819 -0.216000
+v -2.678982 1.390819 0.216000
+v -2.675200 1.641600 0.000000
+v -2.675200 1.641600 0.000000
+v -2.673549 2.090707 -0.216000
+v -2.673549 2.090707 0.216000
+v -2.670428 1.534053 -0.144000
+v -2.670428 1.534053 0.144000
+v -2.663050 1.225463 -0.216000
+v -2.663050 1.225463 0.216000
+v -2.660842 1.912874 0.081000
+v -2.660842 1.912874 -0.081000
+v -2.653085 1.979755 -0.189000
+v -2.653085 1.979755 0.189000
+v -2.652800 1.909800 0.000000
+v -2.652800 1.909800 0.000000
+v -2.650604 1.544903 0.081000
+v -2.650604 1.544903 -0.081000
+v -2.647539 1.413994 -0.189000
+v -2.647539 1.413994 0.189000
+v -2.643300 1.548900 0.000000
+v -2.637200 2.064600 -0.225000
+v -2.637200 2.064600 0.225000
+v -2.634375 1.253906 0.225000
+v -2.634375 1.253906 -0.225000
+v -2.625000 2.193750 0.000000
+v -2.622811 1.963199 -0.144000
+v -2.622811 1.963199 0.144000
+v -2.621645 1.433078 -0.144000
+v -2.621645 1.433078 0.144000
+v -2.619050 2.188238 -0.081000
+v -2.619050 2.188238 0.081000
+v -2.611200 1.038600 0.000000
+v -2.611200 1.038600 0.000000
+v -2.607034 1.044497 0.081000
+v -2.607034 1.044497 -0.081000
+v -2.605700 1.282350 -0.216000
+v -2.605700 1.282350 0.216000
+v -2.604074 1.446029 -0.081000
+v -2.604074 1.446029 0.081000
+v -2.602900 2.173275 -0.144000
+v -2.602900 2.173275 0.144000
+v -2.602268 1.951964 -0.081000
+v -2.602268 1.951964 0.081000
+v -2.600851 2.038493 -0.216000
+v -2.600851 2.038493 0.216000
+v -2.597600 1.450800 0.000000
+v -2.595725 1.060502 -0.144000
+v -2.595725 1.060502 0.144000
+v -2.594700 1.947825 0.000000
+v -2.579350 1.308488 -0.189000
+v -2.579350 1.308488 0.189000
+v -2.579100 2.151225 -0.189000
+v -2.579100 2.151225 0.189000
+v -2.579059 1.084090 -0.189000
+v -2.579059 1.084090 0.189000
+v -2.567450 2.014502 -0.189000
+v -2.567450 2.014502 0.189000
+v -2.558822 1.112731 0.216000
+v -2.558822 1.112731 -0.216000
+v -2.557650 1.330013 -0.144000
+v -2.557650 1.330013 0.144000
+v -2.550200 2.124450 -0.216000
+v -2.550200 2.124450 0.216000
+v -2.542925 1.344619 0.081000
+v -2.542925 1.344619 -0.081000
+v -2.539942 1.994746 -0.144000
+v -2.539942 1.994746 0.144000
+v -2.537500 1.350000 0.000000
+v -2.537500 1.350000 0.000000
+v -2.536800 1.143900 0.225000
+v -2.536800 1.143900 -0.225000
+v -2.521277 1.981339 -0.081000
+v -2.521277 1.981339 0.081000
+v -2.518750 2.095312 -0.225000
+v -2.518750 2.095312 0.225000
+v -2.514778 1.175069 0.216000
+v -2.514778 1.175069 -0.216000
+v -2.514400 1.976400 0.000000
+v -2.514400 1.976400 0.000000
+v -2.494541 1.203710 -0.189000
+v -2.494541 1.203710 0.189000
+v -2.487300 2.066175 -0.216000
+v -2.487300 2.066175 0.216000
+v -2.477875 1.227298 -0.144000
+v -2.477875 1.227298 0.144000
+v -2.468350 0.922987 0.000000
+v -2.466566 1.243303 0.081000
+v -2.466566 1.243303 -0.081000
+v -2.465644 0.929375 -0.081000
+v -2.465644 0.929375 0.081000
+v -2.462400 1.249200 0.000000
+v -2.462400 1.249200 0.000000
+v -2.460000 2.221200 0.000000
+v -2.460000 2.221200 0.000000
+v -2.458400 2.039400 -0.189000
+v -2.458400 2.039400 0.189000
+v -2.458298 0.946711 -0.144000
+v -2.458298 0.946711 0.144000
+v -2.455229 2.215303 -0.081000
+v -2.455229 2.215303 0.081000
+v -2.447474 0.972260 0.189000
+v -2.447474 0.972260 -0.189000
+v -2.442278 2.199298 -0.144000
+v -2.442278 2.199298 0.144000
+v -2.434600 2.017350 -0.144000
+v -2.434600 2.017350 0.144000
+v -2.434329 1.003283 -0.216000
+v -2.434329 1.003283 0.216000
+v -2.423194 2.175710 -0.189000
+v -2.423194 2.175710 0.189000
+v -2.420025 1.037044 -0.225000
+v -2.420025 1.037044 0.225000
+v -2.418450 2.002387 -0.081000
+v -2.418450 2.002388 0.081000
+v -2.412500 1.996875 0.000000
+v -2.412500 1.996875 0.000000
+v -2.405721 1.070804 -0.216000
+v -2.405721 1.070804 0.216000
+v -2.400019 2.147069 -0.216000
+v -2.400019 2.147069 0.216000
+v -2.392576 1.101828 -0.189000
+v -2.392576 1.101828 0.189000
+v -2.381752 1.127376 -0.144000
+v -2.381752 1.127376 0.144000
+v -2.374800 2.115900 -0.225000
+v -2.374800 2.115900 0.225000
+v -2.374406 1.144713 0.081000
+v -2.374406 1.144713 -0.081000
+v -2.371700 1.151100 0.000000
+v -2.349581 2.084731 -0.216000
+v -2.349581 2.084731 0.216000
+v -2.326406 2.056090 -0.189000
+v -2.326406 2.056090 0.189000
+v -2.307322 2.032502 -0.144000
+v -2.307322 2.032502 0.144000
+v -2.302400 0.811200 0.000000
+v -2.302400 0.811200 0.000000
+v -2.301347 0.818122 0.081000
+v -2.301347 0.818122 -0.081000
+v -2.298490 0.836909 0.144000
+v -2.298490 0.836909 -0.144000
+v -2.294371 2.016497 -0.081000
+v -2.294371 2.016497 0.081000
+v -2.294278 0.864595 0.189000
+v -2.294278 0.864595 -0.189000
+v -2.289600 2.010600 0.000000
+v -2.289600 2.010600 0.000000
+v -2.289165 0.898214 0.216000
+v -2.289165 0.898214 -0.216000
+v -2.283600 0.934800 0.225000
+v -2.283600 0.934800 -0.225000
+v -2.278035 0.971386 0.216000
+v -2.278035 0.971386 -0.216000
+v -2.272922 1.005005 0.189000
+v -2.272922 1.005005 -0.189000
+v -2.268710 1.032691 -0.144000
+v -2.268710 1.032691 0.144000
+v -2.265853 1.051478 0.081000
+v -2.265853 1.051478 -0.081000
+v -2.265000 2.237850 0.000000
+v -2.264800 1.058400 0.000000
+v -2.264800 1.058400 0.000000
+v -2.261676 2.231720 -0.081000
+v -2.261676 2.231720 0.081000
+v -2.252655 2.215082 -0.144000
+v -2.252655 2.215082 0.144000
+v -2.239361 2.190562 -0.189000
+v -2.239361 2.190562 0.189000
+v -2.223218 2.160788 -0.216000
+v -2.223218 2.160788 0.216000
+v -2.205650 2.128387 0.225000
+v -2.205650 2.128388 -0.225000
+v -2.188082 2.095987 -0.216000
+v -2.188082 2.095987 0.216000
+v -2.171939 2.066213 -0.189000
+v -2.171939 2.066213 0.189000
+v -2.158645 2.041693 -0.144000
+v -2.158645 2.041693 0.144000
+v -2.149624 2.025055 -0.081000
+v -2.149624 2.025055 0.081000
+v -2.146300 2.018925 0.000000
+v -2.141100 0.973800 0.000000
+v -2.141100 0.973800 0.000000
+v -2.140315 0.966231 0.081000
+v -2.140315 0.966231 -0.081000
+v -2.138183 0.945685 0.144000
+v -2.138183 0.945685 -0.144000
+v -2.135041 0.915407 0.189000
+v -2.135041 0.915407 -0.189000
+v -2.131226 0.878641 0.216000
+v -2.131226 0.878641 -0.216000
+v -2.127075 0.838631 0.225000
+v -2.127075 0.838631 -0.225000
+v -2.122924 0.798621 0.216000
+v -2.122924 0.798621 -0.216000
+v -2.119109 0.761855 0.189000
+v -2.119109 0.761855 -0.189000
+v -2.115967 0.731578 0.144000
+v -2.115967 0.731578 -0.144000
+v -2.113835 0.711032 0.081000
+v -2.113835 0.711032 -0.081000
+v -2.113050 0.703463 0.000000
+v -2.113050 0.703463 0.000000
+v -2.040000 2.246400 0.000000
+v -2.040000 2.246400 0.000000
+v -2.038410 2.240150 -0.081000
+v -2.038410 2.240150 0.081000
+v -2.034093 2.223187 -0.144000
+v -2.034093 2.223187 0.144000
+v -2.027731 2.198189 -0.189000
+v -2.027731 2.198189 0.189000
+v -2.020006 2.167834 0.216000
+v -2.020006 2.167834 -0.216000
+v -2.011600 2.134800 0.225000
+v -2.011600 2.134800 -0.225000
+v -2.003194 2.101766 0.216000
+v -2.003194 2.101766 -0.216000
+v -2.000000 0.900000 0.000000
+v -2.000000 0.900000 0.000000
+v -2.000000 0.900000 0.000000
+v -1.997200 0.891600 0.081000
+v -1.997200 0.891600 -0.081000
+v -1.995469 2.071411 -0.189000
+v -1.995469 2.071411 0.189000
+v -1.992750 1.037175 -0.000000
+v -1.992750 1.037175 0.000000
+v -1.989600 0.868800 0.144000
+v -1.989600 0.868800 -0.144000
+v -1.989107 2.046413 0.144000
+v -1.989107 2.046413 -0.144000
+v -1.986000 0.771675 0.000000
+v -1.986000 0.771675 0.000000
+v -1.984790 2.029450 -0.081000
+v -1.984790 2.029450 0.081000
+v -1.983200 2.023200 0.000000
+v -1.983200 2.023200 0.000000
+v -1.978400 0.835200 0.189000
+v -1.978400 0.835200 -0.189000
+v -1.974240 0.900000 -0.328160
+v -1.974240 0.900000 -0.328160
+v -1.974240 0.900000 0.328160
+v -1.972000 1.178400 -0.000000
+v -1.972000 1.178400 0.000000
+v -1.967083 1.037175 -0.326970
+v -1.967083 1.037175 0.326970
+v -1.964800 0.794400 0.216000
+v -1.964800 0.794400 -0.216000
+v -1.960420 0.771675 -0.325863
+v -1.960420 0.771675 0.325863
+v -1.950000 0.750000 -0.225000
+v -1.950000 0.750000 0.225000
+v -1.948000 0.656400 0.000000
+v -1.948000 0.656400 0.000000
+v -1.946601 1.178400 -0.323566
+v -1.946601 1.178400 0.323566
+v -1.939250 1.323225 0.000000
+v -1.939250 1.323225 0.000000
+v -1.935200 0.705600 0.216000
+v -1.935200 0.705600 -0.216000
+v -1.922910 0.656400 -0.319628
+v -1.922910 0.656400 0.319628
+v -1.921600 0.664800 0.189000
+v -1.921600 0.664800 -0.189000
+v -1.914272 1.323225 -0.318192
+v -1.914272 1.323225 0.318192
+v -1.910400 0.631200 0.144000
+v -1.910400 0.631200 -0.144000
+v -1.902800 0.608400 0.081000
+v -1.902800 0.608400 -0.081000
+v -1.900000 0.600000 0.000000
+v -1.900000 0.600000 0.000000
+v -1.899520 0.900000 -0.638080
+v -1.899520 0.900000 -0.638080
+v -1.899520 0.900000 0.638080
+v -1.899520 0.900000 0.638080
+v -1.896000 1.471200 0.000000
+v -1.896000 1.471200 0.000000
+v -1.892634 1.037175 -0.635767
+v -1.892634 1.037175 0.635767
+v -1.892000 0.553725 0.000000
+v -1.892000 0.553725 0.000000
+v -1.886223 0.771675 -0.633613
+v -1.886223 0.771675 0.633613
+v -1.872927 1.178400 -0.629147
+v -1.872927 1.178400 0.629147
+v -1.871580 1.471200 -0.311096
+v -1.871580 1.471200 0.311096
+v -1.867631 0.553725 -0.310439
+v -1.867631 0.553725 0.310439
+v -1.850132 0.656400 -0.621490
+v -1.850132 0.656400 0.621490
+v -1.843750 1.621875 0.000000
+v -1.843750 1.621875 0.000000
+v -1.841822 1.323225 -0.618698
+v -1.841822 1.323225 0.618698
+v -1.824000 0.463200 -0.000000
+v -1.824000 0.463200 0.000000
+v -1.820003 1.621875 -0.302522
+v -1.820003 1.621875 0.302523
+v -1.800900 2.024775 0.000000
+v -1.800745 1.471200 -0.604900
+v -1.800745 1.471200 0.604900
+v -1.800507 0.463200 -0.299282
+v -1.800507 0.463200 0.299282
+v -1.800455 2.031069 -0.081000
+v -1.800455 2.031069 0.081000
+v -1.799246 2.048152 -0.144000
+v -1.799246 2.048152 0.144000
+v -1.797466 2.073326 -0.189000
+v -1.797466 2.073326 0.189000
+v -1.796946 0.553725 -0.603624
+v -1.796946 0.553725 0.603624
+v -1.795303 2.103896 -0.216000
+v -1.795303 2.103896 0.216000
+v -1.792950 2.137163 -0.225000
+v -1.792950 2.137163 0.225000
+v -1.790597 2.170429 -0.216000
+v -1.790597 2.170429 0.216000
+v -1.788434 2.200999 -0.189000
+v -1.788434 2.200999 0.189000
+v -1.786654 2.226173 -0.144000
+v -1.786654 2.226173 0.144000
+v -1.785445 2.243256 -0.081000
+v -1.785445 2.243256 0.081000
+v -1.785000 2.249550 0.000000
+v -1.784000 1.774800 -0.000000
+v -1.784000 1.774800 0.000000
+v -1.779680 0.900000 -0.925920
+v -1.779680 0.900000 -0.925920
+v -1.779680 0.900000 0.925920
+v -1.779680 0.900000 0.925920
+v -1.773229 1.037175 -0.922564
+v -1.773229 1.037175 0.922564
+v -1.767222 0.771675 -0.919439
+v -1.767222 0.771675 0.919439
+v -1.761022 1.774800 -0.292719
+v -1.761022 1.774800 0.292719
+v -1.754764 1.178400 -0.912957
+v -1.754764 1.178400 0.912957
+v -1.751120 1.621875 -0.588230
+v -1.751120 1.621875 0.588230
+v -1.750000 0.384375 -0.000000
+v -1.750000 0.384375 0.000000
+v -1.733408 0.656400 -0.901846
+v -1.733408 0.656400 0.901846
+v -1.732362 0.463200 -0.581929
+v -1.732362 0.463200 0.581929
+v -1.727460 0.384375 -0.287140
+v -1.727460 0.384375 0.287140
+v -1.725622 1.323225 -0.897795
+v -1.725622 1.323225 0.897795
+v -1.718250 1.929525 -0.000000
+v -1.718250 1.929525 0.000000
+v -1.696119 1.929525 -0.281930
+v -1.696119 1.929525 0.281930
+v -1.694372 1.774800 -0.569167
+v -1.694372 1.774800 0.569167
+v -1.687137 1.471200 -0.877772
+v -1.687137 1.471200 0.877772
+v -1.683577 0.553725 -0.875920
+v -1.683577 0.553725 0.875920
+v -1.676000 0.316800 0.000000
+v -1.676000 0.316800 0.000000
+v -1.662080 0.384375 -0.558320
+v -1.662080 0.384375 0.558320
+v -1.654413 0.316800 -0.274998
+v -1.654413 0.316800 0.274998
+v -1.648000 2.085600 0.000000
+v -1.648000 2.085600 0.000000
+v -1.640643 1.621875 -0.853583
+v -1.640643 1.621875 0.853583
+v -1.631925 1.929525 -0.548190
+v -1.631925 1.929525 0.548190
+v -1.626774 2.085600 -0.270404
+v -1.626774 2.085600 0.270404
+v -1.623068 0.463200 -0.844439
+v -1.623068 0.463200 0.844439
+v -1.618560 0.900000 -1.187840
+v -1.618560 0.900000 -1.187840
+v -1.618560 0.900000 1.187840
+v -1.618560 0.900000 1.187840
+v -1.612693 1.037175 -1.183534
+v -1.612693 1.037175 1.183534
+v -1.608000 0.260025 -0.000000
+v -1.608000 0.260025 0.000000
+v -1.607230 0.771675 -1.179525
+v -1.607230 0.771675 1.179525
+v -1.600000 2.025000 0.000000
+v -1.597200 2.031300 -0.081000
+v -1.597200 2.031300 0.081000
+v -1.595900 1.178400 -1.171210
+v -1.595900 1.178400 1.171210
+v -1.591798 0.316800 -0.534711
+v -1.591798 0.316800 0.534711
+v -1.589600 2.048400 -0.144000
+v -1.589600 2.048400 0.144000
+v -1.587475 1.774800 -0.825921
+v -1.587475 1.774800 0.825921
+v -1.587289 0.260025 0.263841
+v -1.587289 0.260025 -0.263841
+v -1.578400 2.073600 -0.189000
+v -1.578400 2.073600 0.189000
+v -1.576477 0.656400 -1.156956
+v -1.576477 0.656400 1.156956
+v -1.574750 2.242575 0.000000
+v -1.574750 2.242575 0.000000
+v -1.569396 1.323225 -1.151759
+v -1.569396 1.323225 1.151759
+v -1.565204 2.085600 -0.525778
+v -1.565204 2.085600 0.525778
+v -1.564800 2.104200 -0.216000
+v -1.564800 2.104200 0.216000
+v -1.557220 0.384375 -0.810180
+v -1.557220 0.384375 0.810180
+v -1.554467 2.242575 -0.258385
+v -1.554467 2.242575 0.258385
+v -1.552000 0.213600 0.000000
+v -1.552000 0.213600 0.000000
+v -1.550000 2.137500 -0.225000
+v -1.550000 2.137500 0.225000
+v -1.535200 2.170800 -0.216000
+v -1.535200 2.170800 0.216000
+v -1.534395 1.471200 -1.126072
+v -1.534395 1.471200 1.126072
+v -1.532010 0.213600 0.254652
+v -1.532010 0.213600 -0.254652
+v -1.531158 0.553725 -1.123697
+v -1.531158 0.553725 1.123697
+v -1.528968 1.929525 -0.795481
+v -1.528968 1.929525 0.795481
+v -1.527214 0.260025 -0.513016
+v -1.527214 0.260025 0.513016
+v -1.521600 2.201400 -0.189000
+v -1.521600 2.201400 0.189000
+v -1.514000 0.177075 0.000000
+v -1.514000 0.177075 0.000000
+v -1.510400 2.226600 -0.144000
+v -1.510400 2.226600 0.144000
+v -1.502800 2.243700 -0.081000
+v -1.502800 2.243700 0.081000
+v -1.500000 2.400000 0.000000
+v -1.500000 0.150000 0.000000
+v -1.500000 2.250000 0.000000
+v -1.500000 2.400000 0.000000
+v -1.500000 0.150000 0.000000
+v -1.496475 0.127575 -0.000000
+v -1.496475 0.127575 0.000000
+v -1.495635 2.242575 -0.502408
+v -1.495635 2.242575 0.502408
+v -1.494500 0.177075 0.248417
+v -1.494500 0.177075 -0.248417
+v -1.492110 1.621875 -1.095040
+v -1.492110 1.621875 1.095040
+v -1.491372 0.316800 -0.775921
+v -1.491372 0.316800 0.775921
+v -1.480800 0.105600 0.000000
+v -1.480800 0.105600 -0.000000
+v -1.480680 2.400000 -0.246120
+v -1.480680 0.150000 0.246120
+v -1.480680 2.400000 0.246120
+v -1.480680 0.150000 -0.246120
+v -1.480680 0.150000 -0.246120
+v -1.480680 0.150000 0.246120
+v -1.480325 2.435437 0.000000
+v -1.480325 2.435437 0.000000
+v -1.477200 0.127575 0.245542
+v -1.477200 0.127575 -0.245542
+v -1.476127 0.463200 -1.083310
+v -1.476127 0.463200 1.083310
+v -1.474028 0.213600 0.495150
+v -1.474028 0.213600 -0.495150
+v -1.466456 2.085600 -0.762958
+v -1.466456 2.085600 0.762958
+v -1.461727 0.105600 -0.242970
+v -1.461727 0.105600 0.242970
+v -1.461258 2.435437 -0.242892
+v -1.461258 2.435437 0.242892
+v -1.459600 2.463000 0.000000
+v -1.459600 2.463000 0.000000
+v -1.445325 0.084525 0.000000
+v -1.445325 0.084525 0.000000
+v -1.443756 1.774800 -1.059553
+v -1.443756 1.774800 1.059553
+v -1.440800 2.463000 -0.239491
+v -1.440800 2.463000 0.239491
+v -1.439025 2.482687 0.000000
+v -1.437937 0.177075 0.483027
+v -1.437937 0.177075 -0.483027
+v -1.430863 0.260025 0.744440
+v -1.430863 0.260025 -0.744440
+v -1.426709 0.084525 -0.237149
+v -1.426709 0.084525 0.237149
+v -1.424640 2.400000 -0.478560
+v -1.424640 0.150000 -0.478560
+v -1.424640 0.150000 -0.478560
+v -1.424640 0.150000 0.478560
+v -1.424640 0.150000 0.478560
+v -1.424640 2.400000 0.478560
+v -1.421292 0.127575 0.477435
+v -1.421292 0.127575 -0.477435
+v -1.420490 2.482687 -0.236115
+v -1.420490 2.482687 0.236115
+v -1.420000 0.900000 -1.420000
+v -1.420000 0.900000 -1.420000
+v -1.420000 0.900000 1.420000
+v -1.420000 0.900000 1.420000
+v -1.419800 2.494500 0.000000
+v -1.419800 2.494500 0.000000
+v -1.416240 0.384375 -1.039360
+v -1.416240 0.384375 1.039360
+v -1.414853 1.037175 -1.414853
+v -1.414853 1.037175 1.414853
+v -1.410060 0.771675 -1.410060
+v -1.410060 0.771675 1.410060
+v -1.406405 0.105600 -0.472434
+v -1.406405 0.105600 0.472434
+v -1.405953 2.435437 -0.472283
+v -1.405953 2.435437 0.472283
+v -1.403125 2.498438 0.000000
+v -1.403125 2.498438 0.000000
+v -1.401513 2.494500 -0.232961
+v -1.401513 2.494500 0.232961
+v -1.401276 2.242575 -0.729046
+v -1.401276 2.242575 0.729046
+v -1.400120 1.178400 -1.400120
+v -1.400120 1.178400 1.400120
+v -1.400000 2.400000 0.000000
+v -1.400000 2.400000 0.000000
+v -1.390545 1.929525 -1.020503
+v -1.390545 1.929525 1.020503
+v -1.390200 2.494500 0.000000
+v -1.390200 2.494500 0.000000
+v -1.386270 2.463000 -0.465671
+v -1.386270 2.463000 0.465671
+v -1.385925 2.435437 0.000000
+v -1.385925 2.435437 0.000000
+v -1.385053 2.498438 -0.230225
+v -1.385053 2.498438 0.230225
+v -1.383080 0.656400 -1.383080
+v -1.383080 0.656400 1.383080
+v -1.382400 0.064800 -0.000000
+v -1.382400 0.064800 0.000000
+v -1.382225 2.482687 -0.000000
+v -1.382225 2.482687 0.000000
+v -1.381968 2.400000 -0.229712
+v -1.381968 2.400000 0.229712
+v -1.381032 0.213600 0.718514
+v -1.381032 0.213600 -0.718514
+v -1.380400 2.463000 0.000000
+v -1.380400 2.463000 0.000000
+v -1.376868 1.323225 -1.376867
+v -1.376867 1.323225 1.376868
+v -1.372712 0.084525 -0.461116
+v -1.372712 0.084525 0.461116
+v -1.372294 2.494500 -0.228104
+v -1.372294 2.494500 0.228104
+v -1.368074 2.435437 -0.227403
+v -1.368074 2.435437 0.227403
+v -1.366728 2.482687 -0.459107
+v -1.366728 2.482687 0.459107
+v -1.364595 0.064800 -0.226824
+v -1.364595 0.064800 0.226824
+v -1.364422 2.482687 -0.226795
+v -1.364422 2.482687 0.226795
+v -1.362620 2.463000 -0.226496
+v -1.362620 2.463000 0.226496
+v -1.356353 0.316800 -0.995410
+v -1.356353 0.316800 0.995410
+v -1.348469 2.494500 -0.452973
+v -1.348469 2.494500 0.452973
+v -1.347218 0.177075 0.700921
+v -1.347218 0.177075 -0.700921
+v -1.346160 1.471200 -1.346160
+v -1.346160 1.471200 1.346160
+v -1.343320 0.553725 -1.343320
+v -1.343320 0.553725 1.343320
+v -1.334760 2.400000 -0.694440
+v -1.334760 0.150000 -0.694440
+v -1.334760 0.150000 0.694440
+v -1.334760 0.150000 0.694440
+v -1.334760 2.400000 0.694440
+v -1.334760 0.150000 -0.694440
+v -1.333693 2.085600 -0.978780
+v -1.333693 2.085600 0.978780
+v -1.332632 2.498438 -0.447653
+v -1.332632 2.498438 0.447653
+v -1.331623 0.127575 0.692808
+v -1.331623 0.127575 -0.692808
+v -1.329664 2.400000 -0.446656
+v -1.329664 2.400000 0.446656
+v -1.320356 2.494500 -0.443529
+v -1.320356 2.494500 0.443529
+v -1.317675 0.105600 -0.685551
+v -1.317675 0.105600 0.685551
+v -1.317252 2.435437 -0.685331
+v -1.317252 2.435437 0.685331
+v -1.316296 2.435437 -0.442166
+v -1.316296 2.435437 0.442166
+v -1.312948 0.064800 0.441041
+v -1.312948 0.064800 -0.441041
+v -1.312782 2.482687 -0.440985
+v -1.312782 2.482687 0.440985
+v -1.311049 2.463000 -0.440403
+v -1.311049 2.463000 0.440403
+v -1.309063 1.621875 -1.309063
+v -1.309063 1.621875 1.309063
+v -1.301322 0.260025 0.955023
+v -1.301322 0.260025 -0.955023
+v -1.300000 2.400000 0.000000
+v -1.300000 2.400000 0.000000
+v -1.298810 2.463000 -0.675736
+v -1.298810 2.463000 0.675736
+v -1.295040 0.463200 -1.295040
+v -1.295040 0.463200 1.295040
+v -1.286108 0.084525 -0.669128
+v -1.286108 0.084525 0.669128
+v -1.284375 0.046875 0.000000
+v -1.284375 0.046875 0.000000
+v -1.283256 2.400000 -0.213304
+v -1.283256 2.400000 0.213304
+v -1.280502 2.482687 -0.666211
+v -1.280502 2.482687 0.666211
+v -1.274600 2.440800 0.000000
+v -1.274600 2.440800 0.000000
+v -1.274414 2.242575 -0.935276
+v -1.274414 2.242575 0.935276
+v -1.267832 0.046875 -0.210740
+v -1.267832 0.046875 0.210740
+v -1.266640 1.774800 -1.266640
+v -1.266640 1.774800 1.266640
+v -1.263395 2.494500 -0.657311
+v -1.263395 2.494500 0.657311
+v -1.258183 2.440800 0.209136
+v -1.258183 2.440800 -0.209136
+v -1.256003 0.213600 0.921764
+v -1.256003 0.213600 -0.921764
+v -1.248557 2.498438 -0.649591
+v -1.248557 2.498438 0.649591
+v -1.245776 2.400000 -0.648144
+v -1.245776 2.400000 0.648144
+v -1.242500 0.384375 -1.242500
+v -1.242500 0.384375 1.242500
+v -1.237056 2.494500 -0.643607
+v -1.237056 2.494500 0.643607
+v -1.234688 2.400000 -0.414752
+v -1.234688 2.400000 0.414752
+v -1.233252 2.435437 -0.641628
+v -1.233252 2.435437 0.641628
+v -1.230115 0.064800 -0.639996
+v -1.230115 0.064800 0.639996
+v -1.229959 2.482687 -0.639915
+v -1.229959 2.482687 0.639915
+v -1.228335 2.463000 -0.639070
+v -1.228335 2.463000 0.639070
+v -1.225250 0.177075 0.899195
+v -1.225250 0.177075 -0.899195
+v -1.219958 1.929525 1.219958
+v -1.219958 1.929525 -1.219958
+v -1.219848 0.046875 -0.409767
+v -1.219848 0.046875 0.409767
+v -1.213920 2.400000 -0.890880
+v -1.213920 0.150000 -0.890880
+v -1.213920 0.150000 -0.890880
+v -1.213920 0.150000 0.890880
+v -1.213920 0.150000 0.890880
+v -1.213920 2.400000 0.890880
+v -1.211067 0.127575 0.888786
+v -1.211067 0.127575 -0.888786
+v -1.210564 2.440800 0.406648
+v -1.210564 2.440800 -0.406648
+v -1.204800 2.474400 0.000000
+v -1.204800 2.474400 0.000000
+v -1.198382 0.105600 -0.879477
+v -1.198382 0.105600 0.879477
+v -1.197997 2.435437 -0.879195
+v -1.197997 2.435437 0.879195
+v -1.189960 0.316800 -1.189960
+v -1.189960 0.316800 1.189960
+v -1.189282 2.474400 -0.197684
+v -1.189282 2.474400 0.197684
+v -1.187840 0.900000 -1.618560
+v -1.187840 0.900000 -1.618560
+v -1.187840 0.900000 1.618560
+v -1.187840 0.900000 1.618560
+v -1.183534 1.037175 -1.612693
+v -1.183534 1.037175 1.612693
+v -1.181225 2.463000 -0.866886
+v -1.181225 2.463000 0.866886
+v -1.179525 0.771675 -1.607230
+v -1.179525 0.771675 1.607230
+v -1.171210 1.178400 -1.595900
+v -1.171210 1.178400 1.595900
+v -1.170080 2.085600 -1.170080
+v -1.170080 2.085600 1.170080
+v -1.169673 0.084525 -0.858407
+v -1.169673 0.084525 0.858407
+v -1.164574 2.482687 -0.854666
+v -1.164574 2.482687 0.854666
+v -1.156956 0.656400 -1.576477
+v -1.156956 0.656400 1.576477
+v -1.156792 2.400000 -0.601848
+v -1.156792 2.400000 0.601848
+v -1.151759 1.323225 -1.569396
+v -1.151759 1.323225 1.569396
+v -1.149016 2.494500 -0.843248
+v -1.149016 2.494500 0.843248
+v -1.144271 2.474400 -0.384379
+v -1.144271 2.474400 0.384379
+v -1.143600 0.031200 0.000000
+v -1.143600 0.031200 0.000000
+v -1.142888 0.046875 -0.594614
+v -1.142888 0.046875 0.594614
+v -1.141680 0.260025 1.141680
+v -1.141680 0.260025 -1.141680
+v -1.135521 2.498438 -0.833344
+v -1.135521 2.498438 0.833344
+v -1.134190 2.440800 0.590089
+v -1.134190 2.440800 -0.590089
+v -1.132992 2.400000 -0.831488
+v -1.132992 2.400000 0.831488
+v -1.128870 0.031200 -0.187642
+v -1.128870 0.031200 0.187642
+v -1.126072 1.471200 -1.534395
+v -1.126072 1.471200 1.534395
+v -1.125061 2.494500 -0.825668
+v -1.125061 2.494500 0.825668
+v -1.123697 0.553725 -1.531158
+v -1.123697 0.553725 1.531158
+v -1.121601 2.435437 -0.823129
+v -1.121601 2.435437 0.823129
+v -1.118749 0.064800 -0.821035
+v -1.118749 0.064800 0.821035
+v -1.118607 2.482687 -0.820931
+v -1.118607 2.482687 0.820931
+v -1.118073 2.242575 -1.118073
+v -1.118073 2.242575 1.118073
+v -1.117130 2.463000 -0.819847
+v -1.117130 2.463000 0.819847
+v -1.101920 0.213600 1.101920
+v -1.101920 0.213600 -1.101920
+v -1.100200 2.502600 0.000000
+v -1.100200 2.502600 0.000000
+v -1.095040 1.621875 -1.492110
+v -1.095040 1.621875 1.492110
+v -1.086146 0.031200 0.364854
+v -1.086146 0.031200 -0.364854
+v -1.086029 2.502600 0.180521
+v -1.086029 2.502600 -0.180521
+v -1.083310 0.463200 -1.476127
+v -1.083310 0.463200 1.476127
+v -1.074940 0.177075 -1.074940
+v -1.074940 0.177075 1.074940
+v -1.072079 2.474400 -0.557774
+v -1.072079 2.474400 0.557774
+v -1.065000 2.400000 -1.065000
+v -1.065000 0.150000 -1.065000
+v -1.065000 0.150000 1.065000
+v -1.065000 2.400000 1.065000
+v -1.062497 0.127575 1.062497
+v -1.062497 0.127575 -1.062497
+v -1.059553 1.774800 -1.443756
+v -1.059553 1.774800 1.443756
+v -1.052064 2.400000 -0.772096
+v -1.052064 2.400000 0.772096
+v -1.051368 0.105600 -1.051368
+v -1.051368 0.105600 1.051368
+v -1.051031 2.435437 -1.051031
+v -1.051031 2.435437 1.051031
+v -1.044926 2.502600 -0.351008
+v -1.044926 2.502600 0.351008
+v -1.039419 0.046875 -0.762816
+v -1.039419 0.046875 0.762816
+v -1.039360 0.384375 -1.416240
+v -1.039360 0.384375 1.416240
+v -1.036316 2.463000 -1.036316
+v -1.036316 2.463000 1.036316
+v -1.031508 2.440800 0.757010
+v -1.031508 2.440800 -0.757010
+v -1.026181 0.084525 -1.026181
+v -1.026181 0.084525 1.026181
+v -1.021708 2.482687 -1.021708
+v -1.021708 2.482687 1.021708
+v -1.020503 1.929525 -1.390545
+v -1.020503 1.929525 1.390545
+v -1.017621 0.031200 0.529441
+v -1.017621 0.031200 -0.529441
+v -1.008058 2.494500 -1.008058
+v -1.008058 2.494500 1.008058
+v -0.996219 2.498438 -0.996219
+v -0.996219 2.498438 0.996219
+v -0.995410 0.316800 -1.356353
+v -0.995410 0.316800 1.356353
+v -0.994000 2.400000 -0.994000
+v -0.994000 2.400000 0.994000
+v -0.987042 2.494500 -0.987042
+v -0.987042 2.494500 0.987042
+v -0.984007 2.435437 -0.984007
+v -0.984007 2.435437 0.984007
+v -0.981504 0.064800 0.981504
+v -0.981504 0.064800 -0.981504
+v -0.981380 2.482687 -0.981380
+v -0.981380 2.482687 0.981380
+v -0.980084 2.463000 -0.980084
+v -0.980084 2.463000 0.980084
+v -0.979002 2.502600 0.509349
+v -0.979002 2.502600 -0.509349
+v -0.978780 2.085600 -1.333693
+v -0.978780 2.085600 1.333693
+v -0.975021 2.474400 -0.715555
+v -0.975021 2.474400 0.715555
+v -0.970400 2.527200 0.000000
+v -0.970400 2.527200 0.000000
+v -0.957901 2.527200 -0.159223
+v -0.957901 2.527200 0.159223
+v -0.955023 0.260025 1.301322
+v -0.955023 0.260025 -1.301322
+v -0.952425 0.018225 -0.000000
+v -0.952425 0.018225 0.000000
+v -0.940158 0.018225 0.156274
+v -0.940158 0.018225 -0.156274
+v -0.935276 2.242575 -1.274414
+v -0.935276 2.242575 1.274414
+v -0.925920 0.900000 -1.779680
+v -0.925920 0.900000 1.779680
+v -0.925920 0.900000 1.779680
+v -0.925920 0.900000 -1.779680
+v -0.925493 0.031200 0.679207
+v -0.925493 0.031200 -0.679207
+v -0.923000 2.400000 -0.923000
+v -0.923000 2.400000 0.923000
+v -0.922564 1.037175 1.773229
+v -0.922564 1.037175 -1.773229
+v -0.921764 0.213600 1.256003
+v -0.921764 0.213600 -1.256003
+v -0.921647 2.527200 -0.309596
+v -0.921647 2.527200 0.309596
+v -0.919439 0.771675 -1.767222
+v -0.919439 0.771675 1.767222
+v -0.912957 1.178400 -1.754764
+v -0.912957 1.178400 1.754764
+v -0.911906 0.046875 -0.911906
+v -0.911906 0.046875 0.911906
+v -0.904966 2.440800 0.904966
+v -0.904966 2.440800 -0.904966
+v -0.904575 0.018225 0.303862
+v -0.904575 0.018225 -0.303862
+v -0.901846 0.656400 -1.733408
+v -0.901846 0.656400 1.733408
+v -0.899195 0.177075 1.225250
+v -0.899195 0.177075 -1.225250
+v -0.897795 1.323225 -1.725622
+v -0.897795 1.323225 1.725622
+v -0.890880 0.150000 -1.213920
+v -0.890880 0.150000 1.213920
+v -0.890880 2.400000 -1.213920
+v -0.890880 0.150000 -1.213920
+v -0.890880 0.150000 1.213920
+v -0.890880 2.400000 1.213920
+v -0.890370 2.502600 -0.653431
+v -0.890370 2.502600 0.653431
+v -0.888786 0.127575 1.211067
+v -0.888786 0.127575 -1.211067
+v -0.879477 0.105600 -1.198382
+v -0.879477 0.105600 1.198382
+v -0.879195 2.435437 -1.197997
+v -0.879195 2.435437 1.197997
+v -0.877772 1.471200 -1.687137
+v -0.877772 1.471200 1.687137
+v -0.875920 0.553725 -1.683577
+v -0.875920 0.553725 1.683577
+v -0.866886 2.463000 -1.181225
+v -0.866886 2.463000 1.181225
+v -0.863501 2.527200 -0.449256
+v -0.863501 2.527200 0.449256
+v -0.858407 0.084525 -1.169673
+v -0.858407 0.084525 1.169673
+v -0.855408 2.474400 -0.855408
+v -0.855408 2.474400 0.855408
+v -0.854666 2.482687 -1.164574
+v -0.854666 2.482687 1.164574
+v -0.853583 1.621875 -1.640643
+v -0.853583 1.621875 1.640643
+v -0.847506 0.018225 -0.440935
+v -0.847506 0.018225 0.440935
+v -0.844439 0.463200 1.623068
+v -0.844439 0.463200 -1.623068
+v -0.843248 2.494500 -1.149016
+v -0.843248 2.494500 1.149016
+v -0.833344 2.498438 -1.135521
+v -0.833344 2.498438 1.135521
+v -0.831488 2.400000 -1.132992
+v -0.831488 2.400000 1.132992
+v -0.825921 1.774800 1.587475
+v -0.825921 1.774800 -1.587475
+v -0.825668 2.494500 -1.125061
+v -0.825668 2.494500 1.125061
+v -0.825000 2.550000 0.000000
+v -0.825000 2.550000 0.000000
+v -0.823129 2.435437 -1.121601
+v -0.823129 2.435437 1.121601
+v -0.821035 0.064800 1.118749
+v -0.821035 0.064800 -1.118749
+v -0.820931 2.482687 1.118607
+v -0.820931 2.482687 -1.118607
+v -0.819847 2.463000 -1.117130
+v -0.819847 2.463000 1.117130
+v -0.814374 2.550000 -0.135366
+v -0.814374 2.550000 0.135366
+v -0.811956 0.031200 0.811956
+v -0.811956 0.031200 -0.811956
+v -0.810180 0.384375 1.557220
+v -0.810180 0.384375 -1.557220
+v -0.795481 1.929525 1.528968
+v -0.795481 1.929525 -1.528968
+v -0.785325 2.527200 -0.576340
+v -0.785325 2.527200 0.576340
+v -0.783552 2.550000 -0.263208
+v -0.783552 2.550000 0.263208
+v -0.781142 2.502600 -0.781142
+v -0.781142 2.502600 0.781142
+v -0.775921 0.316800 -1.491372
+v -0.775921 0.316800 1.491372
+v -0.772096 2.400000 -1.052064
+v -0.772096 2.400000 1.052064
+v -0.770779 0.018225 0.565664
+v -0.770779 0.018225 -0.565664
+v -0.762958 2.085600 -1.466456
+v -0.762958 2.085600 1.466456
+v -0.762816 0.046875 -1.039419
+v -0.762816 0.046875 1.039419
+v -0.757010 2.440800 1.031508
+v -0.757010 2.440800 -1.031508
+v -0.744440 0.260025 1.430863
+v -0.744440 0.260025 -1.430863
+v -0.734118 2.550000 -0.381942
+v -0.734118 2.550000 0.381942
+v -0.729046 2.242575 -1.401276
+v -0.729046 2.242575 1.401276
+v -0.718514 0.213600 1.381032
+v -0.718514 0.213600 -1.381032
+v -0.715555 2.474400 -0.975021
+v -0.715555 2.474400 0.975021
+v -0.703200 0.008400 0.000000
+v -0.700921 0.177075 1.347218
+v -0.700921 0.177075 -1.347218
+v -0.694440 0.150000 -1.334760
+v -0.694440 0.150000 1.334760
+v -0.694440 2.400000 1.334760
+v -0.694440 0.150000 1.334760
+v -0.694440 2.400000 -1.334760
+v -0.694440 0.150000 -1.334760
+v -0.694143 0.008400 -0.115381
+v -0.694143 0.008400 0.115381
+v -0.692808 0.127575 1.331623
+v -0.692808 0.127575 -1.331623
+v -0.688984 2.527200 -0.688984
+v -0.688984 2.527200 0.688984
+v -0.685551 0.105600 -1.317675
+v -0.685551 0.105600 1.317675
+v -0.685331 2.435437 -1.317252
+v -0.685331 2.435437 1.317252
+v -0.679207 0.031200 -0.925493
+v -0.679207 0.031200 0.925493
+v -0.676222 0.018225 0.676222
+v -0.676222 0.018225 -0.676222
+v -0.675736 2.463000 -1.298810
+v -0.675736 2.463000 1.298810
+v -0.673600 2.572800 0.000000
+v -0.673600 2.572800 0.000000
+v -0.669128 0.084525 -1.286108
+v -0.669128 0.084525 1.286108
+v -0.667871 0.008400 -0.224349
+v -0.667871 0.008400 0.224349
+v -0.667656 2.550000 -0.489984
+v -0.667656 2.550000 0.489984
+v -0.666211 2.482687 1.280502
+v -0.666211 2.482687 -1.280502
+v -0.664924 2.572800 -0.110524
+v -0.664924 2.572800 0.110524
+v -0.657311 2.494500 -1.263395
+v -0.657311 2.494500 1.263395
+v -0.653431 2.502600 -0.890370
+v -0.653431 2.502600 0.890370
+v -0.649591 2.498438 -1.248557
+v -0.649591 2.498438 1.248557
+v -0.648144 2.400000 -1.245776
+v -0.648144 2.400000 1.245776
+v -0.643607 2.494500 -1.237056
+v -0.643607 2.494500 1.237056
+v -0.641628 2.435437 -1.233252
+v -0.641628 2.435437 1.233252
+v -0.639996 0.064800 -1.230115
+v -0.639996 0.064800 1.230115
+v -0.639915 2.482687 1.229959
+v -0.639915 2.482687 -1.229959
+v -0.639758 2.572800 -0.214905
+v -0.639758 2.572800 0.214905
+v -0.639070 2.463000 -1.228335
+v -0.639070 2.463000 1.228335
+v -0.638080 0.900000 -1.899520
+v -0.638080 0.900000 -1.899520
+v -0.638080 0.900000 1.899520
+v -0.638080 0.900000 1.899520
+v -0.635767 1.037175 -1.892634
+v -0.635767 1.037175 1.892634
+v -0.633613 0.771675 -1.886223
+v -0.633613 0.771675 1.886223
+v -0.629147 1.178400 -1.872927
+v -0.629147 1.178400 1.872927
+v -0.625735 0.008400 0.325553
+v -0.625735 0.008400 -0.325553
+v -0.621490 0.656400 -1.850132
+v -0.621490 0.656400 1.850132
+v -0.618698 1.323225 -1.841822
+v -0.618698 1.323225 1.841822
+v -0.604900 1.471200 -1.800745
+v -0.604900 1.471200 1.800745
+v -0.603624 0.553725 -1.796946
+v -0.603624 0.553725 1.796946
+v -0.601848 2.400000 -1.156792
+v -0.601848 2.400000 1.156792
+v -0.599396 2.572800 -0.311850
+v -0.599396 2.572800 0.311850
+v -0.594614 0.046875 -1.142888
+v -0.594614 0.046875 1.142888
+v -0.590089 2.440800 1.134190
+v -0.590089 2.440800 -1.134190
+v -0.588230 1.621875 -1.751120
+v -0.588230 1.621875 1.751120
+v -0.585750 2.550000 -0.585750
+v -0.585750 2.550000 0.585750
+v -0.581929 0.463200 -1.732362
+v -0.581929 0.463200 1.732362
+v -0.576340 2.527200 -0.785325
+v -0.576340 2.527200 0.785325
+v -0.569167 1.774800 -1.694372
+v -0.569167 1.774800 1.694372
+v -0.569086 0.008400 -0.417645
+v -0.569086 0.008400 0.417645
+v -0.565664 0.018225 0.770779
+v -0.565664 0.018225 -0.770779
+v -0.558320 0.384375 -1.662080
+v -0.558320 0.384375 1.662080
+v -0.557774 2.474400 -1.072079
+v -0.557774 2.474400 1.072079
+v -0.548190 1.929525 -1.631925
+v -0.548190 1.929525 1.631925
+v -0.545131 2.572800 -0.400065
+v -0.545131 2.572800 0.400065
+v -0.534711 0.316800 -1.591798
+v -0.534711 0.316800 1.591798
+v -0.529441 0.031200 -1.017621
+v -0.529441 0.031200 1.017621
+v -0.525800 2.597400 0.000000
+v -0.525800 2.597400 0.000000
+v -0.525778 2.085600 -1.565204
+v -0.525778 2.085600 1.565204
+v -0.519028 2.597400 0.086273
+v -0.519028 2.597400 -0.086273
+v -0.513016 0.260025 -1.527214
+v -0.513016 0.260025 1.527214
+v -0.509349 2.502600 0.979002
+v -0.509349 2.502600 -0.979002
+v -0.502408 2.242575 -1.495635
+v -0.502408 2.242575 1.495635
+v -0.499384 2.597400 -0.167751
+v -0.499384 2.597400 0.167751
+v -0.499272 0.008400 -0.499272
+v -0.499272 0.008400 0.499272
+v -0.495150 0.213600 -1.474028
+v -0.495150 0.213600 1.474028
+v -0.489984 2.550000 -0.667656
+v -0.489984 2.550000 0.667656
+v -0.483027 0.177075 -1.437937
+v -0.483027 0.177075 1.437937
+v -0.478560 0.150000 1.424640
+v -0.478560 2.400000 -1.424640
+v -0.478560 0.150000 -1.424640
+v -0.478560 0.150000 -1.424640
+v -0.478560 0.150000 1.424640
+v -0.478560 2.400000 1.424640
+v -0.478256 2.572800 -0.478256
+v -0.478256 2.572800 0.478256
+v -0.477435 0.127575 1.421292
+v -0.477435 0.127575 -1.421292
+v -0.472434 0.105600 1.406405
+v -0.472434 0.105600 -1.406405
+v -0.472283 2.435437 -1.405953
+v -0.472283 2.435437 1.405953
+v -0.467878 2.597400 -0.243424
+v -0.467878 2.597400 0.243424
+v -0.465671 2.463000 -1.386270
+v -0.465671 2.463000 1.386270
+v -0.461116 0.084525 1.372712
+v -0.461116 0.084525 -1.372712
+v -0.459107 2.482687 -1.366728
+v -0.459107 2.482687 1.366728
+v -0.452973 2.494500 -1.348469
+v -0.452973 2.494500 1.348469
+v -0.449256 2.527200 -0.863501
+v -0.449256 2.527200 0.863501
+v -0.447653 2.498438 -1.332632
+v -0.447653 2.498438 1.332632
+v -0.446656 2.400000 -1.329664
+v -0.446656 2.400000 1.329664
+v -0.443529 2.494500 -1.320356
+v -0.443529 2.494500 1.320356
+v -0.442166 2.435437 -1.316296
+v -0.442166 2.435437 1.316296
+v -0.441041 0.064800 1.312948
+v -0.441041 0.064800 -1.312948
+v -0.440985 2.482687 -1.312782
+v -0.440985 2.482687 1.312782
+v -0.440935 0.018225 0.847506
+v -0.440935 0.018225 -0.847506
+v -0.440403 2.463000 -1.311049
+v -0.440403 2.463000 1.311049
+v -0.425519 2.597400 0.312283
+v -0.425519 2.597400 -0.312283
+v -0.417645 0.008400 -0.569086
+v -0.417645 0.008400 0.569086
+v -0.414752 2.400000 -1.234688
+v -0.414752 2.400000 1.234688
+v -0.409767 0.046875 1.219848
+v -0.409767 0.046875 -1.219848
+v -0.406648 2.440800 -1.210564
+v -0.406648 2.440800 1.210564
+v -0.400065 2.572800 -0.545131
+v -0.400065 2.572800 0.545131
+v -0.391200 2.625600 0.000000
+v -0.391200 2.625600 0.000000
+v -0.388275 0.002175 -0.000000
+v -0.388275 0.002175 0.000000
+v -0.386161 2.625600 -0.064188
+v -0.386161 2.625600 0.064188
+v -0.384379 2.474400 -1.144271
+v -0.384379 2.474400 1.144271
+v -0.383274 0.002175 -0.063708
+v -0.383274 0.002175 0.063708
+v -0.381942 2.550000 -0.734118
+v -0.381942 2.550000 0.734118
+v -0.373318 2.597400 -0.373318
+v -0.373318 2.597400 0.373318
+v -0.371546 2.625600 -0.124808
+v -0.371546 2.625600 0.124808
+v -0.368768 0.002175 -0.123875
+v -0.368768 0.002175 0.123875
+v -0.364854 0.031200 1.086146
+v -0.364854 0.031200 -1.086146
+v -0.358400 3.034800 0.000000
+v -0.358400 3.034800 0.000000
+v -0.358200 3.081150 0.000000
+v -0.358200 3.081150 0.000000
+v -0.353807 3.034800 -0.059016
+v -0.353807 3.034800 0.059016
+v -0.353610 3.081150 -0.058988
+v -0.353610 3.081150 0.058988
+v -0.351008 2.502600 -1.044926
+v -0.351008 2.502600 1.044926
+v -0.348105 2.625600 -0.181110
+v -0.348105 2.625600 0.181110
+v -0.345503 0.002175 -0.179756
+v -0.345503 0.002175 0.179756
+v -0.340477 3.034800 -0.114676
+v -0.340477 3.034800 0.114676
+v -0.340289 3.081150 -0.114619
+v -0.340289 3.081150 0.114619
+v -0.328160 0.900000 -1.974240
+v -0.328160 0.900000 1.974240
+v -0.328160 0.900000 1.974240
+v -0.326970 1.037175 -1.967083
+v -0.326970 1.037175 1.967083
+v -0.325863 0.771675 -1.960420
+v -0.325863 0.771675 1.960420
+v -0.325553 0.008400 -0.625735
+v -0.325553 0.008400 0.625735
+v -0.325000 2.981250 0.000000
+v -0.325000 2.981250 0.000000
+v -0.323566 1.178400 -1.946601
+v -0.323566 1.178400 1.946601
+v -0.320834 2.981250 -0.053508
+v -0.320834 2.981250 0.053508
+v -0.319628 0.656400 -1.922910
+v -0.319628 0.656400 1.922910
+v -0.319082 3.034800 -0.166306
+v -0.319082 3.034800 0.166306
+v -0.318907 3.081150 -0.166221
+v -0.318907 3.081150 0.166221
+v -0.318192 1.323225 -1.914272
+v -0.318192 1.323225 1.914272
+v -0.316590 2.625600 -0.232342
+v -0.316590 2.625600 0.232342
+v -0.314223 0.002175 -0.230604
+v -0.314223 0.002175 0.230604
+v -0.312283 2.597400 -0.425519
+v -0.312283 2.597400 0.425519
+v -0.311850 2.572800 -0.599396
+v -0.311850 2.572800 0.599396
+v -0.311096 1.471200 -1.871580
+v -0.311096 1.471200 1.871580
+v -0.310439 0.553725 -1.867631
+v -0.310439 0.553725 1.867631
+v -0.309596 2.527200 -0.921647
+v -0.309596 2.527200 0.921647
+v -0.308800 3.117600 0.000000
+v -0.308800 3.117600 0.000000
+v -0.308744 2.981250 -0.103976
+v -0.308744 2.981250 0.103976
+v -0.304843 3.117600 -0.050855
+v -0.304843 3.117600 0.050855
+v -0.303862 0.018225 0.904575
+v -0.303862 0.018225 -0.904575
+v -0.302523 1.621875 -1.820003
+v -0.302522 1.621875 1.820003
+v -0.299282 0.463200 -1.800507
+v -0.299282 0.463200 1.800507
+v -0.293360 3.117600 -0.098814
+v -0.293360 3.117600 0.098814
+v -0.292719 1.774800 -1.761022
+v -0.292719 1.774800 1.761022
+v -0.290295 3.034800 -0.213234
+v -0.290295 3.034800 0.213234
+v -0.290138 3.081150 -0.213123
+v -0.290138 3.081150 0.213123
+v -0.289340 2.981250 -0.150793
+v -0.289340 2.981250 0.150793
+v -0.287140 0.384375 -1.727460
+v -0.287140 0.384375 1.727460
+v -0.281930 1.929525 1.696119
+v -0.281930 1.929525 -1.696119
+v -0.279400 2.659200 0.000000
+v -0.277752 2.625600 -0.277752
+v -0.277752 2.625600 0.277752
+v -0.275801 2.659200 -0.045844
+v -0.275801 2.659200 0.045844
+v -0.275675 0.002175 -0.275675
+v -0.275675 0.002175 0.275675
+v -0.274998 0.316800 -1.654413
+v -0.274998 0.316800 1.654413
+v -0.274928 3.117600 -0.143301
+v -0.274928 3.117600 0.143301
+v -0.273600 2.923200 0.000000
+v -0.273600 2.923200 0.000000
+v -0.270404 2.085600 -1.626774
+v -0.270404 2.085600 1.626774
+v -0.270092 2.923200 -0.045032
+v -0.270092 2.923200 0.045032
+v -0.265363 2.659200 -0.089140
+v -0.265363 2.659200 0.089140
+v -0.263841 0.260025 1.587289
+v -0.263841 0.260025 -1.587289
+v -0.263232 2.981250 -0.193348
+v -0.263232 2.981250 0.193348
+v -0.263208 2.550000 -0.783552
+v -0.263208 2.550000 0.783552
+v -0.259910 2.923200 -0.087511
+v -0.259910 2.923200 0.087511
+v -0.258385 2.242575 -1.554467
+v -0.258385 2.242575 1.554467
+v -0.254788 3.034800 -0.254788
+v -0.254788 3.034800 0.254788
+v -0.254653 3.081150 -0.254653
+v -0.254653 3.081150 0.254653
+v -0.254652 0.213600 -1.532010
+v -0.254652 0.213600 1.532010
+v -0.250127 3.117600 -0.183734
+v -0.250127 3.117600 0.183734
+v -0.248621 2.659200 0.129351
+v -0.248621 2.659200 -0.129351
+v -0.248417 0.177075 -1.494500
+v -0.248417 0.177075 1.494500
+v -0.246120 0.150000 1.480680
+v -0.246120 2.400000 -1.480680
+v -0.246120 0.150000 -1.480680
+v -0.246120 0.150000 -1.480680
+v -0.246120 0.150000 1.480680
+v -0.246120 2.400000 1.480680
+v -0.245542 0.127575 1.477200
+v -0.245542 0.127575 -1.477200
+v -0.243569 2.923200 -0.126920
+v -0.243569 2.923200 0.126920
+v -0.243424 2.597400 0.467878
+v -0.243424 2.597400 -0.467878
+v -0.242970 0.105600 1.461727
+v -0.242970 0.105600 -1.461727
+v -0.242892 2.435437 -1.461258
+v -0.242892 2.435437 1.461258
+v -0.239491 2.463000 -1.440800
+v -0.239491 2.463000 1.440800
+v -0.237149 0.084525 1.426709
+v -0.237149 0.084525 -1.426709
+v -0.236115 2.482687 -1.420490
+v -0.236115 2.482687 1.420490
+v -0.232961 2.494500 -1.401513
+v -0.232961 2.494500 1.401513
+v -0.232342 2.625600 -0.316590
+v -0.232342 2.625600 0.316590
+v -0.231031 2.981250 -0.231031
+v -0.231031 2.981250 0.231031
+v -0.230604 0.002175 -0.314223
+v -0.230604 0.002175 0.314223
+v -0.230225 2.498438 -1.385053
+v -0.230225 2.498438 1.385053
+v -0.229712 2.400000 -1.381968
+v -0.229712 2.400000 1.381968
+v -0.228104 2.494500 -1.372294
+v -0.228104 2.494500 1.372294
+v -0.227403 2.435437 -1.368074
+v -0.227403 2.435437 1.368074
+v -0.226824 0.064800 1.364595
+v -0.226824 0.064800 -1.364595
+v -0.226795 2.482687 1.364422
+v -0.226795 2.482687 -1.364422
+v -0.226496 2.463000 -1.362620
+v -0.226496 2.463000 1.362620
+v -0.226113 2.659200 -0.165941
+v -0.226113 2.659200 0.165941
+v -0.224349 0.008400 0.667871
+v -0.224349 0.008400 -0.667871
+v -0.221585 2.923200 -0.162745
+v -0.221585 2.923200 0.162745
+v -0.219800 2.863350 0.000000
+v -0.219800 2.863350 0.000000
+v -0.219536 3.117600 -0.219536
+v -0.219536 3.117600 0.219536
+v -0.216979 2.863350 0.036157
+v -0.216979 2.863350 -0.036157
+v -0.214905 2.572800 -0.639758
+v -0.214905 2.572800 0.639758
+v -0.213304 2.400000 -1.283256
+v -0.213304 2.400000 1.283256
+v -0.213234 3.034800 -0.290295
+v -0.213234 3.034800 0.290295
+v -0.213123 3.081150 -0.290138
+v -0.213123 3.081150 0.290138
+v -0.210740 0.046875 -1.267832
+v -0.210740 0.046875 1.267832
+v -0.209136 2.440800 -1.258183
+v -0.209136 2.440800 1.258183
+v -0.208794 2.863350 0.070270
+v -0.208794 2.863350 -0.070270
+v -0.200000 2.700000 0.000000
+v -0.200000 2.700000 0.000000
+v -0.200000 2.700000 0.000000
+v -0.200000 2.700000 0.000000
+v -0.198374 2.659200 -0.198374
+v -0.198374 2.659200 0.198374
+v -0.197684 2.474400 -1.189282
+v -0.197684 2.474400 1.189282
+v -0.197424 2.700000 -0.032816
+v -0.197424 2.700000 0.032816
+v -0.197424 2.700000 0.032816
+v -0.197424 2.700000 -0.032816
+v -0.195658 2.863350 -0.101925
+v -0.195658 2.863350 0.101925
+v -0.194600 3.141450 0.000000
+v -0.194600 3.141450 0.000000
+v -0.194472 2.923200 -0.194472
+v -0.194472 2.923200 0.194472
+v -0.193348 2.981250 -0.263232
+v -0.193348 2.981250 0.263232
+v -0.192107 3.141450 -0.032048
+v -0.192107 3.141450 0.032048
+v -0.189952 2.700000 -0.063808
+v -0.189952 2.700000 0.063808
+v -0.189952 2.700000 0.063808
+v -0.189952 2.700000 -0.063808
+v -0.187642 0.031200 1.128870
+v -0.187642 0.031200 -1.128870
+v -0.184870 3.141450 -0.062272
+v -0.184870 3.141450 0.062272
+v -0.183734 3.117600 -0.250127
+v -0.183734 3.117600 0.250127
+v -0.181110 2.625600 0.348105
+v -0.181110 2.625600 -0.348105
+v -0.180521 2.502600 -1.086029
+v -0.180521 2.502600 1.086029
+v -0.179756 0.002175 -0.345503
+v -0.179756 0.002175 0.345503
+v -0.179200 2.804400 0.000000
+v -0.179200 2.804400 0.000000
+v -0.177989 2.863350 -0.130707
+v -0.177989 2.863350 0.130707
+v -0.177968 2.700000 -0.092592
+v -0.177968 2.700000 0.092592
+v -0.177968 2.700000 0.092592
+v -0.177968 2.700000 -0.092592
+v -0.176897 2.804400 0.029450
+v -0.176897 2.804400 -0.029450
+v -0.173255 3.141450 -0.090306
+v -0.173255 3.141450 0.090306
+v -0.170215 2.804400 0.057246
+v -0.170215 2.804400 -0.057246
+v -0.167751 2.597400 -0.499384
+v -0.167751 2.597400 0.499384
+v -0.167400 2.749050 0.000000
+v -0.167400 2.749050 0.000000
+v -0.166306 3.034800 -0.319082
+v -0.166306 3.034800 0.319082
+v -0.166221 3.081150 0.318907
+v -0.166221 3.081150 -0.318907
+v -0.165941 2.659200 -0.226113
+v -0.165941 2.659200 0.226113
+v -0.165245 2.749050 0.027480
+v -0.165245 2.749050 -0.027480
+v -0.162745 2.923200 -0.221585
+v -0.162745 2.923200 0.221585
+v -0.161856 2.700000 -0.118784
+v -0.161856 2.700000 0.118784
+v -0.161856 2.700000 0.118784
+v -0.161856 2.700000 -0.118784
+v -0.159496 2.804400 0.083047
+v -0.159496 2.804400 -0.083047
+v -0.159223 2.527200 -0.957901
+v -0.159223 2.527200 0.957901
+v -0.158995 2.749050 0.053428
+v -0.158995 2.749050 -0.053428
+v -0.157626 3.141450 -0.115787
+v -0.157626 3.141450 0.115787
+v -0.156274 0.018225 0.940158
+v -0.156274 0.018225 -0.940158
+v -0.156200 2.863350 -0.156200
+v -0.156200 2.863350 0.156200
+v -0.150793 2.981250 -0.289340
+v -0.150793 2.981250 0.289340
+v -0.148969 2.749050 0.077523
+v -0.148969 2.749050 -0.077523
+v -0.145078 2.804400 0.106513
+v -0.145078 2.804400 -0.106513
+v -0.143301 3.117600 -0.274928
+v -0.143301 3.117600 0.274928
+v -0.142000 2.700000 -0.142000
+v -0.142000 2.700000 0.142000
+v -0.142000 2.700000 0.142000
+v -0.142000 2.700000 -0.142000
+v -0.138348 3.141450 -0.138348
+v -0.138348 3.141450 0.138348
+v -0.135489 2.749050 0.099446
+v -0.135489 2.749050 -0.099446
+v -0.135366 2.550000 -0.814374
+v -0.135366 2.550000 0.814374
+v -0.130707 2.863350 -0.177989
+v -0.130707 2.863350 0.177989
+v -0.129351 2.659200 0.248621
+v -0.129351 2.659200 -0.248621
+v -0.127304 2.804400 0.127304
+v -0.127304 2.804400 -0.127304
+v -0.126920 2.923200 -0.243569
+v -0.126920 2.923200 0.243569
+v -0.124808 2.625600 -0.371546
+v -0.124808 2.625600 0.371546
+v -0.123875 0.002175 0.368768
+v -0.123875 0.002175 -0.368768
+v -0.118874 2.749050 0.118874
+v -0.118874 2.749050 -0.118874
+v -0.118784 2.700000 -0.161856
+v -0.118784 2.700000 0.161856
+v -0.118784 2.700000 0.161856
+v -0.118784 2.700000 -0.161856
+v -0.115787 3.141450 -0.157626
+v -0.115787 3.141450 0.157626
+v -0.115381 0.008400 0.694143
+v -0.115381 0.008400 -0.694143
+v -0.114676 3.034800 -0.340477
+v -0.114676 3.034800 0.340477
+v -0.114619 3.081150 -0.340289
+v -0.114619 3.081150 0.340289
+v -0.110524 2.572800 -0.664924
+v -0.110524 2.572800 0.664924
+v -0.106513 2.804400 -0.145078
+v -0.106513 2.804400 0.145078
+v -0.103976 2.981250 -0.308744
+v -0.103976 2.981250 0.308744
+v -0.101925 2.863350 -0.195658
+v -0.101925 2.863350 0.195658
+v -0.099446 2.749050 0.135489
+v -0.099446 2.749050 -0.135489
+v -0.098814 3.117600 -0.293360
+v -0.098814 3.117600 0.293360
+v -0.092592 2.700000 -0.177968
+v -0.092592 2.700000 0.177968
+v -0.092592 2.700000 -0.177968
+v -0.092592 2.700000 0.177968
+v -0.090306 3.141450 -0.173255
+v -0.090306 3.141450 0.173255
+v -0.089140 2.659200 -0.265363
+v -0.089140 2.659200 0.265363
+v -0.087511 2.923200 -0.259910
+v -0.087511 2.923200 0.259910
+v -0.086273 2.597400 -0.519028
+v -0.086273 2.597400 0.519028
+v -0.083047 2.804400 -0.159496
+v -0.083047 2.804400 0.159496
+v -0.077523 2.749050 -0.148969
+v -0.077523 2.749050 0.148969
+v -0.070270 2.863350 -0.208794
+v -0.070270 2.863350 0.208794
+v -0.064188 2.625600 -0.386161
+v -0.064188 2.625600 0.386161
+v -0.063808 2.700000 -0.189952
+v -0.063808 2.700000 0.189952
+v -0.063808 2.700000 -0.189952
+v -0.063808 2.700000 0.189952
+v -0.063708 0.002175 0.383274
+v -0.063708 0.002175 -0.383274
+v -0.062272 3.141450 -0.184870
+v -0.062272 3.141450 0.184870
+v -0.059016 3.034800 -0.353807
+v -0.059016 3.034800 0.353807
+v -0.058988 3.081150 -0.353610
+v -0.058988 3.081150 0.353610
+v -0.057246 2.804400 -0.170215
+v -0.057246 2.804400 0.170215
+v -0.053508 2.981250 -0.320834
+v -0.053508 2.981250 0.320834
+v -0.053428 2.749050 -0.158995
+v -0.053428 2.749050 0.158995
+v -0.050855 3.117600 -0.304843
+v -0.050855 3.117600 0.304843
+v -0.045844 2.659200 -0.275801
+v -0.045844 2.659200 0.275801
+v -0.045032 2.923200 -0.270092
+v -0.045032 2.923200 0.270092
+v -0.036157 2.863350 -0.216979
+v -0.036157 2.863350 0.216979
+v -0.032816 2.700000 -0.197424
+v -0.032816 2.700000 0.197424
+v -0.032816 2.700000 -0.197424
+v -0.032816 2.700000 0.197424
+v -0.032048 3.141450 -0.192107
+v -0.032048 3.141450 0.192107
+v -0.029450 2.804400 -0.176897
+v -0.029450 2.804400 0.176897
+v -0.027480 2.749050 -0.165245
+v -0.027480 2.749050 0.165245
+v -0.000000 0.260025 1.608000
+v -0.000000 1.929525 1.718250
+v -0.000000 2.085600 -1.648000
+v -0.000000 0.656400 -1.948000
+v -0.000000 0.771675 -1.986000
+v -0.000000 2.482687 1.382225
+v -0.000000 2.700000 -0.200000
+v -0.000000 0.127575 1.496475
+v -0.000000 2.474400 -1.204800
+v -0.000000 2.749050 -0.167400
+v -0.000000 0.018225 0.952425
+v -0.000000 0.046875 -1.284375
+v -0.000000 0.064800 1.382400
+v -0.000000 0.384375 1.750000
+v -0.000000 0.463200 1.824000
+v -0.000000 0.553725 -1.892000
+v -0.000000 1.037175 1.992750
+v -0.000000 1.178400 1.972000
+v -0.000000 1.323225 -1.939250
+v -0.000000 1.621875 -1.843750
+v -0.000000 1.774800 1.784000
+v -0.000000 2.400000 -1.300000
+v -0.000000 2.435437 -1.480325
+v -0.000000 2.435437 -1.385925
+v -0.000000 2.463000 -1.459600
+v -0.000000 2.463000 -1.380400
+v -0.000000 2.494500 -1.390200
+v -0.000000 2.502600 -1.100200
+v -0.000000 2.804400 -0.179200
+v -0.000000 2.863350 -0.219800
+v -0.000000 2.572800 -0.673600
+v -0.000000 0.105600 1.480800
+v -0.000000 0.177075 -1.514000
+v -0.000000 2.494500 -1.419800
+v -0.000000 2.527200 -0.970400
+v -0.000000 2.923200 -0.273600
+v -0.000000 3.117600 -0.308800
+v -0.000000 2.597400 -0.525800
+v -0.000000 2.700000 -0.200000
+v -0.000000 2.981250 -0.325000
+v -0.000000 3.141450 -0.194600
+v -0.000000 0.002175 0.388275
+v -0.000000 3.081150 -0.358200
+v 0.000000 0.000000 0.000000
+v 0.000000 0.002175 -0.388275
+v 0.000000 0.002175 0.388275
+v 0.000000 0.008400 -0.703200
+v 0.000000 0.008400 0.703200
+v 0.000000 0.018225 -0.952425
+v 0.000000 0.018225 0.952425
+v 0.000000 0.031200 -1.143600
+v 0.000000 0.031200 -1.143600
+v 0.000000 0.031200 1.143600
+v 0.000000 0.031200 1.143600
+v 0.000000 0.046875 -1.284375
+v 0.000000 0.046875 1.284375
+v 0.000000 0.064800 -1.382400
+v 0.000000 0.064800 1.382400
+v 0.000000 0.084525 -1.445325
+v 0.000000 0.084525 -1.445325
+v 0.000000 0.084525 1.445325
+v 0.000000 0.084525 1.445325
+v 0.000000 0.105600 -1.480800
+v 0.000000 0.105600 1.480800
+v 0.000000 0.127575 -1.496475
+v 0.000000 0.127575 1.496475
+v 0.000000 0.150000 -1.500000
+v 0.000000 0.150000 -1.500000
+v 0.000000 0.150000 1.500000
+v 0.000000 0.150000 1.500000
+v 0.000000 0.177075 -1.514000
+v 0.000000 0.177075 1.514000
+v 0.000000 0.213600 -1.552000
+v 0.000000 0.213600 -1.552000
+v 0.000000 0.213600 1.552000
+v 0.000000 0.213600 1.552000
+v 0.000000 0.260025 -1.608000
+v 0.000000 0.260025 1.608000
+v 0.000000 0.316800 -1.676000
+v 0.000000 0.316800 -1.676000
+v 0.000000 0.316800 1.676000
+v 0.000000 0.316800 1.676000
+v 0.000000 0.384375 -1.750000
+v 0.000000 0.384375 1.750000
+v 0.000000 0.463200 -1.824000
+v 0.000000 0.463200 1.824000
+v 0.000000 0.553725 -1.892000
+v 0.000000 0.553725 1.892000
+v 0.000000 0.656400 -1.948000
+v 0.000000 0.656400 1.948000
+v 0.000000 0.771675 -1.986000
+v 0.000000 0.771675 1.986000
+v 0.000000 0.900000 -2.000000
+v 0.000000 0.900000 -2.000000
+v 0.000000 0.900000 2.000000
+v 0.000000 0.900000 2.000000
+v 0.000000 1.037175 -1.992750
+v 0.000000 1.037175 1.992750
+v 0.000000 1.178400 -1.972000
+v 0.000000 1.178400 1.972000
+v 0.000000 1.323225 -1.939250
+v 0.000000 1.323225 1.939250
+v 0.000000 1.471200 -1.896000
+v 0.000000 1.471200 -1.896000
+v 0.000000 1.471200 1.896000
+v 0.000000 1.471200 1.896000
+v 0.000000 1.621875 -1.843750
+v 0.000000 1.621875 1.843750
+v 0.000000 1.774800 -1.784000
+v 0.000000 1.774800 1.784000
+v 0.000000 1.929525 -1.718250
+v 0.000000 1.929525 1.718250
+v 0.000000 2.085600 -1.648000
+v 0.000000 2.085600 1.648000
+v 0.000000 2.242575 -1.574750
+v 0.000000 2.242575 -1.574750
+v 0.000000 2.242575 1.574750
+v 0.000000 2.242575 1.574750
+v 0.000000 2.400000 -1.500000
+v 0.000000 2.400000 -1.500000
+v 0.000000 2.400000 -1.400000
+v 0.000000 2.400000 -1.400000
+v 0.000000 2.400000 -1.300000
+v 0.000000 2.400000 1.300000
+v 0.000000 2.400000 1.400000
+v 0.000000 2.400000 1.400000
+v 0.000000 2.400000 1.500000
+v 0.000000 2.400000 1.500000
+v 0.000000 2.435437 -1.480325
+v 0.000000 2.435437 -1.385925
+v 0.000000 2.435437 1.385925
+v 0.000000 2.435437 1.480325
+v 0.000000 2.440800 -1.274600
+v 0.000000 2.440800 -1.274600
+v 0.000000 2.440800 1.274600
+v 0.000000 2.440800 1.274600
+v 0.000000 2.463000 -1.459600
+v 0.000000 2.463000 -1.380400
+v 0.000000 2.463000 1.380400
+v 0.000000 2.463000 1.459600
+v 0.000000 2.474400 -1.204800
+v 0.000000 2.474400 1.204800
+v 0.000000 2.482687 -1.439025
+v 0.000000 2.482687 -1.382225
+v 0.000000 2.482687 1.382225
+v 0.000000 2.482687 1.439025
+v 0.000000 2.494500 -1.419800
+v 0.000000 2.494500 -1.390200
+v 0.000000 2.494500 1.390200
+v 0.000000 2.494500 1.419800
+v 0.000000 2.498438 -1.403125
+v 0.000000 2.498438 -1.403125
+v 0.000000 2.498438 1.403125
+v 0.000000 2.498438 1.403125
+v 0.000000 2.502600 -1.100200
+v 0.000000 2.502600 1.100200
+v 0.000000 2.527200 -0.970400
+v 0.000000 2.527200 0.970400
+v 0.000000 2.550000 -0.825000
+v 0.000000 2.550000 -0.825000
+v 0.000000 2.550000 0.825000
+v 0.000000 2.550000 0.825000
+v 0.000000 2.572800 -0.673600
+v 0.000000 2.572800 0.673600
+v 0.000000 2.597400 -0.525800
+v 0.000000 2.597400 0.525800
+v 0.000000 2.625600 -0.391200
+v 0.000000 2.625600 -0.391200
+v 0.000000 2.625600 0.391200
+v 0.000000 2.625600 0.391200
+v 0.000000 2.659200 -0.279400
+v 0.000000 2.659200 0.279400
+v 0.000000 2.700000 -0.200000
+v 0.000000 2.700000 -0.200000
+v 0.000000 2.700000 0.200000
+v 0.000000 2.700000 0.200000
+v 0.000000 2.749050 -0.167400
+v 0.000000 2.749050 0.167400
+v 0.000000 2.804400 -0.179200
+v 0.000000 2.804400 0.179200
+v 0.000000 2.863350 -0.219800
+v 0.000000 2.863350 0.219800
+v 0.000000 2.923200 -0.273600
+v 0.000000 2.923200 0.273600
+v 0.000000 2.981250 -0.325000
+v 0.000000 2.981250 0.325000
+v 0.000000 3.034800 -0.358400
+v 0.000000 3.034800 -0.358400
+v 0.000000 3.034800 0.358400
+v 0.000000 3.034800 0.358400
+v 0.000000 3.081150 -0.358200
+v 0.000000 3.081150 0.358200
+v 0.000000 3.117600 -0.308800
+v 0.000000 3.117600 0.308800
+v 0.000000 3.141450 -0.194600
+v 0.000000 3.141450 0.194600
+v 0.000000 3.150000 0.000000
+v 0.000000 0.002175 -0.388275
+v 0.000000 3.081150 0.358200
+v 0.000000 2.597400 0.525800
+v 0.000000 2.700000 0.200000
+v 0.000000 2.981250 0.325000
+v 0.000000 3.141450 0.194600
+v 0.000000 3.117600 0.308800
+v 0.000000 0.105600 -1.480800
+v 0.000000 0.177075 1.514000
+v 0.000000 2.494500 1.419800
+v 0.000000 2.527200 0.970400
+v 0.000000 2.923200 0.273600
+v 0.000000 2.572800 0.673600
+v 0.000000 2.863350 0.219800
+v 0.000000 0.018225 -0.952425
+v 0.000000 0.046875 1.284375
+v 0.000000 0.064800 -1.382400
+v 0.000000 0.384375 -1.750000
+v 0.000000 0.463200 -1.824000
+v 0.000000 0.553725 1.892000
+v 0.000000 1.037175 -1.992750
+v 0.000000 1.178400 -1.972000
+v 0.000000 1.323225 1.939250
+v 0.000000 1.621875 1.843750
+v 0.000000 1.774800 -1.784000
+v 0.000000 2.400000 1.300000
+v 0.000000 2.435437 1.385925
+v 0.000000 2.435437 1.480325
+v 0.000000 2.463000 1.380400
+v 0.000000 2.463000 1.459600
+v 0.000000 2.494500 1.390200
+v 0.000000 2.502600 1.100200
+v 0.000000 2.804400 0.179200
+v 0.000000 2.749050 0.167400
+v 0.000000 0.127575 -1.496475
+v 0.000000 2.474400 1.204800
+v 0.000000 0.656400 1.948000
+v 0.000000 0.771675 1.986000
+v 0.000000 2.482687 -1.382225
+v 0.000000 2.700000 0.200000
+v 0.000000 0.260025 -1.608000
+v 0.000000 1.929525 -1.718250
+v 0.000000 2.085600 1.648000
+v 0.027480 2.749050 -0.165245
+v 0.027480 2.749050 0.165245
+v 0.029450 2.804400 -0.176897
+v 0.029450 2.804400 0.176897
+v 0.032048 3.141450 -0.192107
+v 0.032048 3.141450 0.192107
+v 0.032816 2.700000 -0.197424
+v 0.032816 2.700000 0.197424
+v 0.032816 2.700000 -0.197424
+v 0.032816 2.700000 0.197424
+v 0.036157 2.863350 -0.216979
+v 0.036157 2.863350 0.216979
+v 0.045032 2.923200 -0.270092
+v 0.045032 2.923200 0.270092
+v 0.045844 2.659200 -0.275801
+v 0.045844 2.659200 0.275801
+v 0.050855 3.117600 -0.304843
+v 0.050855 3.117600 0.304843
+v 0.053428 2.749050 -0.158995
+v 0.053428 2.749050 0.158995
+v 0.053508 2.981250 -0.320834
+v 0.053508 2.981250 0.320834
+v 0.057246 2.804400 -0.170215
+v 0.057246 2.804400 0.170215
+v 0.058988 3.081150 -0.353610
+v 0.058988 3.081150 0.353610
+v 0.059016 3.034800 -0.353807
+v 0.059016 3.034800 0.353807
+v 0.062272 3.141450 -0.184870
+v 0.062272 3.141450 0.184870
+v 0.063708 0.002175 0.383274
+v 0.063708 0.002175 -0.383274
+v 0.063808 2.700000 -0.189952
+v 0.063808 2.700000 0.189952
+v 0.063808 2.700000 -0.189952
+v 0.063808 2.700000 0.189952
+v 0.064188 2.625600 -0.386161
+v 0.064188 2.625600 0.386161
+v 0.070270 2.863350 -0.208794
+v 0.070270 2.863350 0.208794
+v 0.077523 2.749050 -0.148969
+v 0.077523 2.749050 0.148969
+v 0.083047 2.804400 -0.159496
+v 0.083047 2.804400 0.159496
+v 0.086273 2.597400 -0.519028
+v 0.086273 2.597400 0.519028
+v 0.087511 2.923200 -0.259910
+v 0.087511 2.923200 0.259910
+v 0.089140 2.659200 -0.265363
+v 0.089140 2.659200 0.265363
+v 0.090306 3.141450 -0.173255
+v 0.090306 3.141450 0.173255
+v 0.092592 2.700000 -0.177968
+v 0.092592 2.700000 0.177968
+v 0.092592 2.700000 -0.177968
+v 0.092592 2.700000 0.177968
+v 0.098814 3.117600 -0.293360
+v 0.098814 3.117600 0.293360
+v 0.099446 2.749050 0.135489
+v 0.099446 2.749050 -0.135489
+v 0.101925 2.863350 -0.195658
+v 0.101925 2.863350 0.195658
+v 0.103976 2.981250 -0.308744
+v 0.103976 2.981250 0.308744
+v 0.106513 2.804400 -0.145078
+v 0.106513 2.804400 0.145078
+v 0.110524 2.572800 -0.664924
+v 0.110524 2.572800 0.664924
+v 0.114619 3.081150 -0.340289
+v 0.114619 3.081150 0.340289
+v 0.114676 3.034800 -0.340477
+v 0.114676 3.034800 0.340477
+v 0.115381 0.008400 0.694143
+v 0.115381 0.008400 -0.694143
+v 0.115787 3.141450 -0.157626
+v 0.115787 3.141450 0.157626
+v 0.118784 2.700000 0.161856
+v 0.118784 2.700000 -0.161856
+v 0.118784 2.700000 -0.161856
+v 0.118784 2.700000 0.161856
+v 0.118874 2.749050 0.118874
+v 0.118874 2.749050 -0.118874
+v 0.123875 0.002175 0.368768
+v 0.123875 0.002175 -0.368768
+v 0.124808 2.625600 -0.371546
+v 0.124808 2.625600 0.371546
+v 0.126920 2.923200 -0.243569
+v 0.126920 2.923200 0.243569
+v 0.127304 2.804400 0.127304
+v 0.127304 2.804400 -0.127304
+v 0.129351 2.659200 0.248621
+v 0.129351 2.659200 -0.248621
+v 0.130707 2.863350 -0.177989
+v 0.130707 2.863350 0.177989
+v 0.135366 2.550000 -0.814374
+v 0.135366 2.550000 0.814374
+v 0.135489 2.749050 0.099446
+v 0.135489 2.749050 -0.099446
+v 0.138348 3.141450 -0.138348
+v 0.138348 3.141450 0.138348
+v 0.142000 2.700000 0.142000
+v 0.142000 2.700000 -0.142000
+v 0.142000 2.700000 -0.142000
+v 0.142000 2.700000 0.142000
+v 0.143301 3.117600 -0.274928
+v 0.143301 3.117600 0.274928
+v 0.145078 2.804400 0.106513
+v 0.145078 2.804400 -0.106513
+v 0.148969 2.749050 0.077523
+v 0.148969 2.749050 -0.077523
+v 0.150793 2.981250 -0.289340
+v 0.150793 2.981250 0.289340
+v 0.156200 2.863350 -0.156200
+v 0.156200 2.863350 0.156200
+v 0.156274 0.018225 0.940158
+v 0.156274 0.018225 -0.940158
+v 0.157626 3.141450 -0.115787
+v 0.157626 3.141450 0.115787
+v 0.158995 2.749050 0.053428
+v 0.158995 2.749050 -0.053428
+v 0.159223 2.527200 -0.957901
+v 0.159223 2.527200 0.957901
+v 0.159496 2.804400 0.083047
+v 0.159496 2.804400 -0.083047
+v 0.161856 2.700000 0.118784
+v 0.161856 2.700000 -0.118784
+v 0.161856 2.700000 -0.118784
+v 0.161856 2.700000 0.118784
+v 0.162745 2.923200 -0.221585
+v 0.162745 2.923200 0.221585
+v 0.165245 2.749050 0.027480
+v 0.165245 2.749050 -0.027480
+v 0.165941 2.659200 -0.226113
+v 0.165941 2.659200 0.226113
+v 0.166221 3.081150 0.318907
+v 0.166221 3.081150 -0.318907
+v 0.166306 3.034800 -0.319082
+v 0.166306 3.034800 0.319082
+v 0.167400 2.749050 -0.000000
+v 0.167400 2.749050 0.000000
+v 0.167751 2.597400 -0.499384
+v 0.167751 2.597400 0.499384
+v 0.170215 2.804400 0.057246
+v 0.170215 2.804400 -0.057246
+v 0.173255 3.141450 -0.090306
+v 0.173255 3.141450 0.090306
+v 0.176897 2.804400 0.029450
+v 0.176897 2.804400 -0.029450
+v 0.177968 2.700000 0.092592
+v 0.177968 2.700000 -0.092592
+v 0.177968 2.700000 -0.092592
+v 0.177968 2.700000 0.092592
+v 0.177989 2.863350 -0.130707
+v 0.177989 2.863350 0.130707
+v 0.179200 2.804400 -0.000000
+v 0.179200 2.804400 0.000000
+v 0.179756 0.002175 -0.345503
+v 0.179756 0.002175 0.345503
+v 0.180521 2.502600 -1.086029
+v 0.180521 2.502600 1.086029
+v 0.181110 2.625600 0.348105
+v 0.181110 2.625600 -0.348105
+v 0.183734 3.117600 -0.250127
+v 0.183734 3.117600 0.250127
+v 0.184870 3.141450 -0.062272
+v 0.184870 3.141450 0.062272
+v 0.187642 0.031200 1.128870
+v 0.187642 0.031200 -1.128870
+v 0.189952 2.700000 0.063808
+v 0.189952 2.700000 -0.063808
+v 0.189952 2.700000 -0.063808
+v 0.189952 2.700000 0.063808
+v 0.192107 3.141450 -0.032048
+v 0.192107 3.141450 0.032048
+v 0.193348 2.981250 -0.263232
+v 0.193348 2.981250 0.263232
+v 0.194472 2.923200 -0.194472
+v 0.194472 2.923200 0.194472
+v 0.194600 3.141450 0.000000
+v 0.194600 3.141450 -0.000000
+v 0.195658 2.863350 -0.101925
+v 0.195658 2.863350 0.101925
+v 0.197424 2.700000 0.032816
+v 0.197424 2.700000 -0.032816
+v 0.197424 2.700000 -0.032816
+v 0.197424 2.700000 0.032816
+v 0.197684 2.474400 -1.189282
+v 0.197684 2.474400 1.189282
+v 0.198374 2.659200 -0.198374
+v 0.198374 2.659200 0.198374
+v 0.200000 2.700000 -0.000000
+v 0.200000 2.700000 0.000000
+v 0.200000 2.700000 0.000000
+v 0.200000 2.700000 -0.000000
+v 0.208794 2.863350 0.070270
+v 0.208794 2.863350 -0.070270
+v 0.209136 2.440800 -1.258183
+v 0.209136 2.440800 1.258183
+v 0.210740 0.046875 -1.267832
+v 0.210740 0.046875 1.267832
+v 0.213123 3.081150 -0.290138
+v 0.213123 3.081150 0.290138
+v 0.213234 3.034800 -0.290295
+v 0.213234 3.034800 0.290295
+v 0.213304 2.400000 -1.283256
+v 0.213304 2.400000 1.283256
+v 0.214905 2.572800 -0.639758
+v 0.214905 2.572800 0.639758
+v 0.216979 2.863350 0.036157
+v 0.216979 2.863350 -0.036157
+v 0.219536 3.117600 -0.219536
+v 0.219536 3.117600 0.219536
+v 0.219800 2.863350 -0.000000
+v 0.219800 2.863350 0.000000
+v 0.221585 2.923200 -0.162745
+v 0.221585 2.923200 0.162745
+v 0.224349 0.008400 0.667871
+v 0.224349 0.008400 -0.667871
+v 0.226113 2.659200 -0.165941
+v 0.226113 2.659200 0.165941
+v 0.226496 2.463000 -1.362620
+v 0.226496 2.463000 1.362620
+v 0.226795 2.482687 1.364422
+v 0.226795 2.482687 -1.364422
+v 0.226824 0.064800 1.364595
+v 0.226824 0.064800 -1.364595
+v 0.227403 2.435437 -1.368074
+v 0.227403 2.435437 1.368074
+v 0.228104 2.494500 -1.372294
+v 0.228104 2.494500 1.372294
+v 0.229712 2.400000 -1.381968
+v 0.229712 2.400000 1.381968
+v 0.230225 2.498438 -1.385053
+v 0.230225 2.498438 1.385053
+v 0.230604 0.002175 -0.314223
+v 0.230604 0.002175 0.314223
+v 0.231031 2.981250 -0.231031
+v 0.231031 2.981250 0.231031
+v 0.232342 2.625600 -0.316590
+v 0.232342 2.625600 0.316590
+v 0.232961 2.494500 -1.401513
+v 0.232961 2.494500 1.401513
+v 0.236115 2.482687 -1.420490
+v 0.236115 2.482687 1.420490
+v 0.237149 0.084525 1.426709
+v 0.237149 0.084525 -1.426709
+v 0.239491 2.463000 -1.440800
+v 0.239491 2.463000 1.440800
+v 0.242892 2.435437 -1.461258
+v 0.242892 2.435437 1.461258
+v 0.242970 0.105600 1.461727
+v 0.242970 0.105600 -1.461727
+v 0.243424 2.597400 0.467878
+v 0.243424 2.597400 -0.467878
+v 0.243569 2.923200 -0.126920
+v 0.243569 2.923200 0.126920
+v 0.245542 0.127575 1.477200
+v 0.245542 0.127575 -1.477200
+v 0.246120 0.150000 -1.480680
+v 0.246120 2.400000 -1.480680
+v 0.246120 0.150000 1.480680
+v 0.246120 0.150000 1.480680
+v 0.246120 2.400000 1.480680
+v 0.246120 0.150000 -1.480680
+v 0.248417 0.177075 -1.494500
+v 0.248417 0.177075 1.494500
+v 0.248621 2.659200 0.129351
+v 0.248621 2.659200 -0.129351
+v 0.250127 3.117600 -0.183734
+v 0.250127 3.117600 0.183734
+v 0.254652 0.213600 -1.532010
+v 0.254652 0.213600 1.532010
+v 0.254653 3.081150 -0.254653
+v 0.254653 3.081150 0.254653
+v 0.254788 3.034800 -0.254788
+v 0.254788 3.034800 0.254788
+v 0.258385 2.242575 -1.554467
+v 0.258385 2.242575 1.554467
+v 0.259910 2.923200 -0.087511
+v 0.259910 2.923200 0.087511
+v 0.263208 2.550000 -0.783552
+v 0.263208 2.550000 0.783552
+v 0.263232 2.981250 -0.193348
+v 0.263232 2.981250 0.193348
+v 0.263841 0.260025 1.587289
+v 0.263841 0.260025 -1.587289
+v 0.265363 2.659200 -0.089140
+v 0.265363 2.659200 0.089140
+v 0.270092 2.923200 -0.045032
+v 0.270092 2.923200 0.045032
+v 0.270404 2.085600 -1.626774
+v 0.270404 2.085600 1.626774
+v 0.273600 2.923200 -0.000000
+v 0.273600 2.923200 0.000000
+v 0.274928 3.117600 -0.143301
+v 0.274928 3.117600 0.143301
+v 0.274998 0.316800 -1.654413
+v 0.274998 0.316800 1.654413
+v 0.275675 0.002175 -0.275675
+v 0.275675 0.002175 0.275675
+v 0.275801 2.659200 -0.045844
+v 0.275801 2.659200 0.045844
+v 0.277752 2.625600 -0.277752
+v 0.277752 2.625600 0.277752
+v 0.279400 2.659200 0.000000
+v 0.281930 1.929525 1.696119
+v 0.281930 1.929525 -1.696119
+v 0.287140 0.384375 -1.727460
+v 0.287140 0.384375 1.727460
+v 0.289340 2.981250 -0.150793
+v 0.289340 2.981250 0.150793
+v 0.290138 3.081150 -0.213123
+v 0.290138 3.081150 0.213123
+v 0.290295 3.034800 -0.213234
+v 0.290295 3.034800 0.213234
+v 0.292719 1.774800 -1.761022
+v 0.292719 1.774800 1.761022
+v 0.293360 3.117600 -0.098814
+v 0.293360 3.117600 0.098814
+v 0.299282 0.463200 -1.800507
+v 0.299282 0.463200 1.800507
+v 0.302522 1.621875 -1.820003
+v 0.302523 1.621875 1.820003
+v 0.303862 0.018225 0.904575
+v 0.303862 0.018225 -0.904575
+v 0.304843 3.117600 -0.050855
+v 0.304843 3.117600 0.050855
+v 0.308744 2.981250 -0.103976
+v 0.308744 2.981250 0.103976
+v 0.308800 3.117600 0.000000
+v 0.308800 3.117600 -0.000000
+v 0.309596 2.527200 -0.921647
+v 0.309596 2.527200 0.921647
+v 0.310439 0.553725 -1.867631
+v 0.310439 0.553725 1.867631
+v 0.311096 1.471200 -1.871580
+v 0.311096 1.471200 1.871580
+v 0.311850 2.572800 -0.599396
+v 0.311850 2.572800 0.599396
+v 0.312283 2.597400 -0.425519
+v 0.312283 2.597400 0.425519
+v 0.314223 0.002175 -0.230604
+v 0.314223 0.002175 0.230604
+v 0.316590 2.625600 -0.232342
+v 0.316590 2.625600 0.232342
+v 0.318192 1.323225 -1.914272
+v 0.318192 1.323225 1.914272
+v 0.318907 3.081150 -0.166221
+v 0.318907 3.081150 0.166221
+v 0.319082 3.034800 -0.166306
+v 0.319082 3.034800 0.166306
+v 0.319628 0.656400 -1.922910
+v 0.319628 0.656400 1.922910
+v 0.320834 2.981250 -0.053508
+v 0.320834 2.981250 0.053508
+v 0.323566 1.178400 -1.946601
+v 0.323566 1.178400 1.946601
+v 0.325000 2.981250 0.000000
+v 0.325000 2.981250 -0.000000
+v 0.325553 0.008400 -0.625735
+v 0.325553 0.008400 0.625735
+v 0.325863 0.771675 -1.960420
+v 0.325863 0.771675 1.960420
+v 0.326970 1.037175 -1.967083
+v 0.326970 1.037175 1.967083
+v 0.328160 0.900000 -1.974240
+v 0.328160 0.900000 -1.974240
+v 0.328160 0.900000 1.974240
+v 0.340289 3.081150 -0.114619
+v 0.340289 3.081150 0.114619
+v 0.340477 3.034800 -0.114676
+v 0.340477 3.034800 0.114676
+v 0.345503 0.002175 -0.179756
+v 0.345503 0.002175 0.179756
+v 0.348105 2.625600 -0.181110
+v 0.348105 2.625600 0.181110
+v 0.351008 2.502600 -1.044926
+v 0.351008 2.502600 1.044926
+v 0.353610 3.081150 -0.058988
+v 0.353610 3.081150 0.058988
+v 0.353807 3.034800 -0.059016
+v 0.353807 3.034800 0.059016
+v 0.358200 3.081150 -0.000000
+v 0.358200 3.081150 0.000000
+v 0.358400 3.034800 0.000000
+v 0.358400 3.034800 0.000000
+v 0.364854 0.031200 1.086146
+v 0.364854 0.031200 -1.086146
+v 0.368768 0.002175 -0.123875
+v 0.368768 0.002175 0.123875
+v 0.371546 2.625600 -0.124808
+v 0.371546 2.625600 0.124808
+v 0.373318 2.597400 -0.373318
+v 0.373318 2.597400 0.373318
+v 0.381942 2.550000 -0.734118
+v 0.381942 2.550000 0.734118
+v 0.383274 0.002175 -0.063708
+v 0.383274 0.002175 0.063708
+v 0.384379 2.474400 -1.144271
+v 0.384379 2.474400 1.144271
+v 0.386161 2.625600 -0.064188
+v 0.386161 2.625600 0.064188
+v 0.388275 0.002175 0.000000
+v 0.388275 0.002175 0.000000
+v 0.391200 2.625600 0.000000
+v 0.391200 2.625600 0.000000
+v 0.400065 2.572800 -0.545131
+v 0.400065 2.572800 0.545131
+v 0.406648 2.440800 -1.210564
+v 0.406648 2.440800 1.210564
+v 0.409767 0.046875 1.219848
+v 0.409767 0.046875 -1.219848
+v 0.414752 2.400000 -1.234688
+v 0.414752 2.400000 1.234688
+v 0.417645 0.008400 -0.569086
+v 0.417645 0.008400 0.569086
+v 0.425519 2.597400 0.312283
+v 0.425519 2.597400 -0.312283
+v 0.440403 2.463000 -1.311049
+v 0.440403 2.463000 1.311049
+v 0.440935 0.018225 0.847506
+v 0.440935 0.018225 -0.847506
+v 0.440985 2.482687 -1.312782
+v 0.440985 2.482687 1.312782
+v 0.441041 0.064800 1.312948
+v 0.441041 0.064800 -1.312948
+v 0.442166 2.435437 -1.316296
+v 0.442166 2.435437 1.316296
+v 0.443529 2.494500 -1.320356
+v 0.443529 2.494500 1.320356
+v 0.446656 2.400000 -1.329664
+v 0.446656 2.400000 1.329664
+v 0.447653 2.498438 -1.332632
+v 0.447653 2.498438 1.332632
+v 0.449256 2.527200 -0.863501
+v 0.449256 2.527200 0.863501
+v 0.452973 2.494500 -1.348469
+v 0.452973 2.494500 1.348469
+v 0.459107 2.482687 -1.366728
+v 0.459107 2.482687 1.366728
+v 0.461116 0.084525 1.372712
+v 0.461116 0.084525 -1.372712
+v 0.465671 2.463000 -1.386270
+v 0.465671 2.463000 1.386270
+v 0.467878 2.597400 -0.243424
+v 0.467878 2.597400 0.243424
+v 0.472283 2.435437 -1.405953
+v 0.472283 2.435437 1.405953
+v 0.472434 0.105600 1.406405
+v 0.472434 0.105600 -1.406405
+v 0.477435 0.127575 1.421292
+v 0.477435 0.127575 -1.421292
+v 0.478256 2.572800 -0.478256
+v 0.478256 2.572800 0.478256
+v 0.478560 0.150000 -1.424640
+v 0.478560 2.400000 -1.424640
+v 0.478560 0.150000 1.424640
+v 0.478560 0.150000 1.424640
+v 0.478560 0.150000 -1.424640
+v 0.478560 2.400000 1.424640
+v 0.483027 0.177075 -1.437937
+v 0.483027 0.177075 1.437937
+v 0.489984 2.550000 -0.667656
+v 0.489984 2.550000 0.667656
+v 0.495150 0.213600 -1.474028
+v 0.495150 0.213600 1.474028
+v 0.499272 0.008400 -0.499272
+v 0.499272 0.008400 0.499272
+v 0.499384 2.597400 -0.167751
+v 0.499384 2.597400 0.167751
+v 0.502408 2.242575 -1.495635
+v 0.502408 2.242575 1.495635
+v 0.509349 2.502600 0.979002
+v 0.509349 2.502600 -0.979002
+v 0.513016 0.260025 -1.527214
+v 0.513016 0.260025 1.527214
+v 0.519028 2.597400 0.086273
+v 0.519028 2.597400 -0.086273
+v 0.525778 2.085600 -1.565204
+v 0.525778 2.085600 1.565204
+v 0.525800 2.597400 -0.000000
+v 0.525800 2.597400 0.000000
+v 0.529441 0.031200 -1.017621
+v 0.529441 0.031200 1.017621
+v 0.534711 0.316800 -1.591798
+v 0.534711 0.316800 1.591798
+v 0.545131 2.572800 -0.400065
+v 0.545131 2.572800 0.400065
+v 0.548190 1.929525 -1.631925
+v 0.548190 1.929525 1.631925
+v 0.557774 2.474400 -1.072079
+v 0.557774 2.474400 1.072079
+v 0.558320 0.384375 -1.662080
+v 0.558320 0.384375 1.662080
+v 0.565664 0.018225 0.770779
+v 0.565664 0.018225 -0.770779
+v 0.569086 0.008400 -0.417645
+v 0.569086 0.008400 0.417645
+v 0.569167 1.774800 -1.694372
+v 0.569167 1.774800 1.694372
+v 0.576340 2.527200 -0.785325
+v 0.576340 2.527200 0.785325
+v 0.581929 0.463200 -1.732362
+v 0.581929 0.463200 1.732362
+v 0.585750 2.550000 -0.585750
+v 0.585750 2.550000 0.585750
+v 0.588230 1.621875 -1.751120
+v 0.588230 1.621875 1.751120
+v 0.590089 2.440800 1.134190
+v 0.590089 2.440800 -1.134190
+v 0.594614 0.046875 -1.142888
+v 0.594614 0.046875 1.142888
+v 0.599396 2.572800 -0.311850
+v 0.599396 2.572800 0.311850
+v 0.601848 2.400000 -1.156792
+v 0.601848 2.400000 1.156792
+v 0.603624 0.553725 -1.796946
+v 0.603624 0.553725 1.796946
+v 0.604900 1.471200 -1.800745
+v 0.604900 1.471200 1.800745
+v 0.618698 1.323225 -1.841822
+v 0.618698 1.323225 1.841822
+v 0.621490 0.656400 -1.850132
+v 0.621490 0.656400 1.850132
+v 0.625735 0.008400 0.325553
+v 0.625735 0.008400 -0.325553
+v 0.629147 1.178400 -1.872927
+v 0.629147 1.178400 1.872927
+v 0.633613 0.771675 -1.886223
+v 0.633613 0.771675 1.886223
+v 0.635767 1.037175 -1.892634
+v 0.635767 1.037175 1.892634
+v 0.638080 0.900000 -1.899520
+v 0.638080 0.900000 -1.899520
+v 0.638080 0.900000 1.899520
+v 0.638080 0.900000 1.899520
+v 0.639070 2.463000 -1.228335
+v 0.639070 2.463000 1.228335
+v 0.639758 2.572800 -0.214905
+v 0.639758 2.572800 0.214905
+v 0.639915 2.482687 1.229959
+v 0.639915 2.482687 -1.229959
+v 0.639996 0.064800 -1.230115
+v 0.639996 0.064800 1.230115
+v 0.641628 2.435437 -1.233252
+v 0.641628 2.435437 1.233252
+v 0.643607 2.494500 -1.237056
+v 0.643607 2.494500 1.237056
+v 0.648144 2.400000 -1.245776
+v 0.648144 2.400000 1.245776
+v 0.649591 2.498438 -1.248557
+v 0.649591 2.498438 1.248557
+v 0.653431 2.502600 -0.890370
+v 0.653431 2.502600 0.890370
+v 0.657311 2.494500 -1.263395
+v 0.657311 2.494500 1.263395
+v 0.664924 2.572800 -0.110524
+v 0.664924 2.572800 0.110524
+v 0.666211 2.482687 1.280502
+v 0.666211 2.482687 -1.280502
+v 0.667656 2.550000 -0.489984
+v 0.667656 2.550000 0.489984
+v 0.667871 0.008400 -0.224349
+v 0.667871 0.008400 0.224349
+v 0.669128 0.084525 -1.286108
+v 0.669128 0.084525 1.286108
+v 0.673600 2.572800 0.000000
+v 0.673600 2.572800 -0.000000
+v 0.675736 2.463000 -1.298810
+v 0.675736 2.463000 1.298810
+v 0.676222 0.018225 0.676222
+v 0.676222 0.018225 -0.676222
+v 0.679207 0.031200 -0.925493
+v 0.679207 0.031200 0.925493
+v 0.685331 2.435437 -1.317252
+v 0.685331 2.435437 1.317252
+v 0.685551 0.105600 -1.317675
+v 0.685551 0.105600 1.317675
+v 0.688984 2.527200 -0.688984
+v 0.688984 2.527200 0.688984
+v 0.692808 0.127575 1.331623
+v 0.692808 0.127575 -1.331623
+v 0.694143 0.008400 -0.115381
+v 0.694143 0.008400 0.115381
+v 0.694440 0.150000 1.334760
+v 0.694440 0.150000 -1.334760
+v 0.694440 2.400000 1.334760
+v 0.694440 0.150000 -1.334760
+v 0.694440 0.150000 1.334760
+v 0.694440 2.400000 -1.334760
+v 0.700921 0.177075 1.347218
+v 0.700921 0.177075 -1.347218
+v 0.703200 0.008400 0.000000
+v 0.715555 2.474400 -0.975021
+v 0.715555 2.474400 0.975021
+v 0.718514 0.213600 1.381032
+v 0.718514 0.213600 -1.381032
+v 0.729046 2.242575 -1.401276
+v 0.729046 2.242575 1.401276
+v 0.734118 2.550000 -0.381942
+v 0.734118 2.550000 0.381942
+v 0.744440 0.260025 1.430863
+v 0.744440 0.260025 -1.430863
+v 0.757010 2.440800 1.031508
+v 0.757010 2.440800 -1.031508
+v 0.762816 0.046875 -1.039419
+v 0.762816 0.046875 1.039419
+v 0.762958 2.085600 -1.466456
+v 0.762958 2.085600 1.466456
+v 0.770779 0.018225 0.565664
+v 0.770779 0.018225 -0.565664
+v 0.772096 2.400000 -1.052064
+v 0.772096 2.400000 1.052064
+v 0.775921 0.316800 -1.491372
+v 0.775921 0.316800 1.491372
+v 0.781142 2.502600 -0.781142
+v 0.781142 2.502600 0.781142
+v 0.783552 2.550000 -0.263208
+v 0.783552 2.550000 0.263208
+v 0.785325 2.527200 -0.576340
+v 0.785325 2.527200 0.576340
+v 0.795481 1.929525 1.528968
+v 0.795481 1.929525 -1.528968
+v 0.810180 0.384375 1.557220
+v 0.810180 0.384375 -1.557220
+v 0.811956 0.031200 0.811956
+v 0.811956 0.031200 -0.811956
+v 0.814374 2.550000 -0.135366
+v 0.814374 2.550000 0.135366
+v 0.819847 2.463000 -1.117130
+v 0.819847 2.463000 1.117130
+v 0.820931 2.482687 1.118607
+v 0.820931 2.482687 -1.118607
+v 0.821035 0.064800 1.118749
+v 0.821035 0.064800 -1.118749
+v 0.823129 2.435437 -1.121601
+v 0.823129 2.435437 1.121601
+v 0.825000 2.550000 0.000000
+v 0.825000 2.550000 0.000000
+v 0.825668 2.494500 -1.125061
+v 0.825668 2.494500 1.125061
+v 0.825921 1.774800 1.587475
+v 0.825921 1.774800 -1.587475
+v 0.831488 2.400000 -1.132992
+v 0.831488 2.400000 1.132992
+v 0.833344 2.498438 -1.135521
+v 0.833344 2.498438 1.135521
+v 0.843248 2.494500 -1.149016
+v 0.843248 2.494500 1.149016
+v 0.844439 0.463200 1.623068
+v 0.844439 0.463200 -1.623068
+v 0.847506 0.018225 -0.440935
+v 0.847506 0.018225 0.440935
+v 0.853583 1.621875 -1.640643
+v 0.853583 1.621875 1.640643
+v 0.854666 2.482687 -1.164574
+v 0.854666 2.482687 1.164574
+v 0.855408 2.474400 -0.855408
+v 0.855408 2.474400 0.855408
+v 0.858407 0.084525 -1.169673
+v 0.858407 0.084525 1.169673
+v 0.863501 2.527200 -0.449256
+v 0.863501 2.527200 0.449256
+v 0.866886 2.463000 -1.181225
+v 0.866886 2.463000 1.181225
+v 0.875920 0.553725 -1.683577
+v 0.875920 0.553725 1.683577
+v 0.877772 1.471200 -1.687137
+v 0.877772 1.471200 1.687137
+v 0.879195 2.435437 -1.197997
+v 0.879195 2.435437 1.197997
+v 0.879477 0.105600 -1.198382
+v 0.879477 0.105600 1.198382
+v 0.888786 0.127575 1.211067
+v 0.888786 0.127575 -1.211067
+v 0.890370 2.502600 -0.653431
+v 0.890370 2.502600 0.653431
+v 0.890880 0.150000 -1.213920
+v 0.890880 0.150000 1.213920
+v 0.890880 2.400000 -1.213920
+v 0.890880 0.150000 -1.213920
+v 0.890880 0.150000 1.213920
+v 0.890880 2.400000 1.213920
+v 0.897795 1.323225 -1.725622
+v 0.897795 1.323225 1.725622
+v 0.899195 0.177075 1.225250
+v 0.899195 0.177075 -1.225250
+v 0.901846 0.656400 -1.733408
+v 0.901846 0.656400 1.733408
+v 0.904575 0.018225 0.303862
+v 0.904575 0.018225 -0.303862
+v 0.904966 2.440800 0.904966
+v 0.904966 2.440800 -0.904966
+v 0.911906 0.046875 -0.911906
+v 0.911906 0.046875 0.911906
+v 0.912957 1.178400 -1.754764
+v 0.912957 1.178400 1.754764
+v 0.919439 0.771675 -1.767222
+v 0.919439 0.771675 1.767222
+v 0.921647 2.527200 -0.309596
+v 0.921647 2.527200 0.309596
+v 0.921764 0.213600 1.256003
+v 0.921764 0.213600 -1.256003
+v 0.922564 1.037175 1.773229
+v 0.922564 1.037175 -1.773229
+v 0.923000 2.400000 -0.923000
+v 0.923000 2.400000 0.923000
+v 0.925493 0.031200 0.679207
+v 0.925493 0.031200 -0.679207
+v 0.925920 0.900000 1.779680
+v 0.925920 0.900000 -1.779680
+v 0.925920 0.900000 -1.779680
+v 0.925920 0.900000 1.779680
+v 0.935276 2.242575 -1.274414
+v 0.935276 2.242575 1.274414
+v 0.940158 0.018225 0.156274
+v 0.940158 0.018225 -0.156274
+v 0.952425 0.018225 0.000000
+v 0.952425 0.018225 0.000000
+v 0.955023 0.260025 1.301322
+v 0.955023 0.260025 -1.301322
+v 0.957901 2.527200 -0.159223
+v 0.957901 2.527200 0.159223
+v 0.970400 2.527200 0.000000
+v 0.970400 2.527200 -0.000000
+v 0.975021 2.474400 -0.715555
+v 0.975021 2.474400 0.715555
+v 0.978780 2.085600 -1.333693
+v 0.978780 2.085600 1.333693
+v 0.979002 2.502600 0.509349
+v 0.979002 2.502600 -0.509349
+v 0.980084 2.463000 -0.980084
+v 0.980084 2.463000 0.980084
+v 0.981380 2.482687 -0.981380
+v 0.981380 2.482687 0.981380
+v 0.981504 0.064800 0.981504
+v 0.981504 0.064800 -0.981504
+v 0.984007 2.435437 -0.984007
+v 0.984007 2.435437 0.984007
+v 0.987042 2.494500 -0.987042
+v 0.987042 2.494500 0.987042
+v 0.994000 2.400000 -0.994000
+v 0.994000 2.400000 0.994000
+v 0.995410 0.316800 -1.356353
+v 0.995410 0.316800 1.356353
+v 0.996219 2.498438 -0.996219
+v 0.996219 2.498438 0.996219
+v 1.008058 2.494500 -1.008058
+v 1.008058 2.494500 1.008058
+v 1.017621 0.031200 0.529441
+v 1.017621 0.031200 -0.529441
+v 1.020503 1.929525 -1.390545
+v 1.020503 1.929525 1.390545
+v 1.021708 2.482687 -1.021708
+v 1.021708 2.482687 1.021708
+v 1.026181 0.084525 -1.026181
+v 1.026181 0.084525 1.026181
+v 1.031508 2.440800 0.757010
+v 1.031508 2.440800 -0.757010
+v 1.036316 2.463000 -1.036316
+v 1.036316 2.463000 1.036316
+v 1.039360 0.384375 -1.416240
+v 1.039360 0.384375 1.416240
+v 1.039419 0.046875 -0.762816
+v 1.039419 0.046875 0.762816
+v 1.044926 2.502600 -0.351008
+v 1.044926 2.502600 0.351008
+v 1.051031 2.435437 -1.051031
+v 1.051031 2.435437 1.051031
+v 1.051368 0.105600 -1.051368
+v 1.051368 0.105600 1.051368
+v 1.052064 2.400000 -0.772096
+v 1.052064 2.400000 0.772096
+v 1.059553 1.774800 -1.443756
+v 1.059553 1.774800 1.443756
+v 1.062497 0.127575 1.062497
+v 1.062497 0.127575 -1.062497
+v 1.065000 0.150000 -1.065000
+v 1.065000 0.150000 1.065000
+v 1.065000 2.400000 -1.065000
+v 1.065000 2.400000 1.065000
+v 1.072079 2.474400 -0.557774
+v 1.072079 2.474400 0.557774
+v 1.074940 0.177075 -1.074940
+v 1.074940 0.177075 1.074940
+v 1.083310 0.463200 -1.476127
+v 1.083310 0.463200 1.476127
+v 1.086029 2.502600 0.180521
+v 1.086029 2.502600 -0.180521
+v 1.086146 0.031200 0.364854
+v 1.086146 0.031200 -0.364854
+v 1.095040 1.621875 -1.492110
+v 1.095040 1.621875 1.492110
+v 1.100200 2.502600 -0.000000
+v 1.100200 2.502600 0.000000
+v 1.101920 0.213600 1.101920
+v 1.101920 0.213600 -1.101920
+v 1.117130 2.463000 -0.819847
+v 1.117130 2.463000 0.819847
+v 1.118073 2.242575 -1.118073
+v 1.118073 2.242575 1.118073
+v 1.118607 2.482687 -0.820931
+v 1.118607 2.482687 0.820931
+v 1.118749 0.064800 -0.821035
+v 1.118749 0.064800 0.821035
+v 1.121601 2.435437 -0.823129
+v 1.121601 2.435437 0.823129
+v 1.123697 0.553725 -1.531158
+v 1.123697 0.553725 1.531158
+v 1.125061 2.494500 -0.825668
+v 1.125061 2.494500 0.825668
+v 1.126072 1.471200 -1.534395
+v 1.126072 1.471200 1.534395
+v 1.128870 0.031200 -0.187642
+v 1.128870 0.031200 0.187642
+v 1.132992 2.400000 -0.831488
+v 1.132992 2.400000 0.831488
+v 1.134190 2.440800 0.590089
+v 1.134190 2.440800 -0.590089
+v 1.135521 2.498438 -0.833344
+v 1.135521 2.498438 0.833344
+v 1.141680 0.260025 1.141680
+v 1.141680 0.260025 -1.141680
+v 1.142888 0.046875 -0.594614
+v 1.142888 0.046875 0.594614
+v 1.143600 0.031200 0.000000
+v 1.143600 0.031200 0.000000
+v 1.144271 2.474400 -0.384379
+v 1.144271 2.474400 0.384379
+v 1.149016 2.494500 -0.843248
+v 1.149016 2.494500 0.843248
+v 1.151759 1.323225 -1.569396
+v 1.151759 1.323225 1.569396
+v 1.156792 2.400000 -0.601848
+v 1.156792 2.400000 0.601848
+v 1.156956 0.656400 -1.576477
+v 1.156956 0.656400 1.576477
+v 1.164574 2.482687 -0.854666
+v 1.164574 2.482687 0.854666
+v 1.169673 0.084525 -0.858407
+v 1.169673 0.084525 0.858407
+v 1.170080 2.085600 -1.170080
+v 1.170080 2.085600 1.170080
+v 1.171210 1.178400 -1.595900
+v 1.171210 1.178400 1.595900
+v 1.179525 0.771675 -1.607230
+v 1.179525 0.771675 1.607230
+v 1.181225 2.463000 -0.866886
+v 1.181225 2.463000 0.866886
+v 1.183534 1.037175 -1.612693
+v 1.183534 1.037175 1.612693
+v 1.187840 0.900000 -1.618560
+v 1.187840 0.900000 -1.618560
+v 1.187840 0.900000 1.618560
+v 1.187840 0.900000 1.618560
+v 1.189282 2.474400 -0.197684
+v 1.189282 2.474400 0.197684
+v 1.189960 0.316800 -1.189960
+v 1.189960 0.316800 1.189960
+v 1.197997 2.435437 -0.879195
+v 1.197997 2.435437 0.879195
+v 1.198382 0.105600 -0.879477
+v 1.198382 0.105600 0.879477
+v 1.204800 2.474400 0.000000
+v 1.204800 2.474400 -0.000000
+v 1.210564 2.440800 0.406648
+v 1.210564 2.440800 -0.406648
+v 1.211067 0.127575 0.888786
+v 1.211067 0.127575 -0.888786
+v 1.213920 0.150000 -0.890880
+v 1.213920 0.150000 -0.890880
+v 1.213920 0.150000 0.890880
+v 1.213920 0.150000 0.890880
+v 1.213920 2.400000 -0.890880
+v 1.213920 2.400000 0.890880
+v 1.219848 0.046875 -0.409767
+v 1.219848 0.046875 0.409767
+v 1.219958 1.929525 1.219958
+v 1.219958 1.929525 -1.219958
+v 1.225250 0.177075 0.899195
+v 1.225250 0.177075 -0.899195
+v 1.228335 2.463000 -0.639070
+v 1.228335 2.463000 0.639070
+v 1.229959 2.482687 -0.639915
+v 1.229959 2.482687 0.639915
+v 1.230115 0.064800 -0.639996
+v 1.230115 0.064800 0.639996
+v 1.233252 2.435437 -0.641628
+v 1.233252 2.435437 0.641628
+v 1.234688 2.400000 -0.414752
+v 1.234688 2.400000 0.414752
+v 1.237056 2.494500 -0.643607
+v 1.237056 2.494500 0.643607
+v 1.242500 0.384375 -1.242500
+v 1.242500 0.384375 1.242500
+v 1.245776 2.400000 -0.648144
+v 1.245776 2.400000 0.648144
+v 1.248557 2.498438 -0.649591
+v 1.248557 2.498438 0.649591
+v 1.256003 0.213600 0.921764
+v 1.256003 0.213600 -0.921764
+v 1.258183 2.440800 0.209136
+v 1.258183 2.440800 -0.209136
+v 1.263395 2.494500 -0.657311
+v 1.263395 2.494500 0.657311
+v 1.266640 1.774800 -1.266640
+v 1.266640 1.774800 1.266640
+v 1.267832 0.046875 -0.210740
+v 1.267832 0.046875 0.210740
+v 1.274414 2.242575 -0.935276
+v 1.274414 2.242575 0.935276
+v 1.274600 2.440800 0.000000
+v 1.274600 2.440800 0.000000
+v 1.280502 2.482687 -0.666211
+v 1.280502 2.482687 0.666211
+v 1.283256 2.400000 -0.213304
+v 1.283256 2.400000 0.213304
+v 1.284375 0.046875 0.000000
+v 1.284375 0.046875 -0.000000
+v 1.286108 0.084525 -0.669128
+v 1.286108 0.084525 0.669128
+v 1.295040 0.463200 -1.295040
+v 1.295040 0.463200 1.295040
+v 1.298810 2.463000 -0.675736
+v 1.298810 2.463000 0.675736
+v 1.300000 2.400000 0.000000
+v 1.300000 2.400000 -0.000000
+v 1.301322 0.260025 0.955023
+v 1.301322 0.260025 -0.955023
+v 1.309063 1.621875 -1.309063
+v 1.309063 1.621875 1.309063
+v 1.311049 2.463000 -0.440403
+v 1.311049 2.463000 0.440403
+v 1.312782 2.482687 -0.440985
+v 1.312782 2.482687 0.440985
+v 1.312948 0.064800 0.441041
+v 1.312948 0.064800 -0.441041
+v 1.316296 2.435437 -0.442166
+v 1.316296 2.435437 0.442166
+v 1.317252 2.435437 -0.685331
+v 1.317252 2.435437 0.685331
+v 1.317675 0.105600 -0.685551
+v 1.317675 0.105600 0.685551
+v 1.320356 2.494500 -0.443529
+v 1.320356 2.494500 0.443529
+v 1.329664 2.400000 -0.446656
+v 1.329664 2.400000 0.446656
+v 1.331623 0.127575 0.692808
+v 1.331623 0.127575 -0.692808
+v 1.332632 2.498438 -0.447653
+v 1.332632 2.498438 0.447653
+v 1.333693 2.085600 -0.978780
+v 1.333693 2.085600 0.978780
+v 1.334760 0.150000 0.694440
+v 1.334760 0.150000 -0.694440
+v 1.334760 0.150000 -0.694440
+v 1.334760 0.150000 0.694440
+v 1.334760 2.400000 -0.694440
+v 1.334760 2.400000 0.694440
+v 1.343320 0.553725 -1.343320
+v 1.343320 0.553725 1.343320
+v 1.346160 1.471200 -1.346160
+v 1.346160 1.471200 1.346160
+v 1.347218 0.177075 0.700921
+v 1.347218 0.177075 -0.700921
+v 1.348469 2.494500 -0.452973
+v 1.348469 2.494500 0.452973
+v 1.356353 0.316800 -0.995410
+v 1.356353 0.316800 0.995410
+v 1.362620 2.463000 -0.226496
+v 1.362620 2.463000 0.226496
+v 1.364422 2.482687 -0.226795
+v 1.364422 2.482687 0.226795
+v 1.364595 0.064800 -0.226824
+v 1.364595 0.064800 0.226824
+v 1.366728 2.482687 -0.459107
+v 1.366728 2.482687 0.459107
+v 1.368074 2.435437 -0.227403
+v 1.368074 2.435437 0.227403
+v 1.372294 2.494500 -0.228104
+v 1.372294 2.494500 0.228104
+v 1.372712 0.084525 -0.461116
+v 1.372712 0.084525 0.461116
+v 1.376867 1.323225 -1.376868
+v 1.376868 1.323225 1.376867
+v 1.380400 2.463000 0.000000
+v 1.380400 2.463000 -0.000000
+v 1.381032 0.213600 0.718514
+v 1.381032 0.213600 -0.718514
+v 1.381968 2.400000 -0.229712
+v 1.381968 2.400000 0.229712
+v 1.382225 2.482687 0.000000
+v 1.382225 2.482687 0.000000
+v 1.382400 0.064800 0.000000
+v 1.382400 0.064800 0.000000
+v 1.383080 0.656400 -1.383080
+v 1.383080 0.656400 1.383080
+v 1.385053 2.498438 -0.230225
+v 1.385053 2.498438 0.230225
+v 1.385925 2.435437 0.000000
+v 1.385925 2.435437 -0.000000
+v 1.386270 2.463000 -0.465671
+v 1.386270 2.463000 0.465671
+v 1.390200 2.494500 0.000000
+v 1.390200 2.494500 -0.000000
+v 1.390545 1.929525 -1.020503
+v 1.390545 1.929525 1.020503
+v 1.400000 2.400000 0.000000
+v 1.400000 2.400000 0.000000
+v 1.400120 1.178400 -1.400120
+v 1.400120 1.178400 1.400120
+v 1.401276 2.242575 -0.729046
+v 1.401276 2.242575 0.729046
+v 1.401513 2.494500 -0.232961
+v 1.401513 2.494500 0.232961
+v 1.403125 2.498438 0.000000
+v 1.403125 2.498438 0.000000
+v 1.405953 2.435437 -0.472283
+v 1.405953 2.435437 0.472283
+v 1.406405 0.105600 -0.472434
+v 1.406405 0.105600 0.472434
+v 1.410060 0.771675 -1.410060
+v 1.410060 0.771675 1.410060
+v 1.414853 1.037175 -1.414853
+v 1.414853 1.037175 1.414853
+v 1.416240 0.384375 -1.039360
+v 1.416240 0.384375 1.039360
+v 1.419800 2.494500 0.000000
+v 1.419800 2.494500 -0.000000
+v 1.420000 0.900000 -1.420000
+v 1.420000 0.900000 -1.420000
+v 1.420000 0.900000 1.420000
+v 1.420000 0.900000 1.420000
+v 1.420490 2.482687 -0.236115
+v 1.420490 2.482687 0.236115
+v 1.421292 0.127575 0.477435
+v 1.421292 0.127575 -0.477435
+v 1.424640 0.150000 -0.478560
+v 1.424640 0.150000 -0.478560
+v 1.424640 0.150000 0.478560
+v 1.424640 0.150000 0.478560
+v 1.424640 2.400000 -0.478560
+v 1.424640 2.400000 0.478560
+v 1.426709 0.084525 -0.237149
+v 1.426709 0.084525 0.237149
+v 1.430863 0.260025 0.744440
+v 1.430863 0.260025 -0.744440
+v 1.437937 0.177075 0.483027
+v 1.437937 0.177075 -0.483027
+v 1.439025 2.482687 0.000000
+v 1.440800 2.463000 -0.239491
+v 1.440800 2.463000 0.239491
+v 1.443756 1.774800 -1.059553
+v 1.443756 1.774800 1.059553
+v 1.445325 0.084525 0.000000
+v 1.445325 0.084525 0.000000
+v 1.459600 2.463000 0.000000
+v 1.459600 2.463000 -0.000000
+v 1.461258 2.435437 -0.242892
+v 1.461258 2.435437 0.242892
+v 1.461727 0.105600 -0.242970
+v 1.461727 0.105600 0.242970
+v 1.466456 2.085600 -0.762958
+v 1.466456 2.085600 0.762958
+v 1.474028 0.213600 0.495150
+v 1.474028 0.213600 -0.495150
+v 1.476127 0.463200 -1.083310
+v 1.476127 0.463200 1.083310
+v 1.477200 0.127575 0.245542
+v 1.477200 0.127575 -0.245542
+v 1.480325 2.435437 0.000000
+v 1.480325 2.435437 -0.000000
+v 1.480680 0.150000 -0.246120
+v 1.480680 0.150000 0.246120
+v 1.480680 0.150000 0.246120
+v 1.480680 0.150000 -0.246120
+v 1.480680 2.400000 -0.246120
+v 1.480680 2.400000 0.246120
+v 1.480800 0.105600 0.000000
+v 1.480800 0.105600 0.000000
+v 1.491372 0.316800 -0.775921
+v 1.491372 0.316800 0.775921
+v 1.492110 1.621875 -1.095040
+v 1.492110 1.621875 1.095040
+v 1.494500 0.177075 0.248417
+v 1.494500 0.177075 -0.248417
+v 1.495635 2.242575 -0.502408
+v 1.495635 2.242575 0.502408
+v 1.496475 0.127575 0.000000
+v 1.496475 0.127575 0.000000
+v 1.500000 0.150000 0.000000
+v 1.500000 0.150000 0.000000
+v 1.500000 2.400000 0.000000
+v 1.500000 2.400000 0.000000
+v 1.514000 0.177075 -0.000000
+v 1.514000 0.177075 0.000000
+v 1.527214 0.260025 -0.513016
+v 1.527214 0.260025 0.513016
+v 1.528968 1.929525 -0.795481
+v 1.528968 1.929525 0.795481
+v 1.531158 0.553725 -1.123697
+v 1.531158 0.553725 1.123697
+v 1.532010 0.213600 0.254652
+v 1.532010 0.213600 -0.254652
+v 1.534395 1.471200 -1.126072
+v 1.534395 1.471200 1.126072
+v 1.552000 0.213600 0.000000
+v 1.552000 0.213600 0.000000
+v 1.554467 2.242575 -0.258385
+v 1.554467 2.242575 0.258385
+v 1.557220 0.384375 -0.810180
+v 1.557220 0.384375 0.810180
+v 1.565204 2.085600 -0.525778
+v 1.565204 2.085600 0.525778
+v 1.569396 1.323225 -1.151759
+v 1.569396 1.323225 1.151759
+v 1.574750 2.242575 0.000000
+v 1.574750 2.242575 0.000000
+v 1.576477 0.656400 -1.156956
+v 1.576477 0.656400 1.156956
+v 1.587289 0.260025 0.263841
+v 1.587289 0.260025 -0.263841
+v 1.587475 1.774800 -0.825921
+v 1.587475 1.774800 0.825921
+v 1.591798 0.316800 -0.534711
+v 1.591798 0.316800 0.534711
+v 1.595900 1.178400 -1.171210
+v 1.595900 1.178400 1.171210
+v 1.607230 0.771675 -1.179525
+v 1.607230 0.771675 1.179525
+v 1.608000 0.260025 0.000000
+v 1.608000 0.260025 0.000000
+v 1.612693 1.037175 -1.183534
+v 1.612693 1.037175 1.183534
+v 1.618560 0.900000 -1.187840
+v 1.618560 0.900000 -1.187840
+v 1.618560 0.900000 1.187840
+v 1.618560 0.900000 1.187840
+v 1.623068 0.463200 -0.844439
+v 1.623068 0.463200 0.844439
+v 1.626774 2.085600 -0.270404
+v 1.626774 2.085600 0.270404
+v 1.631925 1.929525 -0.548190
+v 1.631925 1.929525 0.548190
+v 1.640643 1.621875 -0.853583
+v 1.640643 1.621875 0.853583
+v 1.648000 2.085600 0.000000
+v 1.648000 2.085600 -0.000000
+v 1.654413 0.316800 -0.274998
+v 1.654413 0.316800 0.274998
+v 1.662080 0.384375 -0.558320
+v 1.662080 0.384375 0.558320
+v 1.676000 0.316800 0.000000
+v 1.676000 0.316800 0.000000
+v 1.683577 0.553725 -0.875920
+v 1.683577 0.553725 0.875920
+v 1.687137 1.471200 -0.877772
+v 1.687137 1.471200 0.877772
+v 1.694372 1.774800 -0.569167
+v 1.694372 1.774800 0.569167
+v 1.696119 1.929525 -0.281930
+v 1.696119 1.929525 0.281930
+v 1.700000 0.600000 0.000000
+v 1.700000 0.600000 0.000000
+v 1.700000 0.623100 0.178200
+v 1.700000 0.623100 -0.178200
+v 1.700000 0.685800 -0.316800
+v 1.700000 0.685800 0.316800
+v 1.700000 0.778200 0.415800
+v 1.700000 0.778200 -0.415800
+v 1.700000 0.890400 -0.475200
+v 1.700000 0.890400 0.475200
+v 1.700000 1.012500 -0.495000
+v 1.700000 1.012500 0.495000
+v 1.700000 1.134600 -0.475200
+v 1.700000 1.134600 0.475200
+v 1.700000 1.246800 0.415800
+v 1.700000 1.246800 -0.415800
+v 1.700000 1.339200 -0.316800
+v 1.700000 1.339200 0.316800
+v 1.700000 1.401900 0.178200
+v 1.700000 1.401900 -0.178200
+v 1.700000 1.425000 0.000000
+v 1.700000 1.425000 0.000000
+v 1.718250 1.929525 0.000000
+v 1.718250 1.929525 0.000000
+v 1.725622 1.323225 -0.897795
+v 1.725622 1.323225 0.897795
+v 1.727460 0.384375 -0.287140
+v 1.727460 0.384375 0.287140
+v 1.732362 0.463200 -0.581929
+v 1.732362 0.463200 0.581929
+v 1.733408 0.656400 -0.901846
+v 1.733408 0.656400 0.901846
+v 1.750000 0.384375 0.000000
+v 1.750000 0.384375 0.000000
+v 1.751120 1.621875 -0.588230
+v 1.751120 1.621875 0.588230
+v 1.754764 1.178400 -0.912957
+v 1.754764 1.178400 0.912957
+v 1.761022 1.774800 -0.292719
+v 1.761022 1.774800 0.292719
+v 1.767222 0.771675 -0.919439
+v 1.767222 0.771675 0.919439
+v 1.773229 1.037175 -0.922564
+v 1.773229 1.037175 0.922564
+v 1.779680 0.900000 -0.925920
+v 1.779680 0.900000 -0.925920
+v 1.779680 0.900000 0.925920
+v 1.779680 0.900000 0.925920
+v 1.784000 1.774800 0.000000
+v 1.784000 1.774800 0.000000
+v 1.796946 0.553725 -0.603624
+v 1.796946 0.553725 0.603624
+v 1.800507 0.463200 -0.299282
+v 1.800507 0.463200 0.299282
+v 1.800745 1.471200 -0.604900
+v 1.800745 1.471200 0.604900
+v 1.820003 1.621875 -0.302523
+v 1.820003 1.621875 0.302522
+v 1.824000 0.463200 0.000000
+v 1.824000 0.463200 0.000000
+v 1.841822 1.323225 -0.618698
+v 1.841822 1.323225 0.618698
+v 1.843750 1.621875 0.000000
+v 1.843750 1.621875 -0.000000
+v 1.850132 0.656400 -0.621490
+v 1.850132 0.656400 0.621490
+v 1.867631 0.553725 -0.310439
+v 1.867631 0.553725 0.310439
+v 1.871580 1.471200 -0.311096
+v 1.871580 1.471200 0.311096
+v 1.872927 1.178400 -0.629147
+v 1.872927 1.178400 0.629147
+v 1.886223 0.771675 -0.633613
+v 1.886223 0.771675 0.633613
+v 1.892000 0.553725 0.000000
+v 1.892000 0.553725 -0.000000
+v 1.892634 1.037175 -0.635767
+v 1.892634 1.037175 0.635767
+v 1.896000 1.471200 0.000000
+v 1.896000 1.471200 0.000000
+v 1.899520 0.900000 -0.638080
+v 1.899520 0.900000 -0.638080
+v 1.899520 0.900000 0.638080
+v 1.899520 0.900000 0.638080
+v 1.914272 1.323225 -0.318192
+v 1.914272 1.323225 0.318192
+v 1.922910 0.656400 -0.319628
+v 1.922910 0.656400 0.319628
+v 1.935900 1.444200 0.000000
+v 1.935900 1.444200 0.000000
+v 1.939250 1.323225 0.000000
+v 1.939250 1.323225 -0.000000
+v 1.939394 1.423221 -0.175100
+v 1.939394 1.423221 0.175100
+v 1.946601 1.178400 -0.323566
+v 1.946601 1.178400 0.323566
+v 1.948000 0.656400 0.000000
+v 1.948000 0.656400 -0.000000
+v 1.948879 1.366278 -0.311290
+v 1.948879 1.366278 0.311290
+v 1.960420 0.771675 -0.325863
+v 1.960420 0.771675 0.325863
+v 1.962857 1.282362 -0.408568
+v 1.962857 1.282362 0.408568
+v 1.967083 1.037175 -0.326970
+v 1.967083 1.037175 0.326970
+v 1.972000 1.178400 0.000000
+v 1.972000 1.178400 0.000000
+v 1.974240 0.900000 -0.328160
+v 1.974240 0.900000 0.328160
+v 1.974240 0.900000 0.328160
+v 1.979830 1.180464 -0.466934
+v 1.979830 1.180464 0.466934
+v 1.986000 0.771675 0.000000
+v 1.986000 0.771675 -0.000000
+v 1.992750 1.037175 0.000000
+v 1.992750 1.037175 0.000000
+v 1.998300 1.069575 -0.486390
+v 1.998300 1.069575 0.486390
+v 2.000000 0.900000 0.000000
+v 2.000000 0.900000 0.000000
+v 2.016770 0.958686 -0.466934
+v 2.016770 0.958686 0.466934
+v 2.033743 0.856788 -0.408568
+v 2.033743 0.856788 0.408568
+v 2.047721 0.772872 0.311290
+v 2.047721 0.772872 -0.311290
+v 2.057206 0.715929 0.175100
+v 2.057206 0.715929 -0.175100
+v 2.060700 0.694950 0.000000
+v 2.060700 0.694950 0.000000
+v 2.111200 1.497600 0.000000
+v 2.111200 1.497600 0.000000
+v 2.116979 1.479120 -0.166687
+v 2.116979 1.479120 0.166687
+v 2.132666 1.428960 -0.296333
+v 2.132666 1.428960 0.296333
+v 2.155782 1.355040 -0.388937
+v 2.155782 1.355040 0.388937
+v 2.183853 1.265280 -0.444499
+v 2.183853 1.265280 0.444499
+v 2.214400 1.167600 -0.463020
+v 2.214400 1.167600 0.463020
+v 2.237300 1.578900 0.000000
+v 2.237300 1.578900 0.000000
+v 2.244457 1.563171 -0.154289
+v 2.244457 1.563171 0.154289
+v 2.244947 1.069920 -0.444499
+v 2.244947 1.069920 0.444499
+v 2.263882 1.520478 -0.274291
+v 2.263882 1.520478 0.274291
+v 2.273018 0.980160 -0.388937
+v 2.273018 0.980160 0.388937
+v 2.292510 1.457562 -0.360007
+v 2.292510 1.457562 0.360007
+v 2.296134 0.906240 -0.296333
+v 2.296134 0.906240 0.296333
+v 2.311821 0.856080 -0.166687
+v 2.311821 0.856080 0.166687
+v 2.317600 0.837600 0.000000
+v 2.317600 0.837600 0.000000
+v 2.325600 1.681800 0.000000
+v 2.325600 1.681800 0.000000
+v 2.327271 1.381164 -0.411437
+v 2.327271 1.381164 0.411437
+v 2.333530 1.668948 -0.139234
+v 2.333530 1.668948 0.139234
+v 2.355053 1.634064 -0.247526
+v 2.355053 1.634064 0.247526
+v 2.365100 1.298025 -0.428580
+v 2.365100 1.298025 0.428580
+v 2.386771 1.582656 -0.324878
+v 2.386771 1.582656 0.324878
+v 2.387500 1.800000 0.000000
+v 2.387500 1.800000 0.000000
+v 2.395900 1.790025 0.122850
+v 2.395900 1.790025 -0.122850
+v 2.402929 1.214886 -0.411437
+v 2.402929 1.214886 0.411437
+v 2.418700 1.762950 -0.218400
+v 2.418700 1.762950 0.218400
+v 2.425286 1.520232 -0.371290
+v 2.425286 1.520232 0.371290
+v 2.434400 1.927200 0.000000
+v 2.434400 1.927200 0.000000
+v 2.437690 1.138488 -0.360007
+v 2.437690 1.138488 0.360007
+v 2.443270 1.919976 0.106466
+v 2.443270 1.919976 -0.106466
+v 2.452300 1.723050 -0.286650
+v 2.452300 1.723050 0.286650
+v 2.466318 1.075572 -0.274291
+v 2.466318 1.075572 0.274291
+v 2.467200 1.452300 -0.386760
+v 2.467200 1.452300 0.386760
+v 2.467347 1.900368 0.189274
+v 2.467347 1.900368 -0.189274
+v 2.477700 2.057100 0.000000
+v 2.477700 2.057100 0.000000
+v 2.485743 1.032879 -0.154289
+v 2.485743 1.032879 0.154289
+v 2.487343 2.052375 -0.091411
+v 2.487343 2.052375 0.091411
+v 2.492900 1.017150 0.000000
+v 2.492900 1.017150 0.000000
+v 2.493100 1.674600 -0.327600
+v 2.493100 1.674600 0.327600
+v 2.502829 1.871472 0.248422
+v 2.502829 1.871472 -0.248422
+v 2.509114 1.384368 -0.371290
+v 2.509114 1.384368 0.371290
+v 2.513518 2.039550 0.162509
+v 2.513518 2.039550 -0.162509
+v 2.528800 2.183400 0.000000
+v 2.537500 1.621875 -0.341250
+v 2.537500 1.621875 0.341250
+v 2.539821 2.180796 -0.079013
+v 2.539821 2.180796 0.079013
+v 2.545914 1.836384 -0.283910
+v 2.545914 1.836384 0.283910
+v 2.547629 1.321944 -0.324878
+v 2.547629 1.321944 0.324878
+v 2.552090 2.020650 -0.213293
+v 2.552090 2.020650 0.213293
+v 2.569734 2.173728 -0.140467
+v 2.569734 2.173728 0.140467
+v 2.579347 1.270536 -0.247526
+v 2.579347 1.270536 0.247526
+v 2.581900 1.569150 -0.327600
+v 2.581900 1.569150 0.327600
+v 2.592800 1.798200 -0.295740
+v 2.592800 1.798200 0.295740
+v 2.598929 1.997700 -0.243763
+v 2.598929 1.997700 0.243763
+v 2.599100 2.299800 0.000000
+v 2.599100 2.299800 0.000000
+v 2.600870 1.235652 -0.139234
+v 2.600870 1.235652 0.139234
+v 2.608800 1.222800 0.000000
+v 2.608800 1.222800 0.000000
+v 2.612406 2.298813 0.070600
+v 2.612406 2.298813 -0.070600
+v 2.613818 2.163312 -0.184363
+v 2.613818 2.163312 0.184363
+v 2.622700 1.520700 -0.286650
+v 2.622700 1.520700 0.286650
+v 2.639686 1.760016 -0.283910
+v 2.639686 1.760016 0.283910
+v 2.648521 2.296134 0.125510
+v 2.648521 2.296134 -0.125510
+v 2.649900 1.972725 0.253920
+v 2.649900 1.972725 -0.253920
+v 2.656300 1.480800 -0.218400
+v 2.656300 1.480800 0.218400
+v 2.667347 2.150664 -0.210701
+v 2.667347 2.150664 0.210701
+v 2.679100 1.453725 0.122850
+v 2.679100 1.453725 -0.122850
+v 2.682771 1.724928 0.248422
+v 2.682771 1.724928 -0.248422
+v 2.687500 1.443750 0.000000
+v 2.687500 1.443750 0.000000
+v 2.700000 2.400000 0.000000
+v 2.700000 2.400000 0.000000
+v 2.700000 2.400000 0.000000
+v 2.700871 1.947750 -0.243763
+v 2.700871 1.947750 0.243763
+v 2.701743 2.292186 0.164732
+v 2.701743 2.292186 -0.164732
+v 2.716800 2.400000 0.067500
+v 2.716800 2.400000 -0.067500
+v 2.716800 2.400000 -0.067500
+v 2.716800 2.400000 0.067500
+v 2.718253 1.696032 0.189274
+v 2.718253 1.696032 -0.189274
+v 2.725600 2.136900 -0.219480
+v 2.725600 2.136900 0.219480
+v 2.729800 2.420250 0.000000
+v 2.742330 1.676424 0.106466
+v 2.742330 1.676424 -0.106466
+v 2.747407 2.420406 -0.066744
+v 2.747407 2.420406 0.066744
+v 2.747710 1.924800 -0.213293
+v 2.747710 1.924800 0.213293
+v 2.751200 1.669200 0.000000
+v 2.751200 1.669200 0.000000
+v 2.758400 2.436000 0.000000
+v 2.762400 2.400000 0.120000
+v 2.762400 2.400000 -0.120000
+v 2.762400 2.400000 -0.120000
+v 2.762400 2.400000 0.120000
+v 2.766370 2.287392 0.188266
+v 2.766370 2.287392 -0.188266
+v 2.776365 2.436302 -0.064692
+v 2.776365 2.436302 0.064692
+v 2.783853 2.123136 -0.210701
+v 2.783853 2.123136 0.210701
+v 2.784600 2.447250 0.000000
+v 2.784600 2.447250 0.000000
+v 2.786282 1.905900 0.162509
+v 2.786282 1.905900 -0.162509
+v 2.795198 2.420829 -0.118656
+v 2.795198 2.420829 0.118656
+v 2.800000 2.400000 0.000000
+v 2.802528 2.447680 -0.061668
+v 2.802528 2.447680 0.061668
+v 2.807200 2.454000 0.000000
+v 2.811200 2.400000 -0.040500
+v 2.811200 2.400000 0.040500
+v 2.812457 1.893075 0.091411
+v 2.812457 1.893075 -0.091411
+v 2.822100 1.888350 0.000000
+v 2.822100 1.888350 0.000000
+v 2.824200 2.420250 0.000000
+v 2.824200 2.420250 0.000000
+v 2.824750 2.454529 -0.057996
+v 2.824750 2.454529 0.057996
+v 2.825000 2.456250 0.000000
+v 2.825000 2.456250 0.000000
+v 2.825126 2.437123 -0.115008
+v 2.825126 2.437123 0.115008
+v 2.829600 2.400000 0.157500
+v 2.829600 2.400000 -0.157500
+v 2.829600 2.400000 -0.157500
+v 2.829600 2.400000 0.157500
+v 2.836672 2.420519 -0.041256
+v 2.836672 2.420519 0.041256
+v 2.836700 2.282175 0.196110
+v 2.836700 2.282175 -0.196110
+v 2.836800 2.454000 0.000000
+v 2.836800 2.454000 0.000000
+v 2.837382 2.110488 -0.184363
+v 2.837382 2.110488 0.184363
+v 2.837600 2.436000 0.000000
+v 2.837600 2.436000 0.000000
+v 2.841400 2.447250 0.000000
+v 2.841400 2.447250 0.000000
+v 2.841600 2.400000 -0.072000
+v 2.841600 2.400000 0.072000
+v 2.841887 2.456841 -0.054000
+v 2.841887 2.456841 0.054000
+v 2.851189 2.448847 -0.109632
+v 2.851189 2.448847 0.109632
+v 2.851331 2.436454 -0.043308
+v 2.851331 2.436454 0.043308
+v 2.852794 2.454605 -0.050004
+v 2.852794 2.454605 0.050004
+v 2.856323 2.447812 -0.046332
+v 2.856323 2.447812 0.046332
+v 2.865626 2.421453 -0.155736
+v 2.865626 2.421453 0.155736
+v 2.870524 2.421250 -0.073344
+v 2.870524 2.421250 0.073344
+v 2.872387 2.455966 -0.103104
+v 2.872387 2.455966 0.103104
+v 2.881466 2.100072 -0.140467
+v 2.881466 2.100072 0.140467
+v 2.886400 2.400000 -0.094500
+v 2.886400 2.400000 0.094500
+v 2.887725 2.458444 -0.096000
+v 2.887725 2.458444 0.096000
+v 2.888602 2.437685 -0.076992
+v 2.888602 2.437685 0.076992
+v 2.896205 2.456246 0.088896
+v 2.896205 2.456246 -0.088896
+v 2.896829 2.449338 -0.082368
+v 2.896829 2.449338 0.082368
+v 2.896986 2.438333 -0.150948
+v 2.896986 2.438333 0.150948
+v 2.907030 2.276958 0.188266
+v 2.907030 2.276958 -0.188266
+v 2.911200 2.400000 -0.180000
+v 2.911200 2.400000 -0.180000
+v 2.911200 2.400000 0.180000
+v 2.911379 2.093004 -0.079013
+v 2.911379 2.093004 0.079013
+v 2.920412 2.422328 -0.096264
+v 2.920412 2.422328 0.096264
+v 2.922400 2.090400 0.000000
+v 2.922899 2.450567 -0.143892
+v 2.922899 2.450567 0.143892
+v 2.940800 2.400000 -0.108000
+v 2.940800 2.400000 0.108000
+v 2.942589 2.458082 -0.135324
+v 2.942589 2.458082 0.135324
+v 2.943526 2.439499 -0.101052
+v 2.943526 2.439499 0.101052
+v 2.951146 2.422210 -0.177984
+v 2.951146 2.422210 0.177984
+v 2.955275 2.460806 -0.126000
+v 2.955275 2.460806 0.126000
+v 2.956523 2.451588 -0.108108
+v 2.956523 2.451588 0.108108
+v 2.960179 2.458666 -0.116676
+v 2.960179 2.458666 0.116676
+v 2.971657 2.272164 0.164732
+v 2.971657 2.272164 -0.164732
+v 2.980990 2.423636 0.110016
+v 2.980990 2.423636 -0.110016
+v 2.984243 2.439802 -0.172512
+v 2.984243 2.439802 0.172512
+v 3.000000 2.400000 -0.187500
+v 3.000000 2.400000 -0.187500
+v 3.000000 2.400000 -0.112500
+v 3.000000 2.400000 0.112500
+v 3.000000 2.400000 0.187500
+v 3.009977 2.452655 -0.164448
+v 3.009977 2.452655 0.164448
+v 3.010221 2.441702 -0.115488
+v 3.010221 2.441702 0.115488
+v 3.024879 2.268216 0.125510
+v 3.024879 2.268216 -0.125510
+v 3.027834 2.460653 -0.154656
+v 3.027834 2.460653 0.154656
+v 3.029007 2.454319 -0.123552
+v 3.029007 2.454319 0.123552
+v 3.037300 2.463675 -0.144000
+v 3.037300 2.463675 0.144000
+v 3.037862 2.461603 0.133344
+v 3.037862 2.461603 -0.133344
+v 3.044212 2.423034 -0.185400
+v 3.044212 2.423034 0.185400
+v 3.046912 2.425059 0.114600
+v 3.046912 2.425059 -0.114600
+v 3.059200 2.400000 -0.108000
+v 3.059200 2.400000 0.108000
+v 3.060994 2.265537 0.070600
+v 3.060994 2.265537 -0.070600
+v 3.074300 2.264550 0.000000
+v 3.074300 2.264550 0.000000
+v 3.079200 2.441400 -0.179700
+v 3.079200 2.441400 0.179700
+v 3.082800 2.444100 -0.120300
+v 3.082800 2.444100 0.120300
+v 3.088800 2.400000 -0.180000
+v 3.088800 2.400000 -0.180000
+v 3.088800 2.400000 0.180000
+v 3.104737 2.454928 -0.171300
+v 3.104738 2.454928 0.171300
+v 3.107887 2.457291 -0.128700
+v 3.107887 2.457291 0.128700
+v 3.112835 2.426483 0.110016
+v 3.112835 2.426483 -0.110016
+v 3.113600 2.400000 -0.094500
+v 3.113600 2.400000 0.094500
+v 3.120600 2.463450 0.161100
+v 3.120600 2.463450 -0.161100
+v 3.122400 2.464800 0.138900
+v 3.122400 2.464800 -0.138900
+v 3.126562 2.466797 -0.150000
+v 3.126562 2.466797 0.150000
+v 3.137279 2.423859 -0.177984
+v 3.137279 2.423859 0.177984
+v 3.155379 2.446498 -0.115488
+v 3.155379 2.446498 0.115488
+v 3.158400 2.400000 -0.072000
+v 3.158400 2.400000 0.072000
+v 3.170400 2.400000 -0.157500
+v 3.170400 2.400000 0.157500
+v 3.170400 2.400000 -0.157500
+v 3.173413 2.427791 -0.096264
+v 3.173413 2.427791 0.096264
+v 3.174157 2.442998 -0.172512
+v 3.174157 2.442998 0.172512
+v 3.186768 2.460263 -0.123552
+v 3.186768 2.460263 0.123552
+v 3.188800 2.400000 -0.040500
+v 3.188800 2.400000 0.040500
+v 3.199498 2.457201 -0.164448
+v 3.199498 2.457201 0.164448
+v 3.200000 2.400000 0.000000
+v 3.206938 2.467997 0.133344
+v 3.206938 2.467997 -0.133344
+v 3.213366 2.466247 -0.154656
+v 3.213366 2.466247 0.154656
+v 3.215825 2.469919 -0.144000
+v 3.215825 2.469919 0.144000
+v 3.222074 2.448701 -0.101052
+v 3.222074 2.448701 0.101052
+v 3.222799 2.424616 -0.155736
+v 3.222799 2.424616 0.155736
+v 3.223301 2.428868 -0.073344
+v 3.223301 2.428868 0.073344
+v 3.237600 2.400000 -0.120000
+v 3.237600 2.400000 0.120000
+v 3.237600 2.400000 -0.120000
+v 3.257153 2.429599 -0.041256
+v 3.257153 2.429599 0.041256
+v 3.259252 2.462994 -0.108108
+v 3.259252 2.462994 0.108108
+v 3.261414 2.444467 -0.150948
+v 3.261414 2.444467 0.150948
+v 3.269625 2.429869 0.000000
+v 3.269625 2.429869 0.000000
+v 3.276998 2.450515 -0.076992
+v 3.276998 2.450515 0.076992
+v 3.283200 2.400000 -0.067500
+v 3.283200 2.400000 0.067500
+v 3.283200 2.400000 -0.067500
+v 3.284621 2.470934 -0.116676
+v 3.284621 2.470934 0.116676
+v 3.286576 2.459289 -0.143892
+v 3.286576 2.459289 0.143892
+v 3.293227 2.425240 -0.118656
+v 3.293227 2.425240 0.118656
+v 3.297850 2.472787 -0.126000
+v 3.297850 2.472788 0.126000
+v 3.298611 2.468818 -0.135324
+v 3.298611 2.468818 0.135324
+v 3.300000 2.400000 0.000000
+v 3.300000 2.400000 0.000000
+v 3.314269 2.451746 -0.043308
+v 3.314269 2.451746 0.043308
+v 3.318946 2.465243 -0.082368
+v 3.318946 2.465243 0.082368
+v 3.328000 2.452200 0.000000
+v 3.328000 2.452200 0.000000
+v 3.333274 2.445677 -0.115008
+v 3.333274 2.445677 0.115008
+v 3.341018 2.425663 -0.066744
+v 3.341018 2.425663 0.066744
+v 3.348595 2.473354 0.088896
+v 3.348595 2.473354 -0.088896
+v 3.358286 2.461009 -0.109632
+v 3.358286 2.461009 0.109632
+v 3.358625 2.425819 0.000000
+v 3.359452 2.466769 -0.046332
+v 3.359452 2.466769 0.046332
+v 3.365400 2.475150 -0.096000
+v 3.365400 2.475150 0.096000
+v 3.368813 2.470934 -0.103104
+v 3.368813 2.470934 0.103104
+v 3.374375 2.467331 0.000000
+v 3.374375 2.467331 0.000000
+v 3.382035 2.446498 -0.064692
+v 3.382035 2.446498 0.064692
+v 3.392006 2.474995 -0.050004
+v 3.392006 2.474995 0.050004
+v 3.400000 2.446800 0.000000
+v 3.406947 2.462176 -0.061668
+v 3.406947 2.462176 0.061668
+v 3.408000 2.475600 0.000000
+v 3.408000 2.475600 0.000000
+v 3.411237 2.476753 -0.054000
+v 3.411237 2.476753 0.054000
+v 3.416450 2.472371 -0.057996
+v 3.416450 2.472371 0.057996
+v 3.424875 2.462606 0.000000
+v 3.428125 2.477344 0.000000
+v 3.428125 2.477344 0.000000
+v 3.434000 2.472900 0.000000
+
+f 2909 2921 2939
+f 2939 2931 2909
+f 2869 2877 2921
+f 2921 2909 2869
+f 2819 2827 2877
+f 2877 2869 2819
+f 2737 2747 2827
+f 2827 2819 2737
+f 2669 2673 2747
+f 2747 2737 2669
+f 2567 2575 2673
+f 2673 2669 2567
+f 2476 2480 2575
+f 2575 2567 2476
+f 2358 2362 2480
+f 2480 2476 2358
+f 2158 2162 2362
+f 2362 2358 2158
+f 1715 1812 2162
+f 2162 2158 1715
+f 2901 2909 2931
+f 2931 2917 2901
+f 2863 2869 2909
+f 2909 2901 2863
+f 2813 2819 2869
+f 2869 2863 2813
+f 2729 2737 2819
+f 2819 2813 2729
+f 2663 2669 2737
+f 2737 2729 2663
+f 2561 2567 2669
+f 2669 2663 2561
+f 2468 2476 2567
+f 2567 2561 2468
+f 2350 2358 2476
+f 2476 2468 2350
+f 2152 2158 2358
+f 2358 2350 2152
+f 1717 1715 2158
+f 2158 2152 1717
+f 2903 2901 2917
+f 2917 2923 2903
+f 2865 2863 2901
+f 2901 2903 2865
+f 2815 2813 2863
+f 2863 2865 2815
+f 2733 2729 2813
+f 2813 2815 2733
+f 2665 2663 2729
+f 2729 2733 2665
+f 2564 2561 2663
+f 2663 2665 2564
+f 2473 2468 2561
+f 2561 2564 2473
+f 2354 2350 2468
+f 2468 2473 2354
+f 2155 2152 2350
+f 2350 2354 2155
+f 1927 1717 2152
+f 2152 2155 1927
+f 2911 2903 2923
+f 2923 2935 2911
+f 2875 2865 2903
+f 2903 2911 2875
+f 2823 2815 2865
+f 2865 2875 2823
+f 2741 2733 2815
+f 2815 2823 2741
+f 2671 2665 2733
+f 2733 2741 2671
+f 2571 2564 2665
+f 2665 2671 2571
+f 2478 2473 2564
+f 2564 2571 2478
+f 2360 2354 2473
+f 2473 2478 2360
+f 2160 2155 2354
+f 2354 2360 2160
+f 1718 1927 2155
+f 2155 2160 1718
+f 2929 2911 2935
+f 2935 2947 2929
+f 2881 2875 2911
+f 2911 2929 2881
+f 2829 2823 2875
+f 2875 2881 2829
+f 2751 2741 2823
+f 2823 2829 2751
+f 2677 2671 2741
+f 2741 2751 2677
+f 2577 2571 2671
+f 2671 2677 2577
+f 2482 2478 2571
+f 2571 2577 2482
+f 2364 2360 2478
+f 2478 2482 2364
+f 2164 2160 2360
+f 2360 2364 2164
+f 1842 1718 2160
+f 2160 2164 1842
+f 2945 2929 2947
+f 2947 2959 2945
+f 2897 2881 2929
+f 2929 2945 2897
+f 2835 2829 2881
+f 2881 2897 2835
+f 2761 2751 2829
+f 2829 2835 2761
+f 2679 2677 2751
+f 2751 2761 2679
+f 2579 2577 2677
+f 2677 2679 2579
+f 2486 2482 2577
+f 2577 2579 2486
+f 2368 2364 2482
+f 2482 2486 2368
+f 2172 2164 2364
+f 2364 2368 2172
+f 1725 1842 2164
+f 2164 2172 1725
+f 2965 2945 2959
+f 2959 2981 2965
+f 2907 2897 2945
+f 2945 2965 2907
+f 2845 2835 2897
+f 2897 2907 2845
+f 2769 2761 2835
+f 2835 2845 2769
+f 2685 2679 2761
+f 2761 2769 2685
+f 2587 2579 2679
+f 2679 2685 2587
+f 2491 2486 2579
+f 2579 2587 2491
+f 2370 2368 2486
+f 2486 2491 2370
+f 2174 2172 2368
+f 2368 2370 2174
+f 1834 1725 2172
+f 2172 2174 1834
+f 2982 2965 2981
+f 2981 2988 2982
+f 2933 2907 2965
+f 2965 2982 2933
+f 2855 2845 2907
+f 2907 2933 2855
+f 2779 2769 2845
+f 2845 2855 2779
+f 2691 2685 2769
+f 2769 2779 2691
+f 2595 2587 2685
+f 2685 2691 2595
+f 2500 2491 2587
+f 2587 2595 2500
+f 2374 2370 2491
+f 2491 2500 2374
+f 2178 2174 2370
+f 2370 2374 2178
+f 1716 1834 2174
+f 2174 2178 1716
+f 2990 2982 2988
+f 2988 3002 2990
+f 2949 2933 2982
+f 2982 2990 2949
+f 2871 2855 2933
+f 2933 2949 2871
+f 2791 2779 2855
+f 2855 2871 2791
+f 2699 2691 2779
+f 2779 2791 2699
+f 2601 2595 2691
+f 2691 2699 2601
+f 2506 2500 2595
+f 2595 2601 2506
+f 2378 2374 2500
+f 2500 2506 2378
+f 2180 2178 2374
+f 2374 2378 2180
+f 1714 1716 2178
+f 2178 2180 1714
+f 3008 2990 3002
+f 3002 3024 3008
+f 2973 2949 2990
+f 2990 3008 2973
+f 2889 2871 2949
+f 2949 2973 2889
+f 2805 2791 2871
+f 2871 2889 2805
+f 2711 2699 2791
+f 2791 2805 2711
+f 2611 2601 2699
+f 2699 2711 2611
+f 2521 2506 2601
+f 2601 2611 2521
+f 2387 2378 2506
+f 2506 2521 2387
+f 2191 2180 2378
+f 2378 2387 2191
+f 1810 1714 2180
+f 2180 2191 1810
+f 1464 1460 1813
+f 1813 1821 1464
+f 1264 1260 1460
+f 1460 1464 1264
+f 1146 1142 1260
+f 1260 1264 1146
+f 1055 1047 1142
+f 1142 1146 1055
+f 953 949 1047
+f 1047 1055 953
+f 885 875 949
+f 949 953 885
+f 803 795 875
+f 875 885 803
+f 753 745 795
+f 795 803 753
+f 713 701 745
+f 745 753 713
+f 691 683 701
+f 701 713 691
+f 1470 1464 1821
+f 1821 1829 1470
+f 1272 1264 1464
+f 1464 1470 1272
+f 1154 1146 1264
+f 1264 1272 1154
+f 1061 1055 1146
+f 1146 1154 1061
+f 959 953 1055
+f 1055 1061 959
+f 893 885 953
+f 953 959 893
+f 809 803 885
+f 885 893 809
+f 759 753 803
+f 803 809 759
+f 721 713 753
+f 753 759 721
+f 705 691 713
+f 713 721 705
+f 1469 1470 1829
+f 1829 1835 1469
+f 1268 1272 1470
+f 1470 1469 1268
+f 1151 1154 1272
+f 1272 1268 1151
+f 1060 1061 1154
+f 1154 1151 1060
+f 957 959 1061
+f 1061 1060 957
+f 889 893 959
+f 959 957 889
+f 807 809 893
+f 893 889 807
+f 757 759 809
+f 809 807 757
+f 719 721 759
+f 759 757 719
+f 699 705 721
+f 721 719 699
+f 1462 1469 1835
+f 1835 1839 1462
+f 1262 1268 1469
+f 1469 1462 1262
+f 1144 1151 1268
+f 1268 1262 1144
+f 1051 1060 1151
+f 1151 1144 1051
+f 951 957 1060
+f 1060 1051 951
+f 881 889 957
+f 957 951 881
+f 799 807 889
+f 889 881 799
+f 747 757 807
+f 807 799 747
+f 711 719 757
+f 757 747 711
+f 687 699 719
+f 719 711 687
+f 1458 1462 1839
+f 1839 1843 1458
+f 1258 1262 1462
+f 1462 1458 1258
+f 1140 1144 1262
+f 1262 1258 1140
+f 1045 1051 1144
+f 1144 1140 1045
+f 945 951 1051
+f 1051 1045 945
+f 871 881 951
+f 951 945 871
+f 793 799 881
+f 881 871 793
+f 741 747 799
+f 799 793 741
+f 693 711 747
+f 747 741 693
+f 675 687 711
+f 711 693 675
+f 1450 1458 1843
+f 1843 1838 1450
+f 1254 1258 1458
+f 1458 1450 1254
+f 1136 1140 1258
+f 1258 1254 1136
+f 1043 1045 1140
+f 1140 1136 1043
+f 943 945 1045
+f 1045 1043 943
+f 861 871 945
+f 945 943 861
+f 787 793 871
+f 871 861 787
+f 725 741 793
+f 793 787 725
+f 677 693 741
+f 741 725 677
+f 663 675 693
+f 693 677 663
+f 1448 1450 1838
+f 1838 1834 1448
+f 1252 1254 1450
+f 1450 1448 1252
+f 1133 1136 1254
+f 1254 1252 1133
+f 1035 1043 1136
+f 1136 1133 1035
+f 937 943 1043
+f 1043 1035 937
+f 853 861 943
+f 943 937 853
+f 777 787 861
+f 861 853 777
+f 715 725 787
+f 787 777 715
+f 657 677 725
+f 725 715 657
+f 642 663 677
+f 677 657 642
+f 1444 1448 1834
+f 1834 1828 1444
+f 1248 1252 1448
+f 1448 1444 1248
+f 1122 1133 1252
+f 1252 1248 1122
+f 1027 1035 1133
+f 1133 1122 1027
+f 931 937 1035
+f 1035 1027 931
+f 843 853 937
+f 937 931 843
+f 767 777 853
+f 853 843 767
+f 689 715 777
+f 777 767 689
+f 640 657 715
+f 715 689 640
+f 634 642 657
+f 657 640 634
+f 1442 1444 1828
+f 1828 1820 1442
+f 1244 1248 1444
+f 1444 1442 1244
+f 1116 1122 1248
+f 1248 1244 1116
+f 1021 1027 1122
+f 1122 1116 1021
+f 923 931 1027
+f 1027 1021 923
+f 831 843 931
+f 931 923 831
+f 751 767 843
+f 843 831 751
+f 673 689 767
+f 767 751 673
+f 632 640 689
+f 689 673 632
+f 620 634 640
+f 640 632 620
+f 1429 1442 1820
+f 1820 1811 1429
+f 1233 1244 1442
+f 1442 1429 1233
+f 1106 1116 1244
+f 1244 1233 1106
+f 1011 1021 1116
+f 1116 1106 1011
+f 911 923 1021
+f 1021 1011 911
+f 817 831 923
+f 923 911 817
+f 733 751 831
+f 831 817 733
+f 649 673 751
+f 751 733 649
+f 614 632 673
+f 673 649 614
+f 597 620 632
+f 632 614 597
+f 714 702 684
+f 684 692 714
+f 754 746 702
+f 702 714 754
+f 804 796 746
+f 746 754 804
+f 886 876 796
+f 796 804 886
+f 954 950 876
+f 876 886 954
+f 1056 1048 950
+f 950 954 1056
+f 1147 1143 1048
+f 1048 1056 1147
+f 1265 1261 1143
+f 1143 1147 1265
+f 1465 1461 1261
+f 1261 1265 1465
+f 1915 1817 1461
+f 1461 1465 1915
+f 722 714 692
+f 692 706 722
+f 760 754 714
+f 714 722 760
+f 810 804 754
+f 754 760 810
+f 894 886 804
+f 804 810 894
+f 960 954 886
+f 886 894 960
+f 1062 1056 954
+f 954 960 1062
+f 1155 1147 1056
+f 1056 1062 1155
+f 1273 1265 1147
+f 1147 1155 1273
+f 1471 1465 1265
+f 1265 1273 1471
+f 1917 1915 1465
+f 1465 1471 1917
+f 720 722 706
+f 706 700 720
+f 758 760 722
+f 722 720 758
+f 808 810 760
+f 760 758 808
+f 890 894 810
+f 810 808 890
+f 958 960 894
+f 894 890 958
+f 1059 1062 960
+f 960 958 1059
+f 1150 1155 1062
+f 1062 1059 1150
+f 1269 1273 1155
+f 1155 1150 1269
+f 1468 1471 1273
+f 1273 1269 1468
+f 1697 1917 1471
+f 1471 1468 1697
+f 712 720 700
+f 700 688 712
+f 748 758 720
+f 720 712 748
+f 800 808 758
+f 758 748 800
+f 882 890 808
+f 808 800 882
+f 952 958 890
+f 890 882 952
+f 1052 1059 958
+f 958 952 1052
+f 1145 1150 1059
+f 1059 1052 1145
+f 1263 1269 1150
+f 1150 1145 1263
+f 1463 1468 1269
+f 1269 1263 1463
+f 1919 1697 1468
+f 1468 1463 1919
+f 694 712 688
+f 688 676 694
+f 742 748 712
+f 712 694 742
+f 794 800 748
+f 748 742 794
+f 872 882 800
+f 800 794 872
+f 946 952 882
+f 882 872 946
+f 1046 1052 952
+f 952 946 1046
+f 1141 1145 1052
+f 1052 1046 1141
+f 1259 1263 1145
+f 1145 1141 1259
+f 1459 1463 1263
+f 1263 1259 1459
+f 1845 1919 1463
+f 1463 1459 1845
+f 678 694 676
+f 676 664 678
+f 726 742 694
+f 694 678 726
+f 788 794 742
+f 742 726 788
+f 862 872 794
+f 794 788 862
+f 944 946 872
+f 872 862 944
+f 1044 1046 946
+f 946 944 1044
+f 1137 1141 1046
+f 1046 1044 1137
+f 1255 1259 1141
+f 1141 1137 1255
+f 1451 1459 1259
+f 1259 1255 1451
+f 1898 1845 1459
+f 1459 1451 1898
+f 658 678 664
+f 664 642 658
+f 716 726 678
+f 678 658 716
+f 778 788 726
+f 726 716 778
+f 854 862 788
+f 788 778 854
+f 938 944 862
+f 862 854 938
+f 1036 1044 944
+f 944 938 1036
+f 1132 1137 1044
+f 1044 1036 1132
+f 1253 1255 1137
+f 1137 1132 1253
+f 1449 1451 1255
+f 1255 1253 1449
+f 1837 1898 1451
+f 1451 1449 1837
+f 641 658 642
+f 642 635 641
+f 690 716 658
+f 658 641 690
+f 768 778 716
+f 716 690 768
+f 844 854 778
+f 778 768 844
+f 932 938 854
+f 854 844 932
+f 1028 1036 938
+f 938 932 1028
+f 1123 1132 1036
+f 1036 1028 1123
+f 1249 1253 1132
+f 1132 1123 1249
+f 1445 1449 1253
+f 1253 1249 1445
+f 1918 1837 1449
+f 1449 1445 1918
+f 633 641 635
+f 635 621 633
+f 674 690 641
+f 641 633 674
+f 752 768 690
+f 690 674 752
+f 832 844 768
+f 768 752 832
+f 924 932 844
+f 844 832 924
+f 1022 1028 932
+f 932 924 1022
+f 1117 1123 1028
+f 1028 1022 1117
+f 1245 1249 1123
+f 1123 1117 1245
+f 1443 1445 1249
+f 1249 1245 1443
+f 1916 1918 1445
+f 1445 1443 1916
+f 616 633 621
+f 621 600 616
+f 654 674 633
+f 633 616 654
+f 737 752 674
+f 674 654 737
+f 822 832 752
+f 752 737 822
+f 914 924 832
+f 832 822 914
+f 1014 1022 924
+f 924 914 1014
+f 1104 1117 1022
+f 1022 1014 1104
+f 1237 1245 1117
+f 1117 1104 1237
+f 1433 1443 1245
+f 1245 1237 1433
+f 1819 1916 1443
+f 1443 1433 1819
+f 2159 2163 1816
+f 1816 1822 2159
+f 2359 2363 2163
+f 2163 2159 2359
+f 2477 2481 2363
+f 2363 2359 2477
+f 2568 2576 2481
+f 2481 2477 2568
+f 2670 2674 2576
+f 2576 2568 2670
+f 2738 2748 2674
+f 2674 2670 2738
+f 2820 2828 2748
+f 2748 2738 2820
+f 2870 2878 2828
+f 2828 2820 2870
+f 2910 2922 2878
+f 2878 2870 2910
+f 2932 2940 2922
+f 2922 2910 2932
+f 2153 2159 1822
+f 1822 1830 2153
+f 2351 2359 2159
+f 2159 2153 2351
+f 2469 2477 2359
+f 2359 2351 2469
+f 2562 2568 2477
+f 2477 2469 2562
+f 2664 2670 2568
+f 2568 2562 2664
+f 2730 2738 2670
+f 2670 2664 2730
+f 2814 2820 2738
+f 2738 2730 2814
+f 2864 2870 2820
+f 2820 2814 2864
+f 2902 2910 2870
+f 2870 2864 2902
+f 2918 2932 2910
+f 2910 2902 2918
+f 2154 2153 1830
+f 1830 1836 2154
+f 2355 2351 2153
+f 2153 2154 2355
+f 2472 2469 2351
+f 2351 2355 2472
+f 2563 2562 2469
+f 2469 2472 2563
+f 2666 2664 2562
+f 2562 2563 2666
+f 2734 2730 2664
+f 2664 2666 2734
+f 2816 2814 2730
+f 2730 2734 2816
+f 2866 2864 2814
+f 2814 2816 2866
+f 2904 2902 2864
+f 2864 2866 2904
+f 2924 2918 2902
+f 2902 2904 2924
+f 2161 2154 1836
+f 1836 1840 2161
+f 2361 2355 2154
+f 2154 2161 2361
+f 2479 2472 2355
+f 2355 2361 2479
+f 2572 2563 2472
+f 2472 2479 2572
+f 2672 2666 2563
+f 2563 2572 2672
+f 2742 2734 2666
+f 2666 2672 2742
+f 2824 2816 2734
+f 2734 2742 2824
+f 2876 2866 2816
+f 2816 2824 2876
+f 2912 2904 2866
+f 2866 2876 2912
+f 2936 2924 2904
+f 2904 2912 2936
+f 2165 2161 1840
+f 1840 1844 2165
+f 2365 2361 2161
+f 2161 2165 2365
+f 2483 2479 2361
+f 2361 2365 2483
+f 2578 2572 2479
+f 2479 2483 2578
+f 2678 2672 2572
+f 2572 2578 2678
+f 2752 2742 2672
+f 2672 2678 2752
+f 2830 2824 2742
+f 2742 2752 2830
+f 2882 2876 2824
+f 2824 2830 2882
+f 2930 2912 2876
+f 2876 2882 2930
+f 2948 2936 2912
+f 2912 2930 2948
+f 2173 2165 1844
+f 1844 1841 2173
+f 2369 2365 2165
+f 2165 2173 2369
+f 2487 2483 2365
+f 2365 2369 2487
+f 2580 2578 2483
+f 2483 2487 2580
+f 2680 2678 2578
+f 2578 2580 2680
+f 2762 2752 2678
+f 2678 2680 2762
+f 2836 2830 2752
+f 2752 2762 2836
+f 2898 2882 2830
+f 2830 2836 2898
+f 2946 2930 2882
+f 2882 2898 2946
+f 2960 2948 2930
+f 2930 2946 2960
+f 2175 2173 1841
+f 1841 1837 2175
+f 2371 2369 2173
+f 2173 2175 2371
+f 2490 2487 2369
+f 2369 2371 2490
+f 2588 2580 2487
+f 2487 2490 2588
+f 2686 2680 2580
+f 2580 2588 2686
+f 2770 2762 2680
+f 2680 2686 2770
+f 2846 2836 2762
+f 2762 2770 2846
+f 2908 2898 2836
+f 2836 2846 2908
+f 2966 2946 2898
+f 2898 2908 2966
+f 2981 2960 2946
+f 2946 2966 2981
+f 2179 2175 1837
+f 1837 1831 2179
+f 2375 2371 2175
+f 2175 2179 2375
+f 2501 2490 2371
+f 2371 2375 2501
+f 2596 2588 2490
+f 2490 2501 2596
+f 2692 2686 2588
+f 2588 2596 2692
+f 2780 2770 2686
+f 2686 2692 2780
+f 2856 2846 2770
+f 2770 2780 2856
+f 2934 2908 2846
+f 2846 2856 2934
+f 2983 2966 2908
+f 2908 2934 2983
+f 2989 2981 2966
+f 2966 2983 2989
+f 2181 2179 1831
+f 1831 1823 2181
+f 2379 2375 2179
+f 2179 2181 2379
+f 2507 2501 2375
+f 2375 2379 2507
+f 2602 2596 2501
+f 2501 2507 2602
+f 2700 2692 2596
+f 2596 2602 2700
+f 2792 2780 2692
+f 2692 2700 2792
+f 2872 2856 2780
+f 2780 2792 2872
+f 2950 2934 2856
+f 2856 2872 2950
+f 2991 2983 2934
+f 2934 2950 2991
+f 3003 2989 2983
+f 2983 2991 3003
+f 2194 2181 1823
+f 1823 1818 2194
+f 2391 2379 2181
+f 2181 2194 2391
+f 2518 2507 2379
+f 2379 2391 2518
+f 2614 2602 2507
+f 2507 2518 2614
+f 2712 2700 2602
+f 2602 2614 2712
+f 2806 2792 2700
+f 2700 2712 2806
+f 2890 2872 2792
+f 2792 2806 2890
+f 2974 2950 2872
+f 2872 2890 2974
+f 3009 2991 2950
+f 2950 2974 3009
+f 3025 3003 2991
+f 2991 3009 3025
+f 3040 3008 3024
+f 3024 3048 3040
+f 3018 2973 3008
+f 3008 3040 3018
+f 2943 2889 2973
+f 2973 3018 2943
+f 2841 2805 2889
+f 2889 2943 2841
+f 2731 2711 2805
+f 2805 2841 2731
+f 2645 2611 2711
+f 2711 2731 2645
+f 2529 2521 2611
+f 2611 2645 2529
+f 2402 2387 2521
+f 2521 2529 2402
+f 2208 2191 2387
+f 2387 2402 2208
+f 1806 1810 2191
+f 2191 2208 1806
+f 3072 3040 3048
+f 3048 3078 3072
+f 3044 3018 3040
+f 3040 3072 3044
+f 2994 2943 3018
+f 3018 3044 2994
+f 2883 2841 2943
+f 2943 2994 2883
+f 2773 2731 2841
+f 2841 2883 2773
+f 2659 2645 2731
+f 2731 2773 2659
+f 2539 2529 2645
+f 2645 2659 2539
+f 2410 2402 2529
+f 2529 2539 2410
+f 2222 2208 2402
+f 2402 2410 2222
+f 1694 1806 2208
+f 2208 2222 1694
+f 3092 3072 3078
+f 3078 3116 3092
+f 3074 3044 3072
+f 3072 3092 3074
+f 3030 2994 3044
+f 3044 3074 3030
+f 2937 2883 2994
+f 2994 3030 2937
+f 2810 2773 2883
+f 2883 2937 2810
+f 2683 2659 2773
+f 2773 2810 2683
+f 2554 2539 2659
+f 2659 2683 2554
+f 2420 2410 2539
+f 2539 2554 2420
+f 2238 2222 2410
+f 2410 2420 2238
+f 1930 1694 2222
+f 2222 2238 1930
+f 3132 3092 3116
+f 3116 3142 3132
+f 3090 3074 3092
+f 3092 3132 3090
+f 3054 3030 3074
+f 3074 3090 3054
+f 2984 2937 3030
+f 3030 3054 2984
+f 2837 2810 2937
+f 2937 2984 2837
+f 2705 2683 2810
+f 2810 2837 2705
+f 2574 2554 2683
+f 2683 2705 2574
+f 2430 2420 2554
+f 2554 2574 2430
+f 2247 2238 2420
+f 2420 2430 2247
+f 1913 1930 2238
+f 2238 2247 1913
+f 3150 3132 3142
+f 3142 3156 3150
+f 3128 3090 3132
+f 3132 3150 3128
+f 3076 3054 3090
+f 3090 3128 3076
+f 3014 2984 3054
+f 3054 3076 3014
+f 2861 2837 2984
+f 2984 3014 2861
+f 2723 2705 2837
+f 2837 2861 2723
+f 2585 2574 2705
+f 2705 2723 2585
+f 2438 2430 2574
+f 2574 2585 2438
+f 2253 2247 2430
+f 2430 2438 2253
+f 1711 1913 2247
+f 2247 2253 1711
+f 3162 3150 3156
+f 3156 3172 3162
+f 3148 3128 3150
+f 3150 3162 3148
+f 3088 3076 3128
+f 3128 3148 3088
+f 3036 3014 3076
+f 3076 3088 3036
+f 2893 2861 3014
+f 3014 3036 2893
+f 2743 2723 2861
+f 2861 2893 2743
+f 2599 2585 2723
+f 2723 2743 2599
+f 2450 2438 2585
+f 2585 2599 2450
+f 2267 2253 2438
+f 2438 2450 2267
+f 1794 1711 2253
+f 2253 2267 1794
+f 3178 3162 3172
+f 3172 3184 3178
+f 3154 3148 3162
+f 3162 3178 3154
+f 3118 3088 3148
+f 3148 3154 3118
+f 3046 3036 3088
+f 3088 3118 3046
+f 2915 2893 3036
+f 3036 3046 2915
+f 2763 2743 2893
+f 2893 2915 2763
+f 2615 2599 2743
+f 2743 2763 2615
+f 2452 2450 2599
+f 2599 2615 2452
+f 2277 2267 2450
+f 2450 2452 2277
+f 1710 1794 2267
+f 2267 2277 1710
+f 3188 3178 3184
+f 3184 3200 3188
+f 3164 3154 3178
+f 3178 3188 3164
+f 3130 3118 3154
+f 3154 3164 3130
+f 3058 3046 3118
+f 3118 3130 3058
+f 2941 2915 3046
+f 3046 3058 2941
+f 2775 2763 2915
+f 2915 2941 2775
+f 2627 2615 2763
+f 2763 2775 2627
+f 2458 2452 2615
+f 2615 2627 2458
+f 2287 2277 2452
+f 2452 2458 2287
+f 1910 1710 2277
+f 2277 2287 1910
+f 3198 3188 3200
+f 3200 3209 3198
+f 3170 3164 3188
+f 3188 3198 3170
+f 3136 3130 3164
+f 3164 3170 3136
+f 3064 3058 3130
+f 3130 3136 3064
+f 2955 2941 3058
+f 3058 3064 2955
+f 2781 2775 2941
+f 2941 2955 2781
+f 2636 2627 2775
+f 2775 2781 2636
+f 2462 2458 2627
+f 2627 2636 2462
+f 2295 2287 2458
+f 2458 2462 2295
+f 1909 1910 2287
+f 2287 2295 1909
+f 3202 3198 3209
+f 3209 3213 3202
+f 3174 3170 3198
+f 3198 3202 3174
+f 3138 3136 3170
+f 3170 3174 3138
+f 3066 3064 3136
+f 3136 3138 3066
+f 2961 2955 3064
+f 3064 3066 2961
+f 2783 2781 2955
+f 2955 2961 2783
+f 2642 2636 2781
+f 2781 2783 2642
+f 2464 2462 2636
+f 2636 2642 2464
+f 2297 2295 2462
+f 2462 2464 2297
+f 1784 1909 2295
+f 2295 2297 1784
+f 1414 1429 1811
+f 1811 1807 1414
+f 1220 1233 1429
+f 1429 1414 1220
+f 1093 1106 1233
+f 1233 1220 1093
+f 977 1011 1106
+f 1106 1093 977
+f 891 911 1011
+f 1011 977 891
+f 781 817 911
+f 911 891 781
+f 679 733 817
+f 817 781 679
+f 604 649 733
+f 733 679 604
+f 571 614 649
+f 649 604 571
+f 561 597 614
+f 614 571 561
+f 1400 1414 1807
+f 1807 1804 1400
+f 1212 1220 1414
+f 1414 1400 1212
+f 1083 1093 1220
+f 1220 1212 1083
+f 963 977 1093
+f 1093 1083 963
+f 849 891 977
+f 977 963 849
+f 739 781 891
+f 891 849 739
+f 628 679 781
+f 781 739 628
+f 565 604 679
+f 679 628 565
+f 530 571 604
+f 604 565 530
+f 524 561 571
+f 571 530 524
+f 1386 1400 1804
+f 1804 1802 1386
+f 1202 1212 1400
+f 1400 1386 1202
+f 1070 1083 1212
+f 1212 1202 1070
+f 939 963 1083
+f 1083 1070 939
+f 814 849 963
+f 963 939 814
+f 685 739 849
+f 849 814 685
+f 585 628 739
+f 739 685 585
+f 528 565 628
+f 628 585 528
+f 510 530 565
+f 565 528 510
+f 508 524 530
+f 530 510 508
+f 1375 1386 1802
+f 1802 1800 1375
+f 1192 1202 1386
+f 1386 1375 1192
+f 1050 1070 1202
+f 1202 1192 1050
+f 917 939 1070
+f 1070 1050 917
+f 785 814 939
+f 939 917 785
+f 638 685 814
+f 814 785 638
+f 553 585 685
+f 685 638 553
+f 512 528 585
+f 585 553 512
+f 492 510 528
+f 528 512 492
+f 482 508 510
+f 510 492 482
+f 1369 1375 1800
+f 1800 1798 1369
+f 1184 1192 1375
+f 1375 1369 1184
+f 1037 1050 1192
+f 1192 1184 1037
+f 899 917 1050
+f 1050 1037 899
+f 761 785 917
+f 917 899 761
+f 608 638 785
+f 785 761 608
+f 526 553 638
+f 638 608 526
+f 496 512 553
+f 553 526 496
+f 454 492 512
+f 512 496 454
+f 448 482 492
+f 492 454 448
+f 1355 1369 1798
+f 1798 1795 1355
+f 1172 1184 1369
+f 1369 1355 1172
+f 1023 1037 1184
+f 1184 1172 1023
+f 879 899 1037
+f 1037 1023 879
+f 729 761 899
+f 899 879 729
+f 579 608 761
+f 761 729 579
+f 514 526 608
+f 608 579 514
+f 457 496 526
+f 526 514 457
+f 442 454 496
+f 496 457 442
+f 432 448 454
+f 454 442 432
+f 1345 1355 1795
+f 1795 1792 1345
+f 1170 1172 1355
+f 1355 1345 1170
+f 1007 1023 1172
+f 1172 1170 1007
+f 859 879 1023
+f 1023 1007 859
+f 707 729 879
+f 879 859 707
+f 563 579 729
+f 729 707 563
+f 506 514 579
+f 579 563 506
+f 450 457 514
+f 514 506 450
+f 420 442 457
+f 457 450 420
+f 412 432 442
+f 442 420 412
+f 1335 1345 1792
+f 1792 1790 1335
+f 1164 1170 1345
+f 1345 1335 1164
+f 995 1007 1170
+f 1170 1164 995
+f 847 859 1007
+f 1007 995 847
+f 681 707 859
+f 859 847 681
+f 547 563 707
+f 707 681 547
+f 494 506 563
+f 563 547 494
+f 440 450 506
+f 506 494 440
+f 410 420 450
+f 450 440 410
+f 398 412 420
+f 420 410 398
+f 1327 1335 1790
+f 1790 1788 1327
+f 1160 1164 1335
+f 1335 1327 1160
+f 988 995 1164
+f 1164 1160 988
+f 841 847 995
+f 995 988 841
+f 667 681 847
+f 847 841 667
+f 538 547 681
+f 681 667 538
+f 488 494 547
+f 547 538 488
+f 434 440 494
+f 494 488 434
+f 400 410 440
+f 440 434 400
+f 381 398 410
+f 410 400 381
+f 1324 1327 1788
+f 1788 1785 1324
+f 1156 1160 1327
+f 1327 1324 1156
+f 979 988 1160
+f 1160 1156 979
+f 837 841 988
+f 988 979 837
+f 659 667 841
+f 841 837 659
+f 534 538 667
+f 667 659 534
+f 484 488 538
+f 538 534 484
+f 428 434 488
+f 488 484 428
+f 395 400 434
+f 434 428 395
+f 374 381 400
+f 400 395 374
+f 572 616 600
+f 600 562 572
+f 605 654 616
+f 616 572 605
+f 680 737 654
+f 654 605 680
+f 782 822 737
+f 737 680 782
+f 892 914 822
+f 822 782 892
+f 978 1014 914
+f 914 892 978
+f 1094 1104 1014
+f 1014 978 1094
+f 1221 1237 1104
+f 1104 1094 1221
+f 1415 1433 1237
+f 1237 1221 1415
+f 1809 1819 1433
+f 1433 1415 1809
+f 531 572 562
+f 562 525 531
+f 566 605 572
+f 572 531 566
+f 629 680 605
+f 605 566 629
+f 740 782 680
+f 680 629 740
+f 850 892 782
+f 782 740 850
+f 964 978 892
+f 892 850 964
+f 1084 1094 978
+f 978 964 1084
+f 1213 1221 1094
+f 1094 1084 1213
+f 1401 1415 1221
+f 1221 1213 1401
+f 1931 1809 1415
+f 1415 1401 1931
+f 511 531 525
+f 525 509 511
+f 529 566 531
+f 531 511 529
+f 586 629 566
+f 566 529 586
+f 686 740 629
+f 629 586 686
+f 813 850 740
+f 740 686 813
+f 940 964 850
+f 850 813 940
+f 1069 1084 964
+f 964 940 1069
+f 1203 1213 1084
+f 1084 1069 1203
+f 1385 1401 1213
+f 1213 1203 1385
+f 1693 1931 1401
+f 1401 1385 1693
+f 493 511 509
+f 509 483 493
+f 513 529 511
+f 511 493 513
+f 554 586 529
+f 529 513 554
+f 639 686 586
+f 586 554 639
+f 786 813 686
+f 686 639 786
+f 918 940 813
+f 813 786 918
+f 1049 1069 940
+f 940 918 1049
+f 1193 1203 1069
+f 1069 1049 1193
+f 1376 1385 1203
+f 1203 1193 1376
+f 1712 1693 1385
+f 1385 1376 1712
+f 455 493 483
+f 483 449 455
+f 497 513 493
+f 493 455 497
+f 527 554 513
+f 513 497 527
+f 609 639 554
+f 554 527 609
+f 762 786 639
+f 639 609 762
+f 900 918 786
+f 786 762 900
+f 1038 1049 918
+f 918 900 1038
+f 1185 1193 1049
+f 1049 1038 1185
+f 1370 1376 1193
+f 1193 1185 1370
+f 1912 1712 1376
+f 1376 1370 1912
+f 443 455 449
+f 449 433 443
+f 458 497 455
+f 455 443 458
+f 515 527 497
+f 497 458 515
+f 580 609 527
+f 527 515 580
+f 730 762 609
+f 609 580 730
+f 880 900 762
+f 762 730 880
+f 1024 1038 900
+f 900 880 1024
+f 1173 1185 1038
+f 1038 1024 1173
+f 1356 1370 1185
+f 1185 1173 1356
+f 1797 1912 1370
+f 1370 1356 1797
+f 421 443 433
+f 433 413 421
+f 451 458 443
+f 443 421 451
+f 507 515 458
+f 458 451 507
+f 564 580 515
+f 515 507 564
+f 708 730 580
+f 580 564 708
+f 860 880 730
+f 730 708 860
+f 1008 1024 880
+f 880 860 1008
+f 1171 1173 1024
+f 1024 1008 1171
+f 1346 1356 1173
+f 1173 1171 1346
+f 1911 1797 1356
+f 1356 1346 1911
+f 411 421 413
+f 413 399 411
+f 441 451 421
+f 421 411 441
+f 495 507 451
+f 451 441 495
+f 548 564 507
+f 507 495 548
+f 682 708 564
+f 564 548 682
+f 848 860 708
+f 708 682 848
+f 996 1008 860
+f 860 848 996
+f 1165 1171 1008
+f 1008 996 1165
+f 1336 1346 1171
+f 1171 1165 1336
+f 1709 1911 1346
+f 1346 1336 1709
+f 401 411 399
+f 399 382 401
+f 435 441 411
+f 411 401 435
+f 489 495 441
+f 441 435 489
+f 539 548 495
+f 495 489 539
+f 668 682 548
+f 548 539 668
+f 842 848 682
+f 682 668 842
+f 987 996 848
+f 848 842 987
+f 1161 1165 996
+f 996 987 1161
+f 1328 1336 1165
+f 1165 1161 1328
+f 1708 1709 1336
+f 1336 1328 1708
+f 397 401 382
+f 382 376 397
+f 431 435 401
+f 401 397 431
+f 487 489 435
+f 435 431 487
+f 537 539 489
+f 489 487 537
+f 662 668 539
+f 539 537 662
+f 840 842 668
+f 668 662 840
+f 981 987 842
+f 842 840 981
+f 1159 1161 987
+f 987 981 1159
+f 1326 1328 1161
+f 1161 1159 1326
+f 1787 1708 1328
+f 1328 1326 1787
+f 2209 2194 1818
+f 1818 1808 2209
+f 2403 2391 2194
+f 2194 2209 2403
+f 2530 2518 2391
+f 2391 2403 2530
+f 2646 2614 2518
+f 2518 2530 2646
+f 2732 2712 2614
+f 2614 2646 2732
+f 2842 2806 2712
+f 2712 2732 2842
+f 2944 2890 2806
+f 2806 2842 2944
+f 3019 2974 2890
+f 2890 2944 3019
+f 3041 3009 2974
+f 2974 3019 3041
+f 3049 3025 3009
+f 3009 3041 3049
+f 2223 2209 1808
+f 1808 1805 2223
+f 2411 2403 2209
+f 2209 2223 2411
+f 2540 2530 2403
+f 2403 2411 2540
+f 2660 2646 2530
+f 2530 2540 2660
+f 2774 2732 2646
+f 2646 2660 2774
+f 2884 2842 2732
+f 2732 2774 2884
+f 2995 2944 2842
+f 2842 2884 2995
+f 3045 3019 2944
+f 2944 2995 3045
+f 3073 3041 3019
+f 3019 3045 3073
+f 3079 3049 3041
+f 3041 3073 3079
+f 2237 2223 1805
+f 1805 1803 2237
+f 2421 2411 2223
+f 2223 2237 2421
+f 2553 2540 2411
+f 2411 2421 2553
+f 2684 2660 2540
+f 2540 2553 2684
+f 2809 2774 2660
+f 2660 2684 2809
+f 2938 2884 2774
+f 2774 2809 2938
+f 3031 2995 2884
+f 2884 2938 3031
+f 3075 3045 2995
+f 2995 3031 3075
+f 3093 3073 3045
+f 3045 3075 3093
+f 3117 3079 3073
+f 3073 3093 3117
+f 2248 2237 1803
+f 1803 1801 2248
+f 2431 2421 2237
+f 2237 2248 2431
+f 2573 2553 2421
+f 2421 2431 2573
+f 2706 2684 2553
+f 2553 2573 2706
+f 2838 2809 2684
+f 2684 2706 2838
+f 2985 2938 2809
+f 2809 2838 2985
+f 3055 3031 2938
+f 2938 2985 3055
+f 3091 3075 3031
+f 3031 3055 3091
+f 3133 3093 3075
+f 3075 3091 3133
+f 3143 3117 3093
+f 3093 3133 3143
+f 2254 2248 1801
+f 1801 1799 2254
+f 2439 2431 2248
+f 2248 2254 2439
+f 2586 2573 2431
+f 2431 2439 2586
+f 2724 2706 2573
+f 2573 2586 2724
+f 2862 2838 2706
+f 2706 2724 2862
+f 3015 2985 2838
+f 2838 2862 3015
+f 3077 3055 2985
+f 2985 3015 3077
+f 3129 3091 3055
+f 3055 3077 3129
+f 3151 3133 3091
+f 3091 3129 3151
+f 3157 3143 3133
+f 3133 3151 3157
+f 2268 2254 1799
+f 1799 1796 2268
+f 2451 2439 2254
+f 2254 2268 2451
+f 2600 2586 2439
+f 2439 2451 2600
+f 2744 2724 2586
+f 2586 2600 2744
+f 2894 2862 2724
+f 2724 2744 2894
+f 3037 3015 2862
+f 2862 2894 3037
+f 3089 3077 3015
+f 3015 3037 3089
+f 3149 3129 3077
+f 3077 3089 3149
+f 3163 3151 3129
+f 3129 3149 3163
+f 3173 3157 3151
+f 3151 3163 3173
+f 2278 2268 1796
+f 1796 1793 2278
+f 2453 2451 2268
+f 2268 2278 2453
+f 2616 2600 2451
+f 2451 2453 2616
+f 2764 2744 2600
+f 2600 2616 2764
+f 2916 2894 2744
+f 2744 2764 2916
+f 3047 3037 2894
+f 2894 2916 3047
+f 3119 3089 3037
+f 3037 3047 3119
+f 3155 3149 3089
+f 3089 3119 3155
+f 3179 3163 3149
+f 3149 3155 3179
+f 3185 3173 3163
+f 3163 3179 3185
+f 2288 2278 1793
+f 1793 1791 2288
+f 2459 2453 2278
+f 2278 2288 2459
+f 2628 2616 2453
+f 2453 2459 2628
+f 2776 2764 2616
+f 2616 2628 2776
+f 2942 2916 2764
+f 2764 2776 2942
+f 3059 3047 2916
+f 2916 2942 3059
+f 3131 3119 3047
+f 3047 3059 3131
+f 3165 3155 3119
+f 3119 3131 3165
+f 3189 3179 3155
+f 3155 3165 3189
+f 3201 3185 3179
+f 3179 3189 3201
+f 2296 2288 1791
+f 1791 1789 2296
+f 2463 2459 2288
+f 2288 2296 2463
+f 2635 2628 2459
+f 2459 2463 2635
+f 2782 2776 2628
+f 2628 2635 2782
+f 2956 2942 2776
+f 2776 2782 2956
+f 3065 3059 2942
+f 2942 2956 3065
+f 3137 3131 3059
+f 3059 3065 3137
+f 3171 3165 3131
+f 3131 3137 3171
+f 3199 3189 3165
+f 3165 3171 3199
+f 3210 3201 3189
+f 3189 3199 3210
+f 2299 2296 1789
+f 1789 1786 2299
+f 2467 2463 2296
+f 2296 2299 2467
+f 2644 2635 2463
+f 2463 2467 2644
+f 2786 2782 2635
+f 2635 2644 2786
+f 2964 2956 2782
+f 2782 2786 2964
+f 3069 3065 2956
+f 2956 2964 3069
+f 3141 3137 3065
+f 3065 3069 3141
+f 3177 3171 3137
+f 3137 3141 3177
+f 3204 3199 3171
+f 3171 3177 3204
+f 3214 3210 3199
+f 3199 3204 3214
+f 3194 3202 3213
+f 3213 3207 3194
+f 3166 3175 3202
+f 3202 3194 3166
+f 3134 3139 3175
+f 3175 3166 3134
+f 3060 3067 3139
+f 3139 3134 3060
+f 2953 2962 3067
+f 3067 3060 2953
+f 2777 2784 2962
+f 2962 2953 2777
+f 2629 2643 2784
+f 2784 2777 2629
+f 2460 2465 2643
+f 2643 2629 2460
+f 2293 2298 2465
+f 2465 2460 2293
+f 1696 1785 2298
+f 2298 2293 1696
+f 3180 3194 3207
+f 3207 3190 3180
+f 3158 3166 3194
+f 3194 3180 3158
+f 3124 3134 3166
+f 3166 3158 3124
+f 3050 3060 3134
+f 3134 3124 3050
+f 2927 2953 3060
+f 3060 3050 2927
+f 2767 2777 2953
+f 2953 2927 2767
+f 2619 2629 2777
+f 2777 2767 2619
+f 2454 2460 2629
+f 2629 2619 2454
+f 2283 2293 2460
+f 2460 2454 2283
+f 1695 1696 2293
+f 2293 2283 1695
+f 3160 3180 3190
+f 3190 3168 3160
+f 3144 3158 3180
+f 3180 3160 3144
+f 3086 3124 3158
+f 3158 3144 3086
+f 3032 3050 3124
+f 3124 3086 3032
+f 2891 2927 3050
+f 3050 3032 2891
+f 2739 2767 2927
+f 2927 2891 2739
+f 2597 2619 2767
+f 2767 2739 2597
+f 2448 2454 2619
+f 2619 2597 2448
+f 2265 2283 2454
+f 2454 2448 2265
+f 1707 1695 2283
+f 2283 2265 1707
+f 3146 3160 3168
+f 3168 3152 3146
+f 3122 3144 3160
+f 3160 3146 3122
+f 3070 3086 3144
+f 3144 3122 3070
+f 2998 3032 3086
+f 3086 3070 2998
+f 2853 2891 3032
+f 3032 2998 2853
+f 2717 2739 2891
+f 2891 2853 2717
+f 2582 2597 2739
+f 2739 2717 2582
+f 2434 2448 2597
+f 2597 2582 2434
+f 2251 2265 2448
+f 2448 2434 2251
+f 1907 1707 2265
+f 2265 2251 1907
+f 3120 3146 3152
+f 3152 3126 3120
+f 3082 3122 3146
+f 3146 3120 3082
+f 3042 3070 3122
+f 3122 3082 3042
+f 2957 2998 3070
+f 3070 3042 2957
+f 2825 2853 2998
+f 2998 2957 2825
+f 2693 2717 2853
+f 2853 2825 2693
+f 2556 2582 2717
+f 2717 2693 2556
+f 2424 2434 2582
+f 2582 2556 2424
+f 2239 2251 2434
+f 2434 2424 2239
+f 1906 1907 2251
+f 2251 2239 1906
+f 3080 3120 3126
+f 3126 3084 3080
+f 3056 3082 3120
+f 3120 3080 3056
+f 3012 3042 3082
+f 3082 3056 3012
+f 2899 2957 3042
+f 3042 3012 2899
+f 2789 2825 2957
+f 2957 2899 2789
+f 2675 2693 2825
+f 2825 2789 2675
+f 2545 2556 2693
+f 2693 2675 2545
+f 2416 2424 2556
+f 2556 2545 2416
+f 2228 2239 2424
+f 2424 2416 2228
+f 1770 1906 2239
+f 2239 2228 1770
+f 3053 3080 3084
+f 3084 3062 3053
+f 3028 3056 3080
+f 3080 3053 3028
+f 2978 3012 3056
+f 3056 3028 2978
+f 2860 2899 3012
+f 3012 2978 2860
+f 2754 2789 2899
+f 2899 2860 2754
+f 2652 2675 2789
+f 2789 2754 2652
+f 2534 2545 2675
+f 2675 2652 2534
+f 2406 2416 2545
+f 2545 2534 2406
+f 2217 2228 2416
+f 2416 2406 2217
+f 1929 1770 2228
+f 2228 2217 1929
+f 3035 3053 3062
+f 3062 3039 3035
+f 2997 3028 3053
+f 3053 3035 2997
+f 2920 2978 3028
+f 3028 2997 2920
+f 2832 2860 2978
+f 2978 2920 2832
+f 2728 2754 2860
+f 2860 2832 2728
+f 2634 2652 2754
+f 2754 2728 2634
+f 2528 2534 2652
+f 2652 2634 2528
+f 2396 2406 2534
+f 2534 2528 2396
+f 2202 2217 2406
+f 2406 2396 2202
+f 1765 1929 2217
+f 2217 2202 1765
+f 3017 3035 3039
+f 3039 3027 3017
+f 2980 2997 3035
+f 3035 3017 2980
+f 2896 2920 2997
+f 2997 2980 2896
+f 2812 2832 2920
+f 2920 2896 2812
+f 2715 2728 2832
+f 2832 2812 2715
+f 2618 2634 2728
+f 2728 2715 2618
+f 2523 2528 2634
+f 2634 2618 2523
+f 2392 2396 2528
+f 2528 2523 2392
+f 2196 2202 2396
+f 2396 2392 2196
+f 1724 1765 2202
+f 2202 2196 1724
+f 3007 3017 3027
+f 3027 3023 3007
+f 2969 2980 3017
+f 3017 3007 2969
+f 2887 2896 2980
+f 2980 2969 2887
+f 2802 2812 2896
+f 2896 2887 2802
+f 2709 2715 2812
+f 2812 2802 2709
+f 2609 2618 2715
+f 2715 2709 2609
+f 2519 2523 2618
+f 2618 2609 2519
+f 2386 2392 2523
+f 2523 2519 2386
+f 2190 2196 2392
+f 2392 2386 2190
+f 1759 1724 2196
+f 2196 2190 1759
+f 1329 1324 1785
+f 1785 1782 1329
+f 1162 1157 1324
+f 1324 1329 1162
+f 993 982 1157
+f 1157 1162 993
+f 845 838 982
+f 982 993 845
+f 669 660 838
+f 838 845 669
+f 542 535 660
+f 660 669 542
+f 490 485 535
+f 535 542 490
+f 438 429 485
+f 485 490 438
+f 404 396 429
+f 429 438 404
+f 387 376 396
+f 396 404 387
+f 1339 1329 1782
+f 1782 1780 1339
+f 1168 1162 1329
+f 1329 1339 1168
+f 1003 993 1162
+f 1162 1168 1003
+f 855 845 993
+f 993 1003 855
+f 695 669 845
+f 845 855 695
+f 559 542 669
+f 669 695 559
+f 500 490 542
+f 542 559 500
+f 446 438 490
+f 490 500 446
+f 416 404 438
+f 438 446 416
+f 408 387 404
+f 404 416 408
+f 1357 1339 1780
+f 1780 1778 1357
+f 1174 1168 1339
+f 1339 1357 1174
+f 1025 1003 1168
+f 1168 1174 1025
+f 883 855 1003
+f 1003 1025 883
+f 731 695 855
+f 855 883 731
+f 583 559 695
+f 695 731 583
+f 516 500 559
+f 559 583 516
+f 467 446 500
+f 500 516 467
+f 444 416 446
+f 446 467 444
+f 436 408 416
+f 416 444 436
+f 1371 1357 1778
+f 1778 1776 1371
+f 1188 1174 1357
+f 1357 1371 1188
+f 1042 1025 1174
+f 1174 1188 1042
+f 905 883 1025
+f 1025 1042 905
+f 769 731 883
+f 883 905 769
+f 624 583 731
+f 731 769 624
+f 532 516 583
+f 583 624 532
+f 502 467 516
+f 516 532 502
+f 459 444 467
+f 467 502 459
+f 452 436 444
+f 444 459 452
+f 1383 1371 1776
+f 1776 1774 1383
+f 1198 1188 1371
+f 1371 1383 1198
+f 1068 1042 1188
+f 1188 1198 1068
+f 929 905 1042
+f 1042 1068 929
+f 797 769 905
+f 905 929 797
+f 665 624 769
+f 769 797 665
+f 569 532 624
+f 624 665 569
+f 520 502 532
+f 532 569 520
+f 504 459 502
+f 502 520 504
+f 498 452 459
+f 459 504 498
+f 1394 1383 1774
+f 1774 1771 1394
+f 1206 1198 1383
+f 1383 1394 1206
+f 1077 1068 1198
+f 1198 1206 1077
+f 947 929 1068
+f 1068 1077 947
+f 833 797 929
+f 929 947 833
+f 723 665 797
+f 797 833 723
+f 610 569 665
+f 665 723 610
+f 549 520 569
+f 569 610 549
+f 522 504 520
+f 520 549 522
+f 518 498 504
+f 504 522 518
+f 1407 1394 1771
+f 1771 1768 1407
+f 1216 1206 1394
+f 1394 1407 1216
+f 1090 1077 1206
+f 1206 1216 1090
+f 972 947 1077
+f 1077 1090 972
+f 870 833 947
+f 947 972 870
+f 764 723 833
+f 833 870 764
+f 646 610 723
+f 723 764 646
+f 587 549 610
+f 610 646 587
+f 556 522 549
+f 549 587 556
+f 540 518 522
+f 522 556 540
+f 1420 1407 1768
+f 1768 1764 1420
+f 1226 1216 1407
+f 1407 1420 1226
+f 1096 1090 1216
+f 1216 1226 1096
+f 990 972 1090
+f 1090 1096 990
+f 896 870 972
+f 972 990 896
+f 792 764 870
+f 870 896 792
+f 704 646 764
+f 764 792 704
+f 627 587 646
+f 646 704 627
+f 582 556 587
+f 587 627 582
+f 574 540 556
+f 556 582 574
+f 1426 1420 1764
+f 1764 1762 1426
+f 1230 1226 1420
+f 1420 1426 1230
+f 1101 1096 1226
+f 1226 1230 1101
+f 1006 990 1096
+f 1096 1101 1006
+f 907 896 990
+f 990 1006 907
+f 812 792 896
+f 896 907 812
+f 728 704 792
+f 792 812 728
+f 644 627 704
+f 704 728 644
+f 607 582 627
+f 627 644 607
+f 592 574 582
+f 582 607 592
+f 1430 1426 1762
+f 1762 1758 1430
+f 1234 1230 1426
+f 1426 1430 1234
+f 1107 1101 1230
+f 1230 1234 1107
+f 1012 1006 1101
+f 1101 1107 1012
+f 912 907 1006
+f 1006 1012 912
+f 819 812 907
+f 907 912 819
+f 738 728 812
+f 812 819 738
+f 651 644 728
+f 728 738 651
+f 618 607 644
+f 644 651 618
+f 601 592 607
+f 607 618 601
+f 405 397 376
+f 376 388 405
+f 439 430 397
+f 397 405 439
+f 491 486 430
+f 430 439 491
+f 543 536 486
+f 486 491 543
+f 670 661 536
+f 536 543 670
+f 846 839 661
+f 661 670 846
+f 994 980 839
+f 839 846 994
+f 1163 1158 980
+f 980 994 1163
+f 1330 1325 1158
+f 1158 1163 1330
+f 1926 1786 1325
+f 1325 1330 1926
+f 417 405 388
+f 388 409 417
+f 447 439 405
+f 405 417 447
+f 501 491 439
+f 439 447 501
+f 560 543 491
+f 491 501 560
+f 696 670 543
+f 543 560 696
+f 856 846 670
+f 670 696 856
+f 1004 994 846
+f 846 856 1004
+f 1169 1163 994
+f 994 1004 1169
+f 1340 1330 1163
+f 1163 1169 1340
+f 1925 1926 1330
+f 1330 1340 1925
+f 445 417 409
+f 409 437 445
+f 468 447 417
+f 417 445 468
+f 517 501 447
+f 447 468 517
+f 584 560 501
+f 501 517 584
+f 732 696 560
+f 560 584 732
+f 884 856 696
+f 696 732 884
+f 1026 1004 856
+f 856 884 1026
+f 1175 1169 1004
+f 1004 1026 1175
+f 1358 1340 1169
+f 1169 1175 1358
+f 1908 1925 1340
+f 1340 1358 1908
+f 460 445 437
+f 437 453 460
+f 503 468 445
+f 445 460 503
+f 533 517 468
+f 468 503 533
+f 625 584 517
+f 517 533 625
+f 770 732 584
+f 584 625 770
+f 906 884 732
+f 732 770 906
+f 1041 1026 884
+f 884 906 1041
+f 1189 1175 1026
+f 1026 1041 1189
+f 1372 1358 1175
+f 1175 1189 1372
+f 1706 1908 1358
+f 1358 1372 1706
+f 505 460 453
+f 453 499 505
+f 521 503 460
+f 460 505 521
+f 570 533 503
+f 503 521 570
+f 666 625 533
+f 533 570 666
+f 798 770 625
+f 625 666 798
+f 930 906 770
+f 770 798 930
+f 1067 1041 906
+f 906 930 1067
+f 1199 1189 1041
+f 1041 1067 1199
+f 1384 1372 1189
+f 1189 1199 1384
+f 1705 1706 1372
+f 1372 1384 1705
+f 523 505 499
+f 499 519 523
+f 550 521 505
+f 505 523 550
+f 611 570 521
+f 521 550 611
+f 724 666 570
+f 570 611 724
+f 834 798 666
+f 666 724 834
+f 948 930 798
+f 798 834 948
+f 1078 1067 930
+f 930 948 1078
+f 1207 1199 1067
+f 1067 1078 1207
+f 1395 1384 1199
+f 1199 1207 1395
+f 1773 1705 1384
+f 1384 1395 1773
+f 555 523 519
+f 519 541 555
+f 588 550 523
+f 523 555 588
+f 645 611 550
+f 550 588 645
+f 763 724 611
+f 611 645 763
+f 869 834 724
+f 724 763 869
+f 971 948 834
+f 834 869 971
+f 1089 1078 948
+f 948 971 1089
+f 1217 1207 1078
+f 1078 1089 1217
+f 1406 1395 1207
+f 1207 1217 1406
+f 1692 1773 1395
+f 1395 1406 1692
+f 581 555 541
+f 541 573 581
+f 626 588 555
+f 555 581 626
+f 703 645 588
+f 588 626 703
+f 791 763 645
+f 645 703 791
+f 895 869 763
+f 763 791 895
+f 989 971 869
+f 869 895 989
+f 1095 1089 971
+f 971 989 1095
+f 1227 1217 1089
+f 1089 1095 1227
+f 1421 1406 1217
+f 1217 1227 1421
+f 1766 1692 1406
+f 1406 1421 1766
+f 606 581 573
+f 573 591 606
+f 643 626 581
+f 581 606 643
+f 727 703 626
+f 626 643 727
+f 811 791 703
+f 703 727 811
+f 908 895 791
+f 791 811 908
+f 1005 989 895
+f 895 908 1005
+f 1100 1095 989
+f 989 1005 1100
+f 1231 1227 1095
+f 1095 1100 1231
+f 1427 1421 1227
+f 1227 1231 1427
+f 1897 1766 1421
+f 1421 1427 1897
+f 615 606 591
+f 591 598 615
+f 653 643 606
+f 606 615 653
+f 735 727 643
+f 643 653 735
+f 820 811 727
+f 727 735 820
+f 913 908 811
+f 811 820 913
+f 1013 1005 908
+f 908 913 1013
+f 1103 1100 1005
+f 1005 1013 1103
+f 1236 1231 1100
+f 1100 1103 1236
+f 1432 1427 1231
+f 1231 1236 1432
+f 1760 1897 1427
+f 1427 1432 1760
+f 2294 2299 1786
+f 1786 1783 2294
+f 2461 2466 2299
+f 2299 2294 2461
+f 2630 2641 2466
+f 2466 2461 2630
+f 2778 2785 2641
+f 2641 2630 2778
+f 2954 2963 2785
+f 2785 2778 2954
+f 3061 3068 2963
+f 2963 2954 3061
+f 3135 3140 3068
+f 3068 3061 3135
+f 3167 3176 3140
+f 3140 3135 3167
+f 3195 3203 3176
+f 3176 3167 3195
+f 3208 3213 3203
+f 3203 3195 3208
+f 2284 2294 1783
+f 1783 1781 2284
+f 2455 2461 2294
+f 2294 2284 2455
+f 2620 2630 2461
+f 2461 2455 2620
+f 2768 2778 2630
+f 2630 2620 2768
+f 2928 2954 2778
+f 2778 2768 2928
+f 3051 3061 2954
+f 2954 2928 3051
+f 3125 3135 3061
+f 3061 3051 3125
+f 3159 3167 3135
+f 3135 3125 3159
+f 3181 3195 3167
+f 3167 3159 3181
+f 3191 3208 3195
+f 3195 3181 3191
+f 2266 2284 1781
+f 1781 1779 2266
+f 2449 2455 2284
+f 2284 2266 2449
+f 2598 2620 2455
+f 2455 2449 2598
+f 2740 2768 2620
+f 2620 2598 2740
+f 2892 2928 2768
+f 2768 2740 2892
+f 3033 3051 2928
+f 2928 2892 3033
+f 3087 3125 3051
+f 3051 3033 3087
+f 3145 3159 3125
+f 3125 3087 3145
+f 3161 3181 3159
+f 3159 3145 3161
+f 3169 3191 3181
+f 3181 3161 3169
+f 2252 2266 1779
+f 1779 1777 2252
+f 2435 2449 2266
+f 2266 2252 2435
+f 2581 2598 2449
+f 2449 2435 2581
+f 2718 2740 2598
+f 2598 2581 2718
+f 2854 2892 2740
+f 2740 2718 2854
+f 2999 3033 2892
+f 2892 2854 2999
+f 3071 3087 3033
+f 3033 2999 3071
+f 3123 3145 3087
+f 3087 3071 3123
+f 3147 3161 3145
+f 3145 3123 3147
+f 3153 3169 3161
+f 3161 3147 3153
+f 2240 2252 1777
+f 1777 1775 2240
+f 2425 2435 2252
+f 2252 2240 2425
+f 2555 2581 2435
+f 2435 2425 2555
+f 2694 2718 2581
+f 2581 2555 2694
+f 2826 2854 2718
+f 2718 2694 2826
+f 2958 2999 2854
+f 2854 2826 2958
+f 3043 3071 2999
+f 2999 2958 3043
+f 3083 3123 3071
+f 3071 3043 3083
+f 3121 3147 3123
+f 3123 3083 3121
+f 3127 3153 3147
+f 3147 3121 3127
+f 2229 2240 1775
+f 1775 1772 2229
+f 2417 2425 2240
+f 2240 2229 2417
+f 2546 2555 2425
+f 2425 2417 2546
+f 2676 2694 2555
+f 2555 2546 2676
+f 2790 2826 2694
+f 2694 2676 2790
+f 2900 2958 2826
+f 2826 2790 2900
+f 3013 3043 2958
+f 2958 2900 3013
+f 3057 3083 3043
+f 3043 3013 3057
+f 3081 3121 3083
+f 3083 3057 3081
+f 3085 3127 3121
+f 3121 3081 3085
+f 2216 2229 1772
+f 1772 1769 2216
+f 2407 2417 2229
+f 2229 2216 2407
+f 2533 2546 2417
+f 2417 2407 2533
+f 2651 2676 2546
+f 2546 2533 2651
+f 2753 2790 2676
+f 2676 2651 2753
+f 2859 2900 2790
+f 2790 2753 2859
+f 2977 3013 2900
+f 2900 2859 2977
+f 3029 3057 3013
+f 3013 2977 3029
+f 3052 3081 3057
+f 3057 3029 3052
+f 3063 3085 3081
+f 3081 3052 3063
+f 2203 2216 1769
+f 1769 1767 2203
+f 2397 2407 2216
+f 2216 2203 2397
+f 2527 2533 2407
+f 2407 2397 2527
+f 2633 2651 2533
+f 2533 2527 2633
+f 2727 2753 2651
+f 2651 2633 2727
+f 2831 2859 2753
+f 2753 2727 2831
+f 2919 2977 2859
+f 2859 2831 2919
+f 2996 3029 2977
+f 2977 2919 2996
+f 3034 3052 3029
+f 3029 2996 3034
+f 3038 3063 3052
+f 3052 3034 3038
+f 2197 2203 1767
+f 1767 1763 2197
+f 2393 2397 2203
+f 2203 2197 2393
+f 2522 2527 2397
+f 2397 2393 2522
+f 2617 2633 2527
+f 2527 2522 2617
+f 2716 2727 2633
+f 2633 2617 2716
+f 2811 2831 2727
+f 2727 2716 2811
+f 2895 2919 2831
+f 2831 2811 2895
+f 2979 2996 2919
+f 2919 2895 2979
+f 3016 3034 2996
+f 2996 2979 3016
+f 3026 3038 3034
+f 3034 3016 3026
+f 2193 2197 1763
+f 1763 1761 2193
+f 2389 2393 2197
+f 2197 2193 2389
+f 2516 2522 2393
+f 2393 2389 2516
+f 2610 2617 2522
+f 2522 2516 2610
+f 2710 2716 2617
+f 2617 2610 2710
+f 2803 2811 2716
+f 2716 2710 2803
+f 2885 2895 2811
+f 2811 2803 2885
+f 2971 2979 2895
+f 2895 2885 2971
+f 3005 3016 2979
+f 2979 2971 3005
+f 3022 3026 3016
+f 3016 3005 3022
+f 461 545 544
+f 544 456 461
+f 463 551 545
+f 545 461 463
+f 465 557 551
+f 551 463 465
+f 469 567 557
+f 557 465 469
+f 471 575 567
+f 567 469 471
+f 473 577 575
+f 575 471 473
+f 475 589 577
+f 577 473 475
+f 477 593 589
+f 589 475 477
+f 479 595 593
+f 593 477 479
+f 481 599 595
+f 595 479 481
+f 389 461 456
+f 456 392 389
+f 386 463 461
+f 461 389 386
+f 379 465 463
+f 463 386 379
+f 373 469 465
+f 465 379 373
+f 371 471 469
+f 469 373 371
+f 369 473 471
+f 471 371 369
+f 366 475 473
+f 473 369 366
+f 364 477 475
+f 475 366 364
+f 362 479 477
+f 477 364 362
+f 361 481 479
+f 479 362 361
+f 335 389 392
+f 392 337 335
+f 333 386 389
+f 389 335 333
+f 331 379 386
+f 386 333 331
+f 329 373 379
+f 379 331 329
+f 328 371 373
+f 373 329 328
+f 325 369 371
+f 371 328 325
+f 323 366 369
+f 369 325 323
+f 321 364 366
+f 366 323 321
+f 319 362 364
+f 364 321 319
+f 316 361 362
+f 362 319 316
+f 298 335 337
+f 337 302 298
+f 290 333 335
+f 335 298 290
+f 288 331 333
+f 333 290 288
+f 286 329 331
+f 331 288 286
+f 281 328 329
+f 329 286 281
+f 275 325 328
+f 328 281 275
+f 265 323 325
+f 325 275 265
+f 259 321 323
+f 323 265 259
+f 255 319 321
+f 321 259 255
+f 249 316 319
+f 319 255 249
+f 269 298 302
+f 302 271 269
+f 261 290 298
+f 298 269 261
+f 251 288 290
+f 290 261 251
+f 238 286 288
+f 288 251 238
+f 230 281 286
+f 286 238 230
+f 218 275 281
+f 281 230 218
+f 208 265 275
+f 275 218 208
+f 196 259 265
+f 265 208 196
+f 186 255 259
+f 259 196 186
+f 181 249 255
+f 255 186 181
+f 228 269 271
+f 271 234 228
+f 222 261 269
+f 269 228 222
+f 212 251 261
+f 261 222 212
+f 200 238 251
+f 251 212 200
+f 177 230 238
+f 238 200 177
+f 160 218 230
+f 230 177 160
+f 134 208 218
+f 218 160 134
+f 112 196 208
+f 208 134 112
+f 102 186 196
+f 196 112 102
+f 96 181 186
+f 186 102 96
+f 198 228 234
+f 234 205 198
+f 182 222 228
+f 228 198 182
+f 168 212 222
+f 222 182 168
+f 146 200 212
+f 212 168 146
+f 118 177 200
+f 200 146 118
+f 92 160 177
+f 177 118 92
+f 74 134 160
+f 160 92 74
+f 63 112 134
+f 134 74 63
+f 53 102 112
+f 112 63 53
+f 50 96 102
+f 102 53 50
+f 167 198 205
+f 205 170 167
+f 154 182 198
+f 198 167 154
+f 126 168 182
+f 182 154 126
+f 100 146 168
+f 168 126 100
+f 83 118 146
+f 146 100 83
+f 61 92 118
+f 118 83 61
+f 46 74 92
+f 92 61 46
+f 32 63 74
+f 74 46 32
+f 25 53 63
+f 63 32 25
+f 21 50 53
+f 53 25 21
+f 143 167 170
+f 170 150 143
+f 124 154 167
+f 167 143 124
+f 104 126 154
+f 154 124 104
+f 84 100 126
+f 126 104 84
+f 65 83 100
+f 100 84 65
+f 44 61 83
+f 83 65 44
+f 30 46 61
+f 61 44 30
+f 17 32 46
+f 46 30 17
+f 9 25 32
+f 32 17 9
+f 5 21 25
+f 25 9 5
+f 132 143 150
+f 150 140 132
+f 116 124 143
+f 143 132 116
+f 94 104 124
+f 124 116 94
+f 76 84 104
+f 104 94 76
+f 55 65 84
+f 84 76 55
+f 40 44 65
+f 65 55 40
+f 22 30 44
+f 44 40 22
+f 11 17 30
+f 30 22 11
+f 2 9 17
+f 17 11 2
+f 1 5 9
+f 9 2 1
+f 480 596 599
+f 599 481 480
+f 478 594 596
+f 596 480 478
+f 476 590 594
+f 594 478 476
+f 474 578 590
+f 590 476 474
+f 472 576 578
+f 578 474 472
+f 470 568 576
+f 576 472 470
+f 466 558 568
+f 568 470 466
+f 464 552 558
+f 558 466 464
+f 462 546 552
+f 552 464 462
+f 456 544 546
+f 546 462 456
+f 363 480 481
+f 481 360 363
+f 365 478 480
+f 480 363 365
+f 367 476 478
+f 478 365 367
+f 368 474 476
+f 476 367 368
+f 370 472 474
+f 474 368 370
+f 372 470 472
+f 472 370 372
+f 380 466 470
+f 470 372 380
+f 385 464 466
+f 466 380 385
+f 390 462 464
+f 464 385 390
+f 391 456 462
+f 462 390 391
+f 320 363 360
+f 360 316 320
+f 322 365 363
+f 363 320 322
+f 324 367 365
+f 365 322 324
+f 326 368 367
+f 367 324 326
+f 327 370 368
+f 368 326 327
+f 330 372 370
+f 370 327 330
+f 332 380 372
+f 372 330 332
+f 334 385 380
+f 380 332 334
+f 336 390 385
+f 385 334 336
+f 337 391 390
+f 390 336 337
+f 256 320 316
+f 316 250 256
+f 260 322 320
+f 320 256 260
+f 266 324 322
+f 322 260 266
+f 276 326 324
+f 324 266 276
+f 282 327 326
+f 326 276 282
+f 287 330 327
+f 327 282 287
+f 289 332 330
+f 330 287 289
+f 291 334 332
+f 332 289 291
+f 299 336 334
+f 334 291 299
+f 303 337 336
+f 336 299 303
+f 187 256 250
+f 250 181 187
+f 197 260 256
+f 256 187 197
+f 209 266 260
+f 260 197 209
+f 219 276 266
+f 266 209 219
+f 231 282 276
+f 276 219 231
+f 239 287 282
+f 282 231 239
+f 252 289 287
+f 287 239 252
+f 262 291 289
+f 289 252 262
+f 270 299 291
+f 291 262 270
+f 272 303 299
+f 299 270 272
+f 103 187 181
+f 181 97 103
+f 113 197 187
+f 187 103 113
+f 135 209 197
+f 197 113 135
+f 161 219 209
+f 209 135 161
+f 178 231 219
+f 219 161 178
+f 201 239 231
+f 231 178 201
+f 213 252 239
+f 239 201 213
+f 223 262 252
+f 252 213 223
+f 229 270 262
+f 262 223 229
+f 235 272 270
+f 270 229 235
+f 54 103 97
+f 97 50 54
+f 64 113 103
+f 103 54 64
+f 75 135 113
+f 113 64 75
+f 93 161 135
+f 135 75 93
+f 119 178 161
+f 161 93 119
+f 147 201 178
+f 178 119 147
+f 169 213 201
+f 201 147 169
+f 183 223 213
+f 213 169 183
+f 199 229 223
+f 223 183 199
+f 205 235 229
+f 229 199 205
+f 24 54 50
+f 50 21 24
+f 33 64 54
+f 54 24 33
+f 47 75 64
+f 64 33 47
+f 62 93 75
+f 75 47 62
+f 82 119 93
+f 93 62 82
+f 101 147 119
+f 119 82 101
+f 127 169 147
+f 147 101 127
+f 155 183 169
+f 169 127 155
+f 166 199 183
+f 183 155 166
+f 171 205 199
+f 199 166 171
+f 10 24 21
+f 21 6 10
+f 18 33 24
+f 24 10 18
+f 31 47 33
+f 33 18 31
+f 45 62 47
+f 47 31 45
+f 66 82 62
+f 62 45 66
+f 85 101 82
+f 82 66 85
+f 105 127 101
+f 101 85 105
+f 125 155 127
+f 127 105 125
+f 144 166 155
+f 155 125 144
+f 151 171 166
+f 166 144 151
+f 3 10 6
+f 6 1 3
+f 12 18 10
+f 10 3 12
+f 23 31 18
+f 18 12 23
+f 41 45 31
+f 31 23 41
+f 56 66 45
+f 45 41 56
+f 77 85 66
+f 66 56 77
+f 95 105 85
+f 85 77 95
+f 117 125 105
+f 105 95 117
+f 133 144 125
+f 125 117 133
+f 140 151 144
+f 144 133 140
+f 138 132 140
+f 140 145 138
+f 122 116 132
+f 132 138 122
+f 98 94 116
+f 116 122 98
+f 80 76 94
+f 94 98 80
+f 60 55 76
+f 76 80 60
+f 42 40 55
+f 55 60 42
+f 28 22 40
+f 40 42 28
+f 13 11 22
+f 22 28 13
+f 7 2 11
+f 11 13 7
+f 4 1 2
+f 2 7 4
+f 152 138 145
+f 145 158 152
+f 136 122 138
+f 138 152 136
+f 108 98 122
+f 122 136 108
+f 89 80 98
+f 98 108 89
+f 70 60 80
+f 80 89 70
+f 52 42 60
+f 60 70 52
+f 38 28 42
+f 42 52 38
+f 26 13 28
+f 28 38 26
+f 19 7 13
+f 13 26 19
+f 15 4 7
+f 7 19 15
+f 173 152 158
+f 158 176 173
+f 162 136 152
+f 152 173 162
+f 142 108 136
+f 136 162 142
+f 111 89 108
+f 108 142 111
+f 91 70 89
+f 89 111 91
+f 73 52 70
+f 70 91 73
+f 58 38 52
+f 52 73 58
+f 48 26 38
+f 38 58 48
+f 37 19 26
+f 26 48 37
+f 35 15 19
+f 19 37 35
+f 194 173 176
+f 176 202 194
+f 184 162 173
+f 173 194 184
+f 174 142 162
+f 162 184 174
+f 156 111 142
+f 142 174 156
+f 128 91 111
+f 111 156 128
+f 106 73 91
+f 91 128 106
+f 86 58 73
+f 73 106 86
+f 78 48 58
+f 58 86 78
+f 68 37 48
+f 48 78 68
+f 67 35 37
+f 37 68 67
+f 221 194 202
+f 202 225 221
+f 216 184 194
+f 194 221 216
+f 206 174 184
+f 184 216 206
+f 192 156 174
+f 174 206 192
+f 180 128 156
+f 156 192 180
+f 164 106 128
+f 128 180 164
+f 148 86 106
+f 106 164 148
+f 130 78 86
+f 86 148 130
+f 121 68 78
+f 78 130 121
+f 115 67 68
+f 68 121 115
+f 244 221 225
+f 225 247 244
+f 240 216 221
+f 221 244 240
+f 236 206 216
+f 216 240 236
+f 233 192 206
+f 206 236 233
+f 227 180 192
+f 192 233 227
+f 215 164 180
+f 180 227 215
+f 210 148 164
+f 164 215 210
+f 203 130 148
+f 148 210 203
+f 191 121 130
+f 130 203 191
+f 188 115 121
+f 121 191 188
+f 284 244 247
+f 247 285 284
+f 279 240 244
+f 244 284 279
+f 277 236 240
+f 240 279 277
+f 273 233 236
+f 236 277 273
+f 267 227 233
+f 233 273 267
+f 263 215 227
+f 227 267 263
+f 258 210 215
+f 215 263 258
+f 253 203 210
+f 210 258 253
+f 245 191 203
+f 203 253 245
+f 242 188 191
+f 191 245 242
+f 315 284 285
+f 285 318 315
+f 312 279 284
+f 284 315 312
+f 311 277 279
+f 279 312 311
+f 309 273 277
+f 277 311 309
+f 307 267 273
+f 273 309 307
+f 305 263 267
+f 267 307 305
+f 301 258 263
+f 263 305 301
+f 297 253 258
+f 258 301 297
+f 295 245 253
+f 253 297 295
+f 293 242 245
+f 245 295 293
+f 341 315 318
+f 318 339 341
+f 343 312 315
+f 315 341 343
+f 345 311 312
+f 312 343 345
+f 347 309 311
+f 311 345 347
+f 349 307 309
+f 309 347 349
+f 351 305 307
+f 307 349 351
+f 353 301 305
+f 305 351 353
+f 355 297 301
+f 301 353 355
+f 357 295 297
+f 297 355 357
+f 359 293 295
+f 295 357 359
+f 378 341 339
+f 339 376 378
+f 384 343 341
+f 341 378 384
+f 394 345 343
+f 343 384 394
+f 403 347 345
+f 345 394 403
+f 406 349 347
+f 347 403 406
+f 415 351 349
+f 349 406 415
+f 419 353 351
+f 351 415 419
+f 423 355 353
+f 353 419 423
+f 425 357 355
+f 355 423 425
+f 427 359 357
+f 357 425 427
+f 8 3 1
+f 1 4 8
+f 14 12 3
+f 3 8 14
+f 29 23 12
+f 12 14 29
+f 43 41 23
+f 23 29 43
+f 59 56 41
+f 41 43 59
+f 81 77 56
+f 56 59 81
+f 99 95 77
+f 77 81 99
+f 123 117 95
+f 95 99 123
+f 139 133 117
+f 117 123 139
+f 145 140 133
+f 133 139 145
+f 20 8 4
+f 4 16 20
+f 27 14 8
+f 8 20 27
+f 39 29 14
+f 14 27 39
+f 51 43 29
+f 29 39 51
+f 71 59 43
+f 43 51 71
+f 88 81 59
+f 59 71 88
+f 109 99 81
+f 81 88 109
+f 137 123 99
+f 99 109 137
+f 153 139 123
+f 123 137 153
+f 159 145 139
+f 139 153 159
+f 36 20 16
+f 16 34 36
+f 49 27 20
+f 20 36 49
+f 57 39 27
+f 27 49 57
+f 72 51 39
+f 39 57 72
+f 90 71 51
+f 51 72 90
+f 110 88 71
+f 71 90 110
+f 141 109 88
+f 88 110 141
+f 163 137 109
+f 109 141 163
+f 172 153 137
+f 137 163 172
+f 176 159 153
+f 153 172 176
+f 69 36 34
+f 34 67 69
+f 79 49 36
+f 36 69 79
+f 87 57 49
+f 49 79 87
+f 107 72 57
+f 57 87 107
+f 129 90 72
+f 72 107 129
+f 157 110 90
+f 90 129 157
+f 175 141 110
+f 110 157 175
+f 185 163 141
+f 141 175 185
+f 195 172 163
+f 163 185 195
+f 202 176 172
+f 172 195 202
+f 120 69 67
+f 67 114 120
+f 131 79 69
+f 69 120 131
+f 149 87 79
+f 79 131 149
+f 165 107 87
+f 87 149 165
+f 179 129 107
+f 107 165 179
+f 193 157 129
+f 129 179 193
+f 207 175 157
+f 157 193 207
+f 217 185 175
+f 175 207 217
+f 220 195 185
+f 185 217 220
+f 224 202 195
+f 195 220 224
+f 190 120 114
+f 114 189 190
+f 204 131 120
+f 120 190 204
+f 211 149 131
+f 131 204 211
+f 214 165 149
+f 149 211 214
+f 226 179 165
+f 165 214 226
+f 232 193 179
+f 179 226 232
+f 237 207 193
+f 193 232 237
+f 241 217 207
+f 207 237 241
+f 243 220 217
+f 217 241 243
+f 248 224 220
+f 220 243 248
+f 246 190 189
+f 189 242 246
+f 254 204 190
+f 190 246 254
+f 257 211 204
+f 204 254 257
+f 264 214 211
+f 211 257 264
+f 268 226 214
+f 214 264 268
+f 274 232 226
+f 226 268 274
+f 278 237 232
+f 232 274 278
+f 280 241 237
+f 237 278 280
+f 283 243 241
+f 241 280 283
+f 285 248 243
+f 243 283 285
+f 294 246 242
+f 242 292 294
+f 296 254 246
+f 246 294 296
+f 300 257 254
+f 254 296 300
+f 304 264 257
+f 257 300 304
+f 306 268 264
+f 264 304 306
+f 308 274 268
+f 268 306 308
+f 310 278 274
+f 274 308 310
+f 313 280 278
+f 278 310 313
+f 314 283 280
+f 280 313 314
+f 317 285 283
+f 283 314 317
+f 356 294 292
+f 292 358 356
+f 354 296 294
+f 294 356 354
+f 352 300 296
+f 296 354 352
+f 350 304 300
+f 300 352 350
+f 348 306 304
+f 304 350 348
+f 346 308 306
+f 306 348 346
+f 344 310 308
+f 308 346 344
+f 342 313 310
+f 310 344 342
+f 340 314 313
+f 313 342 340
+f 338 317 314
+f 314 340 338
+f 424 356 358
+f 358 426 424
+f 422 354 356
+f 356 424 422
+f 418 352 354
+f 354 422 418
+f 414 350 352
+f 352 418 414
+f 407 348 350
+f 350 414 407
+f 402 346 348
+f 348 407 402
+f 393 344 346
+f 346 402 393
+f 383 342 344
+f 344 393 383
+f 377 340 342
+f 342 383 377
+f 375 338 340
+f 340 377 375
+f 3186 3113 3115
+f 3115 3182 3186
+f 3192 3110 3113
+f 3113 3186 3192
+f 3196 3109 3110
+f 3110 3192 3196
+f 3205 3106 3109
+f 3109 3196 3205
+f 3211 3104 3106
+f 3106 3205 3211
+f 3215 3102 3104
+f 3104 3211 3215
+f 3217 3101 3102
+f 3102 3215 3217
+f 3220 3098 3101
+f 3101 3217 3220
+f 3222 3097 3098
+f 3098 3220 3222
+f 3223 3095 3097
+f 3097 3222 3223
+f 3227 3186 3182
+f 3182 3225 3227
+f 3229 3192 3186
+f 3186 3227 3229
+f 3231 3196 3192
+f 3192 3229 3231
+f 3233 3205 3196
+f 3196 3231 3233
+f 3235 3211 3205
+f 3205 3233 3235
+f 3241 3215 3211
+f 3211 3235 3241
+f 3245 3217 3215
+f 3215 3241 3245
+f 3249 3220 3217
+f 3217 3245 3249
+f 3251 3222 3220
+f 3220 3249 3251
+f 3253 3223 3222
+f 3222 3251 3253
+f 3239 3227 3225
+f 3225 3237 3239
+f 3243 3229 3227
+f 3227 3239 3243
+f 3247 3231 3229
+f 3229 3243 3247
+f 3257 3233 3231
+f 3231 3247 3257
+f 3263 3235 3233
+f 3233 3257 3263
+f 3271 3241 3235
+f 3235 3263 3271
+f 3279 3245 3241
+f 3241 3271 3279
+f 3285 3249 3245
+f 3245 3279 3285
+f 3293 3251 3249
+f 3249 3285 3293
+f 3297 3253 3251
+f 3251 3293 3297
+f 3259 3239 3237
+f 3237 3255 3259
+f 3261 3243 3239
+f 3239 3259 3261
+f 3265 3247 3243
+f 3243 3261 3265
+f 3275 3257 3247
+f 3247 3265 3275
+f 3287 3263 3257
+f 3257 3275 3287
+f 3303 3271 3263
+f 3263 3287 3303
+f 3314 3279 3271
+f 3271 3303 3314
+f 3320 3285 3279
+f 3279 3314 3320
+f 3330 3293 3285
+f 3285 3320 3330
+f 3332 3297 3293
+f 3293 3330 3332
+f 3270 3259 3255
+f 3255 3268 3270
+f 3273 3261 3259
+f 3259 3270 3273
+f 3283 3265 3261
+f 3261 3273 3283
+f 3299 3275 3265
+f 3265 3283 3299
+f 3308 3287 3275
+f 3275 3299 3308
+f 3322 3303 3287
+f 3287 3308 3322
+f 3338 3314 3303
+f 3303 3322 3338
+f 3346 3320 3314
+f 3314 3338 3346
+f 3351 3330 3320
+f 3320 3346 3351
+f 3355 3332 3330
+f 3330 3351 3355
+f 3282 3270 3268
+f 3268 3278 3282
+f 3290 3273 3270
+f 3270 3282 3290
+f 3302 3283 3273
+f 3273 3290 3302
+f 3312 3299 3283
+f 3283 3302 3312
+f 3324 3308 3299
+f 3299 3312 3324
+f 3340 3322 3308
+f 3308 3324 3340
+f 3353 3338 3322
+f 3322 3340 3353
+f 3368 3346 3338
+f 3338 3353 3368
+f 3373 3351 3346
+f 3346 3368 3373
+f 3379 3355 3351
+f 3351 3373 3379
+f 3295 3282 3278
+f 3278 3292 3295
+f 3306 3290 3282
+f 3282 3295 3306
+f 3316 3302 3290
+f 3290 3306 3316
+f 3326 3312 3302
+f 3302 3316 3326
+f 3345 3324 3312
+f 3312 3326 3345
+f 3359 3340 3324
+f 3324 3345 3359
+f 3376 3353 3340
+f 3340 3359 3376
+f 3394 3368 3353
+f 3353 3376 3394
+f 3404 3373 3368
+f 3368 3394 3404
+f 3406 3379 3373
+f 3373 3404 3406
+f 3310 3295 3292
+f 3292 3307 3310
+f 3318 3306 3295
+f 3295 3310 3318
+f 3336 3316 3306
+f 3306 3318 3336
+f 3348 3326 3316
+f 3316 3336 3348
+f 3369 3345 3326
+f 3326 3348 3369
+f 3389 3359 3345
+f 3345 3369 3389
+f 3425 3376 3359
+f 3359 3389 3425
+f 3449 3394 3376
+f 3376 3425 3449
+f 3468 3404 3394
+f 3394 3449 3468
+f 3472 3406 3404
+f 3404 3468 3472
+f 3335 3310 3307
+f 3307 3329 3335
+f 3343 3318 3310
+f 3310 3335 3343
+f 3362 3336 3318
+f 3318 3343 3362
+f 3386 3348 3336
+f 3336 3362 3386
+f 3422 3369 3348
+f 3348 3386 3422
+f 3464 3389 3369
+f 3369 3422 3464
+f 3490 3425 3389
+f 3389 3464 3490
+f 3505 3449 3425
+f 3425 3490 3505
+f 3521 3468 3449
+f 3449 3505 3521
+f 3523 3472 3468
+f 3468 3521 3523
+f 3364 3335 3329
+f 3329 3357 3364
+f 3382 3343 3335
+f 3335 3364 3382
+f 3416 3362 3343
+f 3343 3382 3416
+f 3465 3386 3362
+f 3362 3416 3465
+f 3495 3422 3386
+f 3386 3465 3495
+f 3528 3464 3422
+f 3422 3495 3528
+f 3553 3490 3464
+f 3464 3528 3553
+f 3579 3505 3490
+f 3490 3553 3579
+f 3592 3521 3505
+f 3505 3579 3592
+f 3604 3523 3521
+f 3521 3592 3604
+f 3221 3096 3094
+f 3094 3224 3221
+f 3219 3099 3096
+f 3096 3221 3219
+f 3218 3100 3099
+f 3099 3219 3218
+f 3216 3103 3100
+f 3100 3218 3216
+f 3212 3105 3103
+f 3103 3216 3212
+f 3206 3107 3105
+f 3105 3212 3206
+f 3197 3108 3107
+f 3107 3206 3197
+f 3193 3111 3108
+f 3108 3197 3193
+f 3187 3112 3111
+f 3111 3193 3187
+f 3183 3114 3112
+f 3112 3187 3183
+f 3252 3221 3224
+f 3224 3254 3252
+f 3250 3219 3221
+f 3221 3252 3250
+f 3246 3218 3219
+f 3219 3250 3246
+f 3242 3216 3218
+f 3218 3246 3242
+f 3236 3212 3216
+f 3216 3242 3236
+f 3234 3206 3212
+f 3212 3236 3234
+f 3232 3197 3206
+f 3206 3234 3232
+f 3230 3193 3197
+f 3197 3232 3230
+f 3228 3187 3193
+f 3193 3230 3228
+f 3226 3183 3187
+f 3187 3228 3226
+f 3294 3252 3254
+f 3254 3298 3294
+f 3286 3250 3252
+f 3252 3294 3286
+f 3280 3246 3250
+f 3250 3286 3280
+f 3272 3242 3246
+f 3246 3280 3272
+f 3264 3236 3242
+f 3242 3272 3264
+f 3258 3234 3236
+f 3236 3264 3258
+f 3248 3232 3234
+f 3234 3258 3248
+f 3244 3230 3232
+f 3232 3248 3244
+f 3240 3228 3230
+f 3230 3244 3240
+f 3238 3226 3228
+f 3228 3240 3238
+f 3331 3294 3298
+f 3298 3333 3331
+f 3321 3286 3294
+f 3294 3331 3321
+f 3315 3280 3286
+f 3286 3321 3315
+f 3304 3272 3280
+f 3280 3315 3304
+f 3288 3264 3272
+f 3272 3304 3288
+f 3276 3258 3264
+f 3264 3288 3276
+f 3266 3248 3258
+f 3258 3276 3266
+f 3262 3244 3248
+f 3248 3266 3262
+f 3260 3240 3244
+f 3244 3262 3260
+f 3256 3238 3240
+f 3240 3260 3256
+f 3350 3331 3333
+f 3333 3354 3350
+f 3347 3321 3331
+f 3331 3350 3347
+f 3339 3315 3321
+f 3321 3347 3339
+f 3323 3304 3315
+f 3315 3339 3323
+f 3309 3288 3304
+f 3304 3323 3309
+f 3300 3276 3288
+f 3288 3309 3300
+f 3284 3266 3276
+f 3276 3300 3284
+f 3274 3262 3266
+f 3266 3284 3274
+f 3269 3260 3262
+f 3262 3274 3269
+f 3267 3256 3260
+f 3260 3269 3267
+f 3372 3350 3354
+f 3354 3378 3372
+f 3367 3347 3350
+f 3350 3372 3367
+f 3352 3339 3347
+f 3347 3367 3352
+f 3341 3323 3339
+f 3339 3352 3341
+f 3325 3309 3323
+f 3323 3341 3325
+f 3313 3300 3309
+f 3309 3325 3313
+f 3301 3284 3300
+f 3300 3313 3301
+f 3289 3274 3284
+f 3284 3301 3289
+f 3281 3269 3274
+f 3274 3289 3281
+f 3277 3267 3269
+f 3269 3281 3277
+f 3403 3372 3378
+f 3378 3405 3403
+f 3393 3367 3372
+f 3372 3403 3393
+f 3377 3352 3367
+f 3367 3393 3377
+f 3360 3341 3352
+f 3352 3377 3360
+f 3344 3325 3341
+f 3341 3360 3344
+f 3327 3313 3325
+f 3325 3344 3327
+f 3317 3301 3313
+f 3313 3327 3317
+f 3305 3289 3301
+f 3301 3317 3305
+f 3296 3281 3289
+f 3289 3305 3296
+f 3291 3277 3281
+f 3281 3296 3291
+f 3469 3403 3405
+f 3405 3472 3469
+f 3450 3393 3403
+f 3403 3469 3450
+f 3426 3377 3393
+f 3393 3450 3426
+f 3390 3360 3377
+f 3377 3426 3390
+f 3370 3344 3360
+f 3360 3390 3370
+f 3349 3327 3344
+f 3344 3370 3349
+f 3337 3317 3327
+f 3327 3349 3337
+f 3319 3305 3317
+f 3317 3337 3319
+f 3311 3296 3305
+f 3305 3319 3311
+f 3307 3291 3296
+f 3296 3311 3307
+f 3520 3469 3472
+f 3472 3522 3520
+f 3504 3450 3469
+f 3469 3520 3504
+f 3489 3426 3450
+f 3450 3504 3489
+f 3463 3390 3426
+f 3426 3489 3463
+f 3421 3370 3390
+f 3390 3463 3421
+f 3385 3349 3370
+f 3370 3421 3385
+f 3361 3337 3349
+f 3349 3385 3361
+f 3342 3319 3337
+f 3337 3361 3342
+f 3334 3311 3319
+f 3319 3342 3334
+f 3328 3307 3311
+f 3311 3334 3328
+f 3591 3520 3522
+f 3522 3603 3591
+f 3578 3504 3520
+f 3520 3591 3578
+f 3552 3489 3504
+f 3504 3578 3552
+f 3530 3463 3489
+f 3489 3552 3530
+f 3499 3421 3463
+f 3463 3530 3499
+f 3467 3385 3421
+f 3421 3499 3467
+f 3415 3361 3385
+f 3385 3467 3415
+f 3381 3342 3361
+f 3361 3415 3381
+f 3363 3334 3342
+f 3342 3381 3363
+f 3356 3328 3334
+f 3334 3363 3356
+f 3374 3365 3358
+f 3358 3371 3374
+f 3395 3383 3365
+f 3365 3374 3395
+f 3443 3417 3383
+f 3383 3395 3443
+f 3481 3466 3417
+f 3417 3443 3481
+f 3514 3496 3466
+f 3466 3481 3514
+f 3545 3529 3496
+f 3496 3514 3545
+f 3573 3551 3529
+f 3529 3545 3573
+f 3597 3577 3551
+f 3551 3573 3597
+f 3613 3590 3577
+f 3577 3597 3613
+f 3619 3603 3590
+f 3590 3613 3619
+f 3387 3374 3371
+f 3371 3380 3387
+f 3413 3395 3374
+f 3374 3387 3413
+f 3461 3443 3395
+f 3395 3413 3461
+f 3493 3481 3443
+f 3443 3461 3493
+f 3524 3514 3481
+f 3481 3493 3524
+f 3556 3545 3514
+f 3514 3524 3556
+f 3584 3573 3545
+f 3545 3556 3584
+f 3611 3597 3573
+f 3573 3584 3611
+f 3628 3613 3597
+f 3597 3611 3628
+f 3632 3619 3613
+f 3613 3628 3632
+f 3398 3387 3380
+f 3380 3391 3398
+f 3435 3413 3387
+f 3387 3398 3435
+f 3473 3461 3413
+f 3413 3435 3473
+f 3500 3493 3461
+f 3461 3473 3500
+f 3531 3524 3493
+f 3493 3500 3531
+f 3562 3556 3524
+f 3524 3531 3562
+f 3595 3584 3556
+f 3556 3562 3595
+f 3617 3611 3584
+f 3584 3595 3617
+f 3633 3628 3611
+f 3611 3617 3633
+f 3641 3632 3628
+f 3628 3633 3641
+f 3409 3398 3391
+f 3391 3400 3409
+f 3447 3435 3398
+f 3398 3409 3447
+f 3477 3473 3435
+f 3435 3447 3477
+f 3506 3500 3473
+f 3473 3477 3506
+f 3540 3531 3500
+f 3500 3506 3540
+f 3567 3562 3531
+f 3531 3540 3567
+f 3601 3595 3562
+f 3562 3567 3601
+f 3624 3617 3595
+f 3595 3601 3624
+f 3639 3633 3617
+f 3617 3624 3639
+f 3644 3641 3633
+f 3633 3639 3644
+f 3433 3409 3400
+f 3400 3411 3433
+f 3453 3447 3409
+f 3409 3433 3453
+f 3483 3477 3447
+f 3447 3453 3483
+f 3510 3506 3477
+f 3477 3483 3510
+f 3543 3540 3506
+f 3506 3510 3543
+f 3569 3567 3540
+f 3540 3543 3569
+f 3599 3601 3567
+f 3567 3569 3599
+f 3622 3624 3601
+f 3601 3599 3622
+f 3637 3639 3624
+f 3624 3622 3637
+f 3642 3644 3639
+f 3639 3637 3642
+f 3439 3433 3411
+f 3411 3424 3439
+f 3458 3453 3433
+f 3433 3439 3458
+f 3487 3483 3453
+f 3453 3458 3487
+f 3513 3510 3483
+f 3483 3487 3513
+f 3542 3543 3510
+f 3510 3513 3542
+f 3566 3569 3543
+f 3543 3542 3566
+f 3593 3599 3569
+f 3569 3566 3593
+f 3616 3622 3599
+f 3599 3593 3616
+f 3630 3637 3622
+f 3622 3616 3630
+f 3636 3642 3637
+f 3637 3630 3636
+f 3441 3439 3424
+f 3424 3429 3441
+f 3459 3458 3439
+f 3439 3441 3459
+f 3485 3487 3458
+f 3458 3459 3485
+f 3508 3513 3487
+f 3487 3485 3508
+f 3533 3542 3513
+f 3513 3508 3533
+f 3558 3566 3542
+f 3542 3533 3558
+f 3582 3593 3566
+f 3566 3558 3582
+f 3607 3616 3593
+f 3593 3582 3607
+f 3620 3630 3616
+f 3616 3607 3620
+f 3626 3636 3630
+f 3630 3620 3626
+f 3437 3441 3429
+f 3429 3427 3437
+f 3455 3459 3441
+f 3441 3437 3455
+f 3479 3485 3459
+f 3459 3455 3479
+f 3502 3508 3485
+f 3485 3479 3502
+f 3526 3533 3508
+f 3508 3502 3526
+f 3547 3558 3533
+f 3533 3526 3547
+f 3571 3582 3558
+f 3558 3547 3571
+f 3588 3607 3582
+f 3582 3571 3588
+f 3605 3620 3607
+f 3607 3588 3605
+f 3609 3626 3620
+f 3620 3605 3609
+f 3419 3437 3427
+f 3427 3408 3419
+f 3445 3455 3437
+f 3437 3419 3445
+f 3470 3479 3455
+f 3455 3445 3470
+f 3492 3502 3479
+f 3479 3470 3492
+f 3517 3526 3502
+f 3502 3492 3517
+f 3536 3547 3526
+f 3526 3517 3536
+f 3554 3571 3547
+f 3547 3536 3554
+f 3575 3588 3571
+f 3571 3554 3575
+f 3580 3605 3588
+f 3588 3575 3580
+f 3587 3609 3605
+f 3605 3580 3587
+f 3401 3419 3408
+f 3408 3397 3401
+f 3431 3445 3419
+f 3419 3401 3431
+f 3451 3470 3445
+f 3445 3431 3451
+f 3475 3492 3470
+f 3470 3451 3475
+f 3497 3517 3492
+f 3492 3475 3497
+f 3518 3536 3517
+f 3517 3497 3518
+f 3537 3554 3536
+f 3536 3518 3537
+f 3549 3575 3554
+f 3554 3537 3549
+f 3560 3580 3575
+f 3575 3549 3560
+f 3564 3587 3580
+f 3580 3560 3564
+f 3614 3591 3603
+f 3603 3619 3614
+f 3598 3578 3591
+f 3591 3614 3598
+f 3574 3552 3578
+f 3578 3598 3574
+f 3546 3530 3552
+f 3552 3574 3546
+f 3515 3499 3530
+f 3530 3546 3515
+f 3482 3467 3499
+f 3499 3515 3482
+f 3444 3418 3467
+f 3467 3482 3444
+f 3396 3384 3418
+f 3418 3444 3396
+f 3375 3366 3384
+f 3384 3396 3375
+f 3371 3358 3366
+f 3366 3375 3371
+f 3629 3614 3619
+f 3619 3632 3629
+f 3612 3598 3614
+f 3614 3629 3612
+f 3585 3574 3598
+f 3598 3612 3585
+f 3557 3546 3574
+f 3574 3585 3557
+f 3525 3515 3546
+f 3546 3557 3525
+f 3494 3482 3515
+f 3515 3525 3494
+f 3462 3444 3482
+f 3482 3494 3462
+f 3414 3396 3444
+f 3444 3462 3414
+f 3388 3375 3396
+f 3396 3414 3388
+f 3380 3371 3375
+f 3375 3388 3380
+f 3634 3629 3632
+f 3632 3641 3634
+f 3618 3612 3629
+f 3629 3634 3618
+f 3596 3585 3612
+f 3612 3618 3596
+f 3563 3557 3585
+f 3585 3596 3563
+f 3532 3525 3557
+f 3557 3563 3532
+f 3501 3494 3525
+f 3525 3532 3501
+f 3474 3462 3494
+f 3494 3501 3474
+f 3436 3414 3462
+f 3462 3474 3436
+f 3399 3388 3414
+f 3414 3436 3399
+f 3392 3380 3388
+f 3388 3399 3392
+f 3640 3634 3641
+f 3641 3644 3640
+f 3625 3618 3634
+f 3634 3640 3625
+f 3602 3596 3618
+f 3618 3625 3602
+f 3568 3563 3596
+f 3596 3602 3568
+f 3539 3532 3563
+f 3563 3568 3539
+f 3507 3501 3532
+f 3532 3539 3507
+f 3478 3474 3501
+f 3501 3507 3478
+f 3448 3436 3474
+f 3474 3478 3448
+f 3410 3399 3436
+f 3436 3448 3410
+f 3400 3392 3399
+f 3399 3410 3400
+f 3638 3640 3644
+f 3644 3643 3638
+f 3623 3625 3640
+f 3640 3638 3623
+f 3600 3602 3625
+f 3625 3623 3600
+f 3570 3568 3602
+f 3602 3600 3570
+f 3544 3539 3568
+f 3568 3570 3544
+f 3511 3507 3539
+f 3539 3544 3511
+f 3484 3478 3507
+f 3507 3511 3484
+f 3454 3448 3478
+f 3478 3484 3454
+f 3434 3410 3448
+f 3448 3454 3434
+f 3412 3400 3410
+f 3410 3434 3412
+f 3631 3638 3643
+f 3643 3635 3631
+f 3615 3623 3638
+f 3638 3631 3615
+f 3594 3600 3623
+f 3623 3615 3594
+f 3565 3570 3600
+f 3600 3594 3565
+f 3541 3544 3570
+f 3570 3565 3541
+f 3512 3511 3544
+f 3544 3541 3512
+f 3488 3484 3511
+f 3511 3512 3488
+f 3457 3454 3484
+f 3484 3488 3457
+f 3440 3434 3454
+f 3454 3457 3440
+f 3423 3412 3434
+f 3434 3440 3423
+f 3621 3631 3635
+f 3635 3627 3621
+f 3608 3615 3631
+f 3631 3621 3608
+f 3583 3594 3615
+f 3615 3608 3583
+f 3559 3565 3594
+f 3594 3583 3559
+f 3534 3541 3565
+f 3565 3559 3534
+f 3509 3512 3541
+f 3541 3534 3509
+f 3486 3488 3512
+f 3512 3509 3486
+f 3460 3457 3488
+f 3488 3486 3460
+f 3442 3440 3457
+f 3457 3460 3442
+f 3430 3423 3440
+f 3440 3442 3430
+f 3606 3621 3627
+f 3627 3610 3606
+f 3589 3608 3621
+f 3621 3606 3589
+f 3572 3583 3608
+f 3608 3589 3572
+f 3548 3559 3583
+f 3583 3572 3548
+f 3527 3534 3559
+f 3559 3548 3527
+f 3503 3509 3534
+f 3534 3527 3503
+f 3480 3486 3509
+f 3509 3503 3480
+f 3456 3460 3486
+f 3486 3480 3456
+f 3438 3442 3460
+f 3460 3456 3438
+f 3428 3430 3442
+f 3442 3438 3428
+f 3581 3606 3610
+f 3610 3586 3581
+f 3576 3589 3606
+f 3606 3581 3576
+f 3555 3572 3589
+f 3589 3576 3555
+f 3535 3548 3572
+f 3572 3555 3535
+f 3516 3527 3548
+f 3548 3535 3516
+f 3491 3503 3527
+f 3527 3516 3491
+f 3471 3480 3503
+f 3503 3491 3471
+f 3446 3456 3480
+f 3480 3471 3446
+f 3420 3438 3456
+f 3456 3446 3420
+f 3407 3428 3438
+f 3438 3420 3407
+f 3561 3581 3586
+f 3586 3564 3561
+f 3550 3576 3581
+f 3581 3561 3550
+f 3538 3555 3576
+f 3576 3550 3538
+f 3519 3535 3555
+f 3555 3538 3519
+f 3498 3516 3535
+f 3535 3519 3498
+f 3476 3491 3516
+f 3516 3498 3476
+f 3452 3471 3491
+f 3491 3476 3452
+f 3432 3446 3471
+f 3471 3452 3432
+f 3402 3420 3446
+f 3446 3432 3402
+f 3397 3407 3420
+f 3420 3402 3397
+f 1888 2110 2104
+f 1888 2104 2096
+f 1888 2096 2076
+f 1888 2076 2048
+f 1888 2048 2030
+f 1888 2030 2006
+f 1888 2006 1982
+f 1888 1982 1960
+f 1888 1960 1936
+f 1888 1936 1732
+f 2257 2104 2110
+f 2110 2261 2257
+f 2249 2096 2104
+f 2104 2257 2249
+f 2226 2076 2096
+f 2096 2249 2226
+f 2200 2048 2076
+f 2076 2226 2200
+f 2142 2030 2048
+f 2048 2200 2142
+f 2094 2006 2030
+f 2030 2142 2094
+f 2036 1982 2006
+f 2006 2094 2036
+f 1988 1960 1982
+f 1982 2036 1988
+f 1948 1936 1960
+f 1960 1988 1948
+f 1728 1732 1936
+f 1936 1948 1728
+f 2310 2257 2261
+f 2261 2315 2310
+f 2300 2249 2257
+f 2257 2310 2300
+f 2279 2226 2249
+f 2249 2300 2279
+f 2243 2200 2226
+f 2226 2279 2243
+f 2204 2142 2200
+f 2200 2243 2204
+f 2132 2094 2142
+f 2142 2204 2132
+f 2067 2036 2094
+f 2094 2132 2067
+f 2000 1988 2036
+f 2036 2067 2000
+f 1956 1948 1988
+f 1988 2000 1956
+f 1734 1728 1948
+f 1948 1956 1734
+f 2312 2310 2315
+f 2315 2316 2312
+f 2302 2300 2310
+f 2310 2312 2302
+f 2281 2279 2300
+f 2300 2302 2281
+f 2245 2243 2279
+f 2279 2281 2245
+f 2206 2204 2243
+f 2243 2245 2206
+f 2134 2132 2204
+f 2204 2206 2134
+f 2068 2067 2132
+f 2132 2134 2068
+f 2002 2000 2067
+f 2067 2068 2002
+f 1958 1956 2000
+f 2000 2002 1958
+f 1878 1734 1956
+f 1956 1958 1878
+f 2285 2312 2316
+f 2316 2289 2285
+f 2259 2302 2312
+f 2312 2285 2259
+f 2241 2281 2302
+f 2302 2259 2241
+f 2214 2245 2281
+f 2281 2241 2214
+f 2168 2206 2245
+f 2245 2214 2168
+f 2106 2134 2206
+f 2206 2168 2106
+f 2042 2068 2134
+f 2134 2106 2042
+f 1994 2002 2068
+f 2068 2042 1994
+f 1952 1958 2002
+f 2002 1994 1952
+f 1731 1878 1958
+f 1958 1952 1731
+f 2220 2285 2289
+f 2289 2225 2220
+f 2210 2259 2285
+f 2285 2220 2210
+f 2186 2241 2259
+f 2259 2210 2186
+f 2146 2214 2241
+f 2241 2186 2146
+f 2108 2168 2214
+f 2214 2146 2108
+f 2060 2106 2168
+f 2168 2108 2060
+f 2018 2042 2106
+f 2106 2060 2018
+f 1978 1994 2042
+f 2042 2018 1978
+f 1944 1952 1994
+f 1994 1978 1944
+f 1727 1731 1952
+f 1952 1944 1727
+f 2141 2220 2225
+f 2225 2145 2141
+f 2127 2210 2220
+f 2220 2141 2127
+f 2112 2186 2210
+f 2210 2127 2112
+f 2084 2146 2186
+f 2186 2112 2084
+f 2044 2108 2146
+f 2146 2084 2044
+f 2024 2060 2108
+f 2108 2044 2024
+f 1992 2018 2060
+f 2060 2024 1992
+f 1970 1978 2018
+f 2018 1992 1970
+f 1942 1944 1978
+f 1978 1970 1942
+f 1721 1727 1944
+f 1944 1942 1721
+f 2079 2141 2145
+f 2145 2087 2079
+f 2075 2127 2141
+f 2141 2079 2075
+f 2055 2112 2127
+f 2127 2075 2055
+f 2039 2084 2112
+f 2112 2055 2039
+f 2021 2044 2084
+f 2084 2039 2021
+f 1996 2024 2044
+f 2044 2021 1996
+f 1974 1992 2024
+f 2024 1996 1974
+f 1954 1970 1992
+f 1992 1974 1954
+f 1934 1942 1970
+f 1970 1954 1934
+f 1720 1721 1942
+f 1942 1934 1720
+f 2063 2079 2087
+f 2087 2071 2063
+f 2051 2075 2079
+f 2079 2063 2051
+f 2041 2055 2075
+f 2075 2051 2041
+f 2029 2039 2055
+f 2055 2041 2029
+f 2013 2021 2039
+f 2039 2029 2013
+f 1991 1996 2021
+f 2021 2013 1991
+f 1972 1974 1996
+f 1996 1991 1972
+f 1950 1954 1974
+f 1974 1972 1950
+f 1932 1934 1954
+f 1954 1950 1932
+f 1701 1720 1934
+f 1934 1932 1701
+f 2115 2063 2071
+f 2071 2123 2115
+f 2101 2051 2063
+f 2063 2115 2101
+f 2081 2041 2051
+f 2051 2101 2081
+f 2057 2029 2041
+f 2041 2081 2057
+f 2033 2013 2029
+f 2029 2057 2033
+f 2009 1991 2013
+f 2013 2033 2009
+f 1984 1972 1991
+f 1991 2009 1984
+f 1964 1950 1972
+f 1972 1984 1964
+f 1938 1932 1950
+f 1950 1964 1938
+f 1698 1701 1932
+f 1932 1938 1698
+f 1888 1886 1686
+f 1888 1686 1662
+f 1888 1662 1640
+f 1888 1640 1616
+f 1888 1616 1592
+f 1888 1592 1574
+f 1888 1574 1546
+f 1888 1546 1526
+f 1888 1526 1518
+f 1888 1518 1512
+f 1674 1686 1886
+f 1886 1884 1674
+f 1634 1662 1686
+f 1686 1674 1634
+f 1586 1640 1662
+f 1662 1634 1586
+f 1528 1616 1640
+f 1640 1586 1528
+f 1480 1592 1616
+f 1616 1528 1480
+f 1422 1574 1592
+f 1592 1480 1422
+f 1396 1546 1574
+f 1574 1422 1396
+f 1373 1526 1546
+f 1546 1396 1373
+f 1365 1518 1526
+f 1526 1373 1365
+f 1361 1512 1518
+f 1518 1365 1361
+f 1666 1674 1884
+f 1884 1882 1666
+f 1622 1634 1674
+f 1674 1666 1622
+f 1557 1586 1634
+f 1634 1622 1557
+f 1490 1528 1586
+f 1586 1557 1490
+f 1418 1480 1528
+f 1528 1490 1418
+f 1379 1422 1480
+f 1480 1418 1379
+f 1343 1396 1422
+f 1422 1379 1343
+f 1322 1373 1396
+f 1396 1343 1322
+f 1312 1365 1373
+f 1373 1322 1312
+f 1309 1361 1365
+f 1365 1312 1309
+f 1664 1666 1882
+f 1882 1879 1664
+f 1620 1622 1666
+f 1666 1664 1620
+f 1554 1557 1622
+f 1622 1620 1554
+f 1488 1490 1557
+f 1557 1554 1488
+f 1416 1418 1490
+f 1490 1488 1416
+f 1377 1379 1418
+f 1418 1416 1377
+f 1341 1343 1379
+f 1379 1377 1341
+f 1320 1322 1343
+f 1343 1341 1320
+f 1310 1312 1322
+f 1322 1320 1310
+f 1306 1309 1312
+f 1312 1310 1306
+f 1670 1664 1879
+f 1879 1876 1670
+f 1628 1620 1664
+f 1664 1670 1628
+f 1580 1554 1620
+f 1620 1628 1580
+f 1516 1488 1554
+f 1554 1580 1516
+f 1454 1416 1488
+f 1488 1516 1454
+f 1408 1377 1416
+f 1416 1454 1408
+f 1381 1341 1377
+f 1377 1408 1381
+f 1363 1320 1341
+f 1341 1381 1363
+f 1337 1310 1320
+f 1320 1363 1337
+f 1333 1306 1310
+f 1310 1337 1333
+f 1678 1670 1876
+f 1876 1874 1678
+f 1644 1628 1670
+f 1670 1678 1644
+f 1604 1580 1628
+f 1628 1644 1604
+f 1562 1516 1580
+f 1580 1604 1562
+f 1514 1454 1516
+f 1516 1562 1514
+f 1476 1408 1454
+f 1454 1514 1476
+f 1436 1381 1408
+f 1408 1476 1436
+f 1412 1363 1381
+f 1381 1436 1412
+f 1402 1337 1363
+f 1363 1412 1402
+f 1399 1333 1337
+f 1337 1402 1399
+f 1680 1678 1874
+f 1874 1872 1680
+f 1652 1644 1678
+f 1678 1680 1652
+f 1630 1604 1644
+f 1644 1652 1630
+f 1598 1562 1604
+f 1604 1630 1598
+f 1578 1514 1562
+f 1562 1598 1578
+f 1538 1476 1514
+f 1514 1578 1538
+f 1510 1436 1476
+f 1476 1538 1510
+f 1497 1412 1436
+f 1436 1510 1497
+f 1483 1402 1412
+f 1412 1497 1483
+f 1479 1399 1402
+f 1402 1483 1479
+f 1688 1680 1872
+f 1872 1870 1688
+f 1668 1652 1680
+f 1680 1688 1668
+f 1648 1630 1652
+f 1652 1668 1648
+f 1626 1598 1630
+f 1630 1648 1626
+f 1603 1578 1598
+f 1598 1626 1603
+f 1585 1538 1578
+f 1578 1603 1585
+f 1569 1510 1538
+f 1538 1585 1569
+f 1549 1497 1510
+f 1510 1569 1549
+f 1545 1483 1497
+f 1497 1549 1545
+f 1537 1479 1483
+f 1483 1545 1537
+f 1690 1688 1870
+f 1870 1868 1690
+f 1672 1668 1688
+f 1688 1690 1672
+f 1650 1648 1668
+f 1668 1672 1650
+f 1633 1626 1648
+f 1648 1650 1633
+f 1611 1603 1626
+f 1626 1633 1611
+f 1595 1585 1603
+f 1603 1611 1595
+f 1583 1569 1585
+f 1585 1595 1583
+f 1573 1549 1569
+f 1569 1583 1573
+f 1561 1545 1549
+f 1549 1573 1561
+f 1553 1537 1545
+f 1545 1561 1553
+f 1684 1690 1868
+f 1868 1865 1684
+f 1658 1672 1690
+f 1690 1684 1658
+f 1638 1650 1672
+f 1672 1658 1638
+f 1615 1633 1650
+f 1650 1638 1615
+f 1591 1611 1633
+f 1633 1615 1591
+f 1567 1595 1611
+f 1611 1591 1567
+f 1543 1583 1595
+f 1595 1567 1543
+f 1523 1573 1583
+f 1583 1543 1523
+f 1509 1561 1573
+f 1573 1523 1509
+f 1501 1553 1561
+f 1561 1509 1501
+f 1888 1513 1519
+f 1888 1519 1527
+f 1888 1527 1547
+f 1888 1547 1575
+f 1888 1575 1593
+f 1888 1593 1617
+f 1888 1617 1641
+f 1888 1641 1663
+f 1888 1663 1687
+f 1888 1687 1894
+f 1366 1519 1513
+f 1513 1362 1366
+f 1374 1527 1519
+f 1519 1366 1374
+f 1397 1547 1527
+f 1527 1374 1397
+f 1423 1575 1547
+f 1547 1397 1423
+f 1481 1593 1575
+f 1575 1423 1481
+f 1529 1617 1593
+f 1593 1481 1529
+f 1587 1641 1617
+f 1617 1529 1587
+f 1635 1663 1641
+f 1641 1587 1635
+f 1675 1687 1663
+f 1663 1635 1675
+f 1895 1894 1687
+f 1687 1675 1895
+f 1313 1366 1362
+f 1362 1308 1313
+f 1323 1374 1366
+f 1366 1313 1323
+f 1344 1397 1374
+f 1374 1323 1344
+f 1380 1423 1397
+f 1397 1344 1380
+f 1419 1481 1423
+f 1423 1380 1419
+f 1491 1529 1481
+f 1481 1419 1491
+f 1556 1587 1529
+f 1529 1491 1556
+f 1623 1635 1587
+f 1587 1556 1623
+f 1667 1675 1635
+f 1635 1623 1667
+f 1890 1895 1675
+f 1675 1667 1890
+f 1311 1313 1308
+f 1308 1307 1311
+f 1321 1323 1313
+f 1313 1311 1321
+f 1342 1344 1323
+f 1323 1321 1342
+f 1378 1380 1344
+f 1344 1342 1378
+f 1417 1419 1380
+f 1380 1378 1417
+f 1489 1491 1419
+f 1419 1417 1489
+f 1555 1556 1491
+f 1491 1489 1555
+f 1621 1623 1556
+f 1556 1555 1621
+f 1665 1667 1623
+f 1623 1621 1665
+f 1881 1890 1667
+f 1667 1665 1881
+f 1338 1311 1307
+f 1307 1334 1338
+f 1364 1321 1311
+f 1311 1338 1364
+f 1382 1342 1321
+f 1321 1364 1382
+f 1409 1378 1342
+f 1342 1382 1409
+f 1455 1417 1378
+f 1378 1409 1455
+f 1517 1489 1417
+f 1417 1455 1517
+f 1581 1555 1489
+f 1489 1517 1581
+f 1629 1621 1555
+f 1555 1581 1629
+f 1671 1665 1621
+f 1621 1629 1671
+f 1893 1881 1665
+f 1665 1671 1893
+f 1403 1338 1334
+f 1334 1398 1403
+f 1413 1364 1338
+f 1338 1403 1413
+f 1437 1382 1364
+f 1364 1413 1437
+f 1477 1409 1382
+f 1382 1437 1477
+f 1515 1455 1409
+f 1409 1477 1515
+f 1563 1517 1455
+f 1455 1515 1563
+f 1605 1581 1517
+f 1517 1563 1605
+f 1645 1629 1581
+f 1581 1605 1645
+f 1679 1671 1629
+f 1629 1645 1679
+f 1900 1893 1671
+f 1671 1679 1900
+f 1482 1403 1398
+f 1398 1478 1482
+f 1496 1413 1403
+f 1403 1482 1496
+f 1511 1437 1413
+f 1413 1496 1511
+f 1539 1477 1437
+f 1437 1511 1539
+f 1579 1515 1477
+f 1477 1539 1579
+f 1599 1563 1515
+f 1515 1579 1599
+f 1631 1605 1563
+f 1563 1599 1631
+f 1653 1645 1605
+f 1605 1631 1653
+f 1681 1679 1645
+f 1645 1653 1681
+f 1902 1900 1679
+f 1679 1681 1902
+f 1544 1482 1478
+f 1478 1536 1544
+f 1548 1496 1482
+f 1482 1544 1548
+f 1568 1511 1496
+f 1496 1548 1568
+f 1584 1539 1511
+f 1511 1568 1584
+f 1602 1579 1539
+f 1539 1584 1602
+f 1627 1599 1579
+f 1579 1602 1627
+f 1649 1631 1599
+f 1599 1627 1649
+f 1669 1653 1631
+f 1631 1649 1669
+f 1689 1681 1653
+f 1653 1669 1689
+f 1921 1902 1681
+f 1681 1689 1921
+f 1560 1544 1536
+f 1536 1552 1560
+f 1572 1548 1544
+f 1544 1560 1572
+f 1582 1568 1548
+f 1548 1572 1582
+f 1594 1584 1568
+f 1568 1582 1594
+f 1610 1602 1584
+f 1584 1594 1610
+f 1632 1627 1602
+f 1602 1610 1632
+f 1651 1649 1627
+f 1627 1632 1651
+f 1673 1669 1649
+f 1649 1651 1673
+f 1691 1689 1669
+f 1669 1673 1691
+f 1922 1921 1689
+f 1689 1691 1922
+f 1508 1560 1552
+f 1552 1500 1508
+f 1522 1572 1560
+f 1560 1508 1522
+f 1542 1582 1572
+f 1572 1522 1542
+f 1566 1594 1582
+f 1582 1542 1566
+f 1590 1610 1594
+f 1594 1566 1590
+f 1614 1632 1610
+f 1610 1590 1614
+f 1639 1651 1632
+f 1632 1614 1639
+f 1659 1673 1651
+f 1651 1639 1659
+f 1685 1691 1673
+f 1673 1659 1685
+f 1928 1922 1691
+f 1691 1685 1928
+f 1888 1887 1937
+f 1888 1937 1961
+f 1888 1961 1983
+f 1888 1983 2007
+f 1888 2007 2031
+f 1888 2031 2049
+f 1888 2049 2077
+f 1888 2077 2097
+f 1888 2097 2105
+f 1888 2105 2111
+f 1949 1937 1887
+f 1887 1885 1949
+f 1989 1961 1937
+f 1937 1949 1989
+f 2037 1983 1961
+f 1961 1989 2037
+f 2095 2007 1983
+f 1983 2037 2095
+f 2143 2031 2007
+f 2007 2095 2143
+f 2201 2049 2031
+f 2031 2143 2201
+f 2227 2077 2049
+f 2049 2201 2227
+f 2250 2097 2077
+f 2077 2227 2250
+f 2258 2105 2097
+f 2097 2250 2258
+f 2262 2111 2105
+f 2105 2258 2262
+f 1957 1949 1885
+f 1885 1883 1957
+f 2001 1989 1949
+f 1949 1957 2001
+f 2066 2037 1989
+f 1989 2001 2066
+f 2133 2095 2037
+f 2037 2066 2133
+f 2205 2143 2095
+f 2095 2133 2205
+f 2244 2201 2143
+f 2143 2205 2244
+f 2280 2227 2201
+f 2201 2244 2280
+f 2301 2250 2227
+f 2227 2280 2301
+f 2311 2258 2250
+f 2250 2301 2311
+f 2314 2262 2258
+f 2258 2311 2314
+f 1959 1957 1883
+f 1883 1880 1959
+f 2003 2001 1957
+f 1957 1959 2003
+f 2069 2066 2001
+f 2001 2003 2069
+f 2135 2133 2066
+f 2066 2069 2135
+f 2207 2205 2133
+f 2133 2135 2207
+f 2246 2244 2205
+f 2205 2207 2246
+f 2282 2280 2244
+f 2244 2246 2282
+f 2303 2301 2280
+f 2280 2282 2303
+f 2313 2311 2301
+f 2301 2303 2313
+f 2317 2314 2311
+f 2311 2313 2317
+f 1953 1959 1880
+f 1880 1877 1953
+f 1995 2003 1959
+f 1959 1953 1995
+f 2043 2069 2003
+f 2003 1995 2043
+f 2107 2135 2069
+f 2069 2043 2107
+f 2169 2207 2135
+f 2135 2107 2169
+f 2215 2246 2207
+f 2207 2169 2215
+f 2242 2282 2246
+f 2246 2215 2242
+f 2260 2303 2282
+f 2282 2242 2260
+f 2286 2313 2303
+f 2303 2260 2286
+f 2290 2317 2313
+f 2313 2286 2290
+f 1945 1953 1877
+f 1877 1875 1945
+f 1979 1995 1953
+f 1953 1945 1979
+f 2019 2043 1995
+f 1995 1979 2019
+f 2061 2107 2043
+f 2043 2019 2061
+f 2109 2169 2107
+f 2107 2061 2109
+f 2147 2215 2169
+f 2169 2109 2147
+f 2187 2242 2215
+f 2215 2147 2187
+f 2211 2260 2242
+f 2242 2187 2211
+f 2221 2286 2260
+f 2260 2211 2221
+f 2224 2290 2286
+f 2286 2221 2224
+f 1943 1945 1875
+f 1875 1873 1943
+f 1971 1979 1945
+f 1945 1943 1971
+f 1993 2019 1979
+f 1979 1971 1993
+f 2025 2061 2019
+f 2019 1993 2025
+f 2045 2109 2061
+f 2061 2025 2045
+f 2085 2147 2109
+f 2109 2045 2085
+f 2113 2187 2147
+f 2147 2085 2113
+f 2126 2211 2187
+f 2187 2113 2126
+f 2140 2221 2211
+f 2211 2126 2140
+f 2144 2224 2221
+f 2221 2140 2144
+f 1935 1943 1873
+f 1873 1871 1935
+f 1955 1971 1943
+f 1943 1935 1955
+f 1975 1993 1971
+f 1971 1955 1975
+f 1997 2025 1993
+f 1993 1975 1997
+f 2020 2045 2025
+f 2025 1997 2020
+f 2038 2085 2045
+f 2045 2020 2038
+f 2054 2113 2085
+f 2085 2038 2054
+f 2074 2126 2113
+f 2113 2054 2074
+f 2078 2140 2126
+f 2126 2074 2078
+f 2086 2144 2140
+f 2140 2078 2086
+f 1933 1935 1871
+f 1871 1869 1933
+f 1951 1955 1935
+f 1935 1933 1951
+f 1973 1975 1955
+f 1955 1951 1973
+f 1990 1997 1975
+f 1975 1973 1990
+f 2012 2020 1997
+f 1997 1990 2012
+f 2028 2038 2020
+f 2020 2012 2028
+f 2040 2054 2038
+f 2038 2028 2040
+f 2050 2074 2054
+f 2054 2040 2050
+f 2062 2078 2074
+f 2074 2050 2062
+f 2070 2086 2078
+f 2078 2062 2070
+f 1939 1933 1869
+f 1869 1866 1939
+f 1965 1951 1933
+f 1933 1939 1965
+f 1985 1973 1951
+f 1951 1965 1985
+f 2008 1990 1973
+f 1973 1985 2008
+f 2032 2012 1990
+f 1990 2008 2032
+f 2056 2028 2012
+f 2012 2032 2056
+f 2080 2040 2028
+f 2028 2056 2080
+f 2100 2050 2040
+f 2040 2080 2100
+f 2114 2062 2050
+f 2050 2100 2114
+f 2122 2070 2062
+f 2062 2114 2122
+f 2232 2116 2124
+f 2124 2236 2232
+f 2218 2102 2116
+f 2116 2232 2218
+f 2199 2082 2102
+f 2102 2218 2199
+f 2150 2058 2082
+f 2082 2199 2150
+f 2120 2034 2058
+f 2058 2150 2120
+f 2064 2010 2034
+f 2034 2120 2064
+f 2023 1986 2010
+f 2010 2064 2023
+f 1980 1966 1986
+f 1986 2023 1980
+f 1946 1940 1966
+f 1966 1980 1946
+f 1862 1730 1940
+f 1940 1946 1862
+f 2332 2232 2236
+f 2236 2336 2332
+f 2322 2218 2232
+f 2232 2332 2322
+f 2306 2199 2218
+f 2218 2322 2306
+f 2275 2150 2199
+f 2199 2306 2275
+f 2234 2120 2150
+f 2150 2275 2234
+f 2170 2064 2120
+f 2120 2234 2170
+f 2093 2023 2064
+f 2064 2170 2093
+f 2016 1980 2023
+f 2023 2093 2016
+f 1968 1946 1980
+f 1980 2016 1968
+f 1858 1862 1946
+f 1946 1968 1858
+f 2409 2332 2336
+f 2336 2413 2409
+f 2400 2322 2332
+f 2332 2409 2400
+f 2376 2306 2322
+f 2322 2400 2376
+f 2349 2275 2306
+f 2306 2376 2349
+f 2324 2234 2275
+f 2275 2349 2324
+f 2271 2170 2234
+f 2234 2324 2271
+f 2185 2093 2170
+f 2170 2271 2185
+f 2072 2016 2093
+f 2093 2185 2072
+f 1976 1968 2016
+f 2016 2072 1976
+f 1729 1858 1968
+f 1968 1976 1729
+f 2488 2409 2413
+f 2413 2498 2488
+f 2470 2400 2409
+f 2409 2488 2470
+f 2444 2376 2400
+f 2400 2470 2444
+f 2418 2349 2376
+f 2376 2444 2418
+f 2384 2324 2349
+f 2349 2418 2384
+f 2338 2271 2324
+f 2324 2384 2338
+f 2269 2185 2271
+f 2271 2338 2269
+f 2138 2072 2185
+f 2185 2269 2138
+f 1998 1976 2072
+f 2072 2138 1998
+f 1722 1729 1976
+f 1976 1998 1722
+f 2559 2488 2498
+f 2498 2569 2559
+f 2549 2470 2488
+f 2488 2559 2549
+f 2531 2444 2470
+f 2470 2549 2531
+f 2492 2418 2444
+f 2444 2531 2492
+f 2436 2384 2418
+f 2418 2492 2436
+f 2394 2338 2384
+f 2384 2436 2394
+f 2326 2269 2338
+f 2338 2394 2326
+f 2212 2138 2269
+f 2269 2326 2212
+f 2026 1998 2138
+f 2138 2212 2026
+f 1850 1722 1998
+f 1998 2026 1850
+f 2653 2559 2569
+f 2569 2655 2653
+f 2631 2549 2559
+f 2559 2653 2631
+f 2593 2531 2549
+f 2549 2631 2593
+f 2551 2492 2531
+f 2531 2593 2551
+f 2510 2436 2492
+f 2492 2551 2510
+f 2432 2394 2436
+f 2436 2510 2432
+f 2366 2326 2394
+f 2394 2432 2366
+f 2263 2212 2326
+f 2326 2366 2263
+f 2052 2026 2212
+f 2212 2263 2052
+f 1726 1850 2026
+f 2026 2052 1726
+f 2720 2653 2655
+f 2655 2726 2720
+f 2697 2631 2653
+f 2653 2720 2697
+f 2662 2593 2631
+f 2631 2697 2662
+f 2607 2551 2593
+f 2593 2662 2607
+f 2547 2510 2551
+f 2551 2607 2547
+f 2484 2432 2510
+f 2510 2547 2484
+f 2405 2366 2432
+f 2432 2484 2405
+f 2308 2263 2366
+f 2366 2405 2308
+f 2090 2052 2263
+f 2263 2308 2090
+f 1719 1726 2052
+f 2052 2090 1719
+f 2787 2720 2726
+f 2726 2795 2787
+f 2759 2697 2720
+f 2720 2787 2759
+f 2713 2662 2697
+f 2697 2759 2713
+f 2657 2607 2662
+f 2662 2713 2657
+f 2589 2547 2607
+f 2607 2657 2589
+f 2525 2484 2547
+f 2547 2589 2525
+f 2422 2405 2484
+f 2484 2525 2422
+f 2330 2308 2405
+f 2405 2422 2330
+f 2118 2090 2308
+f 2308 2330 2118
+f 1700 1719 2090
+f 2090 2118 1700
+f 2834 2787 2795
+f 2795 2844 2834
+f 2798 2759 2787
+f 2787 2834 2798
+f 2750 2713 2759
+f 2759 2798 2750
+f 2690 2657 2713
+f 2713 2750 2690
+f 2624 2589 2657
+f 2657 2690 2624
+f 2536 2525 2589
+f 2589 2624 2536
+f 2441 2422 2525
+f 2525 2536 2441
+f 2340 2330 2422
+f 2422 2441 2340
+f 2128 2118 2330
+f 2330 2340 2128
+f 1825 1700 2118
+f 2118 2128 1825
+f 2847 2834 2844
+f 2844 2857 2847
+f 2821 2798 2834
+f 2834 2847 2821
+f 2765 2750 2798
+f 2798 2821 2765
+f 2703 2690 2750
+f 2750 2765 2703
+f 2637 2624 2690
+f 2690 2703 2637
+f 2543 2536 2624
+f 2624 2637 2543
+f 2446 2441 2536
+f 2536 2543 2446
+f 2344 2340 2441
+f 2441 2446 2344
+f 2136 2128 2340
+f 2340 2344 2136
+f 1713 1825 2128
+f 2128 2136 1713
+f 1676 1682 1864
+f 1864 1862 1676
+f 1642 1656 1682
+f 1682 1676 1642
+f 1601 1636 1656
+f 1656 1642 1601
+f 1558 1612 1636
+f 1636 1601 1558
+f 1502 1588 1612
+f 1612 1558 1502
+f 1472 1564 1588
+f 1588 1502 1472
+f 1425 1540 1564
+f 1564 1472 1425
+f 1404 1520 1540
+f 1540 1425 1404
+f 1390 1506 1520
+f 1520 1404 1390
+f 1387 1498 1506
+f 1506 1390 1387
+f 1654 1676 1862
+f 1862 1859 1654
+f 1606 1642 1676
+f 1676 1654 1606
+f 1531 1601 1642
+f 1642 1606 1531
+f 1452 1558 1601
+f 1601 1531 1452
+f 1388 1502 1558
+f 1558 1452 1388
+f 1347 1472 1502
+f 1502 1388 1347
+f 1316 1425 1472
+f 1472 1347 1316
+f 1300 1404 1425
+f 1425 1316 1300
+f 1290 1390 1404
+f 1404 1300 1290
+f 1286 1387 1390
+f 1390 1290 1286
+f 1646 1654 1859
+f 1859 1856 1646
+f 1550 1606 1654
+f 1654 1646 1550
+f 1439 1531 1606
+f 1606 1550 1439
+f 1351 1452 1531
+f 1531 1439 1351
+f 1298 1388 1452
+f 1452 1351 1298
+f 1275 1347 1388
+f 1388 1298 1275
+f 1246 1316 1347
+f 1347 1275 1246
+f 1222 1300 1316
+f 1316 1246 1222
+f 1215 1290 1300
+f 1300 1222 1215
+f 1211 1286 1290
+f 1290 1215 1211
+f 1624 1646 1856
+f 1856 1854 1624
+f 1484 1550 1646
+f 1646 1624 1484
+f 1353 1439 1550
+f 1550 1484 1353
+f 1284 1351 1439
+f 1439 1353 1284
+f 1238 1298 1351
+f 1351 1284 1238
+f 1204 1275 1298
+f 1298 1238 1204
+f 1178 1246 1275
+f 1275 1204 1178
+f 1152 1222 1246
+f 1246 1178 1152
+f 1134 1215 1222
+f 1222 1152 1134
+f 1124 1211 1215
+f 1215 1134 1124
+f 1596 1624 1854
+f 1854 1851 1596
+f 1410 1484 1624
+f 1624 1596 1410
+f 1296 1353 1484
+f 1484 1410 1296
+f 1228 1284 1353
+f 1353 1296 1228
+f 1186 1238 1284
+f 1284 1228 1186
+f 1130 1204 1238
+f 1238 1186 1130
+f 1091 1178 1204
+f 1204 1130 1091
+f 1073 1152 1178
+f 1178 1091 1073
+f 1063 1134 1152
+f 1152 1073 1063
+f 1053 1124 1134
+f 1134 1063 1053
+f 1570 1596 1851
+f 1851 1848 1570
+f 1359 1410 1596
+f 1596 1570 1359
+f 1256 1296 1410
+f 1410 1359 1256
+f 1190 1228 1296
+f 1296 1256 1190
+f 1112 1186 1228
+f 1228 1190 1112
+f 1071 1130 1186
+f 1186 1112 1071
+f 1029 1091 1130
+f 1130 1071 1029
+f 991 1073 1091
+f 1091 1029 991
+f 969 1063 1073
+f 1073 991 969
+f 967 1053 1063
+f 1063 969 967
+f 1532 1570 1848
+f 1848 1846 1532
+f 1314 1359 1570
+f 1570 1532 1314
+f 1219 1256 1359
+f 1359 1314 1219
+f 1138 1190 1256
+f 1256 1219 1138
+f 1075 1112 1190
+f 1190 1138 1075
+f 1015 1071 1112
+f 1112 1075 1015
+f 962 1029 1071
+f 1071 1015 962
+f 925 991 1029
+f 1029 962 925
+f 904 969 991
+f 991 925 904
+f 898 967 969
+f 969 904 898
+f 1504 1532 1846
+f 1846 1832 1504
+f 1292 1314 1532
+f 1532 1504 1292
+f 1200 1219 1314
+f 1314 1292 1200
+f 1097 1138 1219
+f 1219 1200 1097
+f 1033 1075 1138
+f 1138 1097 1033
+f 965 1015 1075
+f 1075 1033 965
+f 909 962 1015
+f 1015 965 909
+f 863 925 962
+f 962 909 863
+f 835 904 925
+f 925 863 835
+f 827 898 904
+f 904 835 827
+f 1494 1504 1832
+f 1832 1824 1494
+f 1282 1292 1504
+f 1504 1494 1282
+f 1183 1200 1292
+f 1292 1282 1183
+f 1088 1097 1200
+f 1200 1183 1088
+f 1000 1033 1097
+f 1097 1088 1000
+f 934 965 1033
+f 1033 1000 934
+f 874 909 965
+f 965 934 874
+f 826 863 909
+f 909 874 826
+f 790 835 863
+f 863 826 790
+f 780 827 835
+f 835 790 780
+f 1486 1494 1824
+f 1824 1814 1486
+f 1278 1282 1494
+f 1494 1486 1278
+f 1176 1183 1282
+f 1282 1278 1176
+f 1079 1088 1183
+f 1183 1176 1079
+f 985 1000 1088
+f 1088 1079 985
+f 919 934 1000
+f 1000 985 919
+f 857 874 934
+f 934 919 857
+f 801 826 874
+f 874 857 801
+f 775 790 826
+f 826 801 775
+f 765 780 790
+f 790 775 765
+f 1391 1507 1499
+f 1499 1387 1391
+f 1405 1521 1507
+f 1507 1391 1405
+f 1424 1541 1521
+f 1521 1405 1424
+f 1473 1565 1541
+f 1541 1424 1473
+f 1503 1589 1565
+f 1565 1473 1503
+f 1559 1613 1589
+f 1589 1503 1559
+f 1600 1637 1613
+f 1613 1559 1600
+f 1643 1657 1637
+f 1637 1600 1643
+f 1677 1683 1657
+f 1657 1643 1677
+f 1863 1892 1683
+f 1683 1677 1863
+f 1291 1391 1387
+f 1387 1287 1291
+f 1301 1405 1391
+f 1391 1291 1301
+f 1317 1424 1405
+f 1405 1301 1317
+f 1348 1473 1424
+f 1424 1317 1348
+f 1389 1503 1473
+f 1473 1348 1389
+f 1453 1559 1503
+f 1503 1389 1453
+f 1530 1600 1559
+f 1559 1453 1530
+f 1607 1643 1600
+f 1600 1530 1607
+f 1655 1677 1643
+f 1643 1607 1655
+f 1861 1863 1677
+f 1677 1655 1861
+f 1214 1291 1287
+f 1287 1210 1214
+f 1223 1301 1291
+f 1291 1214 1223
+f 1247 1317 1301
+f 1301 1223 1247
+f 1274 1348 1317
+f 1317 1247 1274
+f 1299 1389 1348
+f 1348 1274 1299
+f 1352 1453 1389
+f 1389 1299 1352
+f 1438 1530 1453
+f 1453 1352 1438
+f 1551 1607 1530
+f 1530 1438 1551
+f 1647 1655 1607
+f 1607 1551 1647
+f 1891 1861 1655
+f 1655 1647 1891
+f 1135 1214 1210
+f 1210 1125 1135
+f 1153 1223 1214
+f 1214 1135 1153
+f 1179 1247 1223
+f 1223 1153 1179
+f 1205 1274 1247
+f 1247 1179 1205
+f 1239 1299 1274
+f 1274 1205 1239
+f 1285 1352 1299
+f 1299 1239 1285
+f 1354 1438 1352
+f 1352 1285 1354
+f 1485 1551 1438
+f 1438 1354 1485
+f 1625 1647 1551
+f 1551 1485 1625
+f 1901 1891 1647
+f 1647 1625 1901
+f 1064 1135 1125
+f 1125 1054 1064
+f 1074 1153 1135
+f 1135 1064 1074
+f 1092 1179 1153
+f 1153 1074 1092
+f 1131 1205 1179
+f 1179 1092 1131
+f 1187 1239 1205
+f 1205 1131 1187
+f 1229 1285 1239
+f 1239 1187 1229
+f 1297 1354 1285
+f 1285 1229 1297
+f 1411 1485 1354
+f 1354 1297 1411
+f 1597 1625 1485
+f 1485 1411 1597
+f 1853 1901 1625
+f 1625 1597 1853
+f 970 1064 1054
+f 1054 968 970
+f 992 1074 1064
+f 1064 970 992
+f 1030 1092 1074
+f 1074 992 1030
+f 1072 1131 1092
+f 1092 1030 1072
+f 1113 1187 1131
+f 1131 1072 1113
+f 1191 1229 1187
+f 1187 1113 1191
+f 1257 1297 1229
+f 1229 1191 1257
+f 1360 1411 1297
+f 1297 1257 1360
+f 1571 1597 1411
+f 1411 1360 1571
+f 1899 1853 1597
+f 1597 1571 1899
+f 903 970 968
+f 968 897 903
+f 926 992 970
+f 970 903 926
+f 961 1030 992
+f 992 926 961
+f 1016 1072 1030
+f 1030 961 1016
+f 1076 1113 1072
+f 1072 1016 1076
+f 1139 1191 1113
+f 1113 1076 1139
+f 1218 1257 1191
+f 1191 1139 1218
+f 1315 1360 1257
+f 1257 1218 1315
+f 1533 1571 1360
+f 1360 1315 1533
+f 1920 1899 1571
+f 1571 1533 1920
+f 836 903 897
+f 897 828 836
+f 864 926 903
+f 903 836 864
+f 910 961 926
+f 926 864 910
+f 966 1016 961
+f 961 910 966
+f 1034 1076 1016
+f 1016 966 1034
+f 1098 1139 1076
+f 1076 1034 1098
+f 1201 1218 1139
+f 1139 1098 1201
+f 1293 1315 1218
+f 1218 1201 1293
+f 1505 1533 1315
+f 1315 1293 1505
+f 1924 1920 1533
+f 1533 1505 1924
+f 789 836 828
+f 828 779 789
+f 825 864 836
+f 836 789 825
+f 873 910 864
+f 864 825 873
+f 933 966 910
+f 910 873 933
+f 999 1034 966
+f 966 933 999
+f 1087 1098 1034
+f 1034 999 1087
+f 1182 1201 1098
+f 1098 1087 1182
+f 1283 1293 1201
+f 1201 1182 1283
+f 1495 1505 1293
+f 1293 1283 1495
+f 1826 1924 1505
+f 1505 1495 1826
+f 776 789 779
+f 779 766 776
+f 802 825 789
+f 789 776 802
+f 858 873 825
+f 825 802 858
+f 920 933 873
+f 873 858 920
+f 986 999 933
+f 933 920 986
+f 1080 1087 999
+f 999 986 1080
+f 1177 1182 1087
+f 1087 1080 1177
+f 1279 1283 1182
+f 1182 1177 1279
+f 1487 1495 1283
+f 1283 1279 1487
+f 1914 1826 1495
+f 1495 1487 1914
+f 1947 1941 1867
+f 1867 1863 1947
+f 1981 1967 1941
+f 1941 1947 1981
+f 2022 1987 1967
+f 1967 1981 2022
+f 2065 2011 1987
+f 1987 2022 2065
+f 2121 2035 2011
+f 2011 2065 2121
+f 2151 2059 2035
+f 2035 2121 2151
+f 2198 2083 2059
+f 2059 2151 2198
+f 2219 2103 2083
+f 2083 2198 2219
+f 2233 2117 2103
+f 2103 2219 2233
+f 2236 2125 2117
+f 2117 2233 2236
+f 1969 1947 1863
+f 1863 1860 1969
+f 2017 1981 1947
+f 1947 1969 2017
+f 2092 2022 1981
+f 1981 2017 2092
+f 2171 2065 2022
+f 2022 2092 2171
+f 2235 2121 2065
+f 2065 2171 2235
+f 2276 2151 2121
+f 2121 2235 2276
+f 2307 2198 2151
+f 2151 2276 2307
+f 2323 2219 2198
+f 2198 2307 2323
+f 2333 2233 2219
+f 2219 2323 2333
+f 2337 2236 2233
+f 2233 2333 2337
+f 1977 1969 1860
+f 1860 1857 1977
+f 2073 2017 1969
+f 1969 1977 2073
+f 2184 2092 2017
+f 2017 2073 2184
+f 2272 2171 2092
+f 2092 2184 2272
+f 2325 2235 2171
+f 2171 2272 2325
+f 2348 2276 2235
+f 2235 2325 2348
+f 2377 2307 2276
+f 2276 2348 2377
+f 2401 2323 2307
+f 2307 2377 2401
+f 2408 2333 2323
+f 2323 2401 2408
+f 2412 2337 2333
+f 2333 2408 2412
+f 1999 1977 1857
+f 1857 1855 1999
+f 2139 2073 1977
+f 1977 1999 2139
+f 2270 2184 2073
+f 2073 2139 2270
+f 2339 2272 2184
+f 2184 2270 2339
+f 2385 2325 2272
+f 2272 2339 2385
+f 2419 2348 2325
+f 2325 2385 2419
+f 2445 2377 2348
+f 2348 2419 2445
+f 2471 2401 2377
+f 2377 2445 2471
+f 2489 2408 2401
+f 2401 2471 2489
+f 2499 2412 2408
+f 2408 2489 2499
+f 2027 1999 1855
+f 1855 1852 2027
+f 2213 2139 1999
+f 1999 2027 2213
+f 2327 2270 2139
+f 2139 2213 2327
+f 2395 2339 2270
+f 2270 2327 2395
+f 2437 2385 2339
+f 2339 2395 2437
+f 2493 2419 2385
+f 2385 2437 2493
+f 2532 2445 2419
+f 2419 2493 2532
+f 2550 2471 2445
+f 2445 2532 2550
+f 2560 2489 2471
+f 2471 2550 2560
+f 2570 2499 2489
+f 2489 2560 2570
+f 2053 2027 1852
+f 1852 1849 2053
+f 2264 2213 2027
+f 2027 2053 2264
+f 2367 2327 2213
+f 2213 2264 2367
+f 2433 2395 2327
+f 2327 2367 2433
+f 2511 2437 2395
+f 2395 2433 2511
+f 2552 2493 2437
+f 2437 2511 2552
+f 2594 2532 2493
+f 2493 2552 2594
+f 2632 2550 2532
+f 2532 2594 2632
+f 2654 2560 2550
+f 2550 2632 2654
+f 2656 2570 2560
+f 2560 2654 2656
+f 2091 2053 1849
+f 1849 1847 2091
+f 2309 2264 2053
+f 2053 2091 2309
+f 2404 2367 2264
+f 2264 2309 2404
+f 2485 2433 2367
+f 2367 2404 2485
+f 2548 2511 2433
+f 2433 2485 2548
+f 2608 2552 2511
+f 2511 2548 2608
+f 2661 2594 2552
+f 2552 2608 2661
+f 2698 2632 2594
+f 2594 2661 2698
+f 2719 2654 2632
+f 2632 2698 2719
+f 2725 2656 2654
+f 2654 2719 2725
+f 2119 2091 1847
+f 1847 1833 2119
+f 2331 2309 2091
+f 2091 2119 2331
+f 2423 2404 2309
+f 2309 2331 2423
+f 2526 2485 2404
+f 2404 2423 2526
+f 2590 2548 2485
+f 2485 2526 2590
+f 2658 2608 2548
+f 2548 2590 2658
+f 2714 2661 2608
+f 2608 2658 2714
+f 2760 2698 2661
+f 2661 2714 2760
+f 2788 2719 2698
+f 2698 2760 2788
+f 2796 2725 2719
+f 2719 2788 2796
+f 2129 2119 1833
+f 1833 1827 2129
+f 2341 2331 2119
+f 2119 2129 2341
+f 2440 2423 2331
+f 2331 2341 2440
+f 2535 2526 2423
+f 2423 2440 2535
+f 2623 2590 2526
+f 2526 2535 2623
+f 2689 2658 2590
+f 2590 2623 2689
+f 2749 2714 2658
+f 2658 2689 2749
+f 2797 2760 2714
+f 2714 2749 2797
+f 2833 2788 2760
+f 2760 2797 2833
+f 2843 2796 2788
+f 2788 2833 2843
+f 2137 2129 1827
+f 1827 1815 2137
+f 2345 2341 2129
+f 2129 2137 2345
+f 2447 2440 2341
+f 2341 2345 2447
+f 2544 2535 2440
+f 2440 2447 2544
+f 2638 2623 2535
+f 2535 2544 2638
+f 2704 2689 2623
+f 2623 2638 2704
+f 2766 2749 2689
+f 2689 2704 2766
+f 2822 2797 2749
+f 2749 2766 2822
+f 2848 2833 2797
+f 2797 2822 2848
+f 2858 2843 2833
+f 2833 2848 2858
+f 1735 2334 2329
+f 1735 2329 2321
+f 1735 2321 2305
+f 1735 2305 2274
+f 1735 2274 2231
+f 1735 2231 2167
+f 1735 2167 2089
+f 1735 2089 2014
+f 1735 2014 1962
+f 1735 1962 1733
+f 2515 2329 2334
+f 2334 2524 2515
+f 2495 2321 2329
+f 2329 2515 2495
+f 2456 2305 2321
+f 2321 2495 2456
+f 2429 2274 2305
+f 2305 2456 2429
+f 2399 2231 2274
+f 2274 2429 2399
+f 2347 2167 2231
+f 2231 2399 2347
+f 2292 2089 2167
+f 2167 2347 2292
+f 2148 2014 2089
+f 2089 2292 2148
+f 2004 1962 2014
+f 2014 2148 2004
+f 1739 1733 1962
+f 1962 2004 1739
+f 2647 2515 2524
+f 2524 2649 2647
+f 2621 2495 2515
+f 2515 2647 2621
+f 2584 2456 2495
+f 2495 2621 2584
+f 2541 2429 2456
+f 2456 2584 2541
+f 2502 2399 2429
+f 2429 2541 2502
+f 2426 2347 2399
+f 2399 2502 2426
+f 2352 2292 2347
+f 2347 2426 2352
+f 2255 2148 2292
+f 2292 2352 2255
+f 2046 2004 2148
+f 2148 2255 2046
+f 1702 1739 2004
+f 2004 2046 1702
+f 2746 2647 2649
+f 2649 2757 2746
+f 2721 2621 2647
+f 2647 2746 2721
+f 2681 2584 2621
+f 2621 2721 2681
+f 2639 2541 2584
+f 2584 2681 2639
+f 2557 2502 2541
+f 2541 2639 2557
+f 2505 2426 2502
+f 2502 2557 2505
+f 2415 2352 2426
+f 2426 2505 2415
+f 2318 2255 2352
+f 2352 2415 2318
+f 2098 2046 2255
+f 2255 2318 2098
+f 1745 1702 2046
+f 2046 2098 1745
+f 2840 2746 2757
+f 2757 2849 2840
+f 2808 2721 2746
+f 2746 2840 2808
+f 2756 2681 2721
+f 2721 2808 2756
+f 2696 2639 2681
+f 2681 2756 2696
+f 2626 2557 2639
+f 2639 2696 2626
+f 2538 2505 2557
+f 2557 2626 2538
+f 2443 2415 2505
+f 2505 2538 2443
+f 2342 2318 2415
+f 2415 2443 2342
+f 2131 2098 2318
+f 2318 2342 2131
+f 1904 1745 2098
+f 2098 2131 1904
+f 2906 2840 2849
+f 2849 2925 2906
+f 2867 2808 2840
+f 2840 2906 2867
+f 2818 2756 2808
+f 2808 2867 2818
+f 2736 2696 2756
+f 2756 2818 2736
+f 2667 2626 2696
+f 2696 2736 2667
+f 2565 2538 2626
+f 2626 2667 2565
+f 2475 2443 2538
+f 2538 2565 2475
+f 2356 2342 2443
+f 2443 2475 2356
+f 2156 2131 2342
+f 2342 2356 2156
+f 1704 1904 2131
+f 2131 2156 1704
+f 2976 2906 2925
+f 2925 2987 2976
+f 2914 2867 2906
+f 2906 2976 2914
+f 2852 2818 2867
+f 2867 2914 2852
+f 2772 2736 2818
+f 2818 2852 2772
+f 2688 2667 2736
+f 2736 2772 2688
+f 2592 2565 2667
+f 2667 2688 2592
+f 2497 2475 2565
+f 2565 2592 2497
+f 2372 2356 2475
+f 2475 2497 2372
+f 2176 2156 2356
+f 2356 2372 2176
+f 1752 1704 2156
+f 2156 2176 1752
+f 2993 2976 2987
+f 2987 3011 2993
+f 2952 2914 2976
+f 2976 2993 2952
+f 2874 2852 2914
+f 2914 2952 2874
+f 2794 2772 2852
+f 2852 2874 2794
+f 2702 2688 2772
+f 2772 2794 2702
+f 2604 2592 2688
+f 2688 2702 2604
+f 2509 2497 2592
+f 2592 2604 2509
+f 2380 2372 2497
+f 2497 2509 2380
+f 2182 2176 2372
+f 2372 2380 2182
+f 1723 1752 2176
+f 2176 2182 1723
+f 3000 2993 3011
+f 3011 3020 3000
+f 2967 2952 2993
+f 2993 3000 2967
+f 2879 2874 2952
+f 2952 2967 2879
+f 2799 2794 2874
+f 2874 2879 2799
+f 2707 2702 2794
+f 2794 2799 2707
+f 2605 2604 2702
+f 2702 2707 2605
+f 2512 2509 2604
+f 2604 2605 2512
+f 2382 2380 2509
+f 2509 2512 2382
+f 2188 2182 2380
+f 2380 2382 2188
+f 1699 1723 2182
+f 2182 2188 1699
+f 3006 3000 3020
+f 3020 3022 3006
+f 2972 2967 3000
+f 3000 3006 2972
+f 2888 2879 2967
+f 2967 2972 2888
+f 2804 2799 2879
+f 2879 2888 2804
+f 2710 2707 2799
+f 2799 2804 2710
+f 2613 2605 2707
+f 2707 2710 2613
+f 2520 2512 2605
+f 2605 2613 2520
+f 2388 2382 2512
+f 2512 2520 2388
+f 2192 2188 2382
+f 2382 2388 2192
+f 1760 1699 2188
+f 2188 2192 1760
+f 1735 1737 1660
+f 1735 1660 1608
+f 1735 1608 1535
+f 1735 1535 1457
+f 1735 1457 1393
+f 1735 1393 1350
+f 1735 1350 1319
+f 1735 1319 1303
+f 1735 1303 1295
+f 1735 1295 1288
+f 1618 1660 1737
+f 1737 1739 1618
+f 1474 1608 1660
+f 1660 1618 1474
+f 1332 1535 1608
+f 1608 1474 1332
+f 1277 1457 1535
+f 1535 1332 1277
+f 1225 1393 1457
+f 1457 1277 1225
+f 1195 1350 1393
+f 1393 1225 1195
+f 1166 1319 1350
+f 1350 1195 1166
+f 1129 1303 1319
+f 1319 1166 1129
+f 1109 1295 1303
+f 1303 1129 1109
+f 1099 1288 1295
+f 1295 1109 1099
+f 1576 1618 1739
+f 1739 1741 1576
+f 1367 1474 1618
+f 1618 1576 1367
+f 1270 1332 1474
+f 1474 1367 1270
+f 1196 1277 1332
+f 1332 1270 1196
+f 1120 1225 1277
+f 1277 1196 1120
+f 1081 1195 1225
+f 1225 1120 1081
+f 1040 1166 1195
+f 1195 1081 1040
+f 1001 1129 1166
+f 1166 1040 1001
+f 975 1109 1129
+f 1129 1001 975
+f 973 1099 1109
+f 1109 975 973
+f 1524 1576 1741
+f 1741 1744 1524
+f 1304 1367 1576
+f 1576 1524 1304
+f 1209 1270 1367
+f 1367 1304 1209
+f 1119 1196 1270
+f 1270 1209 1119
+f 1065 1120 1196
+f 1196 1119 1065
+f 983 1081 1120
+f 1120 1065 983
+f 941 1040 1081
+f 1081 983 941
+f 901 1001 1040
+f 1040 941 901
+f 878 975 1001
+f 1001 901 878
+f 865 973 975
+f 975 878 865
+f 1493 1524 1744
+f 1744 1747 1493
+f 1280 1304 1524
+f 1524 1493 1280
+f 1181 1209 1304
+f 1304 1280 1181
+f 1086 1119 1209
+f 1209 1181 1086
+f 998 1065 1119
+f 1119 1086 998
+f 928 983 1065
+f 1065 998 928
+f 868 941 983
+f 983 928 868
+f 816 901 941
+f 941 868 816
+f 784 878 901
+f 901 816 784
+f 773 865 878
+f 878 784 773
+f 1466 1493 1747
+f 1747 1749 1466
+f 1266 1280 1493
+f 1493 1466 1266
+f 1149 1181 1280
+f 1280 1266 1149
+f 1057 1086 1181
+f 1181 1149 1057
+f 955 998 1086
+f 1086 1057 955
+f 888 928 998
+f 998 955 888
+f 806 868 928
+f 928 888 806
+f 755 816 868
+f 868 806 755
+f 718 784 816
+f 816 755 718
+f 697 773 784
+f 784 718 697
+f 1446 1466 1749
+f 1749 1753 1446
+f 1250 1266 1466
+f 1466 1446 1250
+f 1127 1149 1266
+f 1266 1250 1127
+f 1032 1057 1149
+f 1149 1127 1032
+f 936 955 1057
+f 1057 1032 936
+f 852 888 955
+f 955 936 852
+f 772 806 888
+f 888 852 772
+f 710 755 806
+f 806 772 710
+f 648 718 755
+f 755 710 648
+f 637 697 718
+f 718 648 637
+f 1440 1446 1753
+f 1753 1755 1440
+f 1242 1250 1446
+f 1446 1440 1242
+f 1115 1127 1250
+f 1250 1242 1115
+f 1020 1032 1127
+f 1127 1115 1020
+f 922 936 1032
+f 1032 1020 922
+f 830 852 936
+f 936 922 830
+f 750 772 852
+f 852 830 750
+f 672 710 772
+f 772 750 672
+f 631 648 710
+f 710 672 631
+f 613 637 648
+f 648 631 613
+f 1434 1440 1755
+f 1755 1757 1434
+f 1240 1242 1440
+f 1440 1434 1240
+f 1110 1115 1242
+f 1242 1240 1110
+f 1017 1020 1115
+f 1115 1110 1017
+f 915 922 1020
+f 1020 1017 915
+f 823 830 922
+f 922 915 823
+f 743 750 830
+f 830 823 743
+f 655 672 750
+f 750 743 655
+f 622 631 672
+f 672 655 622
+f 602 613 631
+f 631 622 602
+f 1428 1434 1757
+f 1757 1760 1428
+f 1232 1240 1434
+f 1434 1428 1232
+f 1105 1110 1240
+f 1240 1232 1105
+f 1010 1017 1110
+f 1110 1105 1010
+f 913 915 1017
+f 1017 1010 913
+f 821 823 915
+f 915 913 821
+f 736 743 823
+f 823 821 736
+f 652 655 743
+f 743 736 652
+f 619 622 655
+f 655 652 619
+f 601 602 622
+f 622 619 601
+f 1735 1289 1294
+f 1735 1294 1302
+f 1735 1302 1318
+f 1735 1318 1349
+f 1735 1349 1392
+f 1735 1392 1456
+f 1735 1456 1534
+f 1735 1534 1609
+f 1735 1609 1661
+f 1735 1661 1889
+f 1108 1294 1289
+f 1289 1099 1108
+f 1128 1302 1294
+f 1294 1108 1128
+f 1167 1318 1302
+f 1302 1128 1167
+f 1194 1349 1318
+f 1318 1167 1194
+f 1224 1392 1349
+f 1349 1194 1224
+f 1276 1456 1392
+f 1392 1224 1276
+f 1331 1534 1456
+f 1456 1276 1331
+f 1475 1609 1534
+f 1534 1331 1475
+f 1619 1661 1609
+f 1609 1475 1619
+f 1738 1889 1661
+f 1661 1619 1738
+f 976 1108 1099
+f 1099 974 976
+f 1002 1128 1108
+f 1108 976 1002
+f 1039 1167 1128
+f 1128 1002 1039
+f 1082 1194 1167
+f 1167 1039 1082
+f 1121 1224 1194
+f 1194 1082 1121
+f 1197 1276 1224
+f 1224 1121 1197
+f 1271 1331 1276
+f 1276 1197 1271
+f 1368 1475 1331
+f 1331 1271 1368
+f 1577 1619 1475
+f 1475 1368 1577
+f 1903 1738 1619
+f 1619 1577 1903
+f 877 976 974
+f 974 866 877
+f 902 1002 976
+f 976 877 902
+f 942 1039 1002
+f 1002 902 942
+f 984 1082 1039
+f 1039 942 984
+f 1066 1121 1082
+f 1082 984 1066
+f 1118 1197 1121
+f 1121 1066 1118
+f 1208 1271 1197
+f 1197 1118 1208
+f 1305 1368 1271
+f 1271 1208 1305
+f 1525 1577 1368
+f 1368 1305 1525
+f 1742 1903 1577
+f 1577 1525 1742
+f 783 877 866
+f 866 774 783
+f 815 902 877
+f 877 783 815
+f 867 942 902
+f 902 815 867
+f 927 984 942
+f 942 867 927
+f 997 1066 984
+f 984 927 997
+f 1085 1118 1066
+f 1066 997 1085
+f 1180 1208 1118
+f 1118 1085 1180
+f 1281 1305 1208
+f 1208 1180 1281
+f 1492 1525 1305
+f 1305 1281 1492
+f 1703 1742 1525
+f 1525 1492 1703
+f 717 783 774
+f 774 698 717
+f 756 815 783
+f 783 717 756
+f 805 867 815
+f 815 756 805
+f 887 927 867
+f 867 805 887
+f 956 997 927
+f 927 887 956
+f 1058 1085 997
+f 997 956 1058
+f 1148 1180 1085
+f 1085 1058 1148
+f 1267 1281 1180
+f 1180 1148 1267
+f 1467 1492 1281
+f 1281 1267 1467
+f 1905 1703 1492
+f 1492 1467 1905
+f 647 717 698
+f 698 636 647
+f 709 756 717
+f 717 647 709
+f 771 805 756
+f 756 709 771
+f 851 887 805
+f 805 771 851
+f 935 956 887
+f 887 851 935
+f 1031 1058 956
+f 956 935 1031
+f 1126 1148 1058
+f 1058 1031 1126
+f 1251 1267 1148
+f 1148 1126 1251
+f 1447 1467 1267
+f 1267 1251 1447
+f 1751 1905 1467
+f 1467 1447 1751
+f 630 647 636
+f 636 612 630
+f 671 709 647
+f 647 630 671
+f 749 771 709
+f 709 671 749
+f 829 851 771
+f 771 749 829
+f 921 935 851
+f 851 829 921
+f 1019 1031 935
+f 935 921 1019
+f 1114 1126 1031
+f 1031 1019 1114
+f 1243 1251 1126
+f 1126 1114 1243
+f 1441 1447 1251
+f 1251 1243 1441
+f 1896 1751 1447
+f 1447 1441 1896
+f 623 630 612
+f 612 603 623
+f 656 671 630
+f 630 623 656
+f 744 749 671
+f 671 656 744
+f 824 829 749
+f 749 744 824
+f 916 921 829
+f 829 824 916
+f 1018 1019 921
+f 921 916 1018
+f 1111 1114 1019
+f 1019 1018 1111
+f 1241 1243 1114
+f 1114 1111 1241
+f 1435 1441 1243
+f 1243 1241 1435
+f 1923 1896 1441
+f 1441 1435 1923
+f 617 623 603
+f 603 601 617
+f 650 656 623
+f 623 617 650
+f 734 744 656
+f 656 650 734
+f 818 824 744
+f 744 734 818
+f 912 916 824
+f 824 818 912
+f 1009 1018 916
+f 916 912 1009
+f 1102 1111 1018
+f 1018 1009 1102
+f 1235 1241 1111
+f 1111 1102 1235
+f 1431 1435 1241
+f 1241 1235 1431
+f 1759 1923 1435
+f 1435 1431 1759
+f 1735 1736 1963
+f 1735 1963 2015
+f 1735 2015 2088
+f 1735 2088 2166
+f 1735 2166 2230
+f 1735 2230 2273
+f 1735 2273 2304
+f 1735 2304 2320
+f 1735 2320 2328
+f 1735 2328 2335
+f 2005 1963 1736
+f 1736 1738 2005
+f 2149 2015 1963
+f 1963 2005 2149
+f 2291 2088 2015
+f 2015 2149 2291
+f 2346 2166 2088
+f 2088 2291 2346
+f 2398 2230 2166
+f 2166 2346 2398
+f 2428 2273 2230
+f 2230 2398 2428
+f 2457 2304 2273
+f 2273 2428 2457
+f 2494 2320 2304
+f 2304 2457 2494
+f 2514 2328 2320
+f 2320 2494 2514
+f 2524 2335 2328
+f 2328 2514 2524
+f 2047 2005 1738
+f 1738 1740 2047
+f 2256 2149 2005
+f 2005 2047 2256
+f 2353 2291 2149
+f 2149 2256 2353
+f 2427 2346 2291
+f 2291 2353 2427
+f 2503 2398 2346
+f 2346 2427 2503
+f 2542 2428 2398
+f 2398 2503 2542
+f 2583 2457 2428
+f 2428 2542 2583
+f 2622 2494 2457
+f 2457 2583 2622
+f 2648 2514 2494
+f 2494 2622 2648
+f 2650 2524 2514
+f 2514 2648 2650
+f 2099 2047 1740
+f 1740 1743 2099
+f 2319 2256 2047
+f 2047 2099 2319
+f 2414 2353 2256
+f 2256 2319 2414
+f 2504 2427 2353
+f 2353 2414 2504
+f 2558 2503 2427
+f 2427 2504 2558
+f 2640 2542 2503
+f 2503 2558 2640
+f 2682 2583 2542
+f 2542 2640 2682
+f 2722 2622 2583
+f 2583 2682 2722
+f 2745 2648 2622
+f 2622 2722 2745
+f 2758 2650 2648
+f 2648 2745 2758
+f 2130 2099 1743
+f 1743 1746 2130
+f 2343 2319 2099
+f 2099 2130 2343
+f 2442 2414 2319
+f 2319 2343 2442
+f 2537 2504 2414
+f 2414 2442 2537
+f 2625 2558 2504
+f 2504 2537 2625
+f 2695 2640 2558
+f 2558 2625 2695
+f 2755 2682 2640
+f 2640 2695 2755
+f 2807 2722 2682
+f 2682 2755 2807
+f 2839 2745 2722
+f 2722 2807 2839
+f 2850 2758 2745
+f 2745 2839 2850
+f 2157 2130 1746
+f 1746 1748 2157
+f 2357 2343 2130
+f 2130 2157 2357
+f 2474 2442 2343
+f 2343 2357 2474
+f 2566 2537 2442
+f 2442 2474 2566
+f 2668 2625 2537
+f 2537 2566 2668
+f 2735 2695 2625
+f 2625 2668 2735
+f 2817 2755 2695
+f 2695 2735 2817
+f 2868 2807 2755
+f 2755 2817 2868
+f 2905 2839 2807
+f 2807 2868 2905
+f 2926 2850 2839
+f 2839 2905 2926
+f 2177 2157 1748
+f 1748 1750 2177
+f 2373 2357 2157
+f 2157 2177 2373
+f 2496 2474 2357
+f 2357 2373 2496
+f 2591 2566 2474
+f 2474 2496 2591
+f 2687 2668 2566
+f 2566 2591 2687
+f 2771 2735 2668
+f 2668 2687 2771
+f 2851 2817 2735
+f 2735 2771 2851
+f 2913 2868 2817
+f 2817 2851 2913
+f 2975 2905 2868
+f 2868 2913 2975
+f 2986 2926 2905
+f 2905 2975 2986
+f 2183 2177 1750
+f 1750 1754 2183
+f 2381 2373 2177
+f 2177 2183 2381
+f 2508 2496 2373
+f 2373 2381 2508
+f 2603 2591 2496
+f 2496 2508 2603
+f 2701 2687 2591
+f 2591 2603 2701
+f 2793 2771 2687
+f 2687 2701 2793
+f 2873 2851 2771
+f 2771 2793 2873
+f 2951 2913 2851
+f 2851 2873 2951
+f 2992 2975 2913
+f 2913 2951 2992
+f 3010 2986 2975
+f 2975 2992 3010
+f 2189 2183 1754
+f 1754 1756 2189
+f 2383 2381 2183
+f 2183 2189 2383
+f 2513 2508 2381
+f 2381 2383 2513
+f 2606 2603 2508
+f 2508 2513 2606
+f 2708 2701 2603
+f 2603 2606 2708
+f 2800 2793 2701
+f 2701 2708 2800
+f 2880 2873 2793
+f 2793 2800 2880
+f 2968 2951 2873
+f 2873 2880 2968
+f 3001 2992 2951
+f 2951 2968 3001
+f 3021 3010 2992
+f 2992 3001 3021
+f 2195 2189 1756
+f 1756 1759 2195
+f 2390 2383 2189
+f 2189 2195 2390
+f 2517 2513 2383
+f 2383 2390 2517
+f 2612 2606 2513
+f 2513 2517 2612
+f 2709 2708 2606
+f 2606 2612 2709
+f 2801 2800 2708
+f 2708 2709 2801
+f 2886 2880 2800
+f 2800 2801 2886
+f 2970 2968 2880
+f 2880 2886 2970
+f 3004 3001 2968
+f 2968 2970 3004
+f 3022 3021 3001
+f 3001 3004 3022
diff --git a/test/data/teddy.obj b/test/data/teddy.obj
new file mode 100644
index 0000000..57ede68
--- /dev/null
+++ b/test/data/teddy.obj
@@ -0,0 +1,4790 @@
+v -4.75738 8.49991 8.28592
+v -4.55816 11.4788 7.74909
+v -4.37277 13.9925 6.2828
+v -5.70826 13.6563 6.26488
+v -4.22943 15.6584 4.11027
+v -4.14648 15.5999 -0.973337
+v -5.89138 15.1606 -0.996753
+v -4.2195 13.8844 -3.11048
+v -5.55499 13.5482 -3.12841
+v -4.3579 11.3375 -4.52382
+v -4.54062 8.34704 -4.99819
+v -6.35434 10.256 7.73386
+v -7.69167 11.733 6.25465
+v -8.56579 12.7062 4.07349
+v -8.84361 13.0274 1.52244
+v -8.48283 12.6477 -1.01012
+v -7.5384 11.6249 -3.13864
+v -6.15408 10.1147 -4.53906
+v -8.97552 6.43001 6.29472
+v -8.77853 5.01807 6.31419
+v -10.2432 5.77752 4.12585
+v -9.98584 3.93274 4.15128
+v -10.6592 5.52786 1.57912
+v -10.3807 3.53107 1.60664
+v -10.1603 5.71902 -0.957758
+v -9.90289 3.87424 -0.932328
+v -8.82225 6.32192 -3.09856
+v -8.62526 4.90998 -3.0791
+v -6.38315 6.06753 7.78159
+v -7.74491 3.99382 6.34284
+v -8.63535 2.59448 4.18872
+v -8.9189 2.08256 1.64716
+v -8.5524 2.53598 -0.894892
+v -7.59164 3.88572 -3.05044
+v -6.18289 5.92629 -4.49133
+v -4.94011 5.5094 7.81156
+v -5.07851 2.96254 6.39822
+v -5.15153 1.24705 4.26107
+v -5.14804 0.624109 1.72548
+v -5.06858 1.18855 -0.82254
+v -4.92524 2.85444 -2.99507
+v -4.73985 5.36817 -4.46136
+v -7.0706 8.92177 7.73752
+v -9.01515 9.26777 6.26142
+v -10.295 9.48523 4.08234
+v -10.7153 9.54105 1.53202
+v -10.212 9.42673 -1.00127
+v -8.86188 9.15967 -3.13186
+v -6.87034 8.78053 -4.53539
+v 3.06689 7.44818 8.1781
+v 4.41256 5.15163 7.73953
+v 5.52882 6.07891 7.74708
+v 5.56925 3.1935 6.39422
+v 7.63182 4.9069 6.40816
+v 6.36086 1.87191 4.34698
+v 9.05574 4.11057 4.36519
+v 6.66688 1.38805 1.90947
+v 9.5838 3.81116 1.92918
+v 6.44072 1.81559 -0.547205
+v 9.1356 4.05425 -0.528994
+v 5.71681 3.08944 -2.64905
+v 7.77938 4.80283 -2.63511
+v 4.60536 5.01566 -4.07607
+v 5.72161 5.94294 -4.06852
+v 3.27557 7.30101 -4.61102
+v 5.50737 7.6147 7.72905
+v 7.59219 7.74466 6.37486
+v 9.00396 7.81828 4.32167
+v 9.52775 7.82435 1.88209
+v 9.08382 7.76196 -0.572506
+v 7.73975 7.64059 -2.66841
+v 5.70017 7.47873 -4.08655
+v 4.24481 2.57376 6.37974
+v 4.6304 1.06218 4.32806
+v 4.79385 0.511608 1.889
+v 4.71026 1.00586 -0.566123
+v 4.39237 2.4697 -2.66353
+v 1.56309 2.21691 -2.70678
+v 2.35738 4.54345 -4.10731
+v 5.3624 8.37733 7.71791
+v 7.32433 9.15382 6.35427
+v 8.65399 9.65944 4.29478
+v 9.14894 9.81721 1.85297
+v 8.73385 9.60312 -0.599405
+v 7.47189 9.04975 -2.689
+v 5.5552 8.24136 -4.09769
+v 5.02716 9.09409 7.70419
+v 6.70488 10.4782 6.32892
+v 7.84464 11.3899 4.26166
+v 8.27291 11.6902 1.81712
+v 7.9245 11.3335 -0.632524
+v 6.85244 10.3742 -2.71435
+v 5.21996 8.95812 -4.11141
+v 3.98509 10.2057 7.67439
+v 4.77938 12.5323 6.27386
+v 5.32885 14.0736 4.18972
+v 5.4087 14.0173 -0.704459
+v 4.92694 12.4282 -2.7694
+v 4.17788 10.0698 -4.1412
+v 1.43857 11.2904 7.99724
+v 1.22297 8.23418 8.54689
+v 1.63826 13.8694 6.49567
+v 1.79161 15.5785 4.27079
+v 1.87656 15.5186 -0.935478
+v 1.79523 13.7587 -3.12426
+v 1.64367 11.1457 -4.57181
+v 1.44496 8.07762 -5.05775
+v 1.22935 5.02143 -4.5081
+v 0.109369 11.5173 8.08861
+v 0.260966 8.39879 8.6545
+v -0.044623 16.484 1.62624
+v 0.318235 11.37 -4.71169
+v 0.48704 8.23935 -5.20045
+v 0.717506 0.806139 4.47118
+v 0.749946 2.4892 -3.10016
+v -1.13035 11.5006 8.13536
+v -1.74668 8.37122 8.69435
+v -3.79653 8.23863 8.48928
+v -0.590454 14.1412 6.59582
+v -0.209199 15.8912 4.31012
+v -0.121782 15.8295 -1.04724
+v -0.428928 14.0273 -3.30329
+v -0.919302 11.3517 -4.79846
+v -1.51825 8.21012 -5.30511
+v -3.57375 8.08151 -5.16403
+v -3.14315 0.751817 4.43647
+v -2.67448 2.44013 -3.20659
+v -3.40434 5.00201 -4.60597
+v -2.13458 5.08079 -4.74612
+v 3.10607 0.36081 1.86319
+v 2.01025 0.665233 3.46159
+v 0.728609 0.709777 4.08052
+v -1.27911 0.713773 4.19302
+v -2.4527 0.646962 3.97884
+v -3.16426 0.572725 3.70493
+v -4.45952 0.631882 2.51377
+v -4.85509 0.544053 1.73118
+v -4.94168 0.630623 1.46448
+v -4.99502 1.0372 -0.246242
+v -4.73528 1.10603 -0.838825
+v -3.67731 1.85411 -2.13205
+v -2.77592 1.97451 -2.59843
+v -2.0077 2.11522 -2.7512
+v -0.284175 2.16168 -2.72592
+v 0.760976 2.13345 -2.63729
+v 1.39634 1.8936 -2.29471
+v 2.51344 1.25355 -1.24982
+v 2.90047 0.885059 -0.688787
+v 3.1935 0.488349 1.32496
+v 3.83935 -0.805325 4.58296
+v 2.00029 -0.824144 5.45809
+v -0.869574 -0.948624 5.60322
+v -3.55014 -1.2731 4.8905
+v -5.39527 -1.27405 3.1765
+v -1.94658 0.998399 -4.33709
+v 2.00733 1.2043 -4.15243
+v 2.92803 0.903234 -3.65708
+v 9.82595 -8.19113 2.72638
+v 7.64818 -6.93235 6.48913
+v 4.84526 -6.13281 8.005
+v 0.361171 -5.01059 8.4029
+v -3.96892 -4.26932 7.40681
+v -6.91388 -3.39355 4.74932
+v -0.949578 -1.32975 -7.55666
+v 10.0569 -7.94343 1.47952
+v 10.2071 -10.3571 2.79878
+v 7.61595 -9.21649 6.92362
+v 4.42178 -8.65619 8.55787
+v -0.641765 -7.93569 8.93227
+v -5.47279 -7.61868 7.76927
+v -8.7732 -6.99782 4.78869
+v -9.83652 -7.07128 2.81003
+v -4.26344 -4.15053 -8.31429
+v -2.2802 -4.06586 -8.73671
+v 6.25629 -5.83678 -7.72208
+v 10.4502 -10.0603 1.42311
+v 10.1841 -12.4521 2.59144
+v 7.40739 -11.5505 6.73944
+v -1.07517 -11.069 8.67438
+v -5.96691 -11.227 7.4371
+v -9.32223 -10.9302 4.37455
+v -10.364 -11.112 2.35613
+v -10.5818 -10.8783 1.66786
+v -10.6979 -9.81779 -2.75388
+v -10.0272 -9.66673 -4.28938
+v -7.22975 -7.84599 -7.64571
+v -4.89419 -7.63186 -8.8633
+v -2.89632 -7.35156 -9.26823
+v 4.25954 -7.60605 -9.0104
+v 5.87931 -8.29567 -8.13353
+v 8.70924 -10.0734 -5.44796
+v 9.67635 -11.0689 -4.00322
+v 10.4167 -12.1307 1.19887
+v 10.0895 -14.4941 2.32402
+v -1.11324 -13.1148 8.37714
+v -9.31946 -12.9744 4.09894
+v -10.3562 -13.155 2.09057
+v -10.5728 -12.9224 1.40573
+v -10.6882 -11.8671 -2.99404
+v -10.0209 -11.717 -4.52194
+v -7.23691 -9.90601 -7.8617
+v -4.91294 -9.69358 -9.07332
+v -2.92492 -9.41523 -9.4763
+v 4.19535 -9.67042 -9.22
+v 10.321 -14.1744 0.938357
+v -10.6247 -13.9039 -3.19465
+v -9.97391 -13.7246 -4.67838
+v -7.33994 -11.822 -7.91513
+v -5.08362 -11.4958 -9.08055
+v -3.16253 -11.1221 -9.46079
+v 9.8982 -15.0515 0.769409
+v -10.0904 -14.7445 -3.20405
+v -9.4711 -14.576 -4.61638
+v -6.95922 -12.7741 -7.69776
+v -4.81125 -12.4712 -8.80781
+v -2.98184 -12.1221 -9.17046
+v -1.27805 -16.1844 6.71326
+v -9.54759 -15.5747 -3.18775
+v -8.96903 -15.4142 -4.50675
+v -6.62996 -13.7181 -7.38393
+v -4.62428 -13.424 -8.41959
+v -2.91689 -13.0884 -8.75724
+v -8.06873 -16.9821 -3.17874
+v -7.54861 -16.8065 -4.36302
+v -5.52178 -15.1527 -6.94087
+v -3.72828 -14.7762 -7.86041
+v -2.21008 -14.3786 -8.15337
+v -4.82157 -15.6691 -6.5723
+v -3.16841 -15.3106 -7.41945
+v -1.76986 -14.9342 -7.68865
+v -3.33284 -15.8714 -6.5609
+v -2.14617 -15.592 -6.79205
+v -7.06631 -17.0586 -4.24813
+v -5.82705 -16.7092 -5.12276
+v -4.75525 -16.185 -6.0021
+v -3.86775 -16.2455 -6.07221
+v -3.32466 -15.9573 -6.44984
+v -3.09409 -15.9621 -6.44236
+v -2.14977 -15.7519 -6.65138
+v -1.64671 -15.868 -6.56379
+v -0.105109 -15.9518 -6.4224
+v -2.2743 -17.7076 4.65422
+v -7.81608 -17.6062 -1.26796
+v -8.37523 -16.8563 -2.61072
+v -8.06944 -17.0008 -3.01084
+v -8.05699 -16.991 -3.16328
+v -8.05326 -16.9898 -3.17889
+v -7.3571 -17.0759 -3.95333
+v 2.41752 -18.5301 -1.49186
+v -6.96729 -17.2164 -3.80403
+v -4.66643 -17.2302 -4.72548
+v -1.06655 -18.8826 -0.00741184
+v -3.13164 -16.658 -5.68162
+v 1.96389 -18.0074 -3.31457
+v 0.221782 -18.5558 -2.03776
+v -2.81702 -18.6062 -2.32675
+v -0.481172 -16.3361 -6.11221
+v -1.55786 -18.2 3.58568
+v 0.272667 -17.8234 -4.01958
+v -3.08719 -17.9962 -3.91307
+v -1.55511 -18.6849 -1.77704
+v -2.40318 -18.8407 -1.07766
+v -2.801 -18.9854 -0.110608
+v -1.38095 -17.1394 -5.1761
+v -1.44724 -18.3031 -3.20154
+v 2.63897 6.1351 7.95529
+v 2.2415 6.52603 8.13076
+v 1.16574 7.35057 8.40694
+v 0.478433 7.47777 8.4854
+v -1.00641 7.51494 8.52513
+v -1.94848 7.31274 8.52364
+v -3.10822 6.81115 8.34621
+v -3.67003 6.14021 8.16263
+v -3.89517 5.22479 7.96594
+v -3.9036 4.7106 7.68634
+v -3.63053 3.16202 6.85597
+v -3.3914 2.65522 6.61963
+v -3.17161 2.36461 6.34011
+v -2.91497 2.09072 6.11252
+v -1.47501 1.49186 5.34954
+v -0.648239 1.47793 5.32492
+v 0.666655 1.52282 5.35938
+v 1.08281 1.59893 5.44738
+v 2.24838 1.99487 5.81618
+v 2.76341 2.44141 6.35709
+v 3.22414 3.60691 7.03159
+v 3.14859 4.88612 7.72196
+v 3.01294 5.69633 7.86877
+v 2.2052 6.28678 8.45224
+v 1.13716 7.11992 8.69955
+v -1.02469 7.29639 8.80526
+v -1.96335 7.09926 8.80657
+v -3.11946 6.60007 8.6408
+v -3.68112 5.92959 8.47579
+v -3.90868 5.01401 8.30595
+v -3.65094 2.92811 7.26233
+v -3.41443 2.41592 7.04268
+v -2.94109 1.83742 6.55607
+v -1.50798 1.21309 5.81901
+v 0.623994 1.23484 5.83492
+v 2.19915 1.71092 6.2809
+v 2.71211 2.16871 6.80783
+v 3.17381 3.34599 7.4466
+v 3.10213 4.63922 8.09611
+v 2.97024 5.45025 8.21819
+v 0.937956 5.77072 9.80431
+v 0.296637 6.35098 9.68917
+v -1.06291 6.55265 9.6228
+v -1.6649 6.47094 9.63976
+v -2.41474 6.17872 9.63116
+v -2.79699 5.76825 9.69004
+v -2.9794 5.20426 9.82267
+v -2.89133 3.72071 9.77564
+v -2.76104 3.36026 9.7917
+v -2.47878 2.88352 9.68015
+v -1.5873 2.28244 9.47233
+v -0.239985 2.22783 9.55589
+v 0.767781 2.56641 9.74771
+v 1.10213 2.95129 9.95104
+v 1.43493 3.78138 10.0291
+v 1.43594 4.69886 10.0629
+v 1.38746 5.20214 9.91659
+v 0.220628 5.43151 10.4831
+v -0.211049 5.8154 10.4491
+v -1.11504 5.93895 10.4276
+v -1.51334 5.87778 10.4375
+v -2.00788 5.67783 10.4178
+v -2.25702 5.39919 10.4325
+v -2.37161 5.0165 10.4846
+v -2.29948 4.04132 10.3566
+v -2.01868 3.49919 10.2363
+v -1.42339 3.12507 10.0541
+v -0.528769 3.09735 10.0967
+v 0.137774 3.31864 10.2386
+v 0.357399 3.56286 10.3956
+v 0.570804 4.10905 10.4988
+v 0.563019 4.71239 10.5808
+v 0.524973 5.05355 10.5173
+v -0.926686 3.93024 10.6759
+v 6.55398 13.5239 1.76797
+v 5.46971 14.2671 0.351879
+v 3.79463 14.9153 -0.000997424
+v 3.22951 15.1785 0.0496842
+v 1.87585 15.8786 0.527197
+v 1.45341 16.0884 1.08913
+v 1.37622 16.2425 1.6522
+v 1.41464 16.0988 2.24668
+v 1.82405 15.803 3.25928
+v 2.68577 15.3446 3.66849
+v 4.66328 14.4889 3.68011
+v 5.3746 14.1816 3.68242
+v 6.63791 13.1611 2.65707
+v 7.30438 13.9627 1.79605
+v 6.27645 14.7225 0.267931
+v 4.25863 15.7361 -0.209935
+v 3.63369 16.0727 -0.15054
+v 2.14165 16.9568 0.397597
+v 1.67574 17.221 1.03887
+v 1.59866 17.399 1.68087
+v 1.63318 17.2304 2.35726
+v 2.07967 16.8625 3.5088
+v 3.02914 16.282 3.97204
+v 6.00867 14.7807 3.98031
+v 7.37626 13.5408 2.80698
+v 7.62385 18.1897 1.89923
+v 6.54958 18.2986 0.56169
+v 4.60843 18.2157 0.124363
+v 3.99531 18.2125 0.167129
+v 2.49325 18.276 0.617373
+v 2.02344 18.2988 1.16372
+v 1.88356 18.4178 1.71247
+v 1.97139 18.322 2.30047
+v 2.44782 18.2585 3.30317
+v 3.40124 18.2254 3.71745
+v 6.27794 18.3265 3.76197
+v 7.84098 17.9263 2.78283
+v 6.90047 19.0397 1.90062
+v 6.04837 19.1606 0.836163
+v 4.50109 19.1527 0.488545
+v 4.01311 19.1682 0.522843
+v 2.81984 19.2621 0.882106
+v 2.44685 19.2932 1.3174
+v 2.33922 19.3909 1.75466
+v 2.40649 19.311 2.22267
+v 2.78407 19.2445 3.02081
+v 3.54193 19.1892 3.35026
+v 5.8341 19.1847 3.38473
+v 7.06579 18.822 2.60364
+v 6.21395 19.8874 1.91849
+v 5.65797 19.9193 1.22765
+v 4.65864 19.8353 1.00156
+v 4.34246 19.8208 1.02349
+v 3.56627 19.8228 1.25547
+v 3.32331 19.8255 1.53735
+v 3.29565 19.8379 2.1241
+v 3.54242 19.8164 2.64189
+v 4.03474 19.8199 2.85601
+v 5.51635 19.9323 2.87953
+v 6.3312 19.7573 2.37501
+v 4.18157 20.3118 1.88735
+v -2.58306 16.091 2.65485
+v -2.94553 16.2995 1.58103
+v -3.49391 16.1588 1.13726
+v -4.14889 16.0292 0.77394
+v -5.27386 15.6877 0.522317
+v -5.9751 15.4942 0.443762
+v -7.15823 14.6199 1.386
+v -7.17212 14.6482 1.53106
+v -7.00148 14.4255 3.20758
+v -6.80753 14.5827 3.34219
+v -5.98386 15.2974 3.709
+v -4.49802 15.6716 3.72825
+v -4.21436 15.7655 3.62701
+v -2.59426 16.0212 2.96948
+v -2.34862 16.9783 2.66933
+v -2.82784 17.1819 1.40039
+v -4.22087 16.6875 0.455503
+v -6.29961 15.7788 0.0843872
+v -7.54425 14.5528 1.21206
+v -7.56239 14.5823 1.38533
+v -7.32352 14.3118 3.30397
+v -6.22077 15.5043 3.96742
+v -4.52457 16.1748 3.97168
+v -2.34542 16.8903 3.0429
+v -3.01288 18.8235 2.54077
+v -3.50457 19.0292 1.24491
+v -4.9252 18.516 0.280331
+v -7.04332 17.5749 -0.0978523
+v -8.30637 16.3142 1.05432
+v -8.07792 16.0681 3.19106
+v -6.95838 17.2929 3.86872
+v -5.22981 17.9884 3.87227
+v -3.0088 18.7334 2.92234
+v -3.41289 19.7473 2.38718
+v -3.79589 19.9859 1.21049
+v -5.11829 19.7359 0.323344
+v -7.13414 19.2235 -0.0441719
+v -8.46645 18.3191 0.98391
+v -8.33636 18.0982 2.91231
+v -7.16604 19.0207 3.52728
+v -5.52726 19.37 3.55378
+v -3.42932 19.6727 2.73144
+v -4.10458 20.8934 1.19076
+v -5.24744 20.6272 0.424129
+v -6.98002 20.1039 0.111395
+v -8.09716 19.2622 1.00788
+v -7.96684 19.069 2.6834
+v -6.98379 19.9143 3.21642
+v -5.57386 20.2822 3.23366
+v -3.76702 20.6306 2.51063
+v -5.99411 20.8336 1.53989
+v -6.56552 20.6337 1.15261
+v -7.41877 20.2657 1.00029
+v -7.93136 19.7663 1.46214
+v -7.84192 19.6675 2.31912
+v -7.38792 20.1538 2.59092
+v -6.69177 20.425 2.59293
+v -5.79748 20.7134 2.21285
+v -7.75956 20.2563 1.94475
+v 4.48925 -0.397565 1.67891
+v 4.57894 -0.882098 3.27228
+v 5.27839 -2.27325 4.02403
+v 6.62658 -4.02433 4.06797
+v 7.87742 -5.27254 2.85548
+v 8.22375 -5.4852 2.27964
+v 8.57684 -5.65355 1.49826
+v 6.9201 -0.0256538 0.20717
+v 6.15406 0.402319 1.66312
+v 6.16107 -0.154891 3.60397
+v 6.7973 -1.69642 4.38487
+v 7.77466 -3.3153 4.5424
+v 8.07509 -3.67347 4.39685
+v 9.26668 -5.10215 3.07468
+v 9.94617 -5.56135 1.61311
+v 9.41036 -0.307409 -2.05757
+v 8.79848 0.353463 -1.14807
+v 7.21724 0.790581 1.26676
+v 7.07029 0.716171 1.68495
+v 10.2365 0.0688409 -2.1062
+v 9.50096 0.683983 -1.18244
+v 7.74608 0.96038 1.28048
+v 7.59074 0.867861 1.71164
+v 9.90186 0.897039 -0.833129
+v 8.25287 1.11061 1.43852
+v 8.10856 1.02133 1.83734
+v 8.29903 0.251361 4.66989
+v -6.36897 -2.08303 3.09681
+v -5.69707 -1.35701 2.56433
+v -5.57289 -0.658732 1.83414
+v -10.1489 -6.09284 -2.26788
+v -10.0235 -6.57983 -0.0838391
+v -9.95684 -6.46862 0.504061
+v -9.46798 -6.09282 2.09362
+v -9.10984 -5.67683 2.87062
+v -8.26308 -4.87005 3.72731
+v -7.45137 -3.37247 3.78015
+v -7.16428 -3.06783 3.67282
+v -6.67091 -0.662902 2.58258
+v -6.50936 -0.0829995 1.98202
+v -11.2538 -4.85307 -2.10646
+v -11.2033 -5.36352 0.0954123
+v -10.6177 -4.93125 2.17868
+v -10.2386 -4.55644 2.91991
+v -9.36367 -3.84182 3.73211
+v -8.48087 -2.46548 3.77105
+v -8.92779 -0.335116 2.33319
+v -8.76011 0.146913 1.81859
+v -8.78474 0.770169 -0.221074
+v -10.1688 -0.658255 -2.58451
+v -11.7086 -2.32491 -2.56433
+v -12.2362 -2.83833 -2.38518
+v -13.1129 -3.63074 -1.61759
+v -13.0839 -4.06319 0.260004
+v -12.5438 -3.72669 2.02999
+v -12.1932 -3.42937 2.65788
+v -11.3999 -2.87291 3.34162
+v -10.5661 -1.75596 3.36453
+v -10.9723 0.631453 2.3975
+v -10.8013 1.1406 1.83161
+v -10.8212 1.66155 0.00288689
+v -10.7461 1.33495 -1.13531
+v -11.6032 0.799209 -1.95499
+v -12.1555 0.351906 -2.20646
+v -13.6342 -1.17553 -2.18182
+v -14.1392 -1.64476 -2.01205
+v -14.9757 -2.36719 -1.28973
+v -14.9527 -2.77136 0.469803
+v -14.4345 -2.46653 2.12641
+v -14.0978 -2.19519 2.71349
+v -13.3407 -1.69077 3.35144
+v -12.5351 -0.662741 3.36961
+v -12.6167 2.19046 2.46841
+v -12.4681 2.59725 2.03055
+v -12.4837 3.12599 0.297094
+v -12.413 2.83047 -0.735134
+v -13.1867 2.34002 -1.47922
+v -13.6849 1.93135 -1.70776
+v -15.0174 0.537896 -1.68679
+v -15.4728 0.109514 -1.53329
+v -16.2279 -0.550468 -0.87897
+v -16.206 -0.917258 0.716651
+v -15.739 -0.638289 2.21944
+v -15.4356 -0.390463 2.75215
+v -14.7522 0.0710721 3.33135
+v -14.0274 1.00785 3.34862
+v -13.4888 3.11345 2.33796
+v -13.3071 3.42523 1.96002
+v -13.2698 3.86014 0.48542
+v -13.2826 3.59795 -0.389068
+v -14.0239 3.31552 -1.00019
+v -14.5113 3.0575 -1.18034
+v -15.8511 2.12023 -1.12333
+v -17.0215 1.41992 -0.404004
+v -17.0296 1.11811 0.952161
+v -16.562 1.27901 2.21493
+v -15.599 1.70969 3.13181
+v -14.8399 2.36841 3.12359
+v -13.9133 3.73789 2.07651
+v -13.7092 3.90976 1.77293
+v -13.6158 4.20632 0.624829
+v -13.7316 4.01734 -0.0456754
+v -14.3675 4.01993 -0.487899
+v -14.7976 3.97045 -0.606147
+v -15.0572 3.90165 -0.62649
+v -16.0229 3.67253 -0.500558
+v -16.4176 3.59725 -0.369986
+v -17.0348 3.50046 0.106818
+v -17.0743 3.29107 1.1601
+v -16.6449 3.28072 2.11708
+v -16.3642 3.31053 2.44668
+v -15.7964 3.32386 2.78544
+v -15.0653 3.58473 2.74197
+v -14.248 4.23078 1.80164
+v -14.0916 4.33262 1.58225
+v -14.012 4.53037 0.761832
+v -14.1192 4.40557 0.286213
+v -14.5735 4.4646 -0.0216396
+v -14.8833 4.46884 -0.100772
+v -15.7752 4.37124 -0.0102543
+v -16.0595 4.35469 0.0876166
+v -16.4988 4.34437 0.434824
+v -16.5335 4.203 1.18668
+v -16.2197 4.15892 1.86371
+v -15.6082 4.11329 2.33008
+v -15.0682 4.23032 2.28962
+v -15.9916 5.14779 1.11682
+v 10.6535 -0.287442 -2.38225
+v 10.5153 0.415482 -1.57533
+v 10.3469 0.894247 -0.640308
+v 10.1346 1.01274 0.475619
+v 9.88308 1.10515 1.7915
+v 9.69893 0.844946 2.71238
+v 9.33596 0.337692 4.52825
+v 9.08499 -1.17756 5.63304
+v 9.03461 -2.56465 5.73982
+v 9.51797 -4.31722 5.12965
+v 9.9375 -5.15482 3.94526
+v 10.1474 -5.47249 3.25563
+v 10.489 -5.76828 1.92136
+v 10.557 -5.79106 1.62117
+v 10.639 -5.68674 1.13277
+v 11.9973 -0.268931 -2.16815
+v 11.8638 0.457681 -1.33087
+v 11.6963 0.952322 -0.361661
+v 11.2215 1.16887 2.15601
+v 10.6491 0.373136 4.98643
+v 10.3723 -1.19507 6.12547
+v 10.3036 -2.6301 6.23188
+v 10.782 -4.4476 5.59469
+v 11.4173 -5.64501 3.65125
+v 11.8355 -5.9747 1.95844
+v 12.2301 -5.30485 -0.523642
+v 12.2942 -4.5346 -1.52329
+v 12.1835 -2.25059 -3.05643
+v 12.0874 -1.80598 -2.93556
+v 13.9572 -1.05232 -1.97531
+v 13.8364 -0.2831 -1.08139
+v 13.6739 0.239951 -0.0488139
+v 13.1815 0.465805 2.62666
+v 12.5597 -0.382192 5.62789
+v 12.2275 -2.04677 6.82773
+v 12.1173 -3.56872 6.93161
+v 12.5759 -5.50606 6.24222
+v 13.2144 -6.78088 4.16964
+v 13.6457 -7.13071 2.36929
+v 14.0763 -6.41394 -0.262485
+v 14.1621 -5.5916 -1.31896
+v 14.1008 -3.15462 -2.93161
+v 15.2963 -2.37617 -1.27917
+v 15.2619 -1.71736 -0.483102
+v 15.1714 -1.27162 0.429207
+v 14.7808 -1.0909 2.77069
+v 14.1901 -1.83818 5.37543
+v 13.7703 -3.28035 6.3905
+v 13.5478 -4.59416 6.45105
+v 13.7791 -6.29929 5.80659
+v 14.2127 -7.41529 3.96813
+v 14.5458 -7.71697 2.38764
+v 14.9621 -7.07538 0.103984
+v 15.0984 -6.34659 -0.801108
+v 15.2385 -4.1925 -2.15696
+v 16.2406 -3.8503 -0.47505
+v 16.3083 -3.36177 0.172286
+v 16.3055 -3.035 0.90512
+v 16.0481 -2.92233 2.75786
+v 15.5154 -3.51171 4.79124
+v 15.0088 -4.60883 5.55006
+v 14.6633 -5.60024 5.55943
+v 14.6115 -6.93099 4.9953
+v 14.7835 -7.7914 3.50789
+v 14.9873 -8.0159 2.25058
+v 15.3736 -7.49633 0.468936
+v 15.5672 -6.91874 -0.221758
+v 15.9477 -5.22139 -1.22188
+v 16.7955 -5.47703 0.304608
+v 16.9407 -5.19506 0.774473
+v 17.0089 -5.01218 1.29822
+v 16.878 -4.97963 2.59659
+v 16.4311 -5.37348 3.99579
+v 15.8915 -6.04891 4.48626
+v 15.4717 -6.64709 4.4569
+v 15.178 -7.49938 4.00698
+v 15.1136 -8.03382 2.93119
+v 15.1939 -8.1604 2.04281
+v 15.5321 -7.79802 0.818895
+v 15.764 -7.41426 0.360111
+v 16.3306 -6.30174 -0.268282
+v 16.8373 -6.37432 0.678351
+v 16.9739 -6.18606 1.03742
+v 17.0446 -6.06653 1.43575
+v 16.9581 -6.05941 2.41707
+v 16.5981 -6.34649 3.46837
+v 16.1379 -6.8164 3.82907
+v 15.7707 -7.2274 3.79816
+v 15.4731 -7.83051 3.44345
+v 15.3708 -8.20161 2.62121
+v 15.4139 -8.28384 1.94764
+v 15.6909 -8.01474 1.02891
+v 15.8952 -7.73726 0.688791
+v 16.4129 -6.93913 0.233048
+v 17.0743 -7.10653 2.04129
+v 7.34296 -13.1902 6.50867
+v 5.91079 -12.3487 7.32778
+v 4.08845 -11.9719 8.25934
+v 2.32839 -12.5529 8.27078
+v 1.85444 -13.2464 8.19529
+v 1.13496 -14.2265 7.77354
+v 0.856109 -15.8474 6.89498
+v 8.70611 -15.016 6.87116
+v 8.22512 -14.5234 7.9584
+v 6.69016 -13.6781 9.10954
+v 4.72019 -13.3159 10.247
+v 2.62295 -13.7927 10.1508
+v 2.01817 -14.4835 9.88869
+v 1.11002 -15.3695 9.17281
+v 0.636617 -16.8784 7.77461
+v 0.75201 -17.4806 6.43341
+v 9.11638 -18.3209 6.87457
+v 9.50146 -17.5945 6.97487
+v 9.43912 -15.9139 8.305
+v 8.85565 -15.1436 9.24869
+v 7.13062 -14.1264 10.1607
+v 5.00841 -13.6458 11.2142
+v 2.87891 -14.3975 11.2923
+v 2.33444 -15.2377 11.2513
+v 1.50657 -16.4485 10.8196
+v 1.21992 -18.4396 9.89118
+v 1.44059 -19.4406 8.73144
+v 2.00535 -20.2057 7.86012
+v 2.92835 -20.7018 6.553
+v 3.51329 -20.8754 5.80802
+v 4.90867 -20.7855 5.08494
+v 5.32743 -20.7163 5.03796
+v 5.72898 -20.6413 5.0824
+v 7.11086 -20.173 5.5667
+v 7.50689 -19.9746 5.80125
+v 8.86898 -18.7036 6.51928
+v 9.19698 -18.532 7.76905
+v 9.55847 -17.8557 7.8679
+v 9.50503 -16.2963 9.12182
+v 8.96256 -15.5825 10.0084
+v 7.35507 -14.6348 10.8674
+v 5.37533 -14.188 11.8547
+v 3.38531 -14.8844 11.9224
+v 2.87472 -15.667 11.878
+v 2.09849 -16.7918 11.4663
+v 1.82533 -18.643 10.5852
+v 2.02847 -19.5696 9.49529
+v 2.55349 -20.2791 8.67627
+v 3.41366 -20.7352 7.45234
+v 3.95916 -20.8934 6.75555
+v 5.26197 -20.8081 6.08103
+v 5.65308 -20.7443 6.03762
+v 6.02815 -20.6758 6.0796
+v 7.31953 -20.2459 6.53493
+v 7.6898 -20.0635 6.75527
+v 8.96493 -18.8859 7.43463
+v 9.81741 -18.6588 8.66122
+v 10.2449 -17.9746 8.86704
+v 10.2752 -16.5025 10.441
+v 9.73164 -15.8465 11.4981
+v 8.05644 -14.8763 12.5682
+v 5.95192 -14.4375 13.7013
+v 3.77198 -15.075 13.6806
+v 3.17795 -15.872 13.5177
+v 2.2792 -16.9622 12.9129
+v 1.88027 -18.7829 11.6941
+v 2.04709 -19.6151 10.3901
+v 2.57207 -20.2757 9.40587
+v 3.47268 -20.6244 8.02631
+v 4.05126 -20.718 7.25598
+v 5.45809 -20.5993 6.54148
+v 5.88236 -20.5472 6.50237
+v 6.28953 -20.5021 6.5551
+v 7.70204 -20.1878 7.09742
+v 8.11031 -20.0483 7.35761
+v 8.25899 -19.9517 7.48511
+v 9.54807 -18.9713 8.25246
+v 9.58057 -18.9569 9.05401
+v 9.96952 -18.3458 9.24909
+v 10.0051 -17.042 10.6882
+v 9.51895 -16.463 11.6502
+v 8.01482 -15.5952 12.6287
+v 6.12098 -15.2046 13.6564
+v 4.15315 -15.7669 13.6292
+v 3.61354 -16.4795 13.4713
+v 2.79767 -17.4484 12.9111
+v 2.42815 -19.0693 11.7871
+v 2.57375 -19.8014 10.6003
+v 3.04308 -20.3854 9.70385
+v 3.8525 -20.6848 8.45562
+v 4.37322 -20.7613 7.76005
+v 5.64145 -20.6517 7.11759
+v 6.02405 -20.6065 7.08297
+v 6.3912 -20.5688 7.13102
+v 7.66584 -20.3009 7.62376
+v 8.03454 -20.1812 7.86008
+v 8.16906 -20.0967 7.97629
+v 9.3361 -19.2313 8.68132
+v 9.16118 -17.9974 10.2502
+v 9.19505 -17.117 11.2743
+v 8.86106 -16.7285 11.9538
+v 7.82098 -16.1324 12.6503
+v 6.50661 -15.8664 13.3726
+v 5.13411 -16.2436 13.3443
+v 4.75392 -16.7325 13.2219
+v 4.17977 -17.3906 12.8153
+v 3.91152 -18.4949 12.0047
+v 4.00758 -18.9836 11.1663
+v 4.32987 -19.3768 10.5323
+v 4.89056 -19.568 9.65874
+v 5.25209 -19.6122 9.17352
+v 6.65683 -19.4807 8.73884
+v 7.89676 -19.1798 9.3344
+v 8.71449 -18.5986 9.83974
+v 6.64402 -18.7074 10.7009
+v -2.7598 -13.1675 7.96074
+v -3.4691 -12.1985 7.92087
+v -4.87975 -11.4074 7.68177
+v -5.80737 -11.289 7.468
+v -5.96726 -11.2781 7.42983
+v -6.64102 -11.1674 6.82182
+v -7.93342 -11.9029 5.52652
+v -8.47724 -13.0491 4.86764
+v -2.717 -16.3949 6.24832
+v -2.54372 -15.4002 6.82977
+v -2.29336 -14.0157 7.62177
+v -3.04888 -13.4592 9.21565
+v -3.76748 -12.4633 9.14836
+v -5.20626 -11.6499 8.8856
+v -6.31952 -11.5165 8.6285
+v -7.00931 -11.416 8.0074
+v -8.32452 -12.1629 6.73106
+v -8.91404 -13.3864 6.07149
+v -8.93624 -14.1109 5.64083
+v -3.03806 -16.8136 7.56161
+v -2.57962 -14.341 8.89267
+v -3.24346 -13.5306 10.835
+v -3.92455 -12.4866 10.4164
+v -5.40134 -11.6197 9.89744
+v -6.59156 -11.4632 9.63007
+v -7.36053 -11.5208 8.99618
+v -8.91596 -12.6001 8.05111
+v -9.69769 -14.0017 7.87677
+v -9.81594 -14.8817 7.72171
+v -10.0166 -16.5107 8.01671
+v -9.40699 -18.1108 7.8723
+v -8.24748 -19.5917 7.7336
+v -7.31257 -20.2074 7.80809
+v -5.98394 -20.4492 8.17118
+v -5.17774 -19.6177 9.30431
+v -3.64583 -17.4907 10.4527
+v -2.84537 -14.5801 10.8295
+v -3.54228 -13.4549 11.8096
+v -4.21392 -12.4257 11.4018
+v -5.66877 -11.5715 10.894
+v -6.84075 -11.4176 10.6306
+v -7.59743 -11.4723 10.0057
+v -9.12705 -12.5324 9.06897
+v -9.89496 -13.9126 8.89019
+v -10.0102 -14.7786 8.73328
+v -10.206 -16.3842 9.01595
+v -9.60367 -17.9583 8.86665
+v -8.46004 -19.4144 8.72389
+v -7.53877 -20.0199 8.79497
+v -6.23046 -20.2581 9.15224
+v -5.43841 -19.4437 10.2724
+v -3.93337 -17.3529 11.4142
+v -3.149 -14.4877 11.7995
+v -3.59656 -13.035 13.5552
+v -4.36284 -11.8849 13.2427
+v -5.97709 -10.9383 12.7791
+v -7.25975 -10.7756 12.4887
+v -8.07597 -10.774 11.7843
+v -9.68946 -11.8445 10.5858
+v -10.4734 -13.3432 10.1801
+v -10.5637 -14.2642 9.88523
+v -10.7218 -16.0524 9.96129
+v -10.0006 -17.717 9.59114
+v -8.69218 -19.2354 9.25694
+v -7.66306 -19.8694 9.26955
+v -6.2298 -20.132 9.65313
+v -5.41467 -19.3793 11.0011
+v -3.86887 -17.2202 12.5683
+v -3.12706 -14.1397 13.4076
+v -4.13339 -13.6667 13.8504
+v -4.83369 -12.6222 13.5908
+v -6.30076 -11.7635 13.187
+v -7.46319 -11.617 12.9233
+v -8.19881 -11.6037 12.284
+v -9.65267 -12.5564 11.167
+v -10.3529 -13.9095 10.7627
+v -10.4283 -14.7377 10.4743
+v -10.5611 -16.3604 10.502
+v -9.89648 -17.8558 10.1312
+v -8.70062 -19.216 9.79826
+v -7.76426 -19.7847 9.79869
+v -6.46503 -20.0229 10.145
+v -5.7351 -19.3669 11.386
+v -4.35209 -17.4374 12.8602
+v -3.70086 -14.6614 13.6931
+v -4.91278 -14.1321 14.0506
+v -5.49384 -13.2785 13.8794
+v -6.69692 -12.5784 13.578
+v -7.64451 -12.4606 13.3622
+v -8.24201 -12.4309 12.8364
+v -9.40828 -13.1741 11.8783
+v -9.96142 -14.2658 11.487
+v -10.0119 -14.9285 11.2164
+v -10.102 -16.2519 11.1689
+v -9.54123 -17.446 10.8074
+v -8.54925 -18.5259 10.486
+v -7.77963 -18.9785 10.468
+v -6.72001 -19.173 10.7481
+v -6.13968 -18.6841 11.791
+v -5.04276 -17.1614 13.0822
+v -4.5481 -14.9304 13.8829
+v -5.7059 -14.6758 13.6914
+v -6.12426 -14.0593 13.5622
+v -6.99242 -13.5534 13.3406
+v -7.677 -13.4681 13.1848
+v -8.10808 -13.449 12.8062
+v -8.95412 -13.9909 12.1198
+v -9.3562 -14.7814 11.8456
+v -9.39417 -15.262 11.655
+v -9.46181 -16.2182 11.6304
+v -9.05933 -17.0845 11.3773
+v -8.34505 -17.8689 11.1519
+v -7.78992 -18.1974 11.1415
+v -7.02448 -18.3379 11.3441
+v -6.60321 -17.9782 12.0934
+v -5.80653 -16.871 13.014
+v -5.44413 -15.2543 13.5757
+v -7.61104 -14.4841 13.0272
+v -2.36336 -9.27381 -9.43989
+v -0.857446 -7.68471 -9.2209
+v 1.1529 -7.85642 -9.15852
+v 1.54786 -8.2889 -9.18625
+v 2.12935 -9.59637 -9.29436
+v 2.26857 -10.644 -9.23577
+v 2.25022 -11.0267 -9.2308
+v 2.23927 -11.2545 -9.16711
+v 1.9765 -12.0524 -8.96194
+v 1.43696 -12.7215 -8.69051
+v 1.1865 -13.0077 -8.58188
+v -1.97388 -12.1079 -9.12807
+v -2.01864 -11.962 -9.16984
+v -2.27164 -11.1064 -9.42293
+v -2.48343 -10.2983 -9.44414
+v -2.74235 -8.71723 -10.2178
+v -0.968673 -6.83641 -10.1894
+v 1.39184 -7.03215 -10.0625
+v 1.85433 -7.54125 -10.0221
+v 2.5331 -9.08247 -9.93657
+v 2.66783 -10.7388 -9.63833
+v 2.6531 -10.9942 -9.52884
+v 2.33804 -11.8909 -9.16934
+v 1.40048 -12.9422 -8.58887
+v -1.06022 -13.3963 -8.47276
+v -1.73711 -13.0139 -8.75024
+v -2.30162 -11.9707 -9.40827
+v -2.64307 -10.8493 -9.9116
+v -2.888 -9.91082 -10.0649
+v -2.37497 -8.28297 -11.9537
+v -0.879504 -6.8486 -11.2672
+v 1.11645 -7.00475 -11.3198
+v 1.50851 -7.39556 -11.4986
+v 2.08559 -8.5767 -12.0453
+v 2.21133 -9.93494 -12.4593
+v 1.95073 -10.9869 -12.5375
+v 1.18125 -12.0158 -12.4745
+v -0.890045 -12.4433 -12.4849
+v -1.4712 -12.0608 -12.5262
+v -1.97157 -11.0335 -12.6041
+v -2.2784 -10.0029 -12.5427
+v -2.49131 -9.2421 -12.2912
+v -1.8619 -7.7257 -12.5409
+v -0.772848 -6.83707 -11.8227
+v 0.669533 -6.92442 -11.9181
+v 0.950917 -7.16305 -12.1201
+v 1.36183 -7.88691 -12.726
+v 1.44901 -8.76163 -13.2642
+v 1.26168 -9.48531 -13.506
+v 0.70872 -10.2217 -13.6372
+v -0.787859 -10.5319 -13.6907
+v -1.2095 -10.2603 -13.6413
+v -1.57475 -9.53026 -13.5017
+v -1.79785 -8.82194 -13.2669
+v -1.94936 -8.33646 -12.9495
+v -1.47495 -7.43161 -12.9047
+v -0.692286 -6.81428 -12.3671
+v 0.342475 -6.87314 -12.4415
+v 0.544019 -7.03825 -12.5939
+v 0.837798 -7.53959 -13.05
+v 0.899551 -8.15126 -13.4611
+v 0.764982 -8.66332 -13.6548
+v 0.368344 -9.18794 -13.7685
+v -0.705431 -9.40987 -13.812
+v -1.00801 -9.21685 -13.7678
+v -1.27019 -8.6977 -13.6459
+v -1.43012 -8.19674 -13.4568
+v -1.53834 -7.85787 -13.2149
+v -0.358819 -8.16598 -14.0506
+v -2.5032 -18.3093 3.42843
+v -2.72296 -17.9243 4.31298
+v -2.77037 -17.7981 4.52864
+v -3.17051 -16.9932 5.54093
+v -3.70045 -17.66 5.78613
+v -4.04795 -18.1936 5.96706
+v -4.35338 -18.6194 5.96883
+v -5.75755 -19.3271 5.65487
+v -3.10401 -18.9815 0.118243
+v -2.87316 -18.9613 0.919021
+v -2.43034 -18.9319 1.51088
+v -2.43755 -18.7311 2.16225
+v -2.45555 -18.6407 2.49948
+v -2.8819 -18.594 2.60579
+v -3.3477 -17.9951 4.22083
+v -4.73169 -18.5409 5.3324
+v -3.05025 -18.8868 1.32695
+v -4.20451 -18.5861 2.46404
+v 0.710033 -18.6592 -1.13716
+v 2.05913 -18.5918 -0.991563
+v 1.1849 -18.6772 -0.388354
+v 2.0053 -18.5954 -0.0572764
+v 6.39237 -19.2056 4.52445
+v 5.64925 -19.492 4.31942
+v 5.11194 -19.7103 4.19143
+v 4.94849 -19.6813 4.14407
+v 4.80878 -19.6293 4.11309
+v 2.31056 -18.5814 0.00696266
+v 2.31729 -18.5894 -0.199142
+v 2.43539 -18.5631 -0.843749
+v 2.44597 -18.5293 -1.4531
+v 2.45303 -18.5229 -1.48664
+v 2.49745 -18.5069 -1.51347
+v 5.1406 -18.077 0.480865
+v 4.07834 -18.3617 0.515857
+v 5.22713 -18.2215 2.5594
+v 5.81359 -17.8825 0.0851822
+v 3.00872 -18.5057 -0.0576055
+v 3.14933 -18.3627 -1.35805
+v 4.38525 -18.2252 -0.367964
+v 5.92121 -18.5314 3.73028
+v 4.34849 -18.3148 1.56501
+v 4.91719 -19.2931 3.9138
+v 5.37922 -18.0257 1.43056
+v 6.05171 -17.8258 1.75273
+v 5.97412 -17.8562 0.703995
+v 6.69838 -17.9455 3.8116
+v 6.21127 -17.8071 2.81881
+v -3.18127 -18.5547 -2.43093
+v -3.67717 -18.7671 -1.69418
+v -3.73708 -18.9004 -1.14441
+v -3.79848 -18.9199 -0.96519
+v -4.00371 -18.9244 -0.291902
+v -4.38725 -18.8175 1.00334
+v -4.56981 -18.6552 1.98117
+v -4.45477 -18.5806 2.4171
+v -4.61064 -18.5087 2.72066
+v -4.84134 -18.3394 3.59287
+v -5.04337 -18.3805 4.2763
+v -5.37729 -18.5271 4.81816
+v -6.32656 -18.9699 5.20353
+v -6.32757 -18.9726 5.201
+v -7.4415 -18.7064 5.42364
+v -7.80517 -17.6252 -1.22005
+v -7.80636 -17.6167 -1.25609
+v -7.78643 -17.6216 -1.28054
+v -7.08846 -17.7627 -2.27
+v -6.73389 -17.8435 -2.48148
+v -5.9734 -17.8601 -3.11616
+v -4.79512 -17.9834 -3.41273
+v -3.7544 -18.2241 -3.20044
+v -3.17943 -18.5076 -2.56594
+v -4.42543 -18.518 -2.23666
+v -6.06803 -18.5928 -0.0746953
+v -4.16776 -18.8596 -1.09056
+v -5.71127 -18.2094 -2.41264
+v -7.01376 -17.9698 -1.5307
+v -4.61365 -18.8628 -0.206156
+v -5.23479 -18.7167 1.11695
+v -7.44639 -17.9894 0.111755
+v -5.2859 -18.4952 2.47464
+v -6.35056 -18.4536 4.46211
+v -5.40649 -18.6302 -1.24815
+v -6.45558 -18.3957 1.31282
+v -4.07559 0.81435 -3.37321
+v -3.01328 0.917503 -3.98176
+v -2.64792 0.82237 -4.31244
+v -2.39854 0.502634 -4.88434
+v -2.43018 -0.562366 -6.31426
+v -1.81383 -1.28142 -7.33229
+v -2.7711 -2.45145 -7.83354
+v -3.89518 -3.07393 -7.81547
+v -4.38702 -3.44545 -7.83122
+v -5.07478 -2.52121 -6.56103
+v -3.59595 -0.128111 -4.91497
+v -3.01339 -1.61036 -7.06429
+v -11.9076 -3.05627 -2.44729
+v -11.4642 -2.59777 -2.63262
+v -11.3807 -2.50191 -2.66664
+v -10.9963 -2.45589 -2.73772
+v -9.54351 -1.92122 -3.00943
+v -9.02267 -1.69639 -3.10809
+v -6.46369 -1.96419 -4.76823
+v -5.91052 -2.75405 -6.16624
+v -5.69149 -3.01245 -6.68104
+v -5.69787 -3.48755 -7.19219
+v -5.7222 -3.6944 -7.32863
+v -5.78445 -4.13586 -7.49004
+v -6.33436 -5.09181 -7.45393
+v -7.1773 -6.32121 -7.1754
+v -8.30267 -6.81799 -5.85339
+v -9.49625 -6.19219 -3.83241
+v -9.72031 -5.83697 -3.05128
+v -9.88143 -5.50292 -2.78206
+v -10.2048 -5.25703 -2.54214
+v -11.0132 -4.37264 -2.38157
+v -10.3347 -3.28058 -2.84892
+v -8.89488 -3.64838 -3.78764
+v -7.39682 -5.1829 -6.51363
+v -7.09365 -2.91284 -5.2027
+v -8.5698 -5.68259 -5.16851
+v -6.25062 -3.7202 -6.81526
+v -7.74301 -4.1912 -5.61262
+v -8.70142 0.594052 -0.920757
+v -6.79699 0.703026 -0.316032
+v -5.87053 -0.099028 0.846976
+v -5.60934 -0.442833 1.28366
+v -5.60657 0.0888788 0.489344
+v -5.53102 0.293355 -0.0556779
+v -5.31261 0.422834 -0.443193
+v -5.21918 0.483345 -0.703625
+v -5.07961 0.530771 -1.05358
+v -5.02496 0.527718 -1.32527
+v -4.68414 0.55934 -2.41843
+v -4.43626 0.629863 -2.94323
+v -4.35969 0.506213 -3.32543
+v -3.97593 -0.133254 -4.57193
+v -4.01385 -0.263501 -4.71016
+v -5.49839 -1.61652 -5.14622
+v -7.7959 -1.95632 -3.82751
+v -8.28439 -1.74111 -3.39577
+v -8.50943 -1.55299 -3.23275
+v -9.24276 -1.10848 -2.90643
+v -9.51959 -0.734962 -2.68105
+v -9.94518 -0.509204 -2.52
+v -10.1194 0.130665 -2.12199
+v -9.9866 0.49603 -1.75844
+v -9.70319 0.877582 -1.27132
+v -9.08794 -0.0765847 -2.05766
+v -5.11385 -0.535856 -4.05713
+v -8.4666 -1.17976 -3.08942
+v -7.39512 0.204022 -1.26135
+v -4.87962 0.368914 -2.61413
+v -6.89682 -1.50643 -4.04277
+v -5.79997 0.354131 -0.842497
+v -6.80961 -0.358092 -2.51956
+v 11.1959 -3.85244 -1.97657
+v 11.5897 -4.46941 -1.60203
+v 11.635 -4.7573 -1.27203
+v 11.6143 -5.1247 -0.762655
+v 10.7871 -5.25766 0.0620276
+v 10.3689 -5.41321 0.683658
+v 9.82201 -5.34246 0.995192
+v 8.79574 -5.3899 1.07006
+v 8.63593 -5.55682 1.00629
+v 8.90097 -6.14035 0.232997
+v 4.1773 0.108464 -1.12358
+v 4.91844 -0.390622 0.436485
+v 4.91401 -0.456217 0.794712
+v 5.59278 -0.347554 0.546112
+v 6.82164 -0.114435 0.152843
+v 6.90477 -0.107049 0.092802
+v 7.95237 -0.263191 -0.902691
+v 6.83938 -2.92594 -6.38791
+v 7.06427 -3.82385 -6.47767
+v 8.75915 -6.01866 -0.508243
+v 9.00918 -6.51361 -0.8432
+v 9.6344 -7.67087 -1.17538
+v 9.91865 -8.29697 -1.41246
+v 9.9463 -8.98907 -2.42912
+v 9.71947 -9.7746 -3.8076
+v 9.26766 -9.31935 -4.56685
+v 8.84103 -8.93539 -5.16779
+v 8.30721 -7.8594 -5.61632
+v 9.68052 -9.04919 -3.54201
+v 9.71911 -8.32666 -2.45901
+v 9.03965 -8.0465 -4.1884
+v 9.05844 -6.98945 -2.35701
+v 8.69724 -0.416741 -1.47101
+v 8.93851 -0.484356 -1.70123
+v 9.193 -0.537614 -1.94412
+v 9.35822 -0.492823 -2.0412
+v 9.4429 -0.502044 -2.0943
+v 9.55262 -0.580751 -2.17612
+v 9.79774 -0.816638 -2.37472
+v 10.8493 -0.994233 -2.72748
+v 10.9286 -1.36502 -2.82725
+v 8.45234 -2.85819 -5.54703
+v 7.56359 -2.82224 -6.05728
+v 6.92526 -2.86857 -6.34005
+v 6.91333 -2.8751 -6.34783
+v 6.88812 -2.83535 -6.32688
+v 9.88231 -1.31778 -2.69931
+v 8.0728 -2.33546 -5.59427
+v 9.13902 -1.70408 -3.72959
+v 9.01551 -2.02018 -4.50899
+v 9.24112 -0.891202 -2.21326
+v 8.62813 -2.33031 -5.18904
+v 9.10216 -1.45939 -2.86325
+v 9.18097 -2.28716 -4.62239
+v 9.34959 -2.23342 -4.19029
+v 9.43874 -2.02307 -3.84721
+v 9.52262 -1.84962 -3.43672
+v 9.88858 -1.37055 -2.7356
+v 9.97292 -1.37318 -2.71743
+v 10.6578 -1.38478 -2.78418
+v 11.4262 -2.25161 -3.07977
+v 11.1491 -3.83057 -1.95336
+v 11.1613 -3.85052 -1.94696
+v 9.86232 -4.75237 0.238385
+v 9.54842 -4.94278 0.477411
+v 8.94152 -5.09735 0.654812
+v 8.53747 -5.22139 0.599743
+v 8.54208 -5.28375 0.192401
+v 8.59503 -5.52132 -0.210122
+v 8.63704 -5.63352 -0.625862
+v 8.67569 -5.7476 -0.761045
+v 8.78515 -5.91158 -1.3542
+v 8.8186 -5.997 -1.90537
+v 8.8466 -6.27868 -2.65807
+v 8.79388 -6.83838 -3.55363
+v 8.5458 -7.08197 -4.84782
+v 8.3055 -7.20489 -5.44861
+v 8.03506 -7.17013 -5.8263
+v 7.58687 -7.06429 -6.31421
+v 7.09222 -6.22165 -6.76013
+v 6.99566 -5.90388 -6.80994
+v 7.11769 -5.44676 -6.57199
+v 7.22574 -4.81445 -6.39822
+v 7.54531 -4.33099 -6.05524
+v 8.17145 -3.53496 -5.58414
+v 8.2829 -3.23598 -5.56374
+v 8.47891 -3.01988 -5.48988
+v 8.71172 -2.8384 -5.34014
+v 8.91588 -2.58714 -4.90522
+v 9.22905 -3.21626 -3.32277
+v 10.4072 -1.86699 -2.8685
+v 10.1464 -3.71109 -1.40823
+v 8.76579 -4.34929 -3.37235
+v 8.34496 -5.61151 -4.79166
+v 7.54086 -6.30524 -6.22704
+v 9.67781 -2.66327 -3.1221
+v 8.76442 -5.78391 -1.78126
+v 8.4693 -3.3148 -5.34054
+v 8.21386 -6.51046 -5.31223
+v 7.77806 -5.35658 -5.75691
+v 8.67782 -5.71098 -3.67877
+v 8.28761 -4.59537 -4.98945
+v 1.93589 -3.13639 -8.07559
+v 2.96972 -2.55539 -7.6485
+v 6.46168 -2.94844 -6.57555
+v 6.48287 -3.24998 -6.73225
+v 6.65251 -3.83651 -6.81666
+v 6.63047 -4.17491 -6.90402
+v 6.53577 -4.92629 -7.12199
+v 6.22202 -5.42954 -7.64814
+v 5.94225 -5.55822 -7.88632
+v 4.47588 -5.97224 -8.66282
+v 3.33678 -5.05508 -8.73225
+v 2.55473 -4.56142 -8.637
+v 2.14119 -3.75666 -8.33357
+v 2.93428 -3.48044 -8.15491
+v 4.72946 -4.99415 -8.39975
+v 4.02671 -2.4857 -7.40436
+v 6.03496 -2.76729 -6.59791
+v 5.79391 -4.84085 -7.7926
+v 3.77326 -4.36602 -8.44775
+v 3.58482 -2.80425 -7.76507
+v 6.08131 -4.03111 -7.22385
+v 4.94066 -4.30357 -8.12438
+v 4.30976 -3.3525 -7.85572
+v -6.69873 -18.1695 2.15848
+v -6.65123 -18.1303 2.61053
+v -6.65005 -18.1919 3.74706
+v -6.59452 -18.248 4.31753
+v -6.60953 -18.2719 4.46994
+v -7.52774 -18.1787 5.15636
+v -8.2386 -17.7983 5.57224
+v -8.99798 -16.0422 5.7175
+v -9.10489 -15.5564 5.6305
+v -8.94158 -14.8465 5.34916
+v -8.85115 -14.3736 5.28458
+v -8.76601 -14.0843 5.16017
+v -9.04013 -13.5063 4.185
+v -9.28124 -13.461 3.89239
+v -10.0332 -13.8429 2.5724
+v -10.2986 -14.034 2.00737
+v -10.4451 -14.0702 1.67098
+v -10.5103 -14.2304 1.23307
+v -10.4303 -14.8195 0.335175
+v -10.3283 -15.0238 -0.154214
+v -10.0309 -15.414 -0.568392
+v -9.81732 -15.7004 -0.680132
+v -9.46997 -16.1514 -0.614495
+v -9.0282 -16.6431 -0.617155
+v -8.59994 -17.1118 -0.389686
+v -8.29905 -17.4767 -0.173699
+v -7.83682 -17.7464 0.305225
+v -7.64837 -17.8425 0.522578
+v -7.12772 -18.0109 1.51616
+v -7.68025 -17.739 4.84566
+v -8.9023 -16.2534 2.43343
+v -7.10701 -17.8596 3.49777
+v -8.83115 -14.9454 4.63058
+v -7.33821 -17.7338 2.37078
+v -8.09006 -16.8863 3.76566
+v -8.23971 -17.3632 0.770131
+v -10.0971 -15.0126 1.4035
+v -8.58815 -16.421 5.16807
+v -9.00825 -16.7204 -0.00615466
+v -9.57552 -14.4795 3.00892
+v -9.33159 -16.2984 1.06898
+v -9.91096 -15.6249 0.0619866
+v 8.3814 -14.9799 6.27751
+v 8.46067 -15.464 5.98351
+v 8.76236 -16.8125 5.91722
+v 8.70327 -17.2075 5.77145
+v 8.45453 -17.6074 5.5089
+v 8.27515 -17.6796 5.34943
+v 7.74341 -18.0918 5.02783
+v 7.04471 -17.7767 4.3167
+v 6.81557 -17.816 3.82756
+v 6.796 -17.8101 3.7521
+v 6.78658 -17.7709 3.57246
+v 6.50413 -17.6945 2.80191
+v 6.61547 -17.6212 2.42455
+v 6.55059 -17.6512 1.96829
+v 6.8621 -17.6354 0.895469
+v 9.67798 -15.38 0.757261
+v 9.7305 -15.27 1.1189
+v 9.61029 -15.0268 2.19635
+v 9.51283 -14.6511 2.81565
+v 8.91128 -14.6703 3.53605
+v 8.01937 -14.2508 5.07888
+v 8.05359 -14.5364 5.5558
+v 8.29367 -15.2241 4.59372
+v 8.37049 -16.2972 2.59206
+v 8.33549 -16.8987 5.24999
+v 7.12357 -17.4404 3.25876
+v 8.85546 -15.2579 3.21689
+v 7.27742 -17.307 1.73947
+v 7.88345 -16.6415 3.88891
+v 3.2997 -20.3881 5.53909
+v 2.77006 -20.1195 6.00748
+v 2.39592 -19.7411 6.15724
+v 1.79724 -19.2007 6.60655
+v 0.903801 -17.5652 6.32278
+v 0.819213 -17.5132 6.3599
+v 0.816415 -17.3996 6.34521
+v 0.872976 -16.4585 6.16572
+v 0.773509 -16.3777 6.13872
+v -0.547262 -17.0551 5.50003
+v -0.973561 -17.5299 4.92954
+v -1.05401 -17.6253 4.77218
+v -1.12574 -17.9811 3.99315
+v -1.2152 -18.0645 3.81685
+v -1.35549 -18.194 3.5383
+v -1.28091 -18.2905 3.2334
+v -1.65231 -18.7287 2.03541
+v -1.52133 -18.7724 1.73952
+v -0.878568 -18.7952 0.622388
+v -0.801691 -18.8344 0.243165
+v -0.266011 -18.7777 0.116888
+v 0.487302 -18.7202 -0.0958914
+v 1.16724 -18.6452 -0.0797194
+v 1.797 -18.5832 0.119665
+v 1.98215 -18.5648 0.221307
+v 2.17779 -18.5519 0.285758
+v 2.36027 -18.5359 0.353912
+v 2.64294 -18.497 0.496052
+v 3.05615 -18.4491 0.756121
+v 3.32277 -18.4161 1.03429
+v 3.70831 -18.378 1.44073
+v 4.03184 -18.3639 1.75021
+v 4.23198 -18.3538 1.87329
+v 4.80725 -18.4013 2.6475
+v 4.70108 -19.2392 3.8415
+v 4.78113 -19.2989 3.9132
+v 4.65522 -19.4986 4.06368
+v 4.49572 -19.6828 4.27025
+v 4.07878 -19.8736 4.63943
+v 3.47393 -20.4479 5.41196
+v 1.77681 -18.6705 5.9658
+v -0.575064 -17.5636 4.78117
+v 0.0633911 -18.6297 0.802927
+v 2.4431 -18.5662 3.27254
+v 2.57915 -19.5432 5.59542
+v -0.585391 -18.574 1.66449
+v 1.23958 -18.587 0.367539
+v 2.84539 -18.4516 1.85583
+v 0.440148 -18.1498 3.5708
+v 3.82994 -18.6094 2.74043
+v 3.79623 -19.2412 4.06544
+v 2.05778 -18.5895 4.72207
+v -0.884839 -18.471 2.4305
+v 2.39938 -18.4968 0.690339
+v 1.4227 -18.4429 1.57717
+v -0.63572 -18.0995 3.62193
+v 0.573386 -17.8004 4.4211
+v 0.359991 -18.3453 2.53648
+v 1.20802 -18.2981 3.52746
+v 3.25102 -19.7958 5.08352
+v 1.62741 -18.4094 2.59641
+v 1.82982 1.1026 -4.29731
+v 2.14285 1.08445 -4.22759
+v 2.95076 0.877488 -3.66644
+v 2.98549 0.855517 -3.62364
+v 3.79793 0.319393 -2.71542
+v 4.12368 0.282059 -1.92775
+v 4.30384 0.0401254 -1.24999
+v 4.56875 -0.177317 -0.761825
+v 4.57058 -0.210269 -0.490365
+v 4.89702 -0.312656 -0.269487
+v 5.22304 -0.380424 0.181221
+v 5.68299 -0.366576 0.289866
+v 6.37003 -0.304144 0.00581551
+v 6.71185 -0.27473 -0.0149846
+v 7.05235 -0.330692 -0.290053
+v 7.89141 -0.313382 -0.890815
+v 7.93923 -0.314016 -0.920161
+v 7.9657 -0.340564 -0.959427
+v 8.22883 -0.450128 -1.21454
+v 8.43247 -0.515643 -1.37359
+v 8.61363 -0.580544 -1.54939
+v 8.73145 -0.656186 -1.6903
+v 8.76697 -0.720041 -1.76831
+v 8.7721 -0.849813 -1.89958
+v 8.75988 -1.10623 -2.26907
+v 8.87818 -1.4298 -2.80345
+v 8.8987 -1.47803 -2.92125
+v 8.92778 -1.64986 -3.58093
+v 8.85436 -1.68043 -3.74827
+v 8.68271 -1.82822 -4.30442
+v 8.55286 -1.90061 -4.57388
+v 8.26347 -2.03901 -5.01986
+v 8.01731 -2.2227 -5.49377
+v 7.84969 -2.24671 -5.59245
+v 7.42064 -2.56668 -5.97796
+v 6.97867 -2.68023 -6.205
+v 6.81232 -2.73732 -6.28186
+v 6.75379 -2.73715 -6.29925
+v 6.63527 -2.72835 -6.33767
+v 6.34126 -2.72592 -6.45932
+v 6.03572 -2.73712 -6.5759
+v 6.01617 -2.72636 -6.57869
+v 5.85948 -2.65841 -6.62155
+v 4.92149 -2.58451 -7.04933
+v 4.49181 -2.33052 -7.08995
+v 4.09961 -2.24 -7.16576
+v 3.52239 -2.00392 -7.02253
+v 2.86916 -1.16863 -6.488
+v 1.76171 0.735625 -4.68584
+v 1.66487 1.01053 -4.4289
+v 2.15187 0.158104 -5.18725
+v 2.7369 -0.0569637 -5.14276
+v 6.18456 -1.18102 -3.30694
+v 5.51754 -0.387007 -0.138093
+v 4.18287 -2.10341 -7.03172
+v 2.31117 -0.186015 -5.544
+v 2.24825 0.599224 -4.61691
+v 2.90344 0.52885 -4.1564
+v 3.42107 -1.02994 -6.21281
+v 6.59803 -1.59551 -5.07391
+v 4.43659 -0.538406 -4.23958
+v 5.33731 -0.6382 -1.96014
+v 7.06308 -1.19329 -1.89896
+v 7.55481 -1.52389 -3.50817
+v 2.74482 -0.569676 -5.86585
+v 3.65393 -1.55781 -6.66293
+v 7.64678 -1.90613 -5.13208
+v 7.18798 -2.17926 -5.72268
+v 6.47164 -2.47556 -6.22422
+v 6.33516 -1.27943 -4.08912
+v 4.30484 -1.22518 -6.06884
+v 3.50179 0.238598 -3.80412
+v 3.62937 -0.242691 -4.69546
+v 5.39263 -0.904666 -3.71166
+v 5.96089 -0.496581 -0.683191
+v 4.75553 -0.22563 -1.33388
+v 4.34791 -0.0232664 -2.25096
+v 5.76271 -0.971029 -2.68868
+v 8.28118 -0.886212 -1.76605
+v 7.38063 -0.591522 -0.964355
+v 6.30434 -0.995099 -1.77953
+v 6.56702 -1.26224 -2.60364
+v 8.45614 -1.47729 -3.02895
+v 7.37405 -1.39978 -2.67078
+v 8.17515 -1.72683 -4.25106
+v 6.86143 -1.38757 -3.41782
+v 7.19747 -1.53097 -4.23492
+v 5.28917 -2.12563 -6.51375
+v 5.4313 -1.34405 -5.44274
+v 4.37997 -1.92762 -6.79422
+v 4.43515 -0.779744 -5.1061
+v 3.86242 0.132564 -3.08555
+v 3.57339 -0.635712 -5.56185
+v 4.83279 -0.281533 -0.577737
+v 4.43921 -0.353131 -3.29897
+v 5.78873 -1.18099 -4.62828
+v 5.10968 -0.934761 -4.6543
+v 5.05985 -0.638208 -2.77254
+v 1.26048 -14.7571 -7.51923
+v 1.61391 -14.1222 -8.00175
+v 1.87284 -13.359 -8.42784
+v 2.11706 -12.859 -8.64877
+v 2.28411 -12.2549 -8.88643
+v 2.32232 -12.0841 -8.94502
+v 2.51235 -11.4023 -9.139
+v 2.64389 -11.2484 -9.17194
+v 2.6727 -11.0391 -9.21257
+v 2.75291 -10.7802 -9.22671
+v 3.10031 -10.3756 -9.23304
+v 4.02232 -9.79451 -9.22524
+v 4.19319 -9.74414 -9.21358
+v 4.49815 -9.97961 -9.06529
+v 5.90631 -9.90898 -8.27079
+v 7.10811 -10.9218 -7.30582
+v 8.2148 -11.3082 -6.29425
+v 8.7225 -11.0683 -5.63808
+v 9.23151 -11.7321 -4.93348
+v 9.622 -12.0219 -4.1483
+v 9.98076 -12.7315 -2.72422
+v 10.1977 -12.891 -0.97509
+v 10.1355 -14.1377 -0.176482
+v 9.787 -15.0687 0.180417
+v 9.6046 -15.4187 0.405968
+v 9.52341 -15.5428 0.486773
+v 9.3482 -15.726 0.605403
+v 9.18502 -15.861 0.750823
+v 8.94719 -16.0392 0.935572
+v 8.58174 -16.3696 1.06587
+v 8.10979 -16.7976 0.826284
+v 7.32337 -17.3813 0.673521
+v 7.03393 -17.5597 0.626916
+v 6.77719 -17.6594 0.335673
+v 6.23446 -17.8087 0.188258
+v 5.86473 -17.8769 0.032473
+v 5.81028 -17.8893 -0.0104367
+v 5.4056 -17.9996 -0.252929
+v 5.11535 -18.0645 -0.483824
+v 4.76998 -18.1185 -0.880798
+v 4.0931 -18.1705 -1.5634
+v 3.41899 -18.1839 -1.97881
+v 2.1625 -17.9792 -3.28478
+v 2.06931 -17.9565 -3.39523
+v 2.05876 -17.887 -3.56022
+v 1.25829 -17.4163 -4.55147
+v 1.05062 -16.7645 -5.43113
+v 0.679545 -16.3491 -5.91016
+v 0.60457 -16.211 -6.06796
+v 0.549024 -16.0492 -6.24893
+v 0.4998 -15.8555 -6.44711
+v 0.652087 -15.1767 -7.01164
+v 1.0161 -15.0351 -7.21567
+v 1.08058 -16.0998 -6.20413
+v 5.37179 -12.6779 -8.19881
+v 8.94052 -15.9579 -1.65372
+v 2.63421 -17.0526 -5.07103
+v 1.4188 -15.3119 -7.01011
+v 8.01085 -12.2902 -6.46064
+v 4.20867 -14.6544 -7.51708
+v 3.85656 -10.857 -9.0447
+v 3.34972 -12.4482 -8.71611
+v 5.7626 -11.141 -8.30145
+v 7.76815 -17.0312 -0.633836
+v 9.63139 -14.2495 -3.36863
+v 9.14863 -15.8788 0.309822
+v 9.71828 -14.9 -0.858731
+v 2.7183 -17.8794 -3.4075
+v 6.69445 -12.7828 -7.40435
+v 8.68633 -11.8452 -5.76163
+v 7.27725 -15.5686 -4.79375
+v 2.93507 -16.0795 -6.3643
+v 3.08804 -13.7476 -8.18434
+v 2.73452 -14.9041 -7.42998
+v 4.76409 -13.8018 -7.92785
+v 6.06211 -17.8126 -0.550002
+v 9.90044 -13.8497 -2.23479
+v 9.27031 -15.0742 -2.83079
+v 9.66072 -13.4775 -3.72397
+v 8.11617 -14.5399 -5.19457
+v 8.29662 -15.3594 -4.04683
+v 5.58873 -17.3002 -3.7367
+v 5.74754 -15.2857 -6.2188
+v 5.85778 -13.6544 -7.5684
+v 8.8628 -13.0972 -5.24432
+v 7.6291 -13.7026 -6.29806
+v 8.13551 -16.3413 -2.70127
+v 9.13848 -14.3695 -4.15261
+v 4.40254 -17.2081 -4.49678
+v 4.26564 -17.9077 -2.68561
+v 5.86252 -17.6355 -2.49267
+v 6.48562 -16.5955 -4.15049
+v 6.93278 -14.8793 -5.85708
+v 5.30878 -14.5859 -7.1558
+v 4.33214 -15.6151 -6.57886
+v 7.49304 -16.145 -3.85419
+v 3.89555 -16.6003 -5.65267
+v 7.1955 -17.2256 -2.10135
+v 5.50509 -16.7471 -4.66901
+v 6.13653 -15.9249 -5.25062
+v 6.29974 -17.1925 -3.43905
+v 6.44628 -14.1865 -6.82055
+v 5.00347 -16.345 -5.4749
+v 6.98854 -16.9314 -3.18964
+f 3 4 2
+f 8 9 7
+f 8 7 6
+f 10 9 8
+f 14 13 4
+f 7 16 15
+f 9 17 16
+f 9 16 7
+f 21 22 20
+f 21 20 19
+f 23 24 22
+f 23 22 21
+f 25 26 23
+f 26 24 23
+f 27 28 25
+f 28 26 25
+f 20 30 29
+f 22 31 30
+f 22 30 20
+f 24 32 31
+f 24 31 22
+f 26 33 24
+f 33 32 24
+f 28 34 26
+f 34 33 26
+f 35 34 28
+f 1 29 36
+f 30 37 36
+f 30 36 29
+f 31 38 37
+f 31 37 30
+f 32 39 38
+f 32 38 31
+f 33 40 32
+f 40 39 32
+f 34 41 33
+f 41 40 33
+f 35 42 34
+f 42 41 34
+f 42 35 11
+f 45 21 19
+f 45 19 44
+f 46 23 21
+f 46 21 45
+f 47 25 46
+f 25 23 46
+f 48 27 47
+f 27 25 47
+f 1 12 43
+f 13 44 12
+f 44 43 12
+f 14 45 13
+f 45 44 13
+f 15 46 14
+f 46 45 14
+f 16 47 46
+f 16 46 15
+f 17 48 47
+f 17 47 16
+f 18 49 48
+f 18 48 17
+f 49 18 11
+f 50 51 52
+f 53 54 52
+f 53 52 51
+f 55 56 54
+f 55 54 53
+f 57 58 56
+f 57 56 55
+f 59 60 57
+f 60 58 57
+f 61 62 59
+f 62 60 59
+f 63 64 61
+f 64 62 61
+f 64 63 65
+f 50 52 66
+f 54 67 52
+f 67 66 52
+f 56 68 54
+f 68 67 54
+f 58 69 56
+f 69 68 56
+f 60 70 69
+f 60 69 58
+f 62 71 70
+f 62 70 60
+f 64 72 71
+f 64 71 62
+f 72 64 65
+f 74 55 73
+f 55 53 73
+f 75 57 74
+f 57 55 74
+f 76 59 57
+f 76 57 75
+f 77 61 59
+f 77 59 76
+f 78 77 76
+f 79 77 78
+f 50 66 80
+f 67 81 80
+f 67 80 66
+f 68 82 81
+f 68 81 67
+f 69 83 82
+f 69 82 68
+f 70 84 69
+f 84 83 69
+f 71 85 70
+f 85 84 70
+f 72 86 71
+f 86 85 71
+f 86 72 65
+f 50 80 87
+f 81 88 87
+f 81 87 80
+f 82 89 88
+f 82 88 81
+f 83 90 89
+f 83 89 82
+f 84 91 83
+f 91 90 83
+f 85 92 84
+f 92 91 84
+f 86 93 85
+f 93 92 85
+f 93 86 65
+f 50 87 94
+f 88 95 94
+f 88 94 87
+f 89 96 95
+f 89 95 88
+f 90 96 89
+f 91 97 90
+f 92 98 91
+f 98 97 91
+f 93 99 92
+f 99 98 92
+f 99 93 65
+f 94 100 101
+f 94 101 50
+f 95 102 100
+f 95 100 94
+f 96 103 102
+f 96 102 95
+f 98 105 97
+f 105 104 97
+f 99 106 98
+f 106 105 98
+f 65 107 99
+f 107 106 99
+f 107 65 108
+f 65 79 108
+f 100 109 110
+f 100 110 101
+f 102 109 100
+f 106 112 105
+f 107 113 106
+f 113 112 106
+f 128 129 127
+f 125 124 129
+f 125 129 128
+f 36 118 1
+f 42 128 41
+f 11 125 42
+f 125 128 42
+f 129 115 127
+f 109 116 110
+f 116 117 110
+f 119 116 109
+f 112 123 122
+f 113 124 123
+f 113 123 112
+f 1 2 12
+f 4 13 2
+f 13 12 2
+f 10 17 9
+f 18 10 11
+f 10 18 17
+f 1 43 29
+f 19 20 29
+f 44 19 29
+f 44 29 43
+f 35 27 48
+f 35 28 27
+f 35 49 11
+f 49 35 48
+f 73 53 51
+f 63 61 77
+f 79 63 77
+f 63 79 65
+f 108 79 78
+f 108 78 115
+f 129 108 115
+f 113 107 108
+f 124 113 108
+f 124 108 129
+f 39 126 38
+f 128 127 41
+f 41 127 40
+f 116 2 117
+f 2 118 117
+f 2 1 118
+f 119 3 116
+f 3 2 116
+f 120 5 119
+f 5 3 119
+f 122 6 121
+f 122 8 6
+f 123 8 122
+f 123 10 8
+f 124 10 123
+f 124 125 10
+f 125 11 10
+f 102 119 109
+f 103 119 102
+f 103 120 119
+f 105 122 104
+f 112 122 105
+f 122 121 104
+f 75 74 114
+f 134 126 135
+f 137 39 138
+f 142 127 143
+f 130 131 150
+f 151 150 131
+f 131 132 151
+f 152 151 132
+f 132 133 152
+f 133 134 152
+f 153 152 134
+f 134 135 153
+f 154 153 135
+f 135 136 154
+f 136 137 154
+f 142 143 155
+f 143 144 155
+f 156 155 144
+f 144 145 156
+f 145 146 156
+f 157 156 146
+f 146 147 157
+f 150 151 160
+f 160 159 150
+f 151 152 161
+f 161 160 151
+f 152 153 162
+f 162 161 152
+f 153 154 163
+f 163 162 153
+f 165 158 176
+f 166 176 158
+f 158 159 167
+f 167 166 158
+f 159 160 168
+f 168 167 159
+f 160 161 168
+f 169 168 161
+f 161 162 169
+f 170 169 162
+f 162 163 170
+f 171 170 163
+f 176 166 193
+f 177 193 166
+f 166 167 178
+f 178 177 166
+f 169 170 179
+f 180 179 170
+f 170 171 180
+f 171 172 181
+f 182 181 172
+f 183 182 172
+f 173 174 188
+f 188 187 173
+f 189 188 174
+f 190 189 175
+f 193 192 176
+f 193 177 205
+f 194 205 177
+f 181 182 196
+f 197 196 182
+f 182 183 198
+f 198 197 182
+f 183 184 199
+f 199 198 183
+f 184 185 199
+f 200 199 185
+f 185 186 201
+f 201 200 185
+f 186 187 202
+f 202 201 186
+f 187 188 203
+f 203 202 187
+f 189 190 204
+f 205 194 211
+f 198 199 206
+f 199 200 207
+f 207 206 199
+f 200 201 208
+f 208 207 200
+f 201 202 209
+f 209 208 201
+f 202 203 210
+f 210 209 202
+f 206 207 212
+f 213 212 207
+f 207 208 214
+f 214 213 207
+f 208 209 214
+f 215 214 209
+f 209 210 216
+f 216 215 209
+f 212 213 218
+f 219 218 213
+f 213 214 220
+f 220 219 213
+f 214 215 221
+f 221 220 214
+f 215 216 222
+f 222 221 215
+f 218 219 223
+f 224 223 219
+f 219 220 225
+f 225 224 219
+f 220 221 225
+f 226 225 221
+f 221 222 226
+f 227 226 222
+f 225 226 228
+f 229 228 226
+f 226 227 229
+f 230 229 227
+f 228 229 231
+f 229 230 232
+f 232 231 229
+f 130 75 131
+f 114 132 131
+f 75 114 131
+f 132 114 133
+f 126 134 133
+f 114 126 133
+f 135 126 136
+f 39 137 136
+f 126 39 136
+f 138 39 139
+f 40 140 139
+f 39 40 139
+f 140 40 141
+f 127 142 141
+f 40 127 141
+f 143 127 144
+f 115 145 144
+f 127 115 144
+f 78 146 145
+f 145 115 78
+f 146 78 147
+f 76 148 147
+f 78 76 147
+f 75 130 149
+f 148 76 149
+f 76 75 149
+f 184 183 172
+f 234 228 235
+f 236 231 237
+f 237 231 238
+f 239 232 240
+f 240 232 241
+f 245 223 246
+f 246 223 247
+f 248 250 247
+f 247 250 246
+f 246 250 245
+f 236 251 235
+f 250 234 251
+f 235 251 234
+f 239 253 238
+f 238 253 237
+f 237 253 236
+f 251 236 253
+f 254 249 255
+f 257 240 241
+f 255 259 254
+f 253 260 251
+f 261 255 252
+f 252 262 261
+f 262 256 261
+f 252 263 262
+f 264 260 253
+f 257 264 240
+f 240 264 239
+f 253 239 264
+f 264 265 260
+f 261 256 265
+f 260 265 256
+f 265 264 259
+f 261 265 255
+f 259 255 265
+f 225 228 234
+f 228 231 236
+f 235 228 236
+f 232 239 238
+f 238 231 232
+f 241 232 230
+f 223 245 244
+f 218 223 244
+f 224 248 247
+f 247 223 224
+f 248 224 233
+f 234 250 233
+f 233 224 234
+f 224 225 234
+f 233 250 248
+f 266 50 267
+f 270 117 271
+f 272 118 273
+f 281 114 282
+f 282 114 283
+f 285 73 286
+f 288 266 305
+f 289 305 266
+f 266 267 289
+f 290 289 267
+f 267 268 290
+f 268 269 290
+f 291 290 269
+f 269 270 291
+f 270 271 291
+f 292 291 271
+f 271 272 292
+f 293 292 272
+f 272 273 293
+f 294 293 273
+f 273 274 294
+f 295 294 274
+f 274 275 295
+f 296 295 275
+f 275 276 296
+f 276 277 296
+f 297 296 277
+f 277 278 297
+f 298 297 278
+f 278 279 298
+f 299 298 279
+f 279 280 299
+f 280 281 299
+f 300 299 281
+f 281 282 300
+f 282 283 300
+f 301 300 283
+f 283 284 301
+f 284 285 301
+f 302 301 285
+f 303 302 285
+f 285 286 303
+f 304 303 286
+f 286 287 304
+f 287 288 304
+f 305 304 288
+f 305 289 322
+f 306 322 289
+f 289 290 306
+f 307 306 290
+f 290 291 307
+f 308 307 291
+f 291 292 308
+f 309 308 292
+f 292 293 310
+f 310 309 292
+f 293 294 311
+f 311 310 293
+f 294 295 312
+f 312 311 294
+f 295 296 313
+f 313 312 295
+f 296 297 314
+f 314 313 296
+f 297 298 315
+f 315 314 297
+f 298 299 316
+f 316 315 298
+f 299 300 317
+f 317 316 299
+f 300 301 317
+f 318 317 301
+f 301 302 318
+f 319 318 302
+f 302 303 319
+f 320 319 303
+f 303 304 320
+f 321 320 304
+f 304 305 321
+f 322 321 305
+f 322 306 338
+f 323 338 306
+f 306 307 323
+f 324 323 307
+f 307 308 324
+f 325 324 308
+f 308 309 325
+f 326 325 309
+f 309 310 327
+f 327 326 309
+f 310 311 327
+f 328 327 311
+f 311 312 328
+f 329 328 312
+f 312 313 330
+f 330 329 312
+f 314 315 331
+f 315 316 332
+f 332 331 315
+f 316 317 333
+f 333 332 316
+f 317 318 334
+f 334 333 317
+f 318 319 334
+f 335 334 319
+f 319 320 335
+f 336 335 320
+f 320 321 336
+f 337 336 321
+f 321 322 338
+f 338 337 321
+f 338 323 339
+f 323 324 339
+f 324 325 339
+f 325 326 339
+f 326 327 339
+f 327 328 339
+f 328 329 339
+f 329 330 339
+f 331 332 339
+f 332 333 339
+f 333 334 339
+f 334 335 339
+f 335 336 339
+f 336 337 339
+f 337 338 339
+f 50 101 268
+f 267 50 268
+f 101 110 269
+f 268 101 269
+f 110 117 270
+f 269 110 270
+f 118 272 271
+f 271 117 118
+f 36 274 273
+f 273 118 36
+f 36 37 275
+f 274 36 275
+f 37 277 276
+f 275 37 276
+f 37 38 278
+f 277 37 278
+f 38 126 279
+f 278 38 279
+f 279 126 280
+f 114 281 280
+f 126 114 280
+f 114 74 284
+f 283 114 284
+f 73 285 284
+f 284 74 73
+f 51 287 286
+f 286 73 51
+f 287 51 288
+f 50 266 288
+f 51 50 288
+f 313 314 330
+f 331 330 314
+f 330 331 339
+f 343 104 344
+f 348 103 349
+f 352 340 364
+f 353 364 340
+f 354 353 340
+f 341 342 355
+f 356 355 342
+f 342 343 356
+f 343 344 356
+f 357 356 344
+f 344 345 357
+f 358 357 345
+f 345 346 358
+f 359 358 346
+f 360 359 346
+f 346 347 360
+f 361 360 347
+f 347 348 361
+f 362 361 348
+f 348 349 362
+f 349 350 362
+f 363 362 350
+f 350 351 363
+f 351 352 363
+f 364 363 352
+f 364 353 376
+f 365 376 353
+f 353 354 365
+f 366 365 354
+f 355 356 367
+f 368 367 356
+f 356 357 368
+f 369 368 357
+f 357 358 369
+f 370 369 358
+f 358 359 370
+f 371 370 359
+f 359 360 372
+f 372 371 359
+f 360 361 373
+f 373 372 360
+f 361 362 374
+f 374 373 361
+f 362 363 375
+f 375 374 362
+f 363 364 376
+f 376 375 363
+f 376 365 388
+f 377 388 365
+f 365 366 377
+f 378 377 366
+f 367 368 379
+f 380 379 368
+f 368 369 381
+f 381 380 368
+f 369 370 382
+f 382 381 369
+f 370 371 382
+f 383 382 371
+f 371 372 384
+f 384 383 371
+f 372 373 385
+f 385 384 372
+f 373 374 385
+f 386 385 374
+f 374 375 387
+f 387 386 374
+f 375 376 388
+f 388 387 375
+f 388 377 399
+f 389 399 377
+f 377 378 389
+f 390 389 378
+f 379 380 392
+f 392 391 379
+f 380 381 393
+f 393 392 380
+f 381 382 394
+f 394 393 381
+f 382 383 394
+f 384 385 395
+f 396 395 385
+f 385 386 396
+f 397 396 386
+f 386 387 397
+f 398 397 387
+f 387 388 399
+f 399 398 387
+f 399 389 400
+f 389 390 400
+f 391 392 400
+f 392 393 400
+f 393 394 400
+f 395 396 400
+f 396 397 400
+f 397 398 400
+f 398 399 400
+f 340 90 97
+f 341 97 342
+f 104 343 342
+f 97 104 342
+f 121 345 344
+f 344 104 121
+f 111 346 345
+f 345 121 111
+f 111 120 347
+f 346 111 347
+f 120 103 348
+f 347 120 348
+f 349 103 96
+f 350 349 96
+f 96 351 350
+f 351 96 352
+f 90 340 352
+f 96 90 352
+f 340 341 354
+f 341 340 97
+f 355 354 341
+f 354 355 366
+f 367 366 355
+f 366 367 378
+f 379 378 367
+f 378 379 391
+f 391 390 378
+f 390 391 400
+f 383 384 394
+f 395 394 384
+f 394 395 400
+f 404 6 405
+f 412 5 413
+f 414 401 424
+f 415 424 401
+f 401 402 415
+f 416 415 402
+f 402 403 416
+f 417 416 403
+f 403 404 417
+f 404 405 417
+f 418 417 405
+f 405 406 418
+f 406 407 418
+f 419 418 407
+f 420 419 407
+f 407 408 420
+f 421 420 408
+f 410 411 422
+f 423 422 411
+f 411 412 423
+f 412 413 423
+f 413 414 423
+f 424 423 414
+f 424 415 433
+f 425 433 415
+f 415 416 425
+f 426 425 416
+f 416 417 426
+f 427 426 417
+f 417 418 428
+f 428 427 417
+f 418 419 429
+f 429 428 418
+f 419 420 429
+f 420 421 430
+f 422 423 432
+f 432 431 422
+f 423 424 433
+f 433 432 423
+f 433 425 442
+f 434 442 425
+f 425 426 434
+f 435 434 426
+f 426 427 436
+f 436 435 426
+f 427 428 437
+f 437 436 427
+f 428 429 438
+f 438 437 428
+f 431 432 440
+f 441 440 432
+f 432 433 441
+f 442 441 433
+f 442 434 450
+f 435 436 443
+f 444 443 436
+f 436 437 445
+f 445 444 436
+f 437 438 446
+f 446 445 437
+f 440 441 448
+f 449 448 441
+f 441 442 449
+f 450 449 442
+f 443 444 451
+f 452 451 444
+f 444 445 452
+f 453 452 445
+f 445 446 453
+f 454 453 446
+f 448 449 457
+f 457 456 448
+f 449 450 458
+f 458 457 449
+f 451 452 459
+f 452 453 459
+f 453 454 459
+f 456 457 459
+f 457 458 459
+f 111 402 401
+f 401 120 111
+f 121 403 402
+f 402 111 121
+f 6 404 403
+f 403 121 6
+f 7 406 405
+f 405 6 7
+f 406 7 407
+f 15 408 407
+f 7 15 407
+f 410 409 14
+f 413 5 414
+f 120 401 414
+f 5 120 414
+f 408 409 421
+f 408 15 409
+f 409 15 14
+f 5 411 3
+f 411 5 412
+f 411 4 3
+f 411 14 4
+f 14 411 410
+f 409 410 421
+f 422 421 410
+f 430 429 420
+f 429 430 439
+f 421 422 430
+f 431 430 422
+f 439 438 429
+f 438 439 447
+f 430 431 439
+f 440 439 431
+f 434 435 450
+f 443 450 435
+f 447 446 438
+f 446 447 455
+f 439 440 447
+f 448 447 440
+f 447 448 456
+f 450 443 458
+f 451 458 443
+f 458 451 459
+f 455 454 446
+f 454 455 459
+f 456 455 447
+f 455 456 459
+f 461 462 469
+f 470 469 462
+f 472 471 463
+f 463 464 472
+f 473 472 464
+f 464 465 473
+f 465 466 473
+f 474 473 466
+f 467 468 477
+f 477 476 467
+f 478 477 468
+f 475 476 480
+f 480 479 475
+f 476 477 481
+f 481 480 476
+f 477 478 482
+f 482 481 477
+f 480 481 484
+f 484 483 480
+f 481 482 485
+f 485 484 481
+f 486 485 482
+f 149 130 460
+f 130 150 461
+f 460 130 461
+f 461 150 462
+f 463 159 464
+f 158 465 464
+f 159 158 464
+f 158 165 466
+f 465 158 466
+f 462 463 470
+f 463 462 150
+f 471 470 463
+f 150 159 463
+f 460 461 468
+f 469 468 461
+f 468 469 478
+f 478 486 482
+f 486 478 469
+f 469 470 486
+f 487 154 488
+f 487 488 498
+f 490 491 501
+f 491 492 501
+f 502 501 492
+f 492 493 502
+f 493 494 502
+f 503 502 494
+f 504 503 494
+f 494 495 504
+f 495 496 504
+f 505 504 496
+f 496 497 505
+f 498 499 507
+f 507 506 498
+f 501 502 514
+f 514 513 501
+f 502 503 515
+f 515 514 502
+f 503 504 516
+f 516 515 503
+f 504 505 517
+f 517 516 504
+f 506 507 518
+f 520 519 508
+f 521 520 508
+f 523 522 509
+f 510 511 524
+f 525 524 511
+f 513 514 528
+f 528 527 513
+f 514 515 529
+f 529 528 514
+f 515 516 530
+f 530 529 515
+f 516 517 531
+f 531 530 516
+f 520 521 535
+f 535 534 520
+f 521 522 535
+f 536 535 522
+f 522 523 536
+f 537 536 523
+f 524 525 539
+f 539 538 524
+f 527 528 541
+f 542 541 528
+f 528 529 542
+f 543 542 529
+f 529 530 544
+f 544 543 529
+f 530 531 544
+f 545 544 531
+f 532 533 546
+f 547 546 533
+f 534 535 549
+f 549 548 534
+f 535 536 549
+f 550 549 536
+f 536 537 551
+f 551 550 536
+f 541 542 554
+f 555 554 542
+f 542 543 555
+f 543 544 556
+f 544 545 556
+f 557 556 545
+f 546 547 558
+f 559 558 547
+f 548 549 561
+f 561 560 548
+f 549 550 562
+f 562 561 549
+f 550 551 563
+f 563 562 550
+f 564 563 551
+f 566 565 552
+f 554 555 568
+f 569 568 555
+f 571 570 556
+f 556 557 571
+f 572 571 557
+f 558 559 573
+f 574 573 559
+f 560 561 576
+f 576 575 560
+f 561 562 576
+f 577 576 562
+f 562 563 578
+f 578 577 562
+f 564 565 579
+f 565 566 580
+f 580 579 565
+f 568 569 582
+f 583 582 569
+f 569 570 583
+f 571 572 584
+f 585 584 572
+f 573 574 586
+f 575 576 586
+f 576 577 586
+f 577 578 586
+f 579 580 586
+f 582 583 586
+f 584 585 586
+f 137 138 489
+f 490 184 491
+f 172 492 491
+f 184 172 491
+f 172 494 493
+f 492 172 493
+f 171 495 494
+f 494 172 171
+f 163 496 495
+f 495 171 163
+f 496 163 497
+f 487 497 163
+f 163 154 487
+f 488 489 498
+f 488 154 489
+f 154 137 489
+f 499 498 489
+f 490 185 184
+f 501 500 490
+f 500 501 513
+f 497 487 505
+f 498 505 487
+f 505 498 506
+f 507 508 519
+f 512 511 500
+f 511 512 525
+f 513 512 500
+f 512 513 527
+f 506 517 505
+f 517 506 518
+f 519 518 507
+f 518 519 533
+f 533 532 518
+f 509 510 523
+f 524 523 510
+f 523 524 538
+f 526 525 512
+f 525 526 539
+f 527 526 512
+f 526 527 541
+f 518 531 517
+f 531 518 532
+f 519 520 533
+f 534 533 520
+f 538 537 523
+f 537 538 552
+f 540 539 526
+f 541 540 526
+f 540 541 554
+f 532 545 531
+f 533 534 547
+f 548 547 534
+f 552 551 537
+f 551 552 565
+f 565 564 551
+f 538 539 552
+f 539 540 552
+f 553 552 540
+f 554 553 540
+f 553 554 568
+f 556 555 543
+f 555 556 570
+f 570 569 555
+f 545 532 557
+f 546 557 532
+f 547 548 559
+f 560 559 548
+f 567 566 552
+f 552 553 567
+f 568 567 553
+f 567 568 582
+f 557 546 572
+f 558 572 546
+f 559 560 574
+f 575 574 560
+f 574 575 586
+f 563 564 578
+f 579 578 564
+f 578 579 586
+f 566 567 581
+f 581 580 566
+f 580 581 586
+f 582 581 567
+f 581 582 586
+f 570 571 583
+f 584 583 571
+f 583 584 586
+f 572 558 585
+f 573 585 558
+f 585 573 586
+f 588 483 589
+f 589 483 590
+f 592 486 593
+f 593 486 594
+f 597 473 598
+f 599 474 600
+f 600 474 601
+f 480 483 588
+f 590 483 484
+f 484 485 591
+f 485 486 592
+f 591 485 592
+f 594 486 470
+f 472 473 597
+f 596 472 597
+f 474 599 598
+f 598 473 474
+f 479 480 588
+f 587 479 588
+f 484 591 590
+f 596 471 472
+f 595 471 596
+f 595 470 471
+f 470 595 594
+f 587 588 602
+f 603 602 588
+f 588 589 603
+f 604 603 589
+f 589 590 604
+f 605 604 590
+f 590 591 605
+f 591 592 605
+f 606 605 592
+f 592 593 606
+f 593 594 606
+f 607 606 594
+f 594 595 607
+f 608 607 595
+f 595 596 608
+f 609 608 596
+f 596 597 609
+f 610 609 597
+f 597 598 610
+f 598 599 610
+f 611 610 599
+f 599 600 611
+f 600 601 611
+f 612 611 601
+f 615 602 616
+f 602 603 617
+f 617 616 602
+f 603 604 618
+f 618 617 603
+f 604 605 619
+f 619 618 604
+f 605 606 619
+f 620 619 606
+f 606 607 620
+f 621 620 607
+f 607 608 621
+f 622 621 608
+f 608 609 622
+f 623 622 609
+f 609 610 623
+f 624 623 610
+f 610 611 624
+f 625 624 611
+f 611 612 626
+f 626 625 611
+f 612 613 627
+f 627 626 612
+f 613 614 628
+f 628 627 613
+f 616 617 630
+f 630 629 616
+f 617 618 631
+f 631 630 617
+f 618 619 632
+f 632 631 618
+f 619 620 632
+f 633 632 620
+f 620 621 633
+f 634 633 621
+f 621 622 634
+f 635 634 622
+f 622 623 635
+f 636 635 623
+f 623 624 636
+f 637 636 624
+f 624 625 637
+f 638 637 625
+f 625 626 639
+f 639 638 625
+f 626 627 640
+f 640 639 626
+f 627 628 641
+f 641 640 627
+f 629 630 643
+f 643 642 629
+f 630 631 644
+f 644 643 630
+f 631 632 645
+f 645 644 631
+f 632 633 646
+f 646 645 632
+f 633 634 646
+f 647 646 634
+f 634 635 647
+f 648 647 635
+f 635 636 648
+f 649 648 636
+f 636 637 649
+f 650 649 637
+f 637 638 650
+f 651 650 638
+f 638 639 652
+f 652 651 638
+f 639 640 653
+f 653 652 639
+f 640 641 654
+f 654 653 640
+f 642 643 656
+f 656 655 642
+f 643 644 657
+f 657 656 643
+f 644 645 658
+f 658 657 644
+f 645 646 659
+f 659 658 645
+f 646 647 659
+f 660 659 647
+f 647 648 660
+f 661 660 648
+f 648 649 661
+f 662 661 649
+f 649 650 662
+f 663 662 650
+f 650 651 663
+f 664 663 651
+f 651 652 665
+f 665 664 651
+f 652 653 666
+f 666 665 652
+f 653 654 667
+f 667 666 653
+f 655 656 669
+f 669 668 655
+f 656 657 670
+f 670 669 656
+f 657 658 671
+f 671 670 657
+f 658 659 672
+f 672 671 658
+f 659 660 672
+f 673 672 660
+f 660 661 673
+f 674 673 661
+f 661 662 674
+f 675 674 662
+f 662 663 675
+f 676 675 663
+f 663 664 676
+f 677 676 664
+f 664 665 678
+f 678 677 664
+f 665 666 679
+f 679 678 665
+f 666 667 680
+f 680 679 666
+f 668 669 681
+f 669 670 681
+f 670 671 681
+f 671 672 681
+f 672 673 681
+f 673 674 681
+f 674 675 681
+f 675 676 681
+f 676 677 681
+f 677 678 681
+f 678 679 681
+f 679 680 681
+f 616 628 615
+f 628 616 629
+f 614 615 628
+f 629 641 628
+f 641 629 642
+f 642 654 641
+f 654 642 655
+f 655 667 654
+f 667 655 668
+f 668 680 667
+f 680 668 681
+f 682 178 683
+f 686 195 687
+f 691 690 682
+f 682 683 691
+f 684 685 693
+f 685 686 693
+f 694 693 686
+f 686 687 694
+f 695 694 687
+f 697 696 688
+f 700 699 689
+f 689 690 700
+f 701 700 690
+f 690 691 702
+f 702 701 690
+f 691 692 702
+f 703 702 692
+f 693 694 704
+f 705 704 694
+f 694 695 706
+f 706 705 694
+f 695 696 707
+f 707 706 695
+f 696 697 708
+f 708 707 696
+f 709 708 697
+f 717 698 737
+f 718 737 698
+f 698 699 719
+f 719 718 698
+f 699 700 719
+f 720 719 700
+f 700 701 720
+f 721 720 701
+f 701 702 722
+f 722 721 701
+f 702 703 723
+f 723 722 702
+f 704 705 724
+f 725 724 705
+f 705 706 726
+f 726 725 705
+f 706 707 727
+f 727 726 706
+f 707 708 728
+f 728 727 707
+f 708 709 729
+f 729 728 708
+f 709 710 730
+f 730 729 709
+f 710 711 731
+f 731 730 710
+f 712 713 732
+f 733 732 713
+f 713 714 733
+f 734 733 714
+f 714 715 734
+f 735 734 715
+f 715 716 735
+f 736 735 716
+f 737 718 758
+f 738 758 718
+f 718 719 738
+f 739 738 719
+f 719 720 739
+f 740 739 720
+f 720 721 740
+f 741 740 721
+f 721 722 741
+f 742 741 722
+f 722 723 742
+f 743 742 723
+f 724 725 745
+f 745 744 724
+f 725 726 746
+f 746 745 725
+f 726 727 747
+f 747 746 726
+f 727 728 748
+f 748 747 727
+f 728 729 749
+f 749 748 728
+f 729 730 750
+f 750 749 729
+f 730 731 751
+f 751 750 730
+f 732 733 752
+f 753 752 733
+f 733 734 753
+f 754 753 734
+f 734 735 754
+f 755 754 735
+f 735 736 755
+f 756 755 736
+f 758 757 737
+f 758 738 779
+f 759 779 738
+f 738 739 760
+f 760 759 738
+f 739 740 761
+f 761 760 739
+f 740 741 762
+f 762 761 740
+f 741 742 763
+f 763 762 741
+f 742 743 764
+f 764 763 742
+f 744 745 765
+f 766 765 745
+f 745 746 766
+f 767 766 746
+f 746 747 767
+f 768 767 747
+f 747 748 768
+f 769 768 748
+f 748 749 769
+f 770 769 749
+f 749 750 771
+f 771 770 749
+f 750 751 772
+f 772 771 750
+f 752 753 773
+f 774 773 753
+f 753 754 774
+f 775 774 754
+f 754 755 775
+f 776 775 755
+f 755 756 776
+f 777 776 756
+f 756 757 777
+f 778 777 757
+f 757 758 779
+f 779 778 757
+f 779 759 795
+f 760 761 780
+f 781 780 761
+f 761 762 781
+f 782 781 762
+f 762 763 782
+f 783 782 763
+f 763 764 784
+f 784 783 763
+f 765 766 786
+f 786 785 765
+f 766 767 787
+f 787 786 766
+f 767 768 788
+f 788 787 767
+f 768 769 789
+f 789 788 768
+f 769 770 790
+f 790 789 769
+f 770 771 791
+f 791 790 770
+f 771 772 792
+f 792 791 771
+f 775 776 793
+f 778 779 794
+f 795 794 779
+f 780 781 796
+f 781 782 796
+f 782 783 796
+f 783 784 796
+f 785 786 796
+f 786 787 796
+f 787 788 796
+f 788 789 796
+f 789 790 796
+f 790 791 796
+f 791 792 796
+f 794 795 796
+f 195 686 685
+f 687 195 217
+f 682 177 178
+f 682 194 177
+f 690 689 682
+f 683 684 691
+f 692 691 684
+f 167 168 684
+f 168 169 684
+f 684 178 167
+f 683 178 684
+f 179 684 169
+f 684 179 195
+f 684 195 685
+f 687 688 695
+f 688 687 217
+f 696 695 688
+f 693 692 684
+f 692 693 704
+f 704 703 692
+f 703 704 724
+f 711 712 732
+f 724 723 703
+f 723 724 744
+f 732 731 711
+f 731 732 752
+f 716 717 736
+f 737 736 717
+f 736 737 757
+f 757 756 736
+f 744 743 723
+f 743 744 765
+f 752 751 731
+f 751 752 773
+f 765 764 743
+f 764 765 785
+f 773 772 751
+f 759 760 795
+f 780 795 760
+f 795 780 796
+f 785 784 764
+f 784 785 796
+f 772 773 792
+f 793 792 773
+f 773 774 793
+f 774 775 793
+f 792 793 796
+f 794 793 776
+f 793 794 796
+f 776 777 794
+f 777 778 794
+f 797 195 798
+f 800 180 801
+f 807 797 817
+f 808 817 797
+f 809 808 797
+f 797 798 809
+f 810 809 798
+f 798 799 810
+f 799 800 810
+f 811 810 800
+f 800 801 811
+f 812 811 801
+f 814 813 803
+f 803 804 814
+f 815 814 804
+f 817 808 833
+f 818 833 808
+f 808 809 819
+f 819 818 808
+f 809 810 820
+f 820 819 809
+f 810 811 820
+f 821 820 811
+f 811 812 822
+f 822 821 811
+f 813 814 823
+f 824 823 814
+f 814 815 824
+f 825 824 815
+f 832 831 816
+f 833 818 849
+f 834 849 818
+f 818 819 835
+f 835 834 818
+f 819 820 836
+f 836 835 819
+f 820 821 836
+f 837 836 821
+f 821 822 838
+f 838 837 821
+f 823 824 840
+f 840 839 823
+f 824 825 841
+f 841 840 824
+f 825 826 841
+f 842 841 826
+f 826 827 843
+f 843 842 826
+f 827 828 844
+f 844 843 827
+f 828 829 845
+f 845 844 828
+f 829 830 846
+f 846 845 829
+f 830 831 846
+f 847 846 831
+f 831 832 847
+f 848 847 832
+f 849 834 865
+f 850 865 834
+f 834 835 851
+f 851 850 834
+f 835 836 852
+f 852 851 835
+f 836 837 852
+f 853 852 837
+f 839 840 856
+f 856 855 839
+f 840 841 857
+f 857 856 840
+f 841 842 858
+f 858 857 841
+f 842 843 859
+f 859 858 842
+f 843 844 860
+f 860 859 843
+f 844 845 861
+f 861 860 844
+f 845 846 861
+f 862 861 846
+f 846 847 862
+f 863 862 847
+f 847 848 863
+f 864 863 848
+f 865 850 866
+f 866 881 865
+f 850 851 867
+f 867 866 850
+f 851 852 868
+f 868 867 851
+f 852 853 868
+f 869 868 853
+f 870 869 853
+f 855 856 871
+f 872 871 856
+f 856 857 872
+f 873 872 857
+f 857 858 873
+f 874 873 858
+f 858 859 874
+f 875 874 859
+f 859 860 876
+f 876 875 859
+f 860 861 877
+f 877 876 860
+f 861 862 878
+f 878 877 861
+f 862 863 878
+f 879 878 863
+f 863 864 880
+f 880 879 863
+f 881 866 897
+f 882 897 866
+f 866 867 883
+f 883 882 866
+f 867 868 883
+f 884 883 868
+f 868 869 884
+f 885 884 869
+f 871 872 887
+f 888 887 872
+f 872 873 889
+f 889 888 872
+f 873 874 889
+f 890 889 874
+f 874 875 891
+f 891 890 874
+f 875 876 892
+f 892 891 875
+f 876 877 893
+f 893 892 876
+f 877 878 894
+f 894 893 877
+f 878 879 894
+f 895 894 879
+f 879 880 895
+f 896 895 880
+f 897 882 898
+f 898 913 897
+f 882 883 899
+f 899 898 882
+f 883 884 899
+f 900 899 884
+f 884 885 900
+f 901 900 885
+f 902 901 885
+f 887 888 903
+f 904 903 888
+f 888 889 904
+f 905 904 889
+f 889 890 905
+f 906 905 890
+f 890 891 907
+f 907 906 890
+f 891 892 908
+f 908 907 891
+f 892 893 909
+f 909 908 892
+f 893 894 910
+f 910 909 893
+f 894 895 910
+f 911 910 895
+f 895 896 911
+f 912 911 896
+f 913 898 914
+f 898 899 914
+f 899 900 914
+f 900 901 914
+f 901 902 914
+f 903 904 914
+f 904 905 914
+f 905 906 914
+f 906 907 914
+f 907 908 914
+f 908 909 914
+f 909 910 914
+f 910 911 914
+f 911 912 914
+f 798 195 179
+f 180 800 799
+f 799 798 179
+f 179 180 799
+f 171 181 802
+f 181 196 804
+f 803 181 804
+f 806 217 807
+f 195 797 807
+f 217 195 807
+f 802 180 171
+f 801 180 802
+f 802 803 813
+f 802 181 803
+f 805 217 806
+f 801 802 812
+f 813 812 802
+f 812 813 823
+f 805 806 816
+f 806 807 816
+f 817 816 807
+f 823 822 812
+f 822 823 839
+f 816 817 832
+f 833 832 817
+f 839 838 822
+f 838 839 855
+f 855 854 838
+f 832 833 848
+f 849 848 833
+f 837 838 854
+f 854 853 837
+f 853 854 870
+f 848 849 864
+f 865 864 849
+f 864 865 881
+f 854 855 870
+f 871 870 855
+f 870 871 887
+f 887 886 870
+f 881 880 864
+f 880 881 897
+f 869 870 886
+f 886 885 869
+f 885 886 902
+f 897 896 880
+f 896 897 913
+f 886 887 902
+f 903 902 887
+f 902 903 914
+f 913 912 896
+f 912 913 914
+f 926 216 927
+f 915 916 930
+f 931 930 916
+f 932 931 916
+f 916 917 932
+f 933 932 917
+f 917 918 933
+f 934 933 918
+f 918 919 934
+f 935 934 919
+f 919 920 935
+f 936 935 920
+f 920 921 936
+f 921 922 936
+f 937 936 922
+f 922 923 937
+f 938 937 923
+f 923 924 938
+f 924 925 938
+f 939 938 925
+f 926 927 941
+f 927 928 941
+f 942 941 928
+f 928 929 942
+f 943 942 929
+f 943 930 956
+f 944 956 930
+f 930 931 944
+f 945 944 931
+f 931 932 946
+f 946 945 931
+f 932 933 947
+f 947 946 932
+f 933 934 948
+f 948 947 933
+f 934 935 949
+f 949 948 934
+f 936 937 950
+f 937 938 951
+f 951 950 937
+f 938 939 952
+f 952 951 938
+f 939 940 952
+f 953 952 940
+f 940 941 953
+f 954 953 941
+f 941 942 954
+f 955 954 942
+f 942 943 955
+f 956 955 943
+f 956 944 969
+f 957 969 944
+f 944 945 957
+f 958 957 945
+f 945 946 959
+f 959 958 945
+f 946 947 960
+f 960 959 946
+f 947 948 961
+f 961 960 947
+f 948 949 962
+f 962 961 948
+f 950 951 964
+f 964 963 950
+f 951 952 965
+f 965 964 951
+f 952 953 965
+f 966 965 953
+f 953 954 966
+f 967 966 954
+f 954 955 967
+f 968 967 955
+f 955 956 968
+f 969 968 956
+f 969 957 982
+f 970 982 957
+f 957 958 970
+f 971 970 958
+f 958 959 972
+f 972 971 958
+f 959 960 973
+f 973 972 959
+f 960 961 974
+f 974 973 960
+f 961 962 975
+f 975 974 961
+f 963 964 977
+f 977 976 963
+f 964 965 978
+f 978 977 964
+f 965 966 978
+f 979 978 966
+f 966 967 979
+f 980 979 967
+f 967 968 980
+f 981 980 968
+f 968 969 981
+f 982 981 969
+f 982 970 983
+f 970 971 983
+f 971 972 983
+f 972 973 983
+f 973 974 983
+f 974 975 983
+f 976 977 983
+f 977 978 983
+f 978 979 983
+f 979 980 983
+f 980 981 983
+f 981 982 983
+f 915 203 188
+f 916 915 188
+f 188 189 916
+f 917 916 189
+f 189 918 917
+f 189 204 919
+f 918 189 919
+f 216 210 928
+f 927 216 928
+f 928 210 929
+f 210 203 929
+f 203 915 929
+f 929 915 943
+f 930 943 915
+f 222 216 926
+f 941 940 926
+f 939 925 227
+f 940 222 926
+f 227 222 940
+f 940 939 227
+f 935 936 949
+f 950 949 936
+f 949 950 963
+f 963 962 949
+f 962 963 976
+f 976 975 962
+f 975 976 983
+f 985 242 986
+f 987 805 988
+f 992 263 993
+f 995 996 997
+f 984 997 996
+f 985 998 984
+f 997 984 998
+f 998 985 986
+f 989 999 988
+f 988 999 987
+f 998 987 999
+f 994 995 1000
+f 997 1000 995
+f 993 1000 992
+f 998 1001 997
+f 1000 997 1001
+f 258 242 985
+f 984 258 985
+f 816 989 988
+f 988 805 816
+f 831 830 990
+f 830 829 991
+f 993 263 252
+f 258 984 996
+f 995 258 996
+f 987 217 805
+f 986 987 998
+f 986 242 987
+f 242 217 987
+f 990 999 989
+f 989 816 990
+f 816 831 990
+f 990 991 999
+f 990 830 991
+f 994 1000 993
+f 252 994 993
+f 1003 1004 1002
+f 1003 1005 1004
+f 252 255 1002
+f 249 1003 1002
+f 1002 255 249
+f 1008 713 1009
+f 1011 1005 1012
+f 1014 249 1015
+f 1015 249 1016
+f 1013 1021 1012
+f 1012 1021 1011
+f 1016 1022 1015
+f 1015 1022 1014
+f 1021 1013 1022
+f 1022 1023 1021
+f 1018 1021 1023
+f 1018 1023 1017
+f 1006 1007 1024
+f 1025 1018 1017
+f 1009 1010 1026
+f 1026 1019 1024
+f 1009 1026 1008
+f 1024 1007 1026
+f 1017 1027 1025
+f 1027 1019 1025
+f 1028 1019 1027
+f 1029 1017 1020
+f 1017 1029 1027
+f 1028 1027 1029
+f 1024 1031 1030
+f 1028 1031 1019
+f 1031 1024 1019
+f 714 1007 1006
+f 1006 715 714
+f 712 1010 1009
+f 1009 713 712
+f 1003 1013 1012
+f 1012 1005 1003
+f 1016 249 254
+f 716 715 1006
+f 1024 1030 1006
+f 1008 714 713
+f 1007 714 1008
+f 1008 1026 1007
+f 1014 1022 1013
+f 1013 1003 1014
+f 1003 249 1014
+f 1032 256 1033
+f 1036 1000 1037
+f 1038 1001 1039
+f 1039 1001 1040
+f 1042 999 1043
+f 1043 999 1044
+f 1047 243 1048
+f 1048 243 1049
+f 1051 250 1052
+f 1032 1054 1055
+f 1053 1054 1056
+f 1033 1056 1032
+f 1054 1032 1056
+f 1035 1058 1034
+f 1034 1058 1033
+f 1056 1033 1058
+f 1059 1051 1052
+f 1056 1059 1053
+f 1052 1053 1059
+f 1049 1060 1048
+f 1048 1060 1047
+f 1059 1060 1051
+f 1050 1051 1060
+f 1061 1036 1037
+f 1038 1062 1037
+f 1037 1062 1061
+f 1057 1061 1062
+f 1057 1063 1060
+f 1060 1063 1047
+f 1039 1064 1038
+f 1062 1038 1064
+f 1064 1039 1040
+f 1040 1041 1064
+f 1065 1044 1045
+f 1044 1065 1043
+f 1042 1043 1065
+f 1064 1041 1065
+f 1042 1065 1041
+f 1066 1060 1059
+f 1058 1066 1056
+f 1059 1056 1066
+f 1066 1058 1061
+f 1061 1057 1066
+f 1060 1066 1057
+f 1063 1057 1067
+f 1062 1067 1057
+f 1067 1062 1064
+f 262 1034 1033
+f 1033 256 262
+f 262 263 1035
+f 1034 262 1035
+f 992 1000 1036
+f 1000 1001 1038
+f 1037 1000 1038
+f 1001 998 1041
+f 1040 1001 1041
+f 998 999 1042
+f 1041 998 1042
+f 991 1045 1044
+f 1044 999 991
+f 1045 991 829
+f 1049 243 244
+f 250 1051 1050
+f 1050 245 250
+f 251 1053 1052
+f 1052 250 251
+f 260 1054 1053
+f 1053 251 260
+f 1054 260 1055
+f 256 1032 1055
+f 260 256 1055
+f 263 992 1036
+f 1058 1036 1061
+f 1035 263 1036
+f 1036 1058 1035
+f 1046 829 828
+f 1045 1046 1065
+f 1045 829 1046
+f 1050 1060 1049
+f 244 1050 1049
+f 1050 244 245
+f 1068 142 1069
+f 1070 155 1071
+f 1075 173 1076
+f 1077 1075 1076
+f 1071 1078 1070
+f 1069 1070 1078
+f 1069 1078 1068
+f 1071 1072 1078
+f 1079 1073 1074
+f 1077 1079 1075
+f 1074 1075 1079
+f 1079 1077 1078
+f 1078 1072 1079
+f 1073 1079 1072
+f 141 142 1068
+f 155 1070 1069
+f 1069 142 155
+f 1071 155 164
+f 1072 1071 164
+f 164 1073 1072
+f 164 174 1074
+f 1073 164 1074
+f 174 173 1075
+f 1074 174 1075
+f 1081 510 1082
+f 1082 510 1083
+f 1087 1077 1088
+f 1090 173 1091
+f 1096 490 1097
+f 1097 490 1098
+f 1080 1081 1099
+f 1097 1098 1100
+f 1098 1099 1100
+f 1083 1100 1082
+f 1082 1100 1081
+f 1099 1081 1100
+f 1085 1101 1084
+f 1100 1084 1101
+f 1095 1096 1101
+f 1096 1097 1101
+f 1100 1101 1097
+f 1102 1092 1093
+f 1087 1103 1086
+f 1101 1104 1095
+f 1091 1092 1105
+f 1102 1105 1092
+f 1091 1105 1090
+f 1089 1090 1105
+f 1089 1105 1088
+f 1103 1087 1105
+f 1088 1105 1087
+f 1105 1106 1103
+f 1104 1101 1106
+f 1103 1106 1101
+f 1104 1106 1102
+f 1106 1105 1102
+f 510 1081 1080
+f 1080 511 510
+f 1083 510 509
+f 1077 1087 1086
+f 1077 1076 1089
+f 1088 1077 1089
+f 1076 173 1090
+f 1089 1076 1090
+f 173 187 1092
+f 1091 173 1092
+f 187 186 1093
+f 1092 187 1093
+f 1094 186 185
+f 490 1096 1095
+f 1095 185 490
+f 500 1099 1098
+f 1098 490 500
+f 1084 1100 1083
+f 509 1084 1083
+f 1094 1102 1093
+f 1093 186 1094
+f 1102 1094 1104
+f 1104 1094 1095
+f 1095 1094 185
+f 1099 500 1080
+f 500 511 1080
+f 1108 499 1109
+f 1112 139 1113
+f 1113 139 1114
+f 1115 140 1116
+f 1116 140 1117
+f 1118 1068 1119
+f 1120 1078 1121
+f 1123 1101 1124
+f 1127 509 1128
+f 1108 1109 1111
+f 1109 1110 1111
+f 1108 1111 1112
+f 1130 1132 1129
+f 1129 1132 1128
+f 1127 1128 1132
+f 1121 1133 1120
+f 1119 1120 1133
+f 1134 1123 1124
+f 1124 1125 1134
+f 1126 1127 1134
+f 1132 1134 1127
+f 1132 1107 1135
+f 1136 1116 1117
+f 1133 1136 1119
+f 1118 1119 1136
+f 1134 1137 1123
+f 1133 1122 1137
+f 1115 1116 1138
+f 1136 1138 1116
+f 1115 1138 1114
+f 1114 1138 1113
+f 1113 1138 1112
+f 1108 1112 1138
+f 1134 1139 1137
+f 1136 1133 1139
+f 1137 1139 1133
+f 1139 1134 1132
+f 1136 1139 1138
+f 1132 1135 1139
+f 1138 1139 1135
+f 507 499 1108
+f 499 489 1110
+f 1109 499 1110
+f 138 1111 1110
+f 1110 489 138
+f 139 1112 1111
+f 1111 138 139
+f 140 1115 1114
+f 1114 139 140
+f 1117 140 141
+f 1068 1078 1120
+f 1119 1068 1120
+f 1122 1077 1086
+f 1085 1125 1124
+f 1124 1101 1085
+f 1085 1084 1126
+f 1084 509 1127
+f 1126 1084 1127
+f 509 522 1129
+f 1128 509 1129
+f 522 521 1130
+f 1129 522 1130
+f 508 1107 1131
+f 521 508 1131
+f 508 507 1108
+f 1135 1108 1138
+f 1107 508 1108
+f 1108 1135 1107
+f 1117 1118 1136
+f 141 1118 1117
+f 1118 141 1068
+f 1122 1133 1121
+f 1121 1078 1122
+f 1078 1077 1122
+f 1086 1137 1122
+f 1123 1103 1101
+f 1103 1123 1086
+f 1123 1137 1086
+f 1125 1126 1134
+f 1125 1085 1126
+f 1130 1131 1132
+f 1130 521 1131
+f 1107 1132 1131
+f 1141 613 1142
+f 1144 601 1145
+f 1147 466 1148
+f 1140 1141 1144
+f 1141 1142 1144
+f 1142 1143 1144
+f 1140 1144 1145
+f 613 1141 1140
+f 1140 614 613
+f 612 601 1144
+f 1143 612 1144
+f 601 474 1146
+f 1145 601 1146
+f 474 466 1147
+f 1146 474 1147
+f 466 165 1149
+f 1148 466 1149
+f 1140 1145 1146
+f 1142 613 1143
+f 613 612 1143
+f 1154 467 1155
+f 1151 1152 1153
+f 149 460 1152
+f 1151 149 1152
+f 468 1153 1152
+f 1152 460 468
+f 467 476 1156
+f 1155 467 1156
+f 1153 468 1154
+f 468 467 1154
+f 1159 1149 1160
+f 1161 165 1162
+f 1165 191 1166
+f 1165 1168 1164
+f 1168 1163 1164
+f 1169 1161 1162
+f 1162 1163 1169
+f 1168 1169 1163
+f 1168 1170 1169
+f 1166 1167 1170
+f 1166 1170 1165
+f 1168 1165 1170
+f 1161 1171 1160
+f 1171 1161 1169
+f 1169 1170 1171
+f 1149 165 1161
+f 1160 1149 1161
+f 176 1163 1162
+f 1162 165 176
+f 192 1164 1163
+f 1163 176 192
+f 192 191 1165
+f 1164 192 1165
+f 191 190 1167
+f 1166 191 1167
+f 1173 475 1174
+f 1174 475 1175
+f 1175 475 1176
+f 1176 475 1177
+f 1177 475 1178
+f 1183 1157 1184
+f 1184 1157 1185
+f 1183 1184 1185
+f 1181 1182 1187
+f 1176 1177 1190
+f 1186 1190 1178
+f 1177 1178 1190
+f 1176 1190 1175
+f 1175 1190 1174
+f 1187 1191 1181
+f 1186 1192 1190
+f 476 475 1173
+f 1172 476 1173
+f 1178 475 479
+f 587 602 1179
+f 615 1180 1179
+f 1179 602 615
+f 1158 1157 1183
+f 1182 1158 1183
+f 1179 479 587
+f 479 1179 1178
+f 1178 1179 1186
+f 1193 1189 1194
+f 1195 1188 1196
+f 1197 1186 1198
+f 1201 1140 1202
+f 1206 1148 1207
+f 1209 1159 1210
+f 1212 1171 1213
+f 1214 1170 1215
+f 1216 1167 1217
+f 1219 175 1220
+f 1223 1158 1224
+f 1227 1191 1228
+f 1201 1202 1203
+f 1194 1229 1193
+f 1207 1229 1206
+f 1230 1196 1197
+f 1199 1230 1198
+f 1197 1198 1230
+f 1205 1231 1204
+f 1200 1231 1230
+f 1227 1228 1232
+f 1229 1232 1228
+f 1209 1232 1208
+f 1229 1207 1232
+f 1208 1232 1207
+f 1221 1234 1220
+f 1217 1218 1234
+f 1218 1219 1234
+f 1220 1234 1219
+f 1195 1196 1235
+f 1230 1235 1196
+f 1229 1194 1235
+f 1195 1235 1194
+f 1235 1230 1231
+f 1213 1236 1212
+f 1212 1236 1211
+f 1232 1209 1236
+f 1210 1236 1209
+f 1237 1224 1225
+f 1225 1226 1237
+f 1232 1237 1227
+f 1234 1238 1217
+f 1216 1217 1238
+f 1216 1238 1215
+f 1233 1214 1238
+f 1215 1238 1214
+f 1222 1239 1221
+f 1234 1221 1239
+f 1234 1239 1238
+f 1233 1238 1239
+f 1239 1222 1223
+f 1236 1240 1232
+f 1233 1240 1214
+f 1236 1213 1240
+f 1241 1233 1239
+f 1237 1241 1224
+f 1239 1223 1241
+f 1224 1241 1223
+f 1233 1241 1240
+f 1240 1241 1232
+f 1237 1232 1241
+f 1188 1195 1194
+f 1194 1189 1188
+f 1179 1199 1198
+f 1198 1186 1179
+f 1199 1179 1180
+f 1200 614 1140
+f 1202 1140 1203
+f 1140 1146 1203
+f 1146 1147 1205
+f 1204 1146 1205
+f 1147 1148 1206
+f 1149 1208 1207
+f 1207 1148 1149
+f 1159 1209 1208
+f 1208 1149 1159
+f 1160 1171 1212
+f 1211 1160 1212
+f 1171 1170 1214
+f 1167 1216 1215
+f 1215 1170 1167
+f 1167 190 1218
+f 1217 1167 1218
+f 190 175 1219
+f 1218 190 1219
+f 1158 1223 1222
+f 1182 1225 1224
+f 1224 1158 1182
+f 1181 1226 1225
+f 1225 1182 1181
+f 1181 1191 1227
+f 1196 1192 1197
+f 1196 1188 1192
+f 1186 1197 1192
+f 1199 1180 1230
+f 1200 615 614
+f 1180 615 1200
+f 1200 1230 1180
+f 1203 1146 1204
+f 1204 1231 1203
+f 1205 1206 1231
+f 1205 1147 1206
+f 1229 1235 1206
+f 1231 1206 1235
+f 1211 1236 1210
+f 1210 1159 1211
+f 1211 1159 1160
+f 1214 1240 1213
+f 1213 1171 1214
+f 1226 1227 1237
+f 1226 1181 1227
+f 1193 1229 1228
+f 1228 1191 1193
+f 1191 1189 1193
+f 1242 164 1243
+f 1244 1157 1245
+f 1246 1158 1247
+f 1249 175 1250
+f 1243 1255 1242
+f 1253 1254 1255
+f 1242 1255 1254
+f 1252 1256 1251
+f 1256 1250 1251
+f 1245 1258 1244
+f 1259 1248 1249
+f 1256 1259 1250
+f 1249 1250 1259
+f 1260 1256 1252
+f 1255 1260 1253
+f 1252 1253 1260
+f 1257 1261 1243
+f 1261 1255 1243
+f 1259 1262 1248
+f 1247 1262 1246
+f 1258 1245 1262
+f 1246 1262 1245
+f 1260 1263 1256
+f 1263 1259 1256
+f 1259 1263 1262
+f 1263 1264 1262
+f 1261 1257 1264
+f 1264 1263 1260
+f 1261 1264 1255
+f 1260 1255 1264
+f 1158 1246 1245
+f 1245 1157 1158
+f 1247 1158 1222
+f 1221 1220 1248
+f 1220 175 1249
+f 1248 1220 1249
+f 175 189 1251
+f 1250 175 1251
+f 1251 189 1252
+f 1253 1252 189
+f 189 174 1253
+f 1253 174 1254
+f 1242 1254 174
+f 174 164 1242
+f 1200 1201 1231
+f 1140 1201 1200
+f 1203 1231 1201
+f 1222 1221 1248
+f 1247 1248 1262
+f 1222 1248 1247
+f 1267 1065 1268
+f 1268 1065 1269
+f 1274 815 1275
+f 1275 815 1276
+f 1277 196 1278
+f 1279 197 1280
+f 1280 197 1281
+f 1284 212 1285
+f 1286 218 1287
+f 1291 1063 1292
+f 1268 1269 1294
+f 1270 1294 1269
+f 1296 1266 1267
+f 1267 1268 1296
+f 1294 1296 1268
+f 1297 1274 1275
+f 1275 1276 1297
+f 1274 1297 1273
+f 1265 1266 1298
+f 1296 1298 1266
+f 1295 1299 1297
+f 1299 1295 1298
+f 1294 1299 1296
+f 1298 1296 1299
+f 1295 1300 1298
+f 1290 1291 1300
+f 1291 1292 1300
+f 1292 1293 1300
+f 1298 1300 1293
+f 1282 1301 1281
+f 1280 1281 1301
+f 1282 1283 1301
+f 1302 1297 1299
+f 1299 1294 1302
+f 1294 1271 1302
+f 1297 1302 1273
+f 1303 1287 1288
+f 1288 1289 1303
+f 1304 1278 1279
+f 1279 1280 1304
+f 1301 1304 1280
+f 1297 1277 1304
+f 1278 1304 1277
+f 1297 1304 1295
+f 1301 1295 1304
+f 1301 1305 1295
+f 1305 1300 1295
+f 1300 1305 1303
+f 1306 1303 1305
+f 1305 1301 1306
+f 1283 1306 1301
+f 1285 1286 1306
+f 1286 1287 1306
+f 1303 1306 1287
+f 1285 1306 1284
+f 1283 1284 1306
+f 1064 1266 1265
+f 1265 1067 1064
+f 1064 1065 1267
+f 1266 1064 1267
+f 1046 1270 1269
+f 1269 1065 1046
+f 1272 827 826
+f 815 1274 1273
+f 1273 825 815
+f 1276 815 804
+f 196 197 1279
+f 1278 196 1279
+f 198 1282 1281
+f 1281 197 198
+f 198 206 1283
+f 1282 198 1283
+f 206 212 1284
+f 1283 206 1284
+f 212 218 1286
+f 1285 212 1286
+f 244 1288 1287
+f 1287 218 244
+f 243 1289 1288
+f 1288 244 243
+f 1063 1291 1290
+f 1290 1047 1063
+f 1067 1293 1292
+f 1292 1063 1067
+f 1271 828 827
+f 1046 828 1271
+f 1270 1271 1294
+f 1270 1046 1271
+f 1271 827 1272
+f 1302 1271 1272
+f 1272 1273 1302
+f 826 1273 1272
+f 1273 826 825
+f 1276 804 1297
+f 804 1277 1297
+f 196 1277 804
+f 1289 1290 1303
+f 1289 243 1290
+f 1290 243 1047
+f 1300 1303 1290
+f 1265 1298 1293
+f 1293 1067 1265
+f 1307 689 1308
+f 1309 699 1310
+f 1315 1030 1316
+f 1316 1030 1317
+f 1318 1031 1319
+f 1322 211 1323
+f 1324 194 1325
+f 1308 1328 1307
+f 1328 1308 1329
+f 1328 1329 1327
+f 1326 1327 1329
+f 1310 1311 1331
+f 1311 1312 1331
+f 1310 1331 1309
+f 1309 1331 1308
+f 1329 1308 1331
+f 1332 1316 1317
+f 1317 1318 1332
+f 1318 1319 1332
+f 1316 1332 1315
+f 1315 1332 1314
+f 1326 1333 1325
+f 1330 1324 1333
+f 1325 1333 1324
+f 1333 1326 1329
+f 1320 1334 1319
+f 1330 1332 1334
+f 1319 1334 1332
+f 1335 1329 1331
+f 1332 1335 1314
+f 1335 1332 1330
+f 1330 1333 1335
+f 1329 1335 1333
+f 689 699 1309
+f 1308 689 1309
+f 698 1311 1310
+f 1310 699 698
+f 717 1312 1311
+f 1311 698 717
+f 717 716 1313
+f 1312 717 1313
+f 1313 716 1006
+f 1030 1315 1314
+f 1314 1006 1030
+f 1031 1318 1317
+f 1317 1030 1031
+f 1028 1320 1319
+f 1319 1031 1028
+f 194 1324 1323
+f 1323 211 194
+f 1325 194 1326
+f 1327 1326 194
+f 1307 1328 682
+f 689 1307 682
+f 1327 682 1328
+f 682 1327 194
+f 1006 1314 1313
+f 1314 1331 1312
+f 1312 1313 1314
+f 1331 1314 1335
+f 1321 1028 1029
+f 1334 1320 1321
+f 1320 1028 1321
+f 1337 710 1338
+f 1341 697 1342
+f 1344 217 1345
+f 1346 242 1347
+f 1348 258 1349
+f 1349 258 1350
+f 1350 258 1351
+f 1354 252 1355
+f 1355 252 1356
+f 1357 1004 1358
+f 1359 1005 1360
+f 1360 1005 1361
+f 1363 1021 1364
+f 1366 1025 1367
+f 1367 1025 1368
+f 1373 712 1374
+f 1340 1341 1342
+f 1340 1342 1343
+f 1370 1371 1372
+f 1343 1376 1340
+f 1340 1376 1339
+f 1338 1339 1376
+f 1348 1377 1347
+f 1344 1345 1377
+f 1345 1346 1377
+f 1347 1377 1346
+f 1356 1378 1355
+f 1354 1355 1378
+f 1380 1336 1337
+f 1337 1338 1380
+f 1376 1380 1338
+f 1353 1354 1381
+f 1378 1381 1354
+f 1360 1382 1359
+f 1359 1382 1358
+f 1358 1382 1357
+f 1365 1366 1383
+f 1366 1367 1383
+f 1385 1369 1370
+f 1385 1379 1383
+f 1369 1385 1368
+f 1383 1367 1385
+f 1368 1385 1367
+f 1386 1379 1385
+f 1372 1373 1386
+f 1374 1386 1373
+f 1385 1370 1386
+f 1372 1386 1370
+f 1387 1376 1343
+f 1387 1379 1386
+f 1376 1387 1380
+f 1388 1351 1352
+f 1381 1388 1353
+f 1352 1353 1388
+f 1382 1360 1389
+f 1361 1389 1360
+f 1389 1361 1362
+f 1362 1363 1389
+f 1363 1364 1389
+f 1383 1389 1365
+f 1364 1365 1389
+f 1390 1378 1382
+f 1383 1390 1389
+f 1382 1389 1390
+f 1348 1391 1377
+f 1391 1348 1349
+f 1349 1350 1391
+f 1350 1351 1391
+f 1351 1388 1391
+f 1392 1344 1377
+f 1384 1392 1391
+f 1377 1391 1392
+f 1344 1392 1343
+f 1343 1392 1387
+f 1393 1378 1390
+f 1378 1393 1381
+f 1381 1393 1388
+f 1388 1393 1391
+f 1384 1391 1393
+f 1394 1379 1387
+f 1387 1392 1394
+f 1384 1394 1392
+f 1394 1384 1393
+f 1395 1336 1380
+f 1386 1395 1387
+f 1380 1387 1395
+f 1386 1374 1395
+f 1396 1379 1394
+f 1394 1393 1396
+f 1390 1396 1393
+f 1379 1396 1383
+f 1396 1390 1383
+f 711 710 1337
+f 1336 711 1337
+f 709 1339 1338
+f 1338 710 709
+f 1339 709 697
+f 1340 1339 697
+f 697 1341 1340
+f 697 688 1343
+f 1342 697 1343
+f 688 217 1344
+f 1343 688 1344
+f 217 242 1346
+f 1345 217 1346
+f 242 258 1348
+f 1347 242 1348
+f 995 1352 1351
+f 1351 258 995
+f 994 1353 1352
+f 1352 995 994
+f 994 252 1354
+f 1353 994 1354
+f 1356 252 1002
+f 1002 1004 1357
+f 1004 1005 1359
+f 1358 1004 1359
+f 1011 1362 1361
+f 1361 1005 1011
+f 1011 1021 1363
+f 1362 1011 1363
+f 1018 1365 1364
+f 1364 1021 1018
+f 1018 1025 1366
+f 1365 1018 1366
+f 1019 1369 1368
+f 1368 1025 1019
+f 1026 1370 1369
+f 1369 1019 1026
+f 1010 1372 1371
+f 1371 1026 1010
+f 1010 712 1373
+f 1372 1010 1373
+f 711 1336 1375
+f 1357 1378 1356
+f 1002 1357 1356
+f 1378 1357 1382
+f 1370 1026 1371
+f 1375 1395 1374
+f 1374 712 1375
+f 712 711 1375
+f 1375 1336 1395
+f 1400 157 1401
+f 1403 1150 1404
+f 1406 1151 1407
+f 1410 1155 1411
+f 1413 1156 1414
+f 1416 1172 1417
+f 1420 1190 1421
+f 1422 1192 1423
+f 1424 1188 1425
+f 1426 1189 1427
+f 1429 1187 1430
+f 1432 1185 1433
+f 1433 1185 1434
+f 1437 1258 1438
+f 1438 1258 1439
+f 1441 1257 1442
+f 1397 1445 1446
+f 1409 1450 1408
+f 1408 1450 1407
+f 1406 1407 1450
+f 1442 1451 1441
+f 1448 1452 1447
+f 1453 1448 1447
+f 1447 1445 1453
+f 1448 1453 1454
+f 1453 1398 1454
+f 1444 1461 1455
+f 1452 1448 1461
+f 1443 1444 1462
+f 1455 1462 1444
+f 1463 1428 1429
+f 1429 1430 1463
+f 1464 1456 1463
+f 1463 1430 1464
+f 1431 1464 1430
+f 1437 1465 1436
+f 1456 1464 1465
+f 1436 1465 1435
+f 1435 1465 1434
+f 1434 1465 1433
+f 1433 1465 1432
+f 1465 1437 1438
+f 1462 1455 1467
+f 1454 1399 1468
+f 1457 1469 1468
+f 1448 1454 1469
+f 1468 1469 1454
+f 1470 1449 1466
+f 1409 1471 1450
+f 1472 1403 1404
+f 1458 1472 1471
+f 1458 1473 1472
+f 1474 1449 1470
+f 1417 1418 1475
+f 1418 1419 1475
+f 1420 1475 1419
+f 1417 1475 1416
+f 1416 1475 1415
+f 1475 1420 1421
+f 1411 1476 1410
+f 1471 1410 1476
+f 1459 1476 1475
+f 1413 1476 1412
+f 1413 1414 1476
+f 1414 1415 1476
+f 1475 1476 1415
+f 1477 1458 1471
+f 1471 1476 1477
+f 1459 1477 1476
+f 1458 1477 1474
+f 1459 1478 1477
+f 1477 1478 1474
+f 1449 1474 1478
+f 1422 1479 1421
+f 1475 1421 1479
+f 1479 1422 1423
+f 1423 1424 1479
+f 1424 1425 1479
+f 1460 1480 1479
+f 1479 1480 1475
+f 1459 1475 1480
+f 1459 1480 1478
+f 1463 1481 1428
+f 1427 1428 1481
+f 1427 1481 1426
+f 1460 1479 1481
+f 1426 1481 1425
+f 1479 1425 1481
+f 1482 1449 1478
+f 1478 1480 1482
+f 1460 1482 1480
+f 1449 1482 1466
+f 1463 1483 1481
+f 1483 1460 1481
+f 1466 1482 1483
+f 1460 1483 1482
+f 1463 1456 1483
+f 1466 1483 1456
+f 1439 1484 1438
+f 1465 1438 1484
+f 1467 1485 1484
+f 1456 1465 1485
+f 1484 1485 1465
+f 1486 1467 1484
+f 1484 1440 1486
+f 1440 1441 1486
+f 1451 1486 1441
+f 1467 1486 1462
+f 1467 1487 1485
+f 1457 1487 1469
+f 1488 1401 1473
+f 1401 1488 1400
+f 1488 1468 1400
+f 1489 1469 1487
+f 1487 1467 1489
+f 1455 1489 1467
+f 1469 1489 1448
+f 1455 1461 1489
+f 1448 1489 1461
+f 1471 1472 1490
+f 1472 1404 1490
+f 1471 1490 1450
+f 1450 1490 1406
+f 1405 1406 1490
+f 1457 1491 1470
+f 1473 1491 1488
+f 1457 1468 1491
+f 1488 1491 1468
+f 1466 1492 1470
+f 1485 1492 1456
+f 1492 1466 1456
+f 1470 1493 1457
+f 1493 1487 1457
+f 1493 1470 1492
+f 1487 1493 1485
+f 1492 1485 1493
+f 1458 1494 1473
+f 1494 1491 1473
+f 1494 1458 1474
+f 1474 1470 1494
+f 1491 1494 1470
+f 1398 156 157
+f 1401 157 147
+f 148 149 1405
+f 1151 1406 1405
+f 1405 149 1151
+f 1153 1408 1407
+f 1407 1151 1153
+f 1153 1154 1409
+f 1408 1153 1409
+f 1154 1155 1410
+f 1156 476 1415
+f 1414 1156 1415
+f 1172 1416 1415
+f 1415 476 1172
+f 1172 1173 1418
+f 1417 1172 1418
+f 1173 1174 1419
+f 1418 1173 1419
+f 1174 1190 1420
+f 1419 1174 1420
+f 1192 1422 1421
+f 1421 1190 1192
+f 1192 1188 1424
+f 1423 1192 1424
+f 1188 1189 1426
+f 1425 1188 1426
+f 1191 1428 1427
+f 1427 1189 1191
+f 1191 1187 1429
+f 1428 1191 1429
+f 1182 1431 1430
+f 1430 1187 1182
+f 1183 1185 1432
+f 1157 1435 1434
+f 1434 1185 1157
+f 1244 1436 1435
+f 1435 1157 1244
+f 1258 1437 1436
+f 1436 1244 1258
+f 1439 1258 1262
+f 1257 1441 1440
+f 1440 1264 1257
+f 1243 164 1444
+f 1443 1243 1444
+f 1445 164 155
+f 155 156 1397
+f 1446 1445 155
+f 1397 1446 155
+f 1397 1398 1445
+f 1397 156 1398
+f 1398 1453 1445
+f 157 1399 1398
+f 1399 1454 1398
+f 1400 1468 1399
+f 1399 157 1400
+f 1401 1402 1473
+f 147 1402 1401
+f 1405 1490 1404
+f 1404 1150 1405
+f 1150 148 1405
+f 1409 1410 1471
+f 1409 1154 1410
+f 1476 1411 1412
+f 1411 1155 1412
+f 1155 1156 1412
+f 1412 1156 1413
+f 1464 1431 1432
+f 1431 1182 1432
+f 1182 1183 1432
+f 1464 1432 1465
+f 1484 1439 1440
+f 1262 1440 1439
+f 1440 1262 1264
+f 1443 1451 1442
+f 1442 1257 1443
+f 1257 1243 1443
+f 1451 1443 1486
+f 1462 1486 1443
+f 1461 1444 1452
+f 1444 164 1452
+f 1452 1445 1447
+f 164 1445 1452
+f 1496 227 1497
+f 1499 923 1500
+f 1501 922 1502
+f 1504 920 1505
+f 1506 204 1507
+f 1507 204 1508
+f 1513 192 1514
+f 1518 211 1519
+f 1520 1322 1521
+f 1526 1321 1527
+f 1527 1321 1528
+f 1530 1020 1531
+f 1533 1023 1534
+f 1537 254 1538
+f 1538 254 1539
+f 1540 259 1541
+f 1544 241 1545
+f 1541 1542 1548
+f 1542 1543 1548
+f 1543 1544 1548
+f 1544 1545 1548
+f 1539 1540 1551
+f 1548 1551 1541
+f 1540 1541 1551
+f 1495 1552 1547
+f 1547 1552 1546
+f 1511 1553 1510
+f 1508 1555 1507
+f 1507 1555 1506
+f 1505 1506 1555
+f 1505 1555 1504
+f 1504 1555 1503
+f 1503 1555 1502
+f 1549 1556 1555
+f 1499 1500 1556
+f 1500 1501 1556
+f 1555 1556 1502
+f 1501 1502 1556
+f 1499 1556 1498
+f 1557 1549 1555
+f 1509 1557 1508
+f 1555 1508 1557
+f 1557 1509 1510
+f 1526 1527 1558
+f 1528 1558 1527
+f 1526 1558 1525
+f 1560 1522 1523
+f 1550 1560 1558
+f 1523 1524 1560
+f 1558 1560 1525
+f 1524 1525 1560
+f 1522 1560 1521
+f 1521 1560 1520
+f 1520 1560 1519
+f 1519 1560 1518
+f 1550 1561 1560
+f 1560 1561 1518
+f 1538 1562 1537
+f 1538 1539 1562
+f 1551 1562 1539
+f 1563 1549 1557
+f 1557 1510 1563
+f 1553 1563 1510
+f 1513 1564 1512
+f 1553 1511 1564
+f 1512 1564 1511
+f 1566 1551 1548
+f 1548 1552 1566
+f 1497 1567 1496
+f 1556 1567 1498
+f 1554 1568 1567
+f 1567 1568 1496
+f 1552 1495 1568
+f 1552 1568 1566
+f 1549 1569 1556
+f 1556 1569 1567
+f 1554 1567 1569
+f 1534 1570 1533
+f 1533 1570 1532
+f 1532 1570 1531
+f 1531 1570 1530
+f 1530 1570 1529
+f 1558 1528 1570
+f 1529 1570 1528
+f 1516 1571 1515
+f 1550 1572 1561
+f 1561 1572 1571
+f 1559 1571 1572
+f 1573 1514 1515
+f 1559 1573 1571
+f 1515 1571 1573
+f 1575 1565 1574
+f 1563 1578 1549
+f 1578 1569 1549
+f 1513 1514 1579
+f 1573 1579 1514
+f 1513 1579 1564
+f 1564 1579 1553
+f 1580 1563 1553
+f 1574 1580 1579
+f 1553 1579 1580
+f 1558 1581 1550
+f 1550 1581 1572
+f 1575 1572 1581
+f 1582 1573 1559
+f 1575 1582 1572
+f 1559 1572 1582
+f 1573 1582 1579
+f 1579 1582 1574
+f 1575 1574 1582
+f 1551 1583 1562
+f 1584 1536 1562
+f 1576 1584 1583
+f 1562 1583 1584
+f 1576 1585 1584
+f 1570 1534 1585
+f 1584 1585 1535
+f 1534 1535 1585
+f 1587 1574 1565
+f 1574 1587 1580
+f 1588 1569 1578
+f 1569 1588 1554
+f 1577 1589 1588
+f 1554 1588 1589
+f 1554 1589 1568
+f 1566 1568 1589
+f 1565 1590 1586
+f 1581 1590 1575
+f 1590 1565 1575
+f 1591 1566 1589
+f 1566 1591 1551
+f 1591 1583 1551
+f 1558 1592 1581
+f 1585 1592 1570
+f 1592 1558 1570
+f 1583 1593 1576
+f 1593 1586 1576
+f 1586 1594 1565
+f 1565 1594 1587
+f 1577 1587 1594
+f 1594 1586 1593
+f 1586 1595 1576
+f 1595 1585 1576
+f 1578 1596 1588
+f 1587 1577 1596
+f 1588 1596 1577
+f 1587 1596 1580
+f 1580 1596 1563
+f 1578 1563 1596
+f 1597 1594 1593
+f 1593 1583 1597
+f 1591 1597 1583
+f 1597 1591 1589
+f 1594 1597 1577
+f 1589 1577 1597
+f 1581 1598 1590
+f 1595 1586 1598
+f 1590 1598 1586
+f 1598 1581 1592
+f 1592 1585 1598
+f 1595 1598 1585
+f 1497 227 925
+f 923 1499 1498
+f 1498 924 923
+f 923 922 1501
+f 1500 923 1501
+f 921 1503 1502
+f 1502 922 921
+f 920 1504 1503
+f 1503 921 920
+f 1505 920 919
+f 190 1509 1508
+f 1508 204 190
+f 190 191 1510
+f 1509 190 1510
+f 191 1512 1511
+f 1510 191 1511
+f 192 1513 1512
+f 1512 191 192
+f 1514 192 1515
+f 1516 1515 192
+f 192 193 1516
+f 1322 1520 1519
+f 1519 211 1322
+f 1322 1323 1522
+f 1521 1322 1522
+f 1323 1324 1523
+f 1522 1323 1523
+f 1330 1524 1523
+f 1523 1324 1330
+f 1334 1525 1524
+f 1524 1330 1334
+f 1334 1321 1526
+f 1525 1334 1526
+f 1029 1529 1528
+f 1528 1321 1029
+f 1020 1530 1529
+f 1529 1029 1020
+f 1020 1017 1532
+f 1531 1020 1532
+f 1017 1023 1533
+f 1532 1017 1533
+f 1023 1022 1535
+f 1534 1023 1535
+f 1022 1016 1536
+f 259 1540 1539
+f 1539 254 259
+f 264 1542 1541
+f 1541 259 264
+f 257 1543 1542
+f 1542 264 257
+f 241 1544 1543
+f 1543 257 241
+f 1495 1547 1546
+f 1546 230 1495
+f 1402 148 1150
+f 147 148 1402
+f 1402 1150 1403
+f 1403 1472 1402
+f 1472 1473 1402
+f 1496 1568 1495
+f 1495 230 1496
+f 1496 230 227
+f 1498 1567 1497
+f 925 1498 1497
+f 1498 925 924
+f 1506 1505 919
+f 919 204 1506
+f 1516 1517 1571
+f 1516 193 1517
+f 193 205 1517
+f 1561 1571 1517
+f 1517 1518 1561
+f 1517 205 1518
+f 205 211 1518
+f 1535 1022 1536
+f 1536 1584 1535
+f 1016 254 1537
+f 1562 1536 1537
+f 1536 1016 1537
+f 1546 1548 1545
+f 1545 241 1546
+f 241 230 1546
+f 1548 1546 1552
diff --git a/test/garden/CMakeLists.txt b/test/garden/CMakeLists.txt
new file mode 100644
index 0000000..28674b9
--- /dev/null
+++ b/test/garden/CMakeLists.txt
@@ -0,0 +1,25 @@
+#-- polygon_triangulator test
+file( GLOB_RECURSE SFCGAL_REGRESS_GARDEN_TEST_SOURCES *.cpp )
+
+set( REGRESS_NAME garden-test-SFCGAL )
+add_executable( ${REGRESS_NAME} ${SFCGAL_REGRESS_GARDEN_TEST_SOURCES} )
+
+target_link_libraries( ${REGRESS_NAME}
+ SFCGAL
+ ${Boost_LIBRARIES}
+ ${CGAL_LIBRARIES}
+)
+if( ${SFCGAL_WITH_MPFR} )
+ target_link_libraries( ${REGRESS_NAME} ${MPFR_LIBRARIES} )
+endif( ${SFCGAL_WITH_MPFR} )
+
+set_target_properties( ${REGRESS_NAME} PROPERTIES DEBUG_POSTFIX "d" )
+install( TARGETS ${REGRESS_NAME} DESTINATION bin )
+
+if (CMAKE_BUILD_TYPE STREQUAL "Debug" )
+ add_test( garden-testd ${CMAKE_CURRENT_BINARY_DIR}/garden-test-SFCGALd )
+else()
+ add_test( garden-test ${CMAKE_CURRENT_BINARY_DIR}/garden-test-SFCGAL )
+endif()
+
+
diff --git a/test/garden/main.cpp b/test/garden/main.cpp
new file mode 100644
index 0000000..f4c51f8
--- /dev/null
+++ b/test/garden/main.cpp
@@ -0,0 +1,624 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <iostream>
+#include <fstream>
+#include <set>
+
+#include <boost/program_options.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/chrono.hpp>
+
+#include <SFCGAL/Exception.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/version.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/io/vtk.h>
+#include <SFCGAL/detail/TestGeometry.h>
+#include <SFCGAL/algorithm/area.h>
+#include <SFCGAL/algorithm/intersects.h>
+#include <SFCGAL/algorithm/intersection.h>
+#include <SFCGAL/algorithm/difference.h>
+#include <SFCGAL/algorithm/union.h>
+#include <SFCGAL/algorithm/plane.h>
+#include <SFCGAL/algorithm/minkowskiSum.h>
+#include <SFCGAL/algorithm/tesselate.h>
+#include <SFCGAL/algorithm/isValid.h>
+#include <SFCGAL/algorithm/distance.h>
+#include <SFCGAL/algorithm/distance3d.h>
+#include <SFCGAL/algorithm/straightSkeleton.h>
+#include <SFCGAL/algorithm/extrude.h>
+#include <SFCGAL/triangulate/triangulate2DZ.h>
+#include <SFCGAL/PreparedGeometry.h>
+
+using namespace SFCGAL ;
+
+namespace po = boost::program_options ;
+
+/*
+ * Monkey testing of the SFCGAL pulic api
+ */
+int main( int argc, char* argv[] )
+{
+ /*
+ * declare options
+ */
+ po::options_description desc( "garden test options : " );
+ desc.add_options()
+ ( "help", "produce help message" )
+ ( "progress", "display progress" )
+ ( "verbose", "verbose mode" )
+ ( "novalidate", "remove validation of input geometries" )
+ ( "vtk", "output vtk geom on failure" )
+ ;
+
+ po::variables_map vm;
+ po::store( po::parse_command_line( argc, argv, desc ), vm );
+ po::notify( vm );
+
+ if ( vm.count( "help" ) ) {
+ std::cout << desc << std::endl ;
+ return 0;
+ }
+
+ bool verbose = vm.count( "verbose" ) != 0 ;
+ bool progress = vm.count( "progress" ) != 0 ;
+ bool vtk = vm.count( "vtk" ) != 0 ;
+
+ SFCGAL::algorithm::SKIP_GEOM_VALIDATION = vm.count( "novalidate" ) != 0 ;
+
+
+ //boost::timer timer ;
+ boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now();
+
+ if ( verbose ) {
+ std::cout << "testing SFCGAL version " << Version() << "\n";
+ }
+
+
+ // construction of a list valid and invalid test geometries
+ GeometryCollection testCollection;
+ {
+ if ( verbose ) {
+ std::cout << "creating test geometries\n";
+ }
+
+ // start with a collection of valid and invalid geometries
+ const std::vector< TestGeometry > testGeom( createTestGeometries() ) ;
+
+ for ( std::vector< TestGeometry >::const_iterator tg=testGeom.begin();
+ tg!=testGeom.end(); ++tg ) {
+ try {
+ std::auto_ptr< Geometry > g( io::readWkt( tg->wkt ) );
+ testCollection.addGeometry( g.release() );
+ }
+ catch ( WktParseException ) {
+ BOOST_ASSERT( !tg->isValid );
+ }
+ }
+
+ // default constructed geometries
+ testCollection.addGeometry( new Point ) ;
+ testCollection.addGeometry( new LineString ) ;
+ testCollection.addGeometry( new Triangle ) ;
+ testCollection.addGeometry( new Polygon ) ;
+ testCollection.addGeometry( new MultiLineString ) ;
+ testCollection.addGeometry( new MultiPoint ) ;
+ testCollection.addGeometry( new MultiPolygon ) ;
+ testCollection.addGeometry( new PolyhedralSurface ) ;
+ testCollection.addGeometry( new TriangulatedSurface ) ;
+ testCollection.addGeometry( new Solid ) ;
+ testCollection.addGeometry( new GeometryCollection ) ;
+
+ // non default constructed
+ testCollection.addGeometry( new Point( 67.8,-57.6568 ) ) ;
+ testCollection.addGeometry( new Point( 67.8,-57.6568, 589.5679 ) ) ;
+ testCollection.addGeometry( new Polygon( LineString() ) ) ;
+ testCollection.addGeometry( new Solid( PolyhedralSurface() ) ) ;
+ }
+
+ // member function calls
+ typedef GeometryCollection::const_iterator GeomIter;
+ const size_t numGeom = testCollection.numGeometries();
+
+ if ( verbose ) {
+ std::cout << "testing member functions on " << numGeom << " geometries\n";
+ }
+
+ for ( size_t g=0; g!=numGeom; g++ ) {
+ const Geometry& geom = testCollection.geometryN( g ); // make copy to modify
+ ( void )geom.is3D() ;
+ ( void )geom.isEmpty() ;
+
+ {
+ srid_t srid = 12; // whatever
+ PreparedGeometry prep( geom.clone(), srid );
+ ( void )prep.geometry();
+ BOOST_ASSERT( prep.SRID() == srid );
+ }
+
+ if ( verbose ) {
+ std::cout << ( boost::format( "% 8d" )%( g+1 ) ) << " - " << ( geom.is3D()?"3D":"2D" ) << " " << geom.geometryType() << ( geom.isEmpty()?" (empty)":"" ) << ( algorithm::isValid( geom )?"":" (invalid)" );
+ }
+
+ switch ( geom.geometryTypeId() ) {
+ case TYPE_POINT : {
+ Point p( geom.as<Point>() ) ;
+
+ try {
+ ( void )p.x();
+ ( void )p.y();
+ ( void )p.z();
+ }
+ catch ( Exception ) {
+ BOOST_ASSERT( p.isEmpty() );
+ }
+ }
+ break;
+
+ case TYPE_LINESTRING : {
+ LineString l( geom.as<LineString>() );
+ const size_t numPoints = l.numPoints();
+
+ if ( verbose ) {
+ std::cout << ", " << numPoints << " points";
+ }
+
+ for ( GeomIter i=testCollection.begin(); i!=testCollection.end(); ++i ) {
+ if ( i->is<Point>() ) {
+ l.addPoint( i->as<Point>() );
+ }
+ }
+
+ if ( verbose ) {
+ std::cout << ", added " << l.numPoints()-numPoints << " points";
+ }
+
+ ( void )l.pointN( 0 );
+ ( void )l.pointN( l.numPoints()-1 );
+# ifdef DEBUG
+ bool threw = false ;
+
+ try {
+ ( void )l.pointN( l.numPoints() );
+ }
+ catch ( std::exception ) {
+ threw = true;
+ }
+
+ BOOST_ASSERT( threw );
+# endif
+ }
+ break;
+
+ case TYPE_POLYGON : {
+ Polygon p( geom.as<Polygon>() ) ;
+
+ for ( GeomIter i=testCollection.begin(); i!=testCollection.end(); ++i ) {
+ if ( i->is<LineString>() ) {
+ p.addRing( i->as<LineString>() );
+ ( void )Polygon( i->as<LineString>() );
+ }
+ }
+
+ ( void )p.exteriorRing();
+
+ if ( p.numInteriorRings() ) {
+ ( void )p.interiorRingN( 0 );
+ ( void )p.interiorRingN( p.numInteriorRings()-1 );
+ }
+
+ ( void )p.isCounterClockWiseOriented();
+# ifdef DEBUG
+ bool threw = false ;
+
+ try {
+ ( void )p.interiorRingN( p.numInteriorRings() );
+ }
+ catch ( std::exception ) {
+ threw = true;
+ }
+
+ BOOST_ASSERT( threw );
+# endif
+ }
+ break;
+
+ case TYPE_MULTIPOINT :
+ geom.as<MultiPoint>() ;
+ break;
+
+ case TYPE_MULTILINESTRING :
+ geom.as<MultiLineString>() ;
+ break;
+
+ case TYPE_MULTIPOLYGON :
+ geom.as<MultiPolygon>() ;
+ break;
+
+ case TYPE_GEOMETRYCOLLECTION :
+ geom.as<GeometryCollection>() ;
+ break;
+
+ case TYPE_POLYHEDRALSURFACE : {
+ PolyhedralSurface s( geom.as<PolyhedralSurface>() ) ;
+
+ for ( GeomIter i=testCollection.begin(); i!=testCollection.end(); ++i ) {
+ if ( i->is<Polygon>() ) {
+ s.addPolygon( i->as<Polygon>() );
+ }
+ }
+
+ if ( s.numPolygons() ) {
+ ( void )s.polygonN( 0 );
+ ( void )s.polygonN( s.numPolygons()-1 );
+ }
+
+# ifdef DEBUG
+ bool threw = false ;
+
+ try {
+ ( void )s.polygonN( s.numPolygons() );
+ }
+ catch ( std::exception ) {
+ threw = true;
+ }
+
+ BOOST_ASSERT( threw );
+# endif
+ }
+ break;
+
+ case TYPE_TRIANGULATEDSURFACE : {
+ TriangulatedSurface s( geom.as<TriangulatedSurface>() ) ;
+
+ for ( GeomIter i=testCollection.begin(); i!=testCollection.end(); ++i ) {
+ if ( i->is<Triangle>() ) {
+ s.addTriangle( i->as<Triangle>() );
+ }
+ }
+
+ if ( s.numTriangles() ) {
+ ( void )s.triangleN( 0 );
+ ( void )s.triangleN( s.numTriangles()-1 );
+ }
+
+# ifdef DEBUG
+ bool threw = false ;
+
+ try {
+ ( void )s.triangleN( s.numTriangles() );
+ }
+ catch ( std::exception ) {
+ threw = true;
+ }
+
+ BOOST_ASSERT( threw );
+# endif
+ }
+ break;
+
+ case TYPE_TRIANGLE : {
+ Triangle t( geom.as<Triangle>() ) ;
+
+ for ( int j=0; j<3; ++j ) {
+ ( void )geom.as<Triangle>().vertex( j ) ; // to execise const
+
+ for ( GeomIter i=testCollection.begin(); i!=testCollection.end(); ++i ) {
+ if ( i->is<Point>() ) {
+ t.vertex( j ) = i->as<Point>() ;
+ BOOST_ASSERT( t.vertex( j ) == i->as<Point>() );
+ }
+ }
+ }
+ }
+ break;
+
+ case TYPE_SOLID : {
+ Solid s( geom.as<Solid>() ) ;
+
+ for ( GeomIter i=testCollection.begin(); i!=testCollection.end(); ++i ) {
+ if ( i->is<PolyhedralSurface>() ) {
+ ( void )Solid( i->as<PolyhedralSurface>() );
+ }
+ }
+
+ if ( s.numShells() ) {
+ ( void )s.shellN( 0 );
+ ( void )s.shellN( s.numShells()-1 );
+ }
+
+# ifdef DEBUG
+
+ try {
+ ( void )s.shellN( s.numShells() );
+ }
+ catch ( std::exception ) {
+ threw = true;
+ }
+
+ BOOST_ASSERT( threw );
+# endif
+ }
+ break;
+
+ case TYPE_MULTISOLID :
+ geom.as<MultiSolid>() ;
+ break;
+ }
+
+ if ( verbose ) {
+ std::cout << "\n";
+ }
+ }
+
+ size_t numFailure = 0;
+ size_t calls = 0;
+
+ // function calls
+ std::set< std::string > notImplemented ;
+#define CATCH_INVALID_GEOM_AND_NOT_IMPLEMENTED( call )\
+ {\
+ ++calls ;\
+ try{ call }\
+ catch ( GeometryInvalidityException ) {}\
+ catch ( InappropriateGeometryException ) {}\
+ catch ( NotImplementedException e ) { notImplemented.insert(e.what()) ; }\
+ catch ( std::exception& e )\
+ { \
+ try{\
+ ++numFailure;\
+ std::cerr << "\n" ;\
+ std::cerr << "error " << numFailure << " in " << #call << ": "\
+ << e.what() << "\n";\
+ std::cerr << "error with " << (algorithm::isValid(*geom1)?"valid":"invalid")\
+ << " geometry " << geom1->asText() ; \
+ if (vtk) io::vtk( *geom1, (boost::format("/tmp/geom1_failure%d.vtk") % numFailure).str() );\
+ if (geom2!=testCollection.end() ) {\
+ std::cerr << " and " << (algorithm::isValid(*geom2)?"valid":"invalid")\
+ << " geometry " << geom2->asText();\
+ if (vtk) io::vtk( *geom2, (boost::format("/tmp/geom2_failure%d.vtk") % numFailure).str() );\
+ }\
+ std::cerr << "\n";\
+ }\
+ catch ( NotImplementedException e ) { notImplemented.insert(e.what()) ; }\
+ }\
+ }
+
+ if ( verbose ) {
+ std::cout << "Testing unary and binary functions\n";
+ }
+
+ for ( GeomIter geom1=testCollection.begin(); geom1!=testCollection.end(); ++geom1 ) {
+
+ GeomIter geom2 = testCollection.end();
+
+ CATCH_INVALID_GEOM_AND_NOT_IMPLEMENTED( ( void )algorithm::area3D( *geom1 ) ; )
+ CATCH_INVALID_GEOM_AND_NOT_IMPLEMENTED( ( void )algorithm::area( *geom1 ) ; )
+
+ if ( geom1->is<Polygon>() ) {
+ CATCH_INVALID_GEOM_AND_NOT_IMPLEMENTED( ( void )algorithm::hasPlane3D<Kernel>( geom1->as<Polygon>() ) ; )
+ }
+
+ CATCH_INVALID_GEOM_AND_NOT_IMPLEMENTED( ( void )algorithm::straightSkeleton( *geom1 ) ; )
+ CATCH_INVALID_GEOM_AND_NOT_IMPLEMENTED( ( void )algorithm::tesselate( *geom1 ) ; )
+
+ CATCH_INVALID_GEOM_AND_NOT_IMPLEMENTED(
+ triangulate::ConstraintDelaunayTriangulation cdt;
+ triangulate::triangulate2DZ( *geom1, cdt );
+ TriangulatedSurface surf;
+ cdt.getTriangles( surf );
+ )
+
+ for ( geom2=testCollection.begin() ; geom2!=testCollection.end(); ++geom2 ) {
+ if ( geom2->is<Point>() && !geom2->isEmpty() ) {
+ CATCH_INVALID_GEOM_AND_NOT_IMPLEMENTED(
+ const Point& p = geom2->as<Point>() ;
+ ( void )algorithm::extrude( *geom1, p.x(), p.y(), p.z() ) ;
+ )
+ }
+
+ CATCH_INVALID_GEOM_AND_NOT_IMPLEMENTED( ( void )algorithm::distance3D( *geom1, *geom2 ) ; )
+ CATCH_INVALID_GEOM_AND_NOT_IMPLEMENTED( ( void )algorithm::distance( *geom1, *geom2 ) ; )
+ CATCH_INVALID_GEOM_AND_NOT_IMPLEMENTED( ( void )algorithm::intersection3D( *geom1, *geom2 ) ; )
+ CATCH_INVALID_GEOM_AND_NOT_IMPLEMENTED( ( void )algorithm::intersection( *geom1, *geom2 ) ; )
+ CATCH_INVALID_GEOM_AND_NOT_IMPLEMENTED( ( void )algorithm::intersects3D( *geom1, *geom2 ) ; )
+ CATCH_INVALID_GEOM_AND_NOT_IMPLEMENTED( ( void )algorithm::intersects( *geom1, *geom2 ) ; )
+ CATCH_INVALID_GEOM_AND_NOT_IMPLEMENTED( ( void )algorithm::difference3D( *geom1, *geom2 ) ; )
+ CATCH_INVALID_GEOM_AND_NOT_IMPLEMENTED( ( void )algorithm::difference( *geom1, *geom2 ) ; )
+ CATCH_INVALID_GEOM_AND_NOT_IMPLEMENTED( ( void )algorithm::union_( *geom1, *geom2 ) ; )
+ CATCH_INVALID_GEOM_AND_NOT_IMPLEMENTED( ( void )algorithm::union3D( *geom1, *geom2 ) ; )
+
+ if ( geom2->is<Polygon>() ) {
+ CATCH_INVALID_GEOM_AND_NOT_IMPLEMENTED( ( void )algorithm::minkowskiSum( *geom1, geom2->as<Polygon>() ) ; )
+ }
+ }
+
+ if ( progress || verbose ) {
+ std::cout << "performed " << calls << " function calls\n";
+ }
+ }
+
+ if ( !notImplemented.empty() ) {
+ std::cout << "Missing implementations\n";
+
+ for ( std::set< std::string >::const_iterator i=notImplemented.begin();
+ i!=notImplemented.end(); ++i ) {
+ std::cout << " " << *i << "\n" ;
+ }
+ }
+
+ boost::chrono::duration<double> elapsed = boost::chrono::system_clock::now() - start;
+
+ if ( verbose ) {
+ std::cout << "elapsed " << elapsed << "\n";
+ }
+
+ if ( numFailure ) {
+ std::cerr << "\n\n**** " << numFailure << " test failed\n";
+ }
+
+ return numFailure==0 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+/* Functions called from lwgeom_sfcgal.c and corresponding C++ api calls
+ *
+sfcgal_geometry_collection_add_geometry(ret_geom, g)
+ *GeometryCollection::addGeometry(geom)
+sfcgal_geometry_collection_create()
+ *GeometryCollection::GeometryCollection()
+sfcgal_geometry_collection_geometry_n(geom, i)
+ *GeometryCollection::geometryN(i)
+sfcgal_geometry_collection_num_geometries(geom)
+ *GeometryCollection::numGeometries()
+sfcgal_geometry_delete(converted)
+ *Geometry::~Geometry()
+sfcgal_geometry_is_3d(geom)
+ *Geometry::is3D()
+sfcgal_geometry_is_empty(geom)
+ *Geometry::isEmpty()
+sfcgal_linestring_add_point(line,
+ *LineString::addPoint()
+sfcgal_linestring_create()
+ *LineString::LineString()
+sfcgal_linestring_num_points(geom)
+ *LineString::numPoints()
+sfcgal_linestring_point_n(geom, i)
+ *LineString::pointN(i)
+sfcgal_multi_linestring_create()
+ *MultiLineString::MultiLineString()
+sfcgal_multi_point_create()
+ *MultiPoint::MultiPoint()
+sfcgal_multi_polygon_create()
+ *MultiPolygon::MultiPolygon()
+sfcgal_point_create()
+ *Point::Point()
+sfcgal_point_create_from_xy(point.x, point.y)
+ *Point::Point(x,y)
+sfcgal_point_create_from_xyz(point.x, point.y, point.z)
+ *Point::Point(x,y,z)
+sfcgal_point_x(pt)
+ *Point::x()
+sfcgal_point_y(pt)
+ *Point::y()
+sfcgal_point_z(pt)
+ *Point::z()
+sfcgal_polygon_add_interior_ring(ret_geom, ring)
+ *Polygon::addRing( ring )
+sfcgal_polygon_create()
+ *Polygon::Polygon()
+sfcgal_polygon_create_from_exterior_ring(exterior_ring)
+ *Polygon::Polygon(exterior_ring)
+sfcgal_polygon_exterior_ring(geom)
+ *Polygon::exteriorRing()
+sfcgal_polygon_interior_ring_n(geom, i)
+ *Polygon::interiorRingN(i)
+sfcgal_polygon_num_interior_rings(geom)
+ *Polygon::numInteriorRings()
+sfcgal_polyhedral_surface_add_polygon(ret_geom, poly)
+ *PolyhedralSurface::addPolygon(poly)
+sfcgal_polyhedral_surface_create()
+ *PolyhedralSurface::PolyhedralSurface()
+sfcgal_polyhedral_surface_num_polygons(geom)
+ *PolyhedralSurface::numPolygons()
+sfcgal_polyhedral_surface_polygon_n( geom, i )
+ *PolyhedralSurface::polygonN(i)
+sfcgal_solid_create_from_exterior_shell(shell)
+ *Solid::Solid(shell)
+sfcgal_solid_num_shells(geom)
+ *Solid::numShells()
+sfcgal_solid_shell_n(geom, i)
+ *Solid::shellN(i)
+sfcgal_triangle_create()
+ *Triangle::Triangle()
+sfcgal_triangle_set_vertex_from_xy (triangle, i, point.x, point.y)
+ *Triangle::vertex(i)
+ *Point(x,y)
+sfcgal_triangle_set_vertex_from_xyz(triangle, 0, point.x, point.y, point.z)
+ *Triangle::vertex(i)
+ *Point(x,y,z)
+sfcgal_triangle_vertex(geom, (i%3))
+ *Triangle::vertex(i) const
+sfcgal_triangulated_surface_add_triangle(ret_geom, triangle)
+ *TriangulatedSurface::addTriangle(triangle)
+sfcgal_triangulated_surface_create()
+ *TriangulatedSurface::TriangulatedSurface()
+sfcgal_triangulated_surface_num_triangles(geom)
+ *TriangulatedSurface::numTriangles()
+sfcgal_triangulated_surface_triangle_n(geom, i)
+ *TriangulatedSurface::triangleN(i)
+sfcgal_version()
+ *Version()
+sfcgal_geometry_area_3d(geom)
+ *algorithm::area3D(geom)
+sfcgal_geometry_area(geom)
+ *algorithm::area(geom)
+sfcgal_geometry_distance_3d(geom0, geom1)
+ *algorithm::distance3D(geom0, geom1)
+sfcgal_geometry_distance(geom0, geom1)
+ *algorithm::distance(geom0, geom1)
+sfcgal_geometry_extrude(geom, dx, dy, dz)
+ *algorithm::extrude(geom, dx, dy, dz)
+sfcgal_geometry_force_lhr(geom)
+ Geometry::clone(geom)
+ Geometry::accept(SFCGAL::transform::ForceOrderPoints)
+sfcgal_geometry_intersection_3d(geom0, geom1)
+ *algorithm::intersection3D(geom0, geo1)
+sfcgal_geometry_intersection(geom0, geom1)
+ *algorithm::intersection(geom0, geo1)
+sfcgal_geometry_intersects_3d(geom0, geom1)
+ *algorithm::intersects3D(geom0, geo1)
+sfcgal_geometry_intersects(geom0, geom1)
+ *algorithm::intersects(geom0, geo1)
+sfcgal_geometry_is_planar(geom)
+ *algorithm::hasPlane3D< SFCGAL::Kernel >(Polygon)
+sfcgal_geometry_minkowski_sum(geom0, geom1)
+ *algorithm::minkowskiSum(geom0, Polygon)
+sfcgal_geometry_orientation(geom)
+ *Polygon::isCounterClockWiseOriented(poly)
+sfcgal_geometry_straight_skeleton(geom)
+ *algorithm::straightSkeleton(geom)
+sfcgal_geometry_tesselate(geom)
+ *algorithm::tesselate(geom)
+sfcgal_geometry_triangulate_2dz(geom)
+ *triangulate::ConstraintDelaunayTriangulation::ConstraintDelaunayTriangulation()
+ *triangulate::triangulate2DZ( geom, ConstraintDelaunayTriangulation)
+ *TriangulatedSurface::TriangulatedSurface() -> surf
+ *triangulate::ConstraintDelaunayTriangulation::getTriangles( surf )
+sfcgal_prepared_geometry_create_from_geometry(geom,srid)
+ *PreparedGeometry::PreparedGeometry(geom, srid)
+sfcgal_prepared_geometry_delete( geom )
+ *PreparedGeometry::~PreparedGeometry()
+sfcgal_prepared_geometry_geometry(geom)
+ PreparedGeometry::geometry()
+sfcgal_prepared_geometry_srid(geom))
+ PreparedGeometry::SRID()
+
+*/
diff --git a/test/implementation_matrix.ods b/test/implementation_matrix.ods
new file mode 100644
index 0000000..05e364b
Binary files /dev/null and b/test/implementation_matrix.ods differ
diff --git a/test/regress/CMakeLists.txt b/test/regress/CMakeLists.txt
new file mode 100644
index 0000000..7b09b24
--- /dev/null
+++ b/test/regress/CMakeLists.txt
@@ -0,0 +1,11 @@
+#-- standalone test
+add_subdirectory( standalone )
+
+#-- test that needs parameters
+add_subdirectory( polygon_triangulator )
+add_subdirectory( convex_hull )
+
+
+
+
+
diff --git a/test/regress/convex_hull/CMakeLists.txt b/test/regress/convex_hull/CMakeLists.txt
new file mode 100644
index 0000000..b54fa50
--- /dev/null
+++ b/test/regress/convex_hull/CMakeLists.txt
@@ -0,0 +1,20 @@
+#-- polygon_triangulator test
+file( GLOB_RECURSE SFCGAL_REGRESS_CONVEX_HULL_TEST_SOURCES *.cpp )
+
+set( REGRESS_NAME test-regress-convex_hull )
+add_executable( ${REGRESS_NAME} ${SFCGAL_REGRESS_CONVEX_HULL_TEST_SOURCES} )
+
+target_link_libraries( ${REGRESS_NAME}
+ SFCGAL
+ ${Boost_LIBRARIES}
+ ${CGAL_LIBRARIES}
+)
+if( ${SFCGAL_WITH_MPFR} )
+ target_link_libraries( ${REGRESS_NAME} ${MPFR_LIBRARIES} )
+endif( ${SFCGAL_WITH_MPFR} )
+
+set_target_properties( ${REGRESS_NAME} PROPERTIES DEBUG_POSTFIX "d" )
+install( TARGETS ${REGRESS_NAME} DESTINATION bin )
+
+
+
diff --git a/test/regress/convex_hull/main.cpp b/test/regress/convex_hull/main.cpp
new file mode 100644
index 0000000..e0ff89d
--- /dev/null
+++ b/test/regress/convex_hull/main.cpp
@@ -0,0 +1,220 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <iostream>
+#include <fstream>
+
+#include <boost/program_options.hpp>
+#include <boost/algorithm/string.hpp>
+
+#include <SFCGAL/Exception.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/convexHull.h>
+
+#include <boost/chrono.hpp>
+
+#include <boost/filesystem.hpp>
+
+using namespace SFCGAL ;
+
+
+namespace po = boost::program_options ;
+
+
+/*
+ * Triangulate each polygon in an input file containing lines in the following format :
+ * <id> "|" ( <wkt polygon> | <wkt multipolygon> )
+ */
+int main( int argc, char* argv[] )
+{
+ /*
+ * declare options
+ */
+ po::options_description desc( "convex hull options : " );
+ desc.add_options()
+ ( "help", "produce help message" )
+ ( "progress", "display progress" )
+ ( "verbose", "verbose mode" )
+ ( "filename", po::value< std::string >(), "input filename (id|wkt_[multi]polygon on each line)" )
+ ;
+
+ po::variables_map vm;
+ po::store( po::parse_command_line( argc, argv, desc ), vm );
+ po::notify( vm );
+
+ if ( vm.count( "help" ) ) {
+ std::cout << desc << std::endl ;
+ return 0;
+ }
+
+ bool verbose = vm.count( "verbose" ) != 0 ;
+ bool progress = vm.count( "progress" ) != 0 ;
+
+ std::string filename ;
+
+ if ( vm.count( "filename" ) ) {
+ filename = vm["filename"].as< std::string >() ;
+ }
+ else {
+ std::cerr << "missing input file" << std::endl;
+ std::cout << desc << std::endl ;
+ return 1 ;
+ }
+
+ /*
+ * open file
+ */
+ std::ifstream ifs( filename.c_str() );
+
+ if ( ! ifs.good() ) {
+ std::cerr << "fail to open : " << filename << std::endl ;
+ return 1;
+ }
+
+ std::string tri_filename( filename+".convex.wkt" );
+ std::ofstream ofs_result( tri_filename.c_str() ) ;
+
+ if ( ! ofs_result.good() ) {
+ std::cerr << "fail to write : " << tri_filename << std::endl ;
+ return 1;
+ }
+
+ std::string error_filename( filename+".error.wkt" );
+ std::ofstream ofs_error( error_filename.c_str() ) ;
+
+ if ( ! ofs_error.good() ) {
+ std::cerr << "fail to write : " << error_filename << std::endl ;
+ return 1;
+ }
+
+
+ //boost::timer timer ;
+ boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now();
+
+ /*
+ * process file
+ */
+ int lineNumber = 0 , numFailed = 0 , numSuccess = 0 ;
+ std::string line ;
+
+ while ( std::getline( ifs, line ) ) {
+ lineNumber++ ;
+
+ boost::algorithm::trim( line );
+
+ if ( line.empty() ) {
+ continue ;
+ }
+
+ if ( verbose ) {
+ std::cout << "#" << line << std::endl;
+ std::cout.flush();
+ }
+
+
+ if ( progress && lineNumber % 1000 == 0 ) {
+ std::cout.width( 12 ) ;
+ boost::chrono::duration<double> elapsed = boost::chrono::system_clock::now() - start;
+ std::cout << std::left << lineNumber << "(" << elapsed << " s)"<< std::endl ;
+ }
+
+
+ std::vector< std::string > tokens ;
+ boost::algorithm::split( tokens, line, boost::is_any_of( "|" ) );
+
+ std::string const& wkt = tokens.back() ;
+ std::string id ;
+
+ if ( tokens.size() > 1 ) {
+ id = tokens.front() ;
+ }
+ else {
+ std::ostringstream oss;
+ oss << lineNumber ;
+ id = oss.str() ;
+ }
+
+ //std::cout << "process " << id << std::endl;
+
+ bool failed = true ;
+
+ std::auto_ptr< Geometry > hull, hull3D ;
+
+ try {
+ std::auto_ptr< Geometry > g;
+ g = io::readWkt( wkt ) ;
+ hull = algorithm::convexHull( *g ) ;
+ hull3D = algorithm::convexHull3D( *g ) ;
+ failed = false ;
+ }
+ catch ( Exception& e ) {
+ std::cerr << "[Exception]" << id << "|" << e.what() << "|" << wkt << std::endl ;
+ }
+ catch ( std::exception& e ) {
+ std::cerr << "[std::exception]" << id << "|" << e.what() << "|" << wkt << std::endl ;
+ }
+ catch ( ... ) {
+ std::cerr << "[...]" << id << "|" << wkt << std::endl ;
+ }
+
+ if ( failed ) {
+ numFailed++ ;
+ ofs_error << line << std::endl ;
+ }
+ else {
+ numSuccess++ ;
+ }
+
+ //output triangulated surface
+ ofs_result << id << "|" << failed << "|" << hull->asText( 5 ) << std::endl;
+ }//end for each line
+
+
+ ofs_error.close();
+ ofs_result.close();
+
+
+ boost::chrono::duration<double> elapsed = boost::chrono::system_clock::now() - start;
+ std::cout << filename << " complete (" << elapsed << " s)---" << std::endl;
+ std::cout << numFailed << " failed /" << ( numFailed + numSuccess ) << std::endl ;
+
+ if ( numFailed == 0 ) {
+ //delete empty error file
+ boost::filesystem::remove( error_filename );
+ return EXIT_SUCCESS ;
+ }
+ else {
+ return EXIT_FAILURE ;
+ }
+}
+
diff --git a/test/regress/polygon_triangulator/CMakeLists.txt b/test/regress/polygon_triangulator/CMakeLists.txt
new file mode 100644
index 0000000..38e4fba
--- /dev/null
+++ b/test/regress/polygon_triangulator/CMakeLists.txt
@@ -0,0 +1,20 @@
+#-- polygon_triangulator test
+file( GLOB_RECURSE SFCGAL_REGRESS_POLYGON_TRIANGULATOR_TEST_SOURCES *.cpp )
+
+set( REGRESS_NAME test-regress-polygon_triangulator )
+add_executable( ${REGRESS_NAME} ${SFCGAL_REGRESS_POLYGON_TRIANGULATOR_TEST_SOURCES} )
+
+target_link_libraries( ${REGRESS_NAME}
+ SFCGAL
+ ${Boost_LIBRARIES}
+ ${CGAL_LIBRARIES}
+)
+if( ${SFCGAL_WITH_MPFR} )
+ target_link_libraries( ${REGRESS_NAME} ${MPFR_LIBRARIES} )
+endif( ${SFCGAL_WITH_MPFR} )
+
+set_target_properties( ${REGRESS_NAME} PROPERTIES DEBUG_POSTFIX "d" )
+install( TARGETS ${REGRESS_NAME} DESTINATION bin )
+
+
+
diff --git a/test/regress/polygon_triangulator/main.cpp b/test/regress/polygon_triangulator/main.cpp
new file mode 100644
index 0000000..425ee12
--- /dev/null
+++ b/test/regress/polygon_triangulator/main.cpp
@@ -0,0 +1,268 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <iostream>
+#include <fstream>
+
+#include <boost/program_options.hpp>
+#include <boost/algorithm/string.hpp>
+
+#include <SFCGAL/Exception.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/io/vtk.h>
+#include <SFCGAL/triangulate/triangulatePolygon.h>
+#include <SFCGAL/algorithm/area.h>
+#include <SFCGAL/algorithm/force2D.h>
+#include <SFCGAL/algorithm/orientation.h>
+
+#include <boost/chrono.hpp>
+
+#include <boost/filesystem.hpp>
+
+using namespace SFCGAL ;
+
+
+namespace po = boost::program_options ;
+
+
+
+
+
+
+/*
+ * Triangulate each polygon in an input file containing lines in the following format :
+ * <id> "|" ( <wkt polygon> | <wkt multipolygon> )
+ */
+int main( int argc, char* argv[] )
+{
+ /*
+ * declare options
+ */
+ po::options_description desc( "polygon triangulator options : " );
+ desc.add_options()
+ ( "help", "produce help message" )
+ ( "progress", "display progress" )
+ ( "verbose", "verbose mode" )
+ ( "force2d","force 2d polygon" )
+ ( "line", po::value< int >(), "line to test" )
+ ( "filename", po::value< std::string >(), "input filename (id|wkt_[multi]polygon on each line)" )
+ ;
+
+ po::variables_map vm;
+ po::store( po::parse_command_line( argc, argv, desc ), vm );
+ po::notify( vm );
+
+ if ( vm.count( "help" ) ) {
+ std::cout << desc << std::endl ;
+ return 0;
+ }
+
+ bool verbose = vm.count( "verbose" ) != 0 ;
+ bool progress = vm.count( "progress" ) != 0 ;
+ bool force2d = vm.count( "force2d" ) != 0 ;
+
+ std::string filename ;
+
+ if ( vm.count( "filename" ) ) {
+ filename = vm["filename"].as< std::string >() ;
+ }
+ else {
+ std::cerr << "missing input file" << std::endl;
+ std::cout << desc << std::endl ;
+ return 1 ;
+ }
+
+ int oneLine = -1;
+
+ if ( vm.count( "line" ) ) {
+ oneLine = vm["line"].as< int >();
+ }
+
+ /*
+ * open file
+ */
+ std::ifstream ifs( filename.c_str() );
+
+ if ( ! ifs.good() ) {
+ std::cerr << "fail to open : " << filename << std::endl ;
+ return 1;
+ }
+
+ const std::string tri_filename( filename+".tri.wkt" );
+
+ std::ofstream tri_ofs( tri_filename.c_str() ) ;
+
+ if ( ! tri_ofs.good() ) {
+ std::cerr << "fail to write : " << tri_filename << std::endl ;
+ return 1;
+ }
+
+ const std::string error_filename( filename+".error.wkt" );
+
+ std::ofstream ofs_error( error_filename.c_str() ) ;
+
+ if ( ! ofs_error.good() ) {
+ std::cerr << "fail to write : " << error_filename << std::endl ;
+ return 1;
+ }
+
+
+ //boost::timer timer ;
+ boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now();
+
+ std::vector< std::string > invalidGeom;
+ std::vector< std::string > inapropriateGeom;
+ /*
+ * process file
+ */
+ int lineNumber = 0 , numFailed = 0 , numSuccess = 0 ;
+ std::string line ;
+
+ while ( std::getline( ifs, line ) ) {
+ lineNumber++ ;
+
+ if ( -1 != oneLine && oneLine != lineNumber ) {
+ continue;
+ }
+
+
+ boost::algorithm::trim( line );
+
+ if ( line.empty() ) {
+ continue ;
+ }
+
+ if ( verbose ) {
+ std::cout << "#" << line << std::endl;
+ std::cout.flush();
+ }
+
+
+ if ( progress && lineNumber % 1000 == 0 ) {
+ std::cout.width( 12 ) ;
+ boost::chrono::duration<double> elapsed = boost::chrono::system_clock::now() - start;
+ std::cout << std::left << lineNumber << "(" << elapsed << " s)"<< std::endl ;
+ }
+
+
+ std::vector< std::string > tokens ;
+ boost::algorithm::split( tokens, line, boost::is_any_of( "|" ) );
+
+ std::string const& wkt = tokens.back() ;
+ std::string id ;
+
+ if ( tokens.size() > 1 ) {
+ id = tokens.front() ;
+ }
+ else {
+ std::ostringstream oss;
+ oss << lineNumber ;
+ id = oss.str() ;
+ }
+
+ //std::cout << "process " << id << std::endl;
+
+ bool failed = true;
+ TriangulatedSurface triangulatedSurface ;
+
+ try {
+ std::auto_ptr< Geometry > g( io::readWkt( wkt ) );
+
+ //io::vtk( *g, (boost::format("/tmp/polygon_%s.vtk") % id ).str() );
+
+ if ( force2d ) {
+ algorithm::force2D( *g ) ;
+ }
+
+ triangulate::triangulatePolygon3D( *g, triangulatedSurface ) ;
+
+ //check area
+ double areaPolygons = algorithm::area3D( *g ) ;
+ double areaTriangles = algorithm::area3D( triangulatedSurface );
+
+ double ratio = fabs( areaPolygons - areaTriangles ) / std::max( areaPolygons, areaTriangles );
+
+ if ( ratio > 0.1 ) {
+ std::cerr << filename << ":" << lineNumber << " error:" << id << "|" << "area(polygon) != area(tin) ( " << areaPolygons << " !=" << areaTriangles << ")" << "|" << g->asText() << "|" << triangulatedSurface.asText() << std::endl ;
+ }
+
+ numSuccess++ ;
+ failed = false;
+ }
+ catch ( InappropriateGeometryException& e ) {
+ inapropriateGeom.push_back( id );
+ numFailed++ ;
+ }
+ catch ( GeometryInvalidityException& e ) {
+ invalidGeom.push_back( id );
+ numFailed++ ;
+ }
+ catch ( std::exception& e ) {
+ BOOST_ASSERT_MSG( false, ( boost::format( "%s:%d: unhandled std::exception: %s" ) % filename % lineNumber % e.what() ).str().c_str() );
+ }
+ catch ( ... ) {
+ BOOST_ASSERT_MSG( false, ( boost::format( "%s:%d: unknown exception" ) % filename % lineNumber ).str().c_str() );
+ }
+
+ //output triangulated surface
+ tri_ofs << id << "|" << failed << "|" << triangulatedSurface.asText( 5 ) << std::endl;
+ }//end for each line
+
+
+ ofs_error.close();
+ tri_ofs.close();
+
+
+ boost::chrono::duration<double> elapsed = boost::chrono::system_clock::now() - start;
+
+ for ( size_t i=0; i!=invalidGeom.size(); ++i ) {
+ std::cout << " " << invalidGeom[i] << " is invalid\n";
+ }
+
+ for ( size_t i=0; i!=inapropriateGeom.size(); ++i ) {
+ std::cout << " " << inapropriateGeom[i] << " is inapropriate for triangulation\n";
+ }
+
+ std::cout << filename << " complete (" << elapsed << " s)---" << std::endl;
+ std::cout << numFailed << " failed /" << ( numFailed + numSuccess ) << std::endl ;
+
+ if ( numFailed == 0 ) {
+ //delete empty error file
+ boost::filesystem::remove( error_filename );
+ return EXIT_SUCCESS ;
+ }
+ else {
+ return EXIT_FAILURE ;
+ }
+}
+
diff --git a/test/regress/standalone/CMakeLists.txt b/test/regress/standalone/CMakeLists.txt
new file mode 100644
index 0000000..2b0df3c
--- /dev/null
+++ b/test/regress/standalone/CMakeLists.txt
@@ -0,0 +1,23 @@
+#-- standalone test
+file( GLOB_RECURSE SFCGAL_REGRESS_STANDALONE_TEST_SOURCES *.cpp )
+add_executable( standalone-regress-test-SFCGAL ${SFCGAL_REGRESS_STANDALONE_TEST_SOURCES} )
+
+target_link_libraries( standalone-regress-test-SFCGAL
+ SFCGAL
+ ${Boost_LIBRARIES}
+ ${CGAL_LIBRARIES}
+)
+if( ${SFCGAL_WITH_MPFR} )
+ target_link_libraries( standalone-regress-test-SFCGAL ${MPFR_LIBRARIES} )
+endif( ${SFCGAL_WITH_MPFR} )
+
+set_target_properties( standalone-regress-test-SFCGAL PROPERTIES DEBUG_POSTFIX "d" )
+install( TARGETS standalone-regress-test-SFCGAL DESTINATION bin )
+
+if (CMAKE_BUILD_TYPE STREQUAL "Debug" )
+ add_test( standalone-regress-testd ${CMAKE_CURRENT_BINARY_DIR}/standalone-regress-test-SFCGALd )
+else()
+ add_test( standalone-regress-test ${CMAKE_CURRENT_BINARY_DIR}/standalone-regress-test-SFCGAL )
+endif()
+
+
diff --git a/test/regress/standalone/SFCGAL/ASCTest.cpp b/test/regress/standalone/SFCGAL/ASCTest.cpp
new file mode 100644
index 0000000..49cd02d
--- /dev/null
+++ b/test/regress/standalone/SFCGAL/ASCTest.cpp
@@ -0,0 +1,102 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <fstream>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/asc.h>
+
+#include "../../../test_config.h"
+
+#include <boost/test/unit_test.hpp>
+using namespace boost::unit_test ;
+
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_ASCTest )
+
+BOOST_AUTO_TEST_CASE( testReadExample )
+{
+ std::string filename( SFCGAL_TEST_DIRECTORY );
+ filename += "/data/example.asc" ;
+
+ std::ifstream ifs( filename.c_str() );
+ BOOST_REQUIRE( ifs.good() ) ;
+ std::auto_ptr< Grid > grid( io::readASC( ifs ) ) ;
+ BOOST_CHECK_EQUAL( grid->ncols(), 4U );
+ BOOST_CHECK_EQUAL( grid->nrows(), 6U );
+
+ BOOST_CHECK_EQUAL( grid->dx(), 50.0 );
+ BOOST_CHECK_EQUAL( grid->dy(), 50.0 );
+
+ Envelope limits = grid->limits();
+ BOOST_CHECK_EQUAL( limits.xMin(), 0.0 );
+ BOOST_CHECK_EQUAL( limits.xMax(), 200.0 );
+ BOOST_CHECK_EQUAL( limits.yMin(), 0.0 );
+ BOOST_CHECK_EQUAL( limits.yMax(), 300.0 );
+
+ // first line
+ BOOST_CHECK( isNaN( grid->z( 0,0 ) ) );
+ BOOST_CHECK( isNaN( grid->z( 0,1 ) ) );
+ BOOST_CHECK_EQUAL( grid->z( 0,2 ), 5.0 );
+ BOOST_CHECK_EQUAL( grid->z( 0,3 ), 2.0 );
+
+ // last line
+ BOOST_CHECK_EQUAL( grid->z( 5,0 ), 13.0 );
+ BOOST_CHECK_EQUAL( grid->z( 5,1 ), 5.0 );
+ BOOST_CHECK_EQUAL( grid->z( 5,2 ), 1.0 );
+ BOOST_CHECK( isNaN( grid->z( 5,3 ) ) );
+
+ // pixel is area convention
+ BOOST_CHECK_EQUAL( grid->pixelConvention(), PIXEL_IS_AREA ) ;
+ Point a00 = grid->point( 0,0 );
+ BOOST_CHECK_EQUAL( a00.x(), 25.0 );
+ BOOST_CHECK_EQUAL( a00.y(), 275.0 );
+
+ {
+ grid->setPixelConvention( PIXEL_IS_AREA );
+ std::auto_ptr< TriangulatedSurface > triangulatedSurface( grid->toTrianguledSurface() ) ;
+ std::string expected( "TIN M(((75.00000 225.00000 20.00000,125.00000 225.00000 100.00000,125.00000 275.00000 5.00000,75.00000 225.00000 20.00000)),((125.00000 225.00000 100.00000,175.00000 225.00000 36.00000,175.00000 275.00000 2.00000,125.00000 225.00000 100.00000)),((125.00000 225.00000 100.00000,175.00000 275.00000 2.00000,125.00000 275.00000 5.00000,125.00000 225.00000 100.00000)),((25.00000 175.00000 3.00000,75.00000 175.00000 8.00000,75.00000 225.00000 20.00000,25.00000 175 [...]
+ BOOST_CHECK_EQUAL( triangulatedSurface->asText( 5 ), expected );
+ }
+ {
+ grid->setPixelConvention( PIXEL_IS_POINT );
+ std::auto_ptr< TriangulatedSurface > triangulatedSurface( grid->toTrianguledSurface() ) ;
+ std::string expected( "TIN M(((66.66667 240.00000 20.00000,133.33333 240.00000 100.00000,133.33333 300.00000 5.00000,66.66667 240.00000 20.00000)),((133.33333 240.00000 100.00000,200.00000 240.00000 36.00000,200.00000 300.00000 2.00000,133.33333 240.00000 100.00000)),((133.33333 240.00000 100.00000,200.00000 300.00000 2.00000,133.33333 300.00000 5.00000,133.33333 240.00000 100.00000)),((0.00000 180.00000 3.00000,66.66667 180.00000 8.00000,66.66667 240.00000 20.00000,0.00000 180.0 [...]
+ BOOST_CHECK_EQUAL( triangulatedSurface->asText( 5 ), expected );
+ }
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/regress/standalone/SFCGAL/AreaTest.cpp b/test/regress/standalone/SFCGAL/AreaTest.cpp
new file mode 100644
index 0000000..3753ad3
--- /dev/null
+++ b/test/regress/standalone/SFCGAL/AreaTest.cpp
@@ -0,0 +1,115 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include "../../../test_config.h"
+
+#include <fstream>
+#include <boost/format.hpp>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+
+#include <SFCGAL/algorithm/area.h>
+#include <SFCGAL/Transform.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+
+class RotateCoordinate : public Transform {
+public:
+
+ virtual void transform( Point& p ) {
+ BOOST_ASSERT( ! p.isEmpty() );
+ p = Point(
+ p.is3D() ? p.z() : 0.0,
+ p.x(),
+ p.y()
+ );
+ }
+
+};
+
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_AreaTest )
+
+/**
+ * Triangulate polygon and make some checks
+ * @ŧodo Check inPolygon.area3D() == outPolygon.area3D();
+ */
+BOOST_AUTO_TEST_CASE( testComputeArea )
+{
+ std::string filename( SFCGAL_TEST_DIRECTORY );
+ filename += "/data/AreaTest.txt" ;
+
+ std::ifstream ifs( filename.c_str() );
+ BOOST_REQUIRE( ifs.good() ) ;
+
+ std::string line;
+
+ while ( std::getline( ifs, line ) ) {
+ if ( line[0] == '#' || line.empty() ) {
+ continue ;
+ }
+
+ std::istringstream iss( line );
+
+ std::string id ;
+ iss >> id ;
+
+ double expectedArea ;
+ iss >> expectedArea ;
+
+ std::string inputWkt ;
+ std::getline( iss, inputWkt ) ;
+
+ std::auto_ptr< Geometry > g( io::readWkt( inputWkt ) );
+ double area = algorithm::area3D( *g ) ;
+ BOOST_TEST_MESSAGE( boost::format( "area( '%1%' ) = %2%" ) % inputWkt % area );
+
+ RotateCoordinate rotateCoordinate ;
+ g->accept( rotateCoordinate );
+ double areaRotate = algorithm::area3D( *g ) ;
+
+ //check area == areaRotate
+ BOOST_CHECK_CLOSE( area, areaRotate, 0.5 );
+ //check area == expectedArea
+ BOOST_CHECK_CLOSE( area, expectedArea, 0.5 );
+ }
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/regress/standalone/SFCGAL/ConstraintDelaunayTriangulationTest.cpp b/test/regress/standalone/SFCGAL/ConstraintDelaunayTriangulationTest.cpp
new file mode 100644
index 0000000..ee91a76
--- /dev/null
+++ b/test/regress/standalone/SFCGAL/ConstraintDelaunayTriangulationTest.cpp
@@ -0,0 +1,86 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <fstream>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/detail/triangulate/ConstraintDelaunayTriangulation.h>
+#include <SFCGAL/algorithm/area.h>
+
+
+#include "../../../test_config.h"
+
+#include <boost/test/unit_test.hpp>
+using namespace boost::unit_test ;
+
+using namespace SFCGAL ;
+using namespace SFCGAL::triangulate ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_ConstraintDelaunayTriangulationTest )
+
+BOOST_AUTO_TEST_CASE( testTriangulateRGC )
+{
+ ConstraintDelaunayTriangulation triangulation ;
+
+ /*
+ * read points from file
+ */
+ std::string filename( SFCGAL_TEST_DIRECTORY );
+ filename += "/data/rgc-france-ign.xyz" ;
+ std::ifstream ifs( filename.c_str() );
+ BOOST_REQUIRE( ifs.good() ) ;
+
+ double x,y,z ;
+
+ while ( ifs >> x >> y >> z ) {
+ triangulation.addVertex( Coordinate( x,y,z ) );
+ }
+
+ ifs.close();
+
+ //std::string wkt = triangulation.getTriangulatedSurface()->asText(5.0) ;
+ //std::cerr << "INSERT INTO draw (geometry) VALUES ( '" << "MULTIPOLYGON" << wkt.substr(3) << "'::geometry );" << std::endl;
+
+ BOOST_CHECK_EQUAL( triangulation.numVertices(), 36566U );
+ BOOST_CHECK_EQUAL( triangulation.numTriangles(), 73114U );
+
+ std::auto_ptr< TriangulatedSurface > triangulatedSurface = triangulation.getTriangulatedSurface() ;
+ BOOST_CHECK_EQUAL( triangulatedSurface->numTriangles(), 73114U );
+ BOOST_CHECK_CLOSE( algorithm::area( *triangulatedSurface ), 818056610000.0, 0.1 );
+}
+
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/regress/standalone/SFCGAL/DistanceTest.cpp b/test/regress/standalone/SFCGAL/DistanceTest.cpp
new file mode 100644
index 0000000..fea4e6c
--- /dev/null
+++ b/test/regress/standalone/SFCGAL/DistanceTest.cpp
@@ -0,0 +1,137 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include "../../../test_config.h"
+
+#include <fstream>
+#include <boost/format.hpp>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+//#include <SFCGAL/io/vtk.h>
+
+#include <SFCGAL/detail/tools/Log.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_DistanceTest )
+
+/**
+ * Compute the area for given geometries
+ */
+BOOST_AUTO_TEST_CASE( testFileDistanceTest )
+{
+ logger().setLogLevel( Logger::Debug );
+
+ std::string filename( SFCGAL_TEST_DIRECTORY );
+ filename += "/data/DistanceTest.txt" ;
+
+ std::ifstream ifs( filename.c_str() );
+ BOOST_REQUIRE( ifs.good() ) ;
+
+ int argc = framework::master_test_suite().argc;
+ char** argv = framework::master_test_suite().argv;
+
+ // look for options
+ int test_one_line = -1;
+
+ for ( int i = 0; i < argc; ++i ) {
+ std::string argi( argv[i] );
+
+ if ( argi == "--line" ) {
+ // only test one line
+ if ( argc > i+1 ) {
+ sscanf( argv[i+1], "%d", &test_one_line );
+ ++i;
+ continue;
+ }
+ }
+ }
+
+ std::string line;
+ int lineNo = 0;
+
+ while ( std::getline( ifs, line ) ) {
+ ++lineNo;
+
+ if ( line[0] == '#' || line.empty() ) {
+ continue ;
+ }
+
+ if ( -1 != test_one_line && lineNo != test_one_line ) {
+ continue;
+ }
+
+ BOOST_TEST_MESSAGE( ( boost::format( "%s:%d" ) % filename % lineNo ).str() );
+
+ std::istringstream iss( line );
+
+ std::string distanceDimension ;
+ std::string wktGA, wktGB ;
+ double expectedDistance ;
+
+ std::getline( iss, distanceDimension, '|' ) ;
+ std::getline( iss, wktGA, '|' ) ;
+ std::getline( iss, wktGB, '|' ) ;
+ iss >> expectedDistance ;
+
+ std::auto_ptr< Geometry > gA( io::readWkt( wktGA ) );
+ std::auto_ptr< Geometry > gB( io::readWkt( wktGB ) );
+
+ //if (43!=lineNo ) continue;
+ //if (43==lineNo )
+ //{
+ // io::vtk(gA->as<Polygon>(), "/tmp/gA.vtk");
+ // io::vtk(gB->as<MultiPolygon>(), "/tmp/gB.vtk");
+ //}
+
+
+ if ( distanceDimension == "2" ) {
+ BOOST_CHECK_CLOSE( gA->distance( *gB ), expectedDistance, 1e-13 );
+ }
+ else if ( distanceDimension == "3" ) {
+ BOOST_CHECK_CLOSE( gA->distance3D( *gB ), expectedDistance, 1e-13 );
+ }
+ else {
+ BOOST_CHECK( false );
+ }
+ }
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/regress/standalone/SFCGAL/IntersectsTest.cpp b/test/regress/standalone/SFCGAL/IntersectsTest.cpp
new file mode 100644
index 0000000..68b2b0c
--- /dev/null
+++ b/test/regress/standalone/SFCGAL/IntersectsTest.cpp
@@ -0,0 +1,113 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <fstream>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/intersects.h>
+
+#include "../../../test_config.h"
+
+#include <boost/test/unit_test.hpp>
+#include <boost/format.hpp>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_IntersectsTest )
+
+//
+// Load an obj
+// Build a polyhedral surface
+// Test intersection with some other objects
+
+// FIXME removed wavefront obj loader, transform to wkt
+//BOOST_AUTO_TEST_CASE( testIntersectsTeapot )
+//{
+// std::string filename( SFCGAL_TEST_DIRECTORY );
+// filename += "/regress/data/teapot.obj" ;
+//
+// io::WaveFrontObj obj;
+// obj.load( filename );
+//
+// //check points defined in all faces
+// PolyhedralSurface surf;
+// for ( size_t i = 0; i < obj.numFaces(); i++ ){
+// LineString ext_ring;
+// const io::WaveFrontFace & face = obj.faceN(i);
+// for ( size_t j = 0; j < face.size(); j++ ) {
+// ext_ring.addPoint( obj.vertexN( face[j].v ) );
+// }
+// // close the polygon
+// ext_ring.addPoint( obj.vertexN( face[0].v ) );
+// surf.addPolygon( Polygon(ext_ring) );
+// }
+//
+// Triangle tri1( Point(3.0, 1.8, 0.0), Point(-2.99, 1.8, -0.081), Point(-2.99, 1.8, 0.081) );
+// Triangle tri2( Point(3.0, 1.8, 5.0), Point(-2.99, 1.8, 5.081), Point(-2.99, 1.8, 5.081) );
+//
+// bool intersects1 = algorithm::intersects3D( tri1, surf );
+// bool intersects2 = algorithm::intersects3D( tri2, surf );
+// BOOST_TEST_MESSAGE( boost::format("triangle1 intersects the teapot: %1%") % (intersects1 ? "YES" : "NO") );
+// BOOST_CHECK_EQUAL( intersects1, true );
+// BOOST_TEST_MESSAGE( boost::format("triangle2 intersects the teapot: %1%") % (intersects2 ? "YES" : "NO") );
+// BOOST_CHECK_EQUAL( intersects2, false );
+//}
+
+
+//
+// Test limit case
+BOOST_AUTO_TEST_CASE( testLimitsIntersects )
+{
+ std::string filename( SFCGAL_TEST_DIRECTORY );
+ filename += "/data/countries.wkt" ;
+
+ std::ifstream ifs( filename.c_str() );
+ BOOST_REQUIRE( ifs.good() ) ;
+
+ std::string wkt1, wkt2;
+ std::getline( ifs, wkt1 );
+ std::getline( ifs, wkt2 );
+
+ std::auto_ptr< Geometry > g1( io::readWkt( wkt1 ) );
+ std::auto_ptr< Geometry > g2( io::readWkt( wkt2 ) );
+
+ // check that a call to intersects() does not throw
+ bool throws = false;
+ algorithm::intersects( *g1, *g2 );
+ BOOST_CHECK_EQUAL( throws, false );
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/regress/standalone/SFCGAL/StraightSkeletonTest.cpp b/test/regress/standalone/SFCGAL/StraightSkeletonTest.cpp
new file mode 100644
index 0000000..ae3d622
--- /dev/null
+++ b/test/regress/standalone/SFCGAL/StraightSkeletonTest.cpp
@@ -0,0 +1,79 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <fstream>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/straightSkeleton.h>
+
+#include "../../../test_config.h"
+
+#include <boost/test/unit_test.hpp>
+using namespace boost::unit_test ;
+
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_StraightSkeletonTest )
+
+BOOST_AUTO_TEST_CASE( testStraightSkeletonTest )
+{
+ std::string filename( SFCGAL_TEST_DIRECTORY );
+ filename += "/data/StraightSkeletonTest.txt" ;
+
+ std::ifstream ifs( filename.c_str() );
+ BOOST_REQUIRE( ifs.good() ) ;
+
+ std::string line;
+
+ while ( std::getline( ifs, line ) ) {
+ if ( line[0] == '#' || line.empty() ) {
+ continue ;
+ }
+
+ std::istringstream iss( line );
+ std::string inputWkt ;
+ std::string outputWkt ;
+
+ BOOST_CHECK( std::getline( iss, inputWkt, '|' ) );
+ BOOST_CHECK( std::getline( iss, outputWkt, '|' ) );
+
+ std::auto_ptr< Geometry > g( io::readWkt( inputWkt ) );
+ std::auto_ptr< MultiLineString > result = algorithm::straightSkeleton( *g ) ;
+ BOOST_CHECK_EQUAL( result->asText( 6 ), outputWkt );
+ }
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/regress/standalone/SFCGAL/TriangulatePolygonTest.cpp b/test/regress/standalone/SFCGAL/TriangulatePolygonTest.cpp
new file mode 100644
index 0000000..51c5a4f
--- /dev/null
+++ b/test/regress/standalone/SFCGAL/TriangulatePolygonTest.cpp
@@ -0,0 +1,127 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "../../../test_config.h"
+
+#include <fstream>
+#include <boost/format.hpp>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/detail/tools/Log.h>
+
+#include <SFCGAL/triangulate/triangulatePolygon.h>
+#include <SFCGAL/algorithm/area.h>
+
+#include <boost/test/unit_test.hpp>
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_TriangulatePolygonTest )
+
+/**
+ * Triangulate polygon and make some checks
+ * @ŧodo Check inPolygon.area3D() == outPolygon.area3D();
+ */
+BOOST_AUTO_TEST_CASE( testTriangulatePolygon )
+{
+ //logger().setLogLevel( Logger::Debug );
+
+ std::string filename( SFCGAL_TEST_DIRECTORY );
+ filename += "/data/TriangulatePolygonTest.txt" ;
+
+ std::ifstream ifs( filename.c_str() );
+ BOOST_REQUIRE( ifs.good() ) ;
+
+ int numLine = 0 ;
+ std::string line;
+
+ while ( std::getline( ifs, line ) ) {
+ numLine++ ;
+
+ if ( line[0] == '#' || line.empty() ) {
+ continue ;
+ }
+
+ BOOST_TEST_MESSAGE( boost::format( "[line#%s]%s" ) % numLine % line );
+
+ std::istringstream iss( line );
+ bool shouldThrowException ;
+ iss >> shouldThrowException ;
+
+ std::string inputWkt ;
+ std::getline( iss, inputWkt ) ;
+
+ /*
+ * parse wkt
+ */
+ std::auto_ptr< Geometry > g( io::readWkt( inputWkt ) );
+
+ /*
+ * check polygon
+ */
+ BOOST_CHECK( g->is< Polygon >() || g->is< MultiPolygon >() );
+
+ /*
+ * triangulate polygon
+ */
+ TriangulatedSurface triangulatedSurface ;
+
+ if ( shouldThrowException ) {
+ BOOST_CHECK_THROW( triangulate::triangulatePolygon3D( *g, triangulatedSurface ), Exception );
+ continue ;
+ }
+
+ BOOST_CHECK_NO_THROW( triangulate::triangulatePolygon3D( *g, triangulatedSurface ) ) ;
+
+ BOOST_TEST_MESSAGE( boost::format( "#%1% triangle(s)" ) % triangulatedSurface.numGeometries() );
+
+ /*
+ * make some checks
+ */
+ if ( ! g->isEmpty() ) {
+ BOOST_CHECK( ! triangulatedSurface.isEmpty() );
+ }
+
+ if ( g->is3D() ) {
+ BOOST_CHECK( triangulatedSurface.is3D() );
+ }
+
+ //check area
+ BOOST_CHECK_CLOSE( algorithm::area3D( *g ), algorithm::area3D( triangulatedSurface ), 0.5 );
+ }
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/regress/standalone/SFCGAL/WaveFrontObjTest.cpp b/test/regress/standalone/SFCGAL/WaveFrontObjTest.cpp
new file mode 100644
index 0000000..fc2d156
--- /dev/null
+++ b/test/regress/standalone/SFCGAL/WaveFrontObjTest.cpp
@@ -0,0 +1,71 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+#include <fstream>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+//#include <SFCGAL/io/WaveFrontObj.h>
+
+#include "../../../test_config.h"
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_io_WaveFrontObjTest )
+
+// FIXME removed wavefront obj loader, transform to wkt
+//BOOST_AUTO_TEST_CASE( testTeaPot )
+//{
+// std::string filename( SFCGAL_TEST_DIRECTORY );
+// filename += "/regress/data/teapot.obj" ;
+//
+// io::WaveFrontObj obj;
+// obj.load( filename );
+//
+// BOOST_CHECK_EQUAL( obj.numVertices(), 3644U );
+// BOOST_CHECK_EQUAL( obj.numFaces(), 6320U );
+//
+// //check points defined in all faces
+// for ( size_t i = 0; i < obj.numFaces(); i++ ){
+// const io::WaveFrontFace & face = obj.faceN(i);
+// for ( size_t j = 0; j < face.size(); j++ ){
+// BOOST_CHECK_GE( face[j].v, 0 );
+// BOOST_CHECK_LT( face[j].v, (int)obj.numVertices() );
+// }
+// }
+//}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/regress/standalone/SFCGAL/WktTest.cpp b/test/regress/standalone/SFCGAL/WktTest.cpp
new file mode 100644
index 0000000..2cfdaff
--- /dev/null
+++ b/test/regress/standalone/SFCGAL/WktTest.cpp
@@ -0,0 +1,74 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <fstream>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+
+#include "../../../test_config.h"
+
+#include <boost/test/unit_test.hpp>
+using namespace boost::unit_test ;
+
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_WktTest )
+
+BOOST_AUTO_TEST_CASE( testReadWriter )
+{
+ std::string filename( SFCGAL_TEST_DIRECTORY );
+ filename += "/data/WktTest.txt" ;
+
+ std::ifstream ifs( filename.c_str() );
+ BOOST_REQUIRE( ifs.good() ) ;
+
+ std::string inputWkt;
+
+ while ( std::getline( ifs, inputWkt ) ) {
+ if ( inputWkt[0] == '#' || inputWkt.empty() ) {
+ continue ;
+ }
+
+ /*
+ * parse wkt and check symmetry
+ */
+ std::auto_ptr< Geometry > g( io::readWkt( inputWkt ) );
+ std::string outputWkt = g->asText( 1 );
+ BOOST_CHECK_EQUAL( inputWkt, outputWkt );
+ }
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/regress/standalone/TestModule.cpp b/test/regress/standalone/TestModule.cpp
new file mode 100644
index 0000000..25e3fe1
--- /dev/null
+++ b/test/regress/standalone/TestModule.cpp
@@ -0,0 +1,29 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#define BOOST_TEST_MODULE RegressTestSFCGAL
+
+#include <boost/test/unit_test.hpp>
+using namespace boost::unit_test ;
+
+
+
+
+
+
diff --git a/test/test_config.h.cmake b/test/test_config.h.cmake
new file mode 100644
index 0000000..063475a
--- /dev/null
+++ b/test/test_config.h.cmake
@@ -0,0 +1,6 @@
+#ifndef _TEST_CONFIG_H_
+#define _TEST_CONFIG_H_
+
+#cmakedefine SFCGAL_TEST_DIRECTORY "@SFCGAL_TEST_DIRECTORY@"
+
+#endif
diff --git a/test/unit/CGAL/AffineTransform3Test.cpp b/test/unit/CGAL/AffineTransform3Test.cpp
new file mode 100644
index 0000000..56f6c4c
--- /dev/null
+++ b/test/unit/CGAL/AffineTransform3Test.cpp
@@ -0,0 +1,87 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <CGAL/Cartesian.h>
+#include <CGAL/Point_2.h>
+#include <CGAL/Point_3.h>
+
+#include <cmath>
+
+#include <CGAL/Aff_transformation_3.h>
+
+typedef CGAL::Cartesian< double > Kernel ;
+typedef Kernel::Vector_2 Vector_2 ;
+typedef Kernel::Vector_3 Vector_3 ;
+typedef Kernel::Point_2 Point_2 ;
+typedef Kernel::Point_3 Point_3 ;
+
+
+// always after CGAL
+using namespace boost::unit_test ;
+
+BOOST_AUTO_TEST_SUITE( CGAL_AffineTransform3Test )
+
+/*
+ * simple translate
+ */
+BOOST_AUTO_TEST_CASE( testTranslate )
+{
+ Vector_3 translate( 4.0,5.0,6.0 );
+ CGAL::Aff_transformation_3< Kernel > affine( CGAL::TRANSLATION, translate );
+
+ /*
+ * @warning : translate is not applied on Vector_3!
+ */
+ Point_3 in( 1.0,2.0,3.0 );
+ Point_3 out = affine( in ) ;
+ BOOST_CHECK_EQUAL( out.x(), 5.0 );
+ BOOST_CHECK_EQUAL( out.y(), 7.0 );
+ BOOST_CHECK_EQUAL( out.z(), 9.0 );
+}
+
+/*
+ * rotate around Z (PI/2), translate( 3.0, 4.0, 5.0 )
+ */
+BOOST_AUTO_TEST_CASE( testRotateAndTranslate )
+{
+ /*
+ * @warning : translate is not applied on Vector_3!
+ */
+
+ CGAL::Aff_transformation_3< Kernel > affine(
+ 0.0, -1.0, 0.0, 3.0,
+ 1.0, 0.0, 0.0, 4.0,
+ 0.0, 0.0, 1.0, 5.0/*,
+ 0.0, 0.0, 0.0, 1.0*/
+ );
+ Point_3 in( 1.0,1.0,3.0 );
+ Point_3 out = affine( in ) ;
+
+ BOOST_CHECK_EQUAL( out.x(), 2.0 ); //-1.0 + 3.0
+ BOOST_CHECK_EQUAL( out.y(), 5.0 ); //1.0 + 4.0
+ BOOST_CHECK_EQUAL( out.z(), 8.0 ); //3.0 + 5.0
+}
+
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/CGAL/GmpqTest.cpp b/test/unit/CGAL/GmpqTest.cpp
new file mode 100644
index 0000000..8016c2b
--- /dev/null
+++ b/test/unit/CGAL/GmpqTest.cpp
@@ -0,0 +1,94 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <iostream>
+
+#include <boost/test/unit_test.hpp>
+
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+
+#include <CGAL/Point_2.h>
+#include <CGAL/Point_3.h>
+#include <CGAL/Plane_3.h>
+
+#include <cmath>
+
+
+// always after CGAL
+using namespace boost::unit_test ;
+
+BOOST_AUTO_TEST_SUITE( CGAL_GmpqTest )
+
+/*
+ * check that CGAL::Gmpq is flooring results
+ */
+BOOST_AUTO_TEST_CASE( testPositiveRationalFloor )
+{
+ // 1 / 3 => 0
+ {
+ CGAL::Gmpq q( 1,3 );
+ BOOST_CHECK_EQUAL( q.numerator() / q.denominator(), 0 );
+ }
+ // 2 / 3 => 0
+ {
+ CGAL::Gmpq q( 2,3 );
+ BOOST_CHECK_EQUAL( q.numerator() / q.denominator(), 0 );
+ }
+ // 2 / 2 => 1
+ {
+ CGAL::Gmpq q( 2,2 );
+ BOOST_CHECK_EQUAL( q.numerator() / q.denominator(), 1 );
+ }
+ // 3 / 2 => 1
+ {
+ CGAL::Gmpq q( 3,2 );
+ BOOST_CHECK_EQUAL( q.numerator() / q.denominator(), 1 );
+ }
+}
+
+/*
+ * check that CGAL::Gmpq is flooring results
+ */
+BOOST_AUTO_TEST_CASE( testNegativeRationalFloor )
+{
+ // - 1 / 3 => 0
+ {
+ CGAL::Gmpq q( -1,3 );
+ BOOST_CHECK_EQUAL( q.numerator() / q.denominator(), 0 );
+ }
+ // - 2 / 3 => 0
+ {
+ CGAL::Gmpq q( -2,3 );
+ BOOST_CHECK_EQUAL( q.numerator() / q.denominator(), 0 );
+ }
+ // - 2 / 2 => 1
+ {
+ CGAL::Gmpq q( -2,2 );
+ BOOST_CHECK_EQUAL( q.numerator() / q.denominator(), -1 );
+ }
+ // - 3 / 2 => 1
+ {
+ CGAL::Gmpq q( -3,2 );
+ BOOST_CHECK_EQUAL( q.numerator() / q.denominator(), -1 );
+ }
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/CGAL/KernelTest.cpp b/test/unit/CGAL/KernelTest.cpp
new file mode 100644
index 0000000..dabde24
--- /dev/null
+++ b/test/unit/CGAL/KernelTest.cpp
@@ -0,0 +1,67 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <iostream>
+
+#include <boost/test/unit_test.hpp>
+
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+
+#include <CGAL/Point_2.h>
+#include <CGAL/Point_3.h>
+#include <CGAL/Plane_3.h>
+
+#include <cmath>
+
+typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel ;
+typedef Kernel::Vector_2 Vector_2 ;
+typedef Kernel::Vector_3 Vector_3 ;
+typedef Kernel::Point_2 Point_2 ;
+typedef Kernel::Point_3 Point_3 ;
+typedef Kernel::Segment_2 Segment_2 ;
+typedef Kernel::Segment_3 Segment_3 ;
+
+// always after CGAL
+using namespace boost::unit_test ;
+
+BOOST_AUTO_TEST_SUITE( CGAL_KernelTest )
+
+BOOST_AUTO_TEST_CASE( testIntersectsRobutness )
+{
+ Segment_2 ab( Point_2( 0.0,0.0 ) , Point_2( 1.0,3.0 ) );
+ Segment_2 cd( Point_2( 0.0,1.0 ) , Point_2( 1.0,1.0 ) );
+ Segment_2 ef( Point_2( -1.0,3.0 ), Point_2( 1.0,0.0 ) );
+
+ CGAL::Object abIcd_ = CGAL::intersection( ab, cd );
+ const Point_2* abIcd = CGAL::object_cast<Point_2>( &abIcd_ ) ;
+ BOOST_REQUIRE( abIcd != NULL );
+
+ CGAL::Object abIef_ = CGAL::intersection( ab, ef );
+ const Point_2* abIef = CGAL::object_cast<Point_2>( &abIef_ ) ;
+ BOOST_REQUIRE( abIef != NULL );
+
+// std::cout << (*abIcd) << std::endl;
+// std::cout << (*abIef) << std::endl;
+ BOOST_CHECK( ( *abIcd ) == ( *abIef ) ) ;
+}
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/CGAL/Plane3Test.cpp b/test/unit/CGAL/Plane3Test.cpp
new file mode 100644
index 0000000..1a4d068
--- /dev/null
+++ b/test/unit/CGAL/Plane3Test.cpp
@@ -0,0 +1,52 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <CGAL/Cartesian.h>
+#include <CGAL/Point_2.h>
+#include <CGAL/Point_3.h>
+#include <CGAL/Plane_3.h>
+
+#include <cmath>
+
+typedef CGAL::Cartesian< double > Kernel ;
+typedef Kernel::Vector_2 Vector_2 ;
+typedef Kernel::Vector_3 Vector_3 ;
+typedef Kernel::Point_2 Point_2 ;
+typedef Kernel::Point_3 Point_3 ;
+typedef CGAL::Plane_3< Kernel > Plane_3 ;
+
+// always after CGAL
+using namespace boost::unit_test ;
+
+BOOST_AUTO_TEST_SUITE( CGAL_Plane3Test )
+
+BOOST_AUTO_TEST_CASE( testTo2D_UnitNormalForPlane )
+{
+ Plane_3 plane( 1.0,0.0,0.0,0.0 );
+ BOOST_CHECK_EQUAL( plane.to_2d( Point_3( 1.0,0.0,0.0 ) ), Point_2( 0.0,0.0 ) );
+ BOOST_CHECK_EQUAL( plane.to_2d( Point_3( 1.0,0.0,1.0 ) ), Point_2( 0.0,1.0 ) );
+ BOOST_CHECK_EQUAL( plane.to_2d( Point_3( 1.0,1.0,1.0 ) ), Point_2( 1.0,1.0 ) );
+ BOOST_CHECK_EQUAL( plane.to_2d( Point_3( 1.0,1.0,0.0 ) ), Point_2( 1.0,0.0 ) );
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/CGAL/WorkWithPoint3AsPoint2.cpp b/test/unit/CGAL/WorkWithPoint3AsPoint2.cpp
new file mode 100644
index 0000000..6348a05
--- /dev/null
+++ b/test/unit/CGAL/WorkWithPoint3AsPoint2.cpp
@@ -0,0 +1,105 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <cmath>
+
+#include <CGAL/Cartesian.h>
+
+
+typedef CGAL::Cartesian< double > Kernel ;
+typedef Kernel::Vector_2 Vector_2 ;
+typedef Kernel::Vector_3 Vector_3 ;
+typedef Kernel::Point_2 Point_2 ;
+typedef Kernel::Point_3 Point_3 ;
+typedef CGAL::Segment_2< Kernel > Segment_2 ;
+typedef CGAL::Segment_3< Kernel > Segment_3 ;
+
+// always after CGAL
+using namespace boost::unit_test ;
+
+BOOST_AUTO_TEST_SUITE( CGAL_WorkWithPoint3AsPoint2 )
+
+BOOST_AUTO_TEST_CASE( testIntersect2dSegmentsIn2d )
+{
+ Point_2 a( 0.0, 0.0 );
+ Point_2 b( 1.0, 1.0 );
+ Point_2 c( 1.0, 0.0 );
+ Point_2 d( 0.0, 1.0 );
+
+ Segment_2 ab( a, b );
+ Segment_2 cd( c, d );
+
+ CGAL::Object obj = CGAL::intersection( ab, cd );
+ const Point_2* p = CGAL::object_cast< Point_2 >( &obj ) ;
+ BOOST_REQUIRE( p != NULL );
+ BOOST_CHECK_EQUAL( p->x(), 0.5 );
+ BOOST_CHECK_EQUAL( p->y(), 0.5 );
+}
+
+BOOST_AUTO_TEST_CASE( testIntersect3dSegmentsIn3d )
+{
+ Point_3 a( 0.0, 0.0, 0.0 );
+ Point_3 b( 1.0, 1.0, 1.0 );
+ Point_3 c( 1.0, 0.0, 0.0 );
+ Point_3 d( 0.0, 1.0, 1.0 );
+
+ Segment_3 ab( a, b );
+ Segment_3 cd( c, d );
+
+ CGAL::Object obj = CGAL::intersection( ab, cd );
+ const Point_3* p = CGAL::object_cast< Point_3 >( &obj ) ;
+ BOOST_REQUIRE( p != NULL );
+ BOOST_CHECK_EQUAL( p->x(), 0.5 );
+ BOOST_CHECK_EQUAL( p->y(), 0.5 );
+ BOOST_CHECK_EQUAL( p->z(), 0.5 );
+}
+
+
+/**
+ *
+ */
+BOOST_AUTO_TEST_CASE( testIntersect3dSegmentsIn2d )
+{
+ Point_3 a( 0.0, 0.0, 0.0 );
+ Point_3 b( 1.0, 1.0, 1.0 );
+ Point_3 c( 1.0, 0.0, 0.0 );
+ Point_3 d( 0.0, 1.0, 1.0 );
+
+ Segment_3 ab( a, b );
+ Segment_3 cd( c, d );
+
+ //TODO : Find the best way to do 2D intersection on 3D segments
+
+ /*
+ CGAL::Object obj = CGAL::intersection(
+
+ );
+ const Point_2 *p = CGAL::object_cast< Point_2 >(&obj) ;
+ BOOST_REQUIRE( p != NULL );
+ BOOST_CHECK_EQUAL( p->x(), 0.5 );
+ BOOST_CHECK_EQUAL( p->y(), 0.5 );
+ */
+}
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
new file mode 100644
index 0000000..bede8ba
--- /dev/null
+++ b/test/unit/CMakeLists.txt
@@ -0,0 +1,30 @@
+#-- build unit tests
+file( GLOB_RECURSE SFCGAL_UNIT_TEST_SOURCES *.cpp )
+add_executable( unit-test-SFCGAL ${SFCGAL_UNIT_TEST_SOURCES} )
+target_link_libraries( unit-test-SFCGAL
+ SFCGAL
+ ${Boost_LIBRARIES}
+ ${CGAL_LIBRARIES}
+)
+if( ${SFCGAL_WITH_MPFR} )
+ target_link_libraries( unit-test-SFCGAL ${MPFR_LIBRARIES} ${GMP_LIBRARIES} )
+endif( ${SFCGAL_WITH_MPFR} )
+
+
+#include( PrecompiledHeader )
+#if(PCHSupport_FOUND)
+# add_precompiled_header(unit-test-SFCGAL
+# ${CMAKE_CURRENT_SOURCE_DIR}/../../include/all.h
+## "-fPIC"
+# )
+#endif()
+
+set_target_properties( unit-test-SFCGAL PROPERTIES DEBUG_POSTFIX "d" )
+install( TARGETS unit-test-SFCGAL DESTINATION bin )
+
+if (CMAKE_BUILD_TYPE STREQUAL "Debug" )
+ add_test( unit-testd ${CMAKE_CURRENT_BINARY_DIR}/unit-test-SFCGALd )
+else()
+ add_test( unit-test ${CMAKE_CURRENT_BINARY_DIR}/unit-test-SFCGAL )
+endif()
+
diff --git a/test/unit/SFCGAL/CoordinateTest.cpp b/test/unit/SFCGAL/CoordinateTest.cpp
new file mode 100644
index 0000000..e981cc6
--- /dev/null
+++ b/test/unit/SFCGAL/CoordinateTest.cpp
@@ -0,0 +1,191 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Coordinate.h>
+#include <SFCGAL/Exception.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_CoordinateTest )
+
+/// Coordinate() ;
+BOOST_AUTO_TEST_CASE( testDefaultConstructor )
+{
+ Coordinate g ;
+ BOOST_CHECK( g.isEmpty() );
+ BOOST_CHECK_THROW( g.x(), Exception );
+ BOOST_CHECK_THROW( g.y(), Exception );
+ BOOST_CHECK_THROW( g.z(), Exception );
+}
+
+/// Coordinate( const Kernel::FT & x, const Kernel::FT & y ) ;
+BOOST_AUTO_TEST_CASE( testXYConstructor )
+{
+ Coordinate g( 3, 4 );
+ BOOST_CHECK( ! g.isEmpty() );
+ BOOST_CHECK( ! g.is3D() );
+ BOOST_CHECK_EQUAL( g.x(), 3 );
+ BOOST_CHECK_EQUAL( g.y(), 4 );
+}
+
+
+/// Coordinate( const Kernel::FT & x, const Kernel::FT & y, const Kernel::FT & z ) ;
+BOOST_AUTO_TEST_CASE( testXYZConstructor )
+{
+ Coordinate g( 3, 4, 5 );
+ BOOST_CHECK( ! g.isEmpty() );
+ BOOST_CHECK( g.is3D() );
+ BOOST_CHECK_EQUAL( g.x(), 3 );
+ BOOST_CHECK_EQUAL( g.y(), 4 );
+ BOOST_CHECK_EQUAL( g.z(), 5 );
+}
+
+/// Coordinate( const double & x, const double & y ) ;
+BOOST_AUTO_TEST_CASE( testXYConstructorDouble )
+{
+ Coordinate g( 3.0, 4.0 );
+ BOOST_CHECK( ! g.isEmpty() );
+ BOOST_CHECK( ! g.is3D() );
+ BOOST_CHECK_EQUAL( g.x(), 3 );
+ BOOST_CHECK_EQUAL( g.y(), 4 );
+}
+/// Coordinate( const double & x, const double & y, const double& z ) ;
+BOOST_AUTO_TEST_CASE( testXYZConstructorDouble )
+{
+ Coordinate g( 3.0, 4.0, 5.0 );
+ BOOST_CHECK( ! g.isEmpty() );
+ BOOST_CHECK( g.is3D() );
+ BOOST_CHECK_EQUAL( g.x(), 3 );
+ BOOST_CHECK_EQUAL( g.y(), 4 );
+ BOOST_CHECK_EQUAL( g.z(), 5 );
+ BOOST_CHECK_THROW( Coordinate( std::numeric_limits<double>::infinity(),0,0 ), NonFiniteValueException );
+ BOOST_CHECK_THROW( Coordinate( 0,std::numeric_limits<double>::infinity(),0 ), NonFiniteValueException );
+ BOOST_CHECK_THROW( Coordinate( 0,0,std::numeric_limits<double>::infinity() ), NonFiniteValueException );
+}
+
+/// Coordinate( const CGAL::Point_2< K > & other ):
+/// Coordinate( const CGAL::Point_3< K > & other ):
+/// Coordinate( const Coordinate & other ) ;
+BOOST_AUTO_TEST_CASE( testCopyConstructorEmpty )
+{
+ Coordinate g ;
+ Coordinate copy( g );
+ BOOST_CHECK( copy.isEmpty() );
+}
+BOOST_AUTO_TEST_CASE( testCopyConstructorXY )
+{
+ Coordinate g( 3,4 ) ;
+ Coordinate copy( g );
+ BOOST_CHECK_EQUAL( copy.x(), 3 );
+ BOOST_CHECK_EQUAL( copy.y(), 4 );
+}
+
+/// Coordinate& operator = ( const Coordinate & other ) ;
+/// ~Coordinate() ;
+/// int coordinateDimension() const ;
+BOOST_AUTO_TEST_CASE( testCoordinateDimensionEmpty )
+{
+ Coordinate g ;
+ BOOST_CHECK_EQUAL( g.coordinateDimension(), 0 );
+}
+BOOST_AUTO_TEST_CASE( testCoordinateDimensionXY )
+{
+ Coordinate g( 3,4 ) ;
+ BOOST_CHECK_EQUAL( g.coordinateDimension(), 2 );
+}
+BOOST_AUTO_TEST_CASE( testCoordinateDimensionXYZ )
+{
+ Coordinate g( 3,4,5 ) ;
+ BOOST_CHECK_EQUAL( g.coordinateDimension(), 3 );
+}
+
+/// bool isEmpty() const ;
+/// bool is3D() const ;
+/// Kernel::FT x() const;
+/// Kernel::FT y() const;
+/// Kernel::FT z() const;
+
+/// Coordinate& round( const Kernel::FT& scaleFactor ) ;
+BOOST_AUTO_TEST_CASE( testRoundInteger )
+{
+ Coordinate g( 0.5,1.5 );
+ g.round();
+ BOOST_CHECK_EQUAL( g.x(), 1 );
+ BOOST_CHECK_EQUAL( g.y(), 2 );
+}
+BOOST_AUTO_TEST_CASE( testRoundOneDecimal )
+{
+ Coordinate g( 0.52,1.57 );
+ g.round( 10 );
+ BOOST_CHECK_CLOSE( g.x(), 0.5, 0.1 );
+ BOOST_CHECK_CLOSE( g.y(), 1.6, 0.1 );
+
+
+ std::ostringstream oss;
+ oss << CGAL::exact( g.x() ) << " " << CGAL::exact( g.y() );
+ BOOST_CHECK_EQUAL( oss.str(), "1/2 8/5" ); //16/10
+}
+
+
+
+///--- comparators
+
+
+/// bool operator < ( const Coordinate & other ) const ;
+BOOST_AUTO_TEST_CASE( testLessEmpty )
+{
+ Coordinate gA ;
+ Coordinate gB ;
+ BOOST_CHECK_THROW( ( gA < gB ), Exception ) ;
+}
+BOOST_AUTO_TEST_CASE( testLessXY_XY )
+{
+ BOOST_CHECK( ! ( Coordinate( 0,0 ) < Coordinate( 0,0 ) ) ) ;
+ BOOST_CHECK( ( Coordinate( 0,0 ) < Coordinate( 1,0 ) ) ) ;
+ BOOST_CHECK( ( Coordinate( 1,0 ) < Coordinate( 1,1 ) ) ) ;
+}
+BOOST_AUTO_TEST_CASE( testLessXYZ_XYZ )
+{
+ BOOST_CHECK( ! ( Coordinate( 0,0,0 ) < Coordinate( 0,0,0 ) ) ) ;
+ BOOST_CHECK( ( Coordinate( 0,0,0 ) < Coordinate( 1,0,0 ) ) ) ;
+ BOOST_CHECK( ( Coordinate( 1,0,0 ) < Coordinate( 1,1,0 ) ) ) ;
+ BOOST_CHECK( ! ( Coordinate( 1,1,0 ) < Coordinate( 1,1,0 ) ) ) ;
+ BOOST_CHECK( ( Coordinate( 1,1,0 ) < Coordinate( 1,1,1 ) ) ) ;
+}
+BOOST_AUTO_TEST_CASE( testLessXY_XYZ )
+{
+ BOOST_CHECK_THROW( ( Coordinate( 0,0 ) < Coordinate( 0,0,0 ) ), Exception ) ;
+}
+
+/// bool operator == ( const Coordinate & other ) const ;
+/// bool operator != ( const Coordinate & other ) const ;
+/// inline Kernel::Vector_2 toVector_2() const
+/// inline Kernel::Vector_3 toVector_3() const
+/// Kernel::Point_2 toPoint_2() const;
+/// Kernel::Point_3 toPoint_3() const;
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/EnvelopeTest.cpp b/test/unit/SFCGAL/EnvelopeTest.cpp
new file mode 100644
index 0000000..0be4aa3
--- /dev/null
+++ b/test/unit/SFCGAL/EnvelopeTest.cpp
@@ -0,0 +1,133 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Envelope.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Solid.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_EnvelopeTest )
+
+//Envelope() ;
+BOOST_AUTO_TEST_CASE( defaultConstructor )
+{
+ Envelope box ;
+ BOOST_CHECK( box.boundsN( 0 ).isEmpty() );
+ BOOST_CHECK( box.boundsN( 1 ).isEmpty() );
+ BOOST_CHECK( box.boundsN( 2 ).isEmpty() );
+}
+
+//Envelope( const Coordinate & p ) ;
+BOOST_AUTO_TEST_CASE( constructorWithCoordinateXY )
+{
+ Envelope box( Coordinate( 1.0,2.0 ) );
+ BOOST_CHECK( box.boundsN( 0 ) == detail::Interval( 1.0 ) );
+ BOOST_CHECK( box.boundsN( 1 ) == detail::Interval( 2.0 ) );
+ BOOST_CHECK( box.boundsN( 2 ).isEmpty() );
+}
+
+//Envelope( const Coordinate & p1, const Coordinate & p2 ) ;
+BOOST_AUTO_TEST_CASE( constructorWithTwoCoordinateXY )
+{
+ Envelope box( Coordinate( 3.0,5.0 ), Coordinate( 1.0,2.0 ) );
+ BOOST_CHECK( box.boundsN( 0 ) == detail::Interval( 1.0,3.0 ) );
+ BOOST_CHECK( box.boundsN( 1 ) == detail::Interval( 2.0,5.0 ) );
+ BOOST_CHECK( box.boundsN( 2 ).isEmpty() );
+}
+
+//Envelope( const Envelope& other ) ;
+//Envelope& operator = ( const Envelope& other ) ;
+//~Envelope() ;
+
+//bool isEmpty() const ;
+BOOST_AUTO_TEST_CASE( testIsEmpty )
+{
+ Envelope box ;
+ BOOST_CHECK( box.isEmpty() );
+}
+BOOST_AUTO_TEST_CASE( testIsNotEmpty )
+{
+ Envelope box( Coordinate( 0.0,0.0 ) ) ;
+ BOOST_CHECK( ! box.isEmpty() );
+}
+//bool is3D() const ;
+BOOST_AUTO_TEST_CASE( testIs3D )
+{
+ Envelope box( Coordinate( 0.0,0.0,0.0 ) ) ;
+ BOOST_CHECK( box.is3D() );
+}
+BOOST_AUTO_TEST_CASE( testNotIs3D )
+{
+ Envelope box( Coordinate( 0.0,0.0 ) ) ;
+ BOOST_CHECK( ! box.is3D() );
+}
+//void expandToInclude( const Coordinate & coordinate ) ;
+
+BOOST_AUTO_TEST_CASE( testExpandToInclude )
+{
+ Envelope box ;
+ BOOST_CHECK( box.isEmpty() );
+
+ box.expandToInclude( Coordinate( 0.0,0.0 ) ) ;
+ BOOST_CHECK( ! box.isEmpty() );
+ BOOST_CHECK( ! box.is3D() );
+
+ BOOST_CHECK( box.boundsN( 0 ) == detail::Interval( 0.0 ) );
+ BOOST_CHECK( box.boundsN( 1 ) == detail::Interval( 0.0 ) );
+
+ box.expandToInclude( Coordinate( 0.0,0.0,0.0 ) ) ;
+ BOOST_CHECK( ! box.isEmpty() );
+ BOOST_CHECK( box.is3D() );
+
+ BOOST_CHECK( box.boundsN( 0 ) == detail::Interval( 0.0 ) );
+ BOOST_CHECK( box.boundsN( 1 ) == detail::Interval( 0.0 ) );
+ BOOST_CHECK( box.boundsN( 2 ) == detail::Interval( 0.0 ) );
+
+ box.expandToInclude( Coordinate( 1.0,2.0 ) ) ;
+ BOOST_CHECK( box.boundsN( 0 ) == detail::Interval( 0.0,1.0 ) );
+ BOOST_CHECK( box.boundsN( 1 ) == detail::Interval( 0.0,2.0 ) );
+ BOOST_CHECK( box.boundsN( 2 ) == detail::Interval( 0.0 ) );
+}
+
+
+//std::auto_ptr< LineString > toRing() const ;
+BOOST_AUTO_TEST_CASE( testToRing )
+{
+ Envelope box( 0.0,1.0,2.0,3.0 );
+ BOOST_CHECK_EQUAL( box.toRing()->asText( 0 ), "LINESTRING(0 2,1 2,1 3,0 3,0 2)" );
+}
+
+//std::auto_ptr< Polygon > toPolygon() const ;
+BOOST_AUTO_TEST_CASE( testToPolygon )
+{
+ Envelope box( 0.0,1.0,2.0,3.0,4.0,5.0 );
+ BOOST_CHECK_EQUAL( box.toSolid()->asText( 0 ), "SOLID((((0 2 4,0 3 4,1 3 4,1 2 4,0 2 4)),((0 2 5,1 2 5,1 3 5,0 3 5,0 2 5)),((0 2 4,1 2 4,1 2 5,0 2 5,0 2 4)),((1 3 4,0 3 4,0 3 5,1 3 5,1 3 4)),((1 2 4,1 3 4,1 3 5,1 2 5,1 2 4)),((0 2 4,0 2 5,0 3 5,0 3 4,0 2 4))))" );
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/GeometryCollectionTest.cpp b/test/unit/SFCGAL/GeometryCollectionTest.cpp
new file mode 100644
index 0000000..b340cc8
--- /dev/null
+++ b/test/unit/SFCGAL/GeometryCollectionTest.cpp
@@ -0,0 +1,163 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <exception>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_GeometryCollectionTest )
+
+//GeometryCollection() ;
+BOOST_AUTO_TEST_CASE( defaultConstructor )
+{
+ GeometryCollection g ;
+ BOOST_CHECK( g.isEmpty() );
+}
+
+//GeometryCollection( GeometryCollection const& other ) ;
+//GeometryCollection& operator = ( const GeometryCollection & other ) ;
+//virtual ~GeometryCollection() ;
+
+//virtual size_t numGeometries() const ;
+//virtual const Geometry & geometryN( size_t const& n ) const ;
+//virtual Geometry & geometryN( size_t const& n ) ;
+//void addGeometry( Geometry * geometry ) ;
+//void addGeometry( Geometry const& geometry ) ;
+BOOST_AUTO_TEST_CASE( testAccessors )
+{
+ GeometryCollection g ;
+
+ g.addGeometry( new Point( 2.0,3.0 ) ) ;
+ BOOST_CHECK_EQUAL( g.numGeometries(), 1U );
+ g.addGeometry( new LineString( Point( 0.0,0.0 ),Point( 1.0,1.0 ) ) ) ;
+ BOOST_CHECK_EQUAL( g.numGeometries(), 2U );
+ g.addGeometry( new Triangle( Point( 0.0,0.0 ),Point( 1.0,0.0 ),Point( 1.0,1.0 ) ) ) ;
+ BOOST_CHECK_EQUAL( g.numGeometries(), 3U );
+
+ BOOST_CHECK_EQUAL( g.geometryN( 0 ).asText( 0 ), "POINT(2 3)" ) ;
+ BOOST_CHECK_EQUAL( g.geometryN( 1 ).asText( 0 ), "LINESTRING(0 0,1 1)" ) ;
+ BOOST_CHECK_EQUAL( g.geometryN( 2 ).asText( 0 ), "TRIANGLE((0 0,1 0,1 1,0 0))" ) ;
+}
+
+
+//-- iterators
+
+//inline iterator begin()
+//inline const_iterator begin() const
+//inline iterator end()
+//inline const_iterator end() const
+BOOST_AUTO_TEST_CASE( testIterators )
+{
+ GeometryCollection g ;
+ g.addGeometry( Point( 0.0,0.0 ) );
+ g.addGeometry( Point( 1.0,1.0 ) );
+
+ GeometryCollection::const_iterator it = g.begin() ;
+
+ BOOST_CHECK_EQUAL( it->asText( 0 ), "POINT(0 0)" );
+ ++it ;
+ BOOST_CHECK_EQUAL( it->asText( 0 ), "POINT(1 1)" );
+ ++it ;
+ BOOST_CHECK( it == g.end() );
+}
+
+
+//-- Geometry
+
+//virtual Geometry * Geometry::clone() const = 0 ;
+//virtual Geometry* Geometry::boundary() const ;
+//Envelope Geometry::envelope() const ;
+
+//std::string Geometry::asText( const int & numDecimals = -1 ) const ;
+BOOST_AUTO_TEST_CASE( asTextEmpty )
+{
+ GeometryCollection g;
+ BOOST_CHECK_EQUAL( g.asText( 1 ), "GEOMETRYCOLLECTION EMPTY" );
+}
+BOOST_AUTO_TEST_CASE( asText2d )
+{
+ GeometryCollection g;
+ g.addGeometry( Point( 2.0,3.0 ) );
+ g.addGeometry( Triangle( Point( 0.0,0.0 ), Point( 1.0,0.0 ), Point( 1.0,1.0 ) ) );
+ BOOST_CHECK_EQUAL( g.asText( 1 ), "GEOMETRYCOLLECTION(POINT(2.0 3.0),TRIANGLE((0.0 0.0,1.0 0.0,1.0 1.0,0.0 0.0)))" );
+}
+BOOST_AUTO_TEST_CASE( asText3d )
+{
+ GeometryCollection g;
+ g.addGeometry( Point( 2.0,3.0,5.0 ) );
+ g.addGeometry( Triangle( Point( 0.0,0.0,6.0 ), Point( 1.0,0.0,6.0 ), Point( 1.0,1.0,6.0 ) ) );
+ BOOST_CHECK_EQUAL( g.asText( 1 ), "GEOMETRYCOLLECTION(POINT(2.0 3.0 5.0),TRIANGLE((0.0 0.0 6.0,1.0 0.0 6.0,1.0 1.0 6.0,0.0 0.0 6.0)))" );
+}
+
+//virtual std::string Geometry::geometryType() const = 0 ;
+BOOST_AUTO_TEST_CASE( testGeometryType )
+{
+ GeometryCollection g;
+ BOOST_CHECK_EQUAL( g.geometryType(), "GeometryCollection" );
+}
+//virtual GeometryType Geometry::geometryTypeId() const = 0 ;
+BOOST_AUTO_TEST_CASE( testGeometryTypeId )
+{
+ GeometryCollection g;
+ BOOST_CHECK_EQUAL( g.geometryTypeId(), TYPE_GEOMETRYCOLLECTION );
+}
+
+//virtual int Geometry::dimension() const = 0 ;
+//virtual int Geometry::coordinateDimension() const = 0 ;
+//virtual bool Geometry::isEmpty() const = 0 ;
+//virtual bool Geometry::is3D() const = 0 ;
+//virtual bool Geometry::isMeasured() const = 0 ;
+//virtual bool Geometry::isSimple() const = 0 ;
+
+//template < typename Derived > inline bool Geometry::is() const
+BOOST_AUTO_TEST_CASE( testIsGeometryCollection )
+{
+ BOOST_CHECK( GeometryCollection().is< GeometryCollection >() );
+ BOOST_CHECK( MultiPoint().is< GeometryCollection >() );
+ BOOST_CHECK( MultiLineString().is< GeometryCollection >() );
+ BOOST_CHECK( MultiPolygon().is< GeometryCollection >() );
+ BOOST_CHECK( MultiSolid().is< GeometryCollection >() );
+}
+
+//template < typename Derived > inline const Derived & Geometry::as() const
+//template < typename Derived > inline Derived & Geometry::as()
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/GeometryTest.cpp b/test/unit/SFCGAL/GeometryTest.cpp
new file mode 100644
index 0000000..ca0e0bf
--- /dev/null
+++ b/test/unit/SFCGAL/GeometryTest.cpp
@@ -0,0 +1,87 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_GeometryTest )
+
+//virtual ~Geometry();
+
+// MAY BE TESTED IN SUBCLASSES
+
+//virtual Geometry * Geometry::clone() const = 0 ;
+//virtual Geometry* Geometry::boundary() const ;
+//Envelope Geometry::envelope() const ;
+//std::string Geometry::asText( const int & numDecimals = -1 ) const ;
+//virtual std::string Geometry::geometryType() const = 0 ;
+//virtual GeometryType Geometry::geometryTypeId() const = 0 ;
+//virtual int Geometry::dimension() const = 0 ;
+//virtual int Geometry::coordinateDimension() const = 0 ;
+//virtual bool Geometry::isEmpty() const = 0 ;
+//virtual bool Geometry::is3D() const = 0 ;
+//virtual bool Geometry::isMeasured() const = 0 ;
+//virtual bool Geometry::isSimple() const = 0 ;
+//template < typename Derived > inline bool Geometry::is() const
+//template < typename Derived > inline const Derived & Geometry::as() const
+//template < typename Derived > inline Derived & Geometry::as()
+
+
+
+//TODO
+//void round( const long & scale = 1 ) ;
+
+//TODO
+//virtual size_t numGeometries() const ;
+//virtual const Geometry & geometryN( size_t const& n ) const ;
+//virtual Geometry & geometryN( size_t const& n ) ;
+
+//-- tested in distance
+//double distance( const Geometry & other ) const ;
+//double distance3D( const Geometry & other ) const ;
+
+
+//-- tested in geometry visitor test
+//virtual void accept( GeometryVisitor & visitor ) = 0 ;
+//virtual void accept( ConstGeometryVisitor & visitor ) const = 0 ;
+
+//TODO
+//template <class Archive> void serialize( Archive& ar, const unsigned int version )
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/GeometryVisitorTest.cpp b/test/unit/SFCGAL/GeometryVisitorTest.cpp
new file mode 100644
index 0000000..8b81ffb
--- /dev/null
+++ b/test/unit/SFCGAL/GeometryVisitorTest.cpp
@@ -0,0 +1,167 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+#include <cmath>
+
+#include <SFCGAL/GeometryVisitor.h>
+
+
+using namespace SFCGAL ;
+
+// always after CGAL
+using namespace boost::unit_test ;
+
+/**
+ * get type from Geometry
+ */
+class DemoVisitorGetType : public ConstGeometryVisitor {
+public:
+
+ virtual void visit( const Point& ) {
+ type = "Point";
+ }
+ virtual void visit( const LineString& ) {
+ type = "LineString";
+ }
+ virtual void visit( const Polygon& ) {
+ type = "Polygon";
+ }
+ virtual void visit( const Triangle& ) {
+ type = "Triangle";
+ }
+ virtual void visit( const Solid& ) {
+ type = "Solid";
+ }
+ virtual void visit( const MultiPoint& ) {
+ type = "MultiPoint";
+ }
+ virtual void visit( const MultiLineString& ) {
+ type = "MultiLineString";
+ }
+ virtual void visit( const MultiPolygon& ) {
+ type = "MultiPolygon";
+ }
+ virtual void visit( const MultiSolid& ) {
+ type = "MultiSolid";
+ }
+
+ virtual void visit( const GeometryCollection& ) {
+ type = "GeometryCollection";
+ }
+
+ virtual void visit( const PolyhedralSurface& ) {
+ type = "PolyhedralSurface";
+ }
+
+ virtual void visit( const TriangulatedSurface& ) {
+ type = "TriangulatedSurface";
+ }
+
+public:
+ std::string type ;
+};
+
+
+template < typename T >
+std::string getTypeWithVisitor()
+{
+ std::auto_ptr< Geometry > geometry( new T() );
+ DemoVisitorGetType visitor;
+ geometry->accept( visitor );
+ return visitor.type ;
+}
+
+
+
+/*
+ * base checks (mainly for compilation issues)
+ */
+BOOST_AUTO_TEST_SUITE( SFCGAL_GeometryVisitorTest )
+
+BOOST_AUTO_TEST_CASE( testVisitPoint )
+{
+ BOOST_CHECK_EQUAL( getTypeWithVisitor< Point >(), "Point" );
+}
+BOOST_AUTO_TEST_CASE( testVisitLineString )
+{
+ BOOST_CHECK_EQUAL( getTypeWithVisitor< LineString >(), "LineString" );
+}
+BOOST_AUTO_TEST_CASE( testVisitPolygon )
+{
+ BOOST_CHECK_EQUAL( getTypeWithVisitor< Polygon >(), "Polygon" );
+}
+BOOST_AUTO_TEST_CASE( testVisitTriangle )
+{
+ BOOST_CHECK_EQUAL( getTypeWithVisitor< Triangle >(), "Triangle" );
+}
+
+BOOST_AUTO_TEST_CASE( testVisitMultiPoint )
+{
+ BOOST_CHECK_EQUAL( getTypeWithVisitor< MultiPoint >(), "MultiPoint" );
+}
+BOOST_AUTO_TEST_CASE( testVisitMultiLineString )
+{
+ BOOST_CHECK_EQUAL( getTypeWithVisitor< MultiLineString >(), "MultiLineString" );
+}
+BOOST_AUTO_TEST_CASE( testVisitMultiPolygon )
+{
+ BOOST_CHECK_EQUAL( getTypeWithVisitor< MultiPolygon >(), "MultiPolygon" );
+}
+BOOST_AUTO_TEST_CASE( testVisitMultiSolid )
+{
+ BOOST_CHECK_EQUAL( getTypeWithVisitor< MultiSolid >(), "MultiSolid" );
+}
+BOOST_AUTO_TEST_CASE( testVisitGeometryCollection )
+{
+ BOOST_CHECK_EQUAL( getTypeWithVisitor< GeometryCollection >(), "GeometryCollection" );
+}
+
+BOOST_AUTO_TEST_CASE( testVisitTriangulatedSurface )
+{
+ BOOST_CHECK_EQUAL( getTypeWithVisitor< TriangulatedSurface >(), "TriangulatedSurface" );
+}
+
+BOOST_AUTO_TEST_CASE( testVisitPolyhedralSurface )
+{
+ BOOST_CHECK_EQUAL( getTypeWithVisitor< PolyhedralSurface >(), "PolyhedralSurface" );
+}
+
+BOOST_AUTO_TEST_CASE( testVisitSolid )
+{
+ BOOST_CHECK_EQUAL( getTypeWithVisitor< Solid >(), "Solid" );
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/GridTest.cpp b/test/unit/SFCGAL/GridTest.cpp
new file mode 100644
index 0000000..e4a581e
--- /dev/null
+++ b/test/unit/SFCGAL/GridTest.cpp
@@ -0,0 +1,180 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <SFCGAL/Grid.h>
+#include <SFCGAL/TriangulatedSurface.h>
+
+#include <boost/test/unit_test.hpp>
+using namespace boost::unit_test ;
+
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_GridTest )
+
+///Grid();
+
+BOOST_AUTO_TEST_CASE( defaultConstructor )
+{
+ Grid g;
+ BOOST_CHECK( g.isEmpty() ) ;
+ BOOST_CHECK_EQUAL( g.pixelConvention(), PIXEL_IS_POINT );
+ BOOST_CHECK_EQUAL( g.ncols(), 0U );
+ BOOST_CHECK_EQUAL( g.nrows(), 0U );
+}
+
+
+///Grid(
+// const size_t & nrows,
+// const size_t & ncols,
+// const double& fillValue = NaN(),
+// const Envelope & limits = Envelope(0.0,1.0,0.0,1.0),
+// const PixelConvention & pixelType = PIXEL_IS_POINT
+//);
+
+BOOST_AUTO_TEST_CASE( constructorWithSize )
+{
+ Grid g( 4, 2, 5.0 );
+ BOOST_CHECK_EQUAL( g.pixelConvention(), PIXEL_IS_POINT );
+ BOOST_CHECK_EQUAL( g.nrows(), 4U );
+ BOOST_CHECK_EQUAL( g.ncols(), 2U );
+
+ for ( size_t i = 0; i < g.nrows(); i++ ) {
+ for ( size_t j = 0; j < g.ncols(); j++ ) {
+ BOOST_CHECK_EQUAL( g.z( i,j ), 5.0 );
+ }
+ }
+}
+
+//Grid(
+// const ublas::matrix< double > & data,
+// const Envelope & limits = Envelope(0.0,1.0,0.0,1.0),
+// const PixelConvention & pixelType = PIXEL_IS_POINT
+//);
+
+BOOST_AUTO_TEST_CASE( constructorWithMatrix )
+{
+ detail::ublas::matrix< double > data = detail::ublas::identity_matrix< double >( 5 );
+ Grid g( data );
+ BOOST_CHECK_EQUAL( g.pixelConvention(), PIXEL_IS_POINT );
+ BOOST_CHECK_EQUAL( g.nrows(), 5U );
+ BOOST_CHECK_EQUAL( g.ncols(), 5U );
+
+ for ( size_t i = 0; i < g.nrows(); i++ ) {
+ for ( size_t j = 0; j < g.ncols(); j++ ) {
+ if ( i == j ) {
+ BOOST_CHECK_EQUAL( g.z( i,j ), 1.0 );
+ }
+ else {
+ BOOST_CHECK_EQUAL( g.z( i,j ), 0.0 );
+ }
+ }
+ }
+}
+
+
+
+//Grid( const Grid & other );
+//Grid& operator = ( const Grid & other );
+//~Grid();
+//
+//inline bool isEmpty() const
+//
+//inline Point point( const size_t & row, const size_t & col ) const ;
+
+BOOST_AUTO_TEST_CASE( testPoint_PixelIsPoint )
+{
+ Grid g( 5, 5, 0.0, Envelope( 0.0,4.0,0.0,4.0 ) );
+ g.setPixelConvention( PIXEL_IS_POINT );
+ BOOST_CHECK_EQUAL( g.point( 0,0 ).x(), 0.0 );
+ BOOST_CHECK_EQUAL( g.point( 0,0 ).y(), 4.0 );
+
+ BOOST_CHECK_EQUAL( g.point( 1,1 ).x(), 1.0 );
+ BOOST_CHECK_EQUAL( g.point( 1,1 ).y(), 3.0 );
+
+ BOOST_CHECK_EQUAL( g.point( 4,4 ).x(), 4.0 );
+ BOOST_CHECK_EQUAL( g.point( 4,4 ).y(), 0.0 );
+}
+
+BOOST_AUTO_TEST_CASE( testPoint_PixelIsArea )
+{
+ Grid g( 4, 4, 0.0, Envelope( 0.0,4.0,0.0,4.0 ) );
+ g.setPixelConvention( PIXEL_IS_AREA );
+ BOOST_CHECK_EQUAL( g.point( 0,0 ).x(), 0.5 );
+ BOOST_CHECK_EQUAL( g.point( 0,0 ).y(), 3.5 );
+
+ BOOST_CHECK_EQUAL( g.point( 1,1 ).x(), 1.5 );
+ BOOST_CHECK_EQUAL( g.point( 1,1 ).y(), 2.5 );
+
+ BOOST_CHECK_EQUAL( g.point( 3,3 ).x(), 3.5 );
+ BOOST_CHECK_EQUAL( g.point( 3,3 ).y(), 0.5 );
+}
+
+
+//inline double dx() const ;
+//inline double dy() const ;
+BOOST_AUTO_TEST_CASE( testDxDy_PixelIsPoint )
+{
+ Grid g( 4,2 );
+ g.setPixelConvention( PIXEL_IS_POINT );
+ BOOST_CHECK_EQUAL( g.dx(), 1.0 );
+ BOOST_CHECK_EQUAL( g.dy(), 1.0/3.0 );
+}
+BOOST_AUTO_TEST_CASE( testDxDy_PixelIsArea )
+{
+ Grid g( 4,2 );
+ g.setPixelConvention( PIXEL_IS_AREA );
+ BOOST_CHECK_EQUAL( g.dx(), 0.50 );
+ BOOST_CHECK_EQUAL( g.dy(), 0.25 );
+}
+
+//
+//inline const double & z( const size_t& row, const size_t& col ) const ;
+//inline double & z( const size_t& row, const size_t& col ) ;
+//
+//inline const size_t nrows() const
+//inline const size_t ncols() const
+//inline const Envelope & limits() const
+//inline void setLimits( const Envelope & limits )
+//inline const PixelConvention & pixelConvention() const
+//inline void setPixelConvention( const PixelConvention & pixelConvention )
+//inline ublas::matrix< double > & data()
+//inline const ublas::matrix< double > & data() const
+
+
+//std::auto_ptr< TriangulatedSurface > toTrianguledSurface() const ;
+BOOST_AUTO_TEST_CASE( testToTriangulatedSurface )
+{
+ Grid g( 2,2 );
+ g.z( 0,0 ) = 0.0 ;
+ g.z( 0,1 ) = 1.0 ;
+ g.z( 1,0 ) = 2.0 ;
+ g.z( 1,1 ) = 3.0 ;
+
+ g.setPixelConvention( PIXEL_IS_POINT );
+ BOOST_CHECK_EQUAL( g.toTrianguledSurface()->asText( 1 ), "TIN M(((0.0 0.0 2.0,1.0 0.0 3.0,1.0 1.0 1.0,0.0 0.0 2.0)),((0.0 0.0 2.0,1.0 1.0 1.0,0.0 1.0 0.0,0.0 0.0 2.0)))" );
+ g.setPixelConvention( PIXEL_IS_AREA );
+ BOOST_CHECK_EQUAL( g.toTrianguledSurface()->asText( 1 ), "TIN M(((0.2 0.2 2.0,0.8 0.2 3.0,0.8 0.8 1.0,0.2 0.2 2.0)),((0.2 0.2 2.0,0.8 0.8 1.0,0.2 0.8 0.0,0.2 0.2 2.0)))" );
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/KernelTest.cpp b/test/unit/SFCGAL/KernelTest.cpp
new file mode 100644
index 0000000..63e91c4
--- /dev/null
+++ b/test/unit/SFCGAL/KernelTest.cpp
@@ -0,0 +1,108 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <iostream>
+
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Coordinate.h>
+#include <SFCGAL/LineString.h>
+
+using namespace SFCGAL ;
+
+typedef Kernel::Vector_2 Vector_2 ;
+typedef Kernel::Vector_3 Vector_3 ;
+typedef Kernel::Point_2 Point_2 ;
+typedef Kernel::Point_3 Point_3 ;
+typedef Kernel::Segment_2 Segment_2 ;
+typedef Kernel::Segment_3 Segment_3 ;
+
+// always after CGAL
+using namespace boost::unit_test ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_KernelTest )
+
+
+/**
+ * 1 - 1/3 - 1/3 - 1/3 = 0
+ */
+BOOST_AUTO_TEST_CASE( testRobustArithmetric )
+{
+ Kernel::FT v = 1 ;
+ v -= Kernel::FT( 1 ) / Kernel::FT( 3 ) ;
+ v -= Kernel::FT( 1 ) / Kernel::FT( 3 ) ;
+ v -= Kernel::FT( 1 ) / Kernel::FT( 3 ) ;
+ BOOST_CHECK_EQUAL( v,0 );
+}
+
+/**
+ * Serialize/Deserialize 1/3
+ * @todo check with hugo's code
+ */
+BOOST_AUTO_TEST_CASE( testSerializeDeserialize )
+{
+ Kernel::FT a = 1 ;
+ a /= 3 ;
+
+ std::ostringstream oss ;
+ oss << CGAL::exact( a ) ;
+
+ Kernel::FT b( oss.str() );
+ BOOST_CHECK_EQUAL( a, b ) ;
+}
+
+
+
+/**
+ * 3 lines intersecting on POINT(1/3 1)
+ */
+BOOST_AUTO_TEST_CASE( testIntersectsRobutness )
+{
+ LineString ab( Point( 0.0,0.0 ), Point( 1.0,3.0 ) );
+ LineString cd( Point( 0.0,1.0 ) , Point( 1.0,1.0 ) );
+ LineString ef( Point( -1.0,3.0 ), Point( 1.0,0.0 ) );
+
+ //ab, cd
+ CGAL::Object abIcd_ = CGAL::intersection(
+ Segment_2( ab.startPoint().toPoint_2(), ab.endPoint().toPoint_2() ),
+ Segment_2( cd.startPoint().toPoint_2(), cd.endPoint().toPoint_2() )
+ );
+ const Point_2* abIcd = CGAL::object_cast<Point_2>( &abIcd_ ) ;
+ BOOST_REQUIRE( abIcd != NULL );
+
+ //would break robustness if construction history is lost
+ Point intersectionA( *abIcd );
+
+ CGAL::Object abIef_ = CGAL::intersection(
+ intersectionA.toPoint_2(),
+ Segment_2( ef.startPoint().toPoint_2(), ef.endPoint().toPoint_2() )
+ );
+ const Point_2* abIef = CGAL::object_cast<Point_2>( &abIef_ ) ;
+ BOOST_REQUIRE( abIef != NULL );
+
+ Point intersectionB( *abIef );
+
+ BOOST_CHECK_EQUAL( intersectionA.toPoint_2(), intersectionB.toPoint_2() );
+}
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/LineStringTest.cpp b/test/unit/SFCGAL/LineStringTest.cpp
new file mode 100644
index 0000000..420633d
--- /dev/null
+++ b/test/unit/SFCGAL/LineStringTest.cpp
@@ -0,0 +1,404 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Envelope.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/GeometryCollection.h>
+
+using namespace SFCGAL ;
+using namespace boost::unit_test ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_LineStringTest )
+
+///LineString() ;
+BOOST_AUTO_TEST_CASE( defaultConstructor )
+{
+ LineString g;
+ BOOST_CHECK( g.isEmpty() );
+ BOOST_CHECK( ! g.is3D() );
+ BOOST_CHECK( ! g.isMeasured() );
+ BOOST_CHECK_EQUAL( g.numPoints(), 0U );
+}
+
+///LineString( const std::vector< Point > & points ) ;
+BOOST_AUTO_TEST_CASE( constructorFromVector )
+{
+ std::vector< Point > points ;
+ points.push_back( Point( 1.0,1.0 ) );
+ points.push_back( Point( 2.0,2.0 ) );
+
+ LineString g( points );
+ BOOST_REQUIRE_EQUAL( g.numPoints(), 2U );
+ BOOST_CHECK_EQUAL( g.pointN( 0 ).x(), 1.0 );
+ BOOST_CHECK_EQUAL( g.pointN( 0 ).y(), 1.0 );
+ BOOST_CHECK_EQUAL( g.pointN( 1 ).x(), 2.0 );
+ BOOST_CHECK_EQUAL( g.pointN( 1 ).y(), 2.0 );
+}
+
+///LineString( const Point & startPoint, const Point & endPoint ) ;
+
+BOOST_AUTO_TEST_CASE( twoPointsConstructor )
+{
+ LineString g( Point( 0.0,0.0 ), Point( 2.0,3.0 ) );
+ BOOST_CHECK( ! g.isEmpty() );
+ BOOST_CHECK( ! g.is3D() );
+ BOOST_CHECK_EQUAL( g.asText( 1 ), "LINESTRING(0.0 0.0,2.0 3.0)" );
+}
+
+///LineString( LineString const& other ) ;
+///LineString& operator = ( const LineString & other ) ;
+///~LineString() ;
+
+
+///void clear() ;
+BOOST_AUTO_TEST_CASE( testClear )
+{
+ LineString g( Point( 0.0,0.0 ), Point( 1.0,1.0 ) );
+ g.clear();
+ BOOST_CHECK( g.isEmpty() );
+}
+
+///void reverse() ;
+BOOST_AUTO_TEST_CASE( testReverse_empty )
+{
+ LineString g ;
+ g.reverse();
+ BOOST_CHECK( g.isEmpty() );
+}
+BOOST_AUTO_TEST_CASE( testReverse_twoPoints )
+{
+ LineString g( Point( 0.0,0.0 ), Point( 1.0,1.0 ) );
+ g.reverse();
+ BOOST_CHECK_EQUAL( g.pointN( 0 ).x(), 1.0 );
+ BOOST_CHECK_EQUAL( g.pointN( 0 ).y(), 1.0 );
+ BOOST_CHECK_EQUAL( g.pointN( 1 ).x(), 0.0 );
+ BOOST_CHECK_EQUAL( g.pointN( 1 ).y(), 0.0 );
+}
+
+///inline size_t numPoints() const { return _points.size(); }
+
+///size_t numSegments() const ;
+BOOST_AUTO_TEST_CASE( testNumSegments_empty )
+{
+ LineString g ;
+ BOOST_CHECK_EQUAL( g.numSegments(), 0U );
+}
+BOOST_AUTO_TEST_CASE( testNumSegments_onlyOnePoint )
+{
+ LineString g ;
+ g.addPoint( Point( 0.0,0.0 ) );
+ BOOST_CHECK_EQUAL( g.numSegments(), 0U );
+}
+BOOST_AUTO_TEST_CASE( testNumSegments_twoPoints )
+{
+ LineString g( Point( 0.0,0.0 ), Point( 1.0,1.0 ) );
+ BOOST_CHECK_EQUAL( g.numSegments(), 1U );
+}
+
+///inline const Point & pointN( size_t const& n ) const
+///inline Point & pointN( size_t const& n )
+///inline const Point & startPoint() const { return _points.front(); }
+///inline Point & startPoint() { return _points.front(); }
+///inline const Point & endPoint() const { return _points.back(); }
+///inline Point & endPoint() { return _points.back(); }
+///inline void addPoint( const Point & p )
+///inline void addPoint( Point* p )
+
+///bool isClosed() const ;
+BOOST_AUTO_TEST_CASE( testIsClosed_empty )
+{
+ LineString g;
+ BOOST_CHECK( ! g.isClosed() );
+}
+BOOST_AUTO_TEST_CASE( testIsClosed_noClosed )
+{
+ LineString g;
+ g.addPoint( Point( 0.0,0.0 ) );
+ g.addPoint( Point( 1.0,0.0 ) );
+ g.addPoint( Point( 1.0,1.0 ) );
+ BOOST_CHECK( ! g.isClosed() );
+}
+BOOST_AUTO_TEST_CASE( testIsClosed_triangle )
+{
+ LineString g;
+ g.addPoint( Point( 0.0,0.0 ) );
+ g.addPoint( Point( 1.0,0.0 ) );
+ g.addPoint( Point( 1.0,1.0 ) );
+ g.addPoint( Point( 0.0,0.0 ) );
+ BOOST_CHECK( g.isClosed() );
+}
+
+///inline iterator begin()
+///inline const_iterator begin() const
+///inline iterator end()
+///inline const_iterator end() const
+BOOST_AUTO_TEST_CASE( simpleIteratorTest )
+{
+ LineString g;
+ g.addPoint( Point( 0.0, 0.0 ) );
+ g.addPoint( Point( 1.0, 1.0 ) );
+ g.addPoint( Point( 2.0, 2.0 ) );
+
+ LineString::const_iterator it = g.begin() ;
+ LineString::const_iterator end = g.end() ;
+ BOOST_CHECK_EQUAL( it->asText( 3 ), "POINT(0.000 0.000)" );
+ ++it ;
+ BOOST_CHECK( it != end );
+ BOOST_CHECK_EQUAL( it->asText( 3 ), "POINT(1.000 1.000)" );
+ ++it ;
+ BOOST_CHECK( it != end );
+ BOOST_CHECK_EQUAL( it->asText( 3 ), "POINT(2.000 2.000)" );
+ ++it ;
+ BOOST_CHECK( it == end );
+}
+
+
+BOOST_AUTO_TEST_CASE( iteratorTests )
+{
+ std::vector<Point> points;
+ points.push_back( Point( 2.0, 3.0, 1.0 ) );
+ points.push_back( Point( 4.0, 5.0, 1.0 ) );
+ points.push_back( Point( 6.0, 7.0, 1.0 ) );
+ points.push_back( Point( 8.0, 9.0, 1.0 ) );
+ LineString g( points );
+
+ LineString::Point_2_const_iterator pi, pi_end;
+ int i = 0;
+
+ for ( boost::tie( pi, pi_end ) = g.points_2(); pi != pi_end; pi++, i++ ) {
+ BOOST_CHECK_EQUAL( *pi, g.pointN( i ).toPoint_2() );
+ }
+
+ LineString::Point_3_const_iterator ppi, ppi_end;
+ i = 0;
+
+ for ( boost::tie( ppi, ppi_end ) = g.points_3(); ppi != ppi_end; ppi++, i++ ) {
+ BOOST_CHECK_EQUAL( *ppi, g.pointN( i ).toPoint_3() );
+ }
+}
+
+
+///void reserve( const size_t & n ) ;
+
+///CGAL::Polygon_2< Kernel > toPolygon_2() const;
+BOOST_AUTO_TEST_CASE( testToPolygon_2_Empty )
+{
+ LineString g ;
+ CGAL::Polygon_2< Kernel > polygon = g.toPolygon_2();
+ BOOST_CHECK( polygon.is_empty() );
+}
+BOOST_AUTO_TEST_CASE( testToPolygon_2_checkOrientation )
+{
+ LineString g ;
+ g.addPoint( Point( 0.0,0.0 ) );
+ g.addPoint( Point( 1.0,1.0 ) );
+ g.addPoint( Point( 1.0,0.0 ) );
+ g.addPoint( g.startPoint() );
+
+ //keep orientation
+ {
+ CGAL::Polygon_2< Kernel > polygon = g.toPolygon_2( false );
+ BOOST_CHECK( ! polygon.is_empty() );
+ BOOST_CHECK( polygon.is_clockwise_oriented() );
+ }
+ //fix orientation
+ {
+ CGAL::Polygon_2< Kernel > polygon = g.toPolygon_2( true );
+ BOOST_CHECK( ! polygon.is_empty() );
+ BOOST_CHECK( polygon.is_counterclockwise_oriented() );
+ }
+}
+
+
+//-- Geometry tests
+
+
+//virtual Geometry * Geometry::clone() const = 0 ;
+BOOST_AUTO_TEST_CASE( testClone )
+{
+ LineString g ;
+ g.addPoint( Point( 0.0,0.0 ) );
+ g.addPoint( Point( 1.0,1.0 ) );
+ std::auto_ptr< Geometry > copy( g.clone() );
+ BOOST_REQUIRE( copy->is< LineString >() );
+ BOOST_CHECK_EQUAL( copy->as< LineString >().numPoints(), 2U );
+}
+
+//virtual Geometry* Geometry::boundary() const ;
+BOOST_AUTO_TEST_CASE( testBoundary_empty )
+{
+ LineString g ;
+ std::auto_ptr< Geometry > boundary( g.boundary() );
+ BOOST_CHECK( boundary->isEmpty() );
+ BOOST_CHECK( boundary->is< GeometryCollection >() );
+}
+BOOST_AUTO_TEST_CASE( testBoundary_3points )
+{
+ LineString g ;
+ g.addPoint( Point( 0.0,0.0 ) );
+ g.addPoint( Point( 1.0,1.0 ) );
+ g.addPoint( Point( 2.0,2.0 ) );
+
+ std::auto_ptr< Geometry > boundary( g.boundary() );
+ BOOST_CHECK( ! boundary->isEmpty() );
+ BOOST_REQUIRE( boundary->is< MultiPoint >() );
+ BOOST_CHECK_EQUAL( boundary->numGeometries(), 2U );
+}
+BOOST_AUTO_TEST_CASE( testBoundary_closed )
+{
+ LineString g ;
+ g.addPoint( Point( 0.0,0.0 ) );
+ g.addPoint( Point( 1.0,1.0 ) );
+ g.addPoint( Point( 2.0,2.0 ) );
+ g.addPoint( g.startPoint() );
+
+ std::auto_ptr< Geometry > boundary( g.boundary() );
+ BOOST_CHECK( boundary->isEmpty() );
+ BOOST_CHECK( boundary->is< GeometryCollection >() );
+}
+
+
+//Envelope Geometry::envelope() const ;
+BOOST_AUTO_TEST_CASE( testEnvelope_empty )
+{
+ BOOST_CHECK( LineString().envelope().isEmpty() );
+}
+BOOST_AUTO_TEST_CASE( testEnvelope_2D )
+{
+ LineString g ;
+ g.addPoint( Point( 1.0,5.0 ) );
+ g.addPoint( Point( 2.0,7.0 ) );
+ g.addPoint( Point( 3.0,9.0 ) );
+
+ Envelope box = g.envelope() ;
+ BOOST_CHECK( ! box.isEmpty() );
+ BOOST_CHECK( ! box.is3D() );
+
+ BOOST_CHECK_EQUAL( box.xMin(), 1.0 );
+ BOOST_CHECK_EQUAL( box.xMax(), 3.0 );
+ BOOST_CHECK_EQUAL( box.yMin(), 5.0 );
+ BOOST_CHECK_EQUAL( box.yMax(), 9.0 );
+}
+BOOST_AUTO_TEST_CASE( testEnvelope_3D )
+{
+ LineString g ;
+ g.addPoint( Point( 1.0,5.0,11.0 ) );
+ g.addPoint( Point( 2.0,7.0,15.0 ) );
+ g.addPoint( Point( 3.0,9.0,17.0 ) );
+
+ Envelope box = g.envelope() ;
+ BOOST_CHECK( ! box.isEmpty() );
+ BOOST_CHECK( box.is3D() );
+
+ BOOST_CHECK_EQUAL( box.xMin(), 1.0 );
+ BOOST_CHECK_EQUAL( box.xMax(), 3.0 );
+ BOOST_CHECK_EQUAL( box.yMin(), 5.0 );
+ BOOST_CHECK_EQUAL( box.yMax(), 9.0 );
+ BOOST_CHECK_EQUAL( box.zMin(), 11.0 );
+ BOOST_CHECK_EQUAL( box.zMax(), 17.0 );
+}
+
+//std::string Geometry::asText( const int & numDecimals = -1 ) const ;
+BOOST_AUTO_TEST_CASE( asTextEmpty )
+{
+ LineString g;
+ BOOST_CHECK_EQUAL( g.asText( 1 ), "LINESTRING EMPTY" );
+}
+BOOST_AUTO_TEST_CASE( asText2d )
+{
+ LineString g(
+ Point( 2.0,3.0 ),
+ Point( 4.0,5.0 )
+ );
+ BOOST_CHECK_EQUAL( g.asText( 3 ), "LINESTRING(2.000 3.000,4.000 5.000)" );
+}
+BOOST_AUTO_TEST_CASE( asText3d )
+{
+ LineString g(
+ Point( 2.0,3.0,7.0 ),
+ Point( 4.0,5.0,8.0 )
+ );
+ BOOST_CHECK_EQUAL( g.asText( 3 ), "LINESTRING(2.000 3.000 7.000,4.000 5.000 8.000)" );
+}
+
+//virtual std::string Geometry::geometryType() const = 0 ;
+BOOST_AUTO_TEST_CASE( testGeometryType )
+{
+ LineString g;
+ BOOST_CHECK_EQUAL( g.geometryType(), "LineString" );
+}
+
+//virtual GeometryType Geometry::geometryTypeId() const = 0 ;
+BOOST_AUTO_TEST_CASE( testGeometryTypeId )
+{
+ LineString g;
+ BOOST_CHECK_EQUAL( g.geometryTypeId(), TYPE_LINESTRING );
+}
+
+//virtual int Geometry::dimension() const = 0 ;
+//virtual int Geometry::coordinateDimension() const = 0 ;
+
+//virtual bool Geometry::isEmpty() const = 0 ;
+BOOST_AUTO_TEST_CASE( testIsEmpty_true )
+{
+ LineString g;
+ BOOST_CHECK( g.isEmpty() );
+}
+BOOST_AUTO_TEST_CASE( testIsEmpty_false )
+{
+ LineString g( Point( 0.0,0.0 ), Point( 1.0,1.0 ) );
+ BOOST_CHECK( ! g.isEmpty() );
+}
+
+//virtual bool Geometry::is3D() const = 0 ;
+BOOST_AUTO_TEST_CASE( testIs3D_false )
+{
+ LineString g( Point( 0.0,0.0 ), Point( 1.0,1.0 ) );
+ BOOST_CHECK( ! g.is3D() );
+}
+BOOST_AUTO_TEST_CASE( testIs3D_true )
+{
+ LineString g( Point( 0.0,0.0,0.0 ), Point( 1.0,1.0,1.0 ) );
+ BOOST_CHECK( g.is3D() );
+}
+
+//virtual bool Geometry::isMeasured() const = 0 ;
+//virtual bool Geometry::isSimple() const = 0 ;
+
+//template < typename Derived > inline bool Geometry::is() const
+BOOST_AUTO_TEST_CASE( isLineString )
+{
+ LineString g;
+ BOOST_CHECK( g.is< LineString >() );
+}
+//template < typename Derived > inline const Derived & Geometry::as() const
+//template < typename Derived > inline Derived & Geometry::as()
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/MultiLineStringTest.cpp b/test/unit/SFCGAL/MultiLineStringTest.cpp
new file mode 100644
index 0000000..4c33d6a
--- /dev/null
+++ b/test/unit/SFCGAL/MultiLineStringTest.cpp
@@ -0,0 +1,89 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <exception>
+
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/MultiLineString.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_MultiLineStringTest )
+
+BOOST_AUTO_TEST_CASE( defaultConstructor )
+{
+ MultiLineString g;
+ BOOST_CHECK( g.isEmpty() ) ;
+ BOOST_CHECK( ! g.is3D() );
+ BOOST_CHECK_EQUAL( g.numGeometries(), 0U );
+}
+
+
+//-- addAllowedGeometry
+BOOST_AUTO_TEST_CASE( addLineString )
+{
+ MultiLineString g;
+ g.addGeometry( new LineString() );
+ BOOST_CHECK_EQUAL( g.numGeometries(), 1U );
+}
+//-- addForbidenGeometry
+BOOST_AUTO_TEST_CASE( addLineStringThrow )
+{
+ MultiLineString g;
+ BOOST_CHECK_THROW( g.addGeometry( Point() ), std::exception );
+}
+
+//-- asText
+
+BOOST_AUTO_TEST_CASE( asTextEmpty )
+{
+ MultiLineString g;
+ BOOST_CHECK_EQUAL( g.asText( 1 ), "MULTILINESTRING EMPTY" );
+}
+
+BOOST_AUTO_TEST_CASE( asText2d )
+{
+ MultiLineString g;
+ g.addGeometry( LineString( Point( 0.0,0.0 ), Point( 1.0,1.0 ) ) );
+ g.addGeometry( LineString( Point( 1.0,1.0 ), Point( 2.0,2.0 ) ) );
+ BOOST_CHECK_EQUAL( g.asText( 1 ), "MULTILINESTRING((0.0 0.0,1.0 1.0),(1.0 1.0,2.0 2.0))" );
+}
+
+//-- is< T >
+
+BOOST_AUTO_TEST_CASE( isGeometryCollection )
+{
+ MultiLineString g;
+ BOOST_CHECK( g.is< GeometryCollection >() );
+}
+
+BOOST_AUTO_TEST_CASE( isMultiLineString )
+{
+ MultiLineString g;
+ BOOST_CHECK( g.is< MultiLineString >() );
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/MultiPointTest.cpp b/test/unit/SFCGAL/MultiPointTest.cpp
new file mode 100644
index 0000000..b79a47a
--- /dev/null
+++ b/test/unit/SFCGAL/MultiPointTest.cpp
@@ -0,0 +1,94 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <exception>
+
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/MultiPoint.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_MultiPointTest )
+
+BOOST_AUTO_TEST_CASE( defaultConstructor )
+{
+ MultiPoint g;
+ BOOST_CHECK( g.isEmpty() ) ;
+ BOOST_CHECK( ! g.is3D() );
+ BOOST_CHECK_EQUAL( g.numGeometries(), 0U );
+}
+
+BOOST_AUTO_TEST_CASE( testGeometryTypeId )
+{
+ MultiPoint g;
+ BOOST_CHECK_EQUAL( g.geometryTypeId(), TYPE_MULTIPOINT );
+}
+
+//-- addAllowedGeometry
+BOOST_AUTO_TEST_CASE( addPoint )
+{
+ MultiPoint g;
+ g.addGeometry( new Point( 2.0, 3.0 ) );
+ BOOST_CHECK_EQUAL( g.numGeometries(), 1U );
+}
+//-- addForbidenGeometry
+BOOST_AUTO_TEST_CASE( addLineStringThrow )
+{
+ MultiPoint g;
+ BOOST_CHECK_THROW( g.addGeometry( LineString() ), std::exception );
+}
+
+//-- asText
+
+BOOST_AUTO_TEST_CASE( asTextEmpty )
+{
+ MultiPoint g;
+ BOOST_CHECK_EQUAL( g.asText( 1 ), "MULTIPOINT EMPTY" );
+}
+
+BOOST_AUTO_TEST_CASE( asText2d )
+{
+ MultiPoint g;
+ g.addGeometry( Point( 2.0,3.0 ) );
+ g.addGeometry( Point( 3.0,4.0 ) );
+ BOOST_CHECK_EQUAL( g.asText( 3 ), "MULTIPOINT((2.000 3.000),(3.000 4.000))" );
+}
+
+//-- is< T >
+
+BOOST_AUTO_TEST_CASE( isGeometryCollection )
+{
+ MultiPoint g;
+ BOOST_CHECK( g.is< GeometryCollection >() );
+}
+
+BOOST_AUTO_TEST_CASE( isMultiPoint )
+{
+ MultiPoint g;
+ BOOST_CHECK( g.is< MultiPoint >() );
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/MultiPolygonTest.cpp b/test/unit/SFCGAL/MultiPolygonTest.cpp
new file mode 100644
index 0000000..8ac8013
--- /dev/null
+++ b/test/unit/SFCGAL/MultiPolygonTest.cpp
@@ -0,0 +1,95 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <exception>
+
+#include <SFCGAL/Envelope.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/MultiPolygon.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_MultiPolygonTest )
+
+BOOST_AUTO_TEST_CASE( defaultConstructor )
+{
+ MultiPolygon g;
+ BOOST_CHECK( g.isEmpty() ) ;
+ BOOST_CHECK( ! g.is3D() );
+ BOOST_CHECK_EQUAL( g.numGeometries(), 0U );
+}
+
+BOOST_AUTO_TEST_CASE( testGeometryTypeId )
+{
+ MultiPolygon g;
+ BOOST_CHECK_EQUAL( g.geometryTypeId(), TYPE_MULTIPOLYGON );
+}
+
+//-- addAllowedGeometry
+BOOST_AUTO_TEST_CASE( addPolygon )
+{
+ MultiPolygon g;
+ g.addGeometry( new Polygon() );
+ BOOST_CHECK_EQUAL( g.numGeometries(), 1U );
+}
+//-- addForbidenGeometry
+BOOST_AUTO_TEST_CASE( addLineStringThrow )
+{
+ MultiPolygon g;
+ BOOST_CHECK_THROW( g.addGeometry( LineString() ), std::exception );
+}
+
+//-- asText
+
+BOOST_AUTO_TEST_CASE( asTextEmpty )
+{
+ MultiPolygon g;
+ BOOST_CHECK_EQUAL( g.asText( 1 ), "MULTIPOLYGON EMPTY" );
+}
+BOOST_AUTO_TEST_CASE( asText2d )
+{
+ MultiPolygon g;
+ g.addGeometry( Envelope( 0.0,1.0,0.0,1.0 ).toPolygon().release() );
+ g.addGeometry( Envelope( 2.0,3.0,4.0,5.0 ).toPolygon().release() );
+ BOOST_CHECK_EQUAL( g.asText( 3 ), "MULTIPOLYGON(((0.000 0.000,1.000 0.000,1.000 1.000,0.000 1.000,0.000 0.000)),((2.000 4.000,3.000 4.000,3.000 5.000,2.000 5.000,2.000 4.000)))" );
+}
+
+//-- is< T >
+
+BOOST_AUTO_TEST_CASE( isGeometryCollection )
+{
+ MultiPolygon g;
+ BOOST_CHECK( g.is< GeometryCollection >() );
+}
+
+BOOST_AUTO_TEST_CASE( isMultiPolygon )
+{
+ MultiPolygon g;
+ BOOST_CHECK( g.is< MultiPolygon >() );
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/MultiSolidTest.cpp b/test/unit/SFCGAL/MultiSolidTest.cpp
new file mode 100644
index 0000000..a93a0ac
--- /dev/null
+++ b/test/unit/SFCGAL/MultiSolidTest.cpp
@@ -0,0 +1,95 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <exception>
+
+#include <SFCGAL/Envelope.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/MultiSolid.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_MultiSolidTest )
+
+BOOST_AUTO_TEST_CASE( defaultConstructor )
+{
+ MultiSolid g;
+ BOOST_CHECK( g.isEmpty() ) ;
+ BOOST_CHECK( ! g.is3D() );
+ BOOST_CHECK_EQUAL( g.numGeometries(), 0U );
+}
+
+BOOST_AUTO_TEST_CASE( testGeometryTypeId )
+{
+ MultiSolid g;
+ BOOST_CHECK_EQUAL( g.geometryTypeId(), TYPE_MULTISOLID );
+}
+
+//-- addAllowedGeometry
+BOOST_AUTO_TEST_CASE( addSolid )
+{
+ MultiSolid g;
+ g.addGeometry( new Solid() );
+ BOOST_CHECK_EQUAL( g.numGeometries(), 1U );
+}
+//-- addForbidenGeometry
+BOOST_AUTO_TEST_CASE( addLineStringThrow )
+{
+ MultiSolid g;
+ BOOST_CHECK_THROW( g.addGeometry( LineString() ), std::exception );
+}
+
+//-- asText
+
+BOOST_AUTO_TEST_CASE( asTextEmpty )
+{
+ MultiSolid g;
+ BOOST_CHECK_EQUAL( g.asText( 1 ), "MULTISOLID EMPTY" );
+}
+BOOST_AUTO_TEST_CASE( asText2d )
+{
+ MultiSolid g;
+ g.addGeometry( Envelope( 0.0,1.0,0.0,1.0,0.0,1.0 ).toSolid().release() );
+ g.addGeometry( Envelope( 2.0,3.0,4.0,5.0,6.0,7.0 ).toSolid().release() );
+ BOOST_CHECK_EQUAL( g.asText( 0 ), "MULTISOLID(((((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),((0 0 1,1 0 1,1 1 1,0 1 1,0 0 1)),((0 0 0,1 0 0,1 0 1,0 0 1,0 0 0)),((1 1 0,0 1 0,0 1 1,1 1 1,1 1 0)),((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)),((0 0 0,0 0 1,0 1 1,0 1 0,0 0 0)))),((((2 4 6,2 5 6,3 5 6,3 4 6,2 4 6)),((2 4 7,3 4 7,3 5 7,2 5 7,2 4 7)),((2 4 6,3 4 6,3 4 7,2 4 7,2 4 6)),((3 5 6,2 5 6,2 5 7,3 5 7,3 5 6)),((3 4 6,3 5 6,3 5 7,3 4 7,3 4 6)),((2 4 6,2 4 7,2 5 7,2 5 6,2 4 6)))))" );
+}
+
+//-- is< T >
+
+BOOST_AUTO_TEST_CASE( isGeometryCollection )
+{
+ MultiSolid g;
+ BOOST_CHECK( g.is< GeometryCollection >() );
+}
+
+BOOST_AUTO_TEST_CASE( isMultiSolid )
+{
+ MultiSolid g;
+ BOOST_CHECK( g.is< MultiSolid >() );
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/NumericTest.cpp b/test/unit/SFCGAL/NumericTest.cpp
new file mode 100644
index 0000000..a4f121f
--- /dev/null
+++ b/test/unit/SFCGAL/NumericTest.cpp
@@ -0,0 +1,70 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <exception>
+
+#include <SFCGAL/numeric.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_NumericTest )
+
+BOOST_AUTO_TEST_CASE( testNaNAndIsNaN )
+{
+ BOOST_CHECK( NaN() != NaN() );
+ BOOST_CHECK( ! isNaN( 0.0 ) );
+ BOOST_CHECK( isNaN( NaN() ) );
+}
+
+BOOST_AUTO_TEST_CASE( testFloorRational )
+{
+ BOOST_CHECK_EQUAL( SFCGAL::floor( CGAL::Gmpq( 0 ) ), 0 ) ;
+ BOOST_CHECK_EQUAL( SFCGAL::floor( CGAL::Gmpq( 1,2 ) ), 0 ) ;
+ BOOST_CHECK_EQUAL( SFCGAL::floor( CGAL::Gmpq( 1,3 ) ), 0 ) ;
+ BOOST_CHECK_EQUAL( SFCGAL::floor( CGAL::Gmpq( 2,3 ) ), 0 ) ;
+ BOOST_CHECK_EQUAL( SFCGAL::floor( CGAL::Gmpq( 1,1 ) ), 1 ) ;
+ BOOST_CHECK_EQUAL( SFCGAL::floor( CGAL::Gmpq( 4,3 ) ), 1 ) ;
+}
+
+BOOST_AUTO_TEST_CASE( testCeilRational )
+{
+ BOOST_CHECK_EQUAL( SFCGAL::ceil( CGAL::Gmpq( 0 ) ), 0 ) ;
+ BOOST_CHECK_EQUAL( SFCGAL::ceil( CGAL::Gmpq( 1,2 ) ), 1 ) ;
+ BOOST_CHECK_EQUAL( SFCGAL::ceil( CGAL::Gmpq( 1,3 ) ), 1 ) ;
+ BOOST_CHECK_EQUAL( SFCGAL::ceil( CGAL::Gmpq( 1,1 ) ), 1 ) ;
+ BOOST_CHECK_EQUAL( SFCGAL::ceil( CGAL::Gmpq( 4,3 ) ), 2 ) ;
+}
+
+BOOST_AUTO_TEST_CASE( testRoundRational )
+{
+ BOOST_CHECK_EQUAL( SFCGAL::round( CGAL::Gmpq( 0 ) ), 0 ) ;
+ BOOST_CHECK_EQUAL( SFCGAL::round( CGAL::Gmpq( 1,2 ) ), 1 ) ;
+ BOOST_CHECK_EQUAL( SFCGAL::round( CGAL::Gmpq( 1,3 ) ), 0 ) ;
+ BOOST_CHECK_EQUAL( SFCGAL::round( CGAL::Gmpq( 1,1 ) ), 1 ) ;
+ BOOST_CHECK_EQUAL( SFCGAL::round( CGAL::Gmpq( 4,3 ) ), 1 ) ;
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/PointTest.cpp b/test/unit/SFCGAL/PointTest.cpp
new file mode 100644
index 0000000..d6b4eb1
--- /dev/null
+++ b/test/unit/SFCGAL/PointTest.cpp
@@ -0,0 +1,279 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <SFCGAL/Kernel.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/Envelope.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/Exception.h>
+
+#include <boost/test/unit_test.hpp>
+using namespace boost::unit_test ;
+
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_PointTest )
+
+
+//Point() ;
+BOOST_AUTO_TEST_CASE( defaultConstructor )
+{
+ Point g;
+ BOOST_CHECK( g.isEmpty() ) ;
+ BOOST_CHECK( ! g.is3D() );
+ BOOST_CHECK( ! g.isMeasured() );
+
+ // no more access to double
+ BOOST_CHECK_THROW( g.x(), Exception );
+ BOOST_CHECK_THROW( g.y(), Exception );
+ BOOST_CHECK_THROW( g.z(), Exception );
+ BOOST_CHECK( isNaN( g.m() ) );
+}
+
+//Point( const Coordinate & coordinate ) ;
+
+//Point( const Kernel::FT & x, const Kernel::FT & y ) ;
+BOOST_AUTO_TEST_CASE( xyConstructor )
+{
+ Point g( 2.0,3.0 );
+ BOOST_CHECK( ! g.isEmpty() ) ;
+ BOOST_CHECK( ! g.is3D() );
+ BOOST_CHECK_EQUAL( g.x(), 2.0 );
+ BOOST_CHECK_EQUAL( g.y(), 3.0 );
+ BOOST_CHECK_EQUAL( g.z(), 0 );
+}
+
+//Point( const Kernel::FT & x, const Kernel::FT & y, const Kernel::FT & z ) ;
+//Point( const double & x, const double & y, const double & z = NaN() ) ;
+BOOST_AUTO_TEST_CASE( xyzConstructor )
+{
+ Point g( 2.0,3.0,4.0 );
+ BOOST_CHECK( ! g.isEmpty() ) ;
+ BOOST_CHECK( g.is3D() );
+ BOOST_CHECK_EQUAL( g.x(), 2.0 );
+ BOOST_CHECK_EQUAL( g.y(), 3.0 );
+ BOOST_CHECK_EQUAL( g.z(), 4.0 );
+}
+//Point( const Kernel::Point_2 & other ) ;
+//Point( const Kernel::Point_3 & other ) ;
+//Point( const Point & other ) ;
+//Point& operator = ( const Point & other ) ;
+//~Point() ;
+
+
+//-- tested in Coordinate
+//inline Kernel::RT x() const { return _coordinate.x() ; }
+//inline Kernel::RT y() const { return _coordinate.y() ; }
+//inline Kernel::RT z() const { return _coordinate.z() ; }
+
+//inline double m() const { return _m ; }
+//inline void setM( const double & m ) { _m = m ; }
+BOOST_AUTO_TEST_CASE( testGetSetM )
+{
+ Point p( 3.0,4.0 );
+ BOOST_CHECK( ! p.isMeasured() );
+ BOOST_CHECK( isNaN( p.m() ) );
+ p.setM( 5.0 );
+ BOOST_CHECK_EQUAL( p.m(), 5.0 );
+}
+
+//bool operator < ( const Point & other ) const ;
+//bool operator == ( const Point & other ) const ;
+//bool operator != ( const Point & other ) const ;
+
+
+//inline Kernel::Vector_2 toVector_2() const
+//inline Kernel::Vector_3 toVector_3() const
+//inline Kernel::Point_2 toPoint_2() const
+//inline Kernel::Point_3 toPoint_3() const
+BOOST_AUTO_TEST_CASE( emptyToVector_2 )
+{
+ Point g ;
+ CGAL::Vector_2< Kernel > p = g.toVector_2();
+ BOOST_CHECK_EQUAL( CGAL::to_double( p.x() ), 0.0 );
+ BOOST_CHECK_EQUAL( CGAL::to_double( p.y() ), 0.0 );
+}
+BOOST_AUTO_TEST_CASE( xyToVector_2 )
+{
+ Point g( 3.0, 4.0 );
+ CGAL::Vector_2< Kernel > p = g.toVector_2();
+ BOOST_CHECK_EQUAL( CGAL::to_double( p.x() ), 3.0 );
+ BOOST_CHECK_EQUAL( CGAL::to_double( p.y() ), 4.0 );
+}
+BOOST_AUTO_TEST_CASE( xyToVector_3 )
+{
+ Point g( 3.0, 4.0 );
+ CGAL::Vector_3< Kernel > p = g.toVector_3();
+
+ BOOST_CHECK_EQUAL( CGAL::to_double( p.x() ), 3.0 );
+ BOOST_CHECK_EQUAL( CGAL::to_double( p.y() ), 4.0 );
+ BOOST_CHECK_EQUAL( CGAL::to_double( p.z() ), 0.0 );
+}
+
+
+//template <int D> typename TypeForDimension<D>::Point toPoint_d() const;
+//inline Coordinate & coordinate() { return _coordinate; }
+//inline const Coordinate & coordinate() const { return _coordinate; }
+
+
+//-- SFCGAL::Geometry
+
+//virtual Geometry * Geometry::clone() const = 0 ;
+BOOST_AUTO_TEST_CASE( testClone )
+{
+ Point p( 3.0,4.0 );
+ std::auto_ptr< Geometry > copy( p.clone() );
+ BOOST_REQUIRE( copy->is< Point >() );
+ BOOST_CHECK_EQUAL( copy->as< Point >().x(), 3.0 );
+ BOOST_CHECK_EQUAL( copy->as< Point >().y(), 4.0 );
+}
+
+//virtual Geometry* Geometry::boundary() const ;
+BOOST_AUTO_TEST_CASE( testBoundary )
+{
+ Point p( 3.0,4.0 );
+ std::auto_ptr< Geometry > boundary( p.boundary() );
+ BOOST_CHECK( boundary->isEmpty() );
+ BOOST_CHECK( boundary->is< GeometryCollection >() );
+}
+
+//Envelope Geometry::envelope() const ;
+BOOST_AUTO_TEST_CASE( testEnvelope_empty )
+{
+ BOOST_CHECK( Point().envelope().isEmpty() );
+}
+BOOST_AUTO_TEST_CASE( testEnvelope_2D )
+{
+ Point g( 3.0,4.0 );
+ Envelope box = g.envelope() ;
+ BOOST_CHECK( ! box.isEmpty() );
+ BOOST_CHECK( ! box.is3D() );
+
+ BOOST_CHECK_EQUAL( box.xMin(), 3.0 );
+ BOOST_CHECK_EQUAL( box.xMax(), 3.0 );
+ BOOST_CHECK_EQUAL( box.yMin(), 4.0 );
+ BOOST_CHECK_EQUAL( box.yMax(), 4.0 );
+}
+BOOST_AUTO_TEST_CASE( testEnvelope_3D )
+{
+ Point g( 3.0,4.0,5.0 );
+ Envelope box = g.envelope() ;
+ BOOST_CHECK( ! box.isEmpty() );
+ BOOST_CHECK( box.is3D() );
+
+ BOOST_CHECK_EQUAL( box.xMin(), 3.0 );
+ BOOST_CHECK_EQUAL( box.xMax(), 3.0 );
+ BOOST_CHECK_EQUAL( box.yMin(), 4.0 );
+ BOOST_CHECK_EQUAL( box.yMax(), 4.0 );
+ BOOST_CHECK_EQUAL( box.zMin(), 5.0 );
+ BOOST_CHECK_EQUAL( box.zMax(), 5.0 );
+}
+
+
+//std::string Geometry::asText( const int & numDecimals = -1 ) const ;
+BOOST_AUTO_TEST_CASE( asTextEmpty )
+{
+ Point g;
+ BOOST_CHECK_EQUAL( g.asText( 1 ), "POINT EMPTY" );
+}
+BOOST_AUTO_TEST_CASE( asText2d )
+{
+ Point g( 2.0,3.0 );
+ BOOST_CHECK_EQUAL( g.asText( 3 ), "POINT(2.000 3.000)" );
+}
+BOOST_AUTO_TEST_CASE( asText3d )
+{
+ Point g( 2.0,3.0,4.0 );
+ BOOST_CHECK_EQUAL( g.asText( 3 ), "POINT(2.000 3.000 4.000)" );
+}
+
+//virtual std::string Geometry::geometryType() const = 0 ;
+BOOST_AUTO_TEST_CASE( testGeometryType )
+{
+ Point g;
+ BOOST_CHECK_EQUAL( g.geometryType(), "Point" );
+}
+//virtual GeometryType Geometry::geometryTypeId() const = 0 ;
+BOOST_AUTO_TEST_CASE( testGeometryTypeId )
+{
+ Point g;
+ BOOST_CHECK_EQUAL( g.geometryTypeId(), TYPE_POINT );
+}
+
+//virtual int Geometry::dimension() const = 0 ;
+BOOST_AUTO_TEST_CASE( testDimension )
+{
+ Point g;
+ BOOST_CHECK_EQUAL( g.dimension(), 0 );
+}
+
+//virtual int Geometry::coordinateDimension() const = 0 ;
+BOOST_AUTO_TEST_CASE( testCoordinateDimension )
+{
+ BOOST_CHECK_EQUAL( Point().coordinateDimension(), 0 );
+ BOOST_CHECK_EQUAL( Point( 2.0,3.0 ).coordinateDimension(), 2 );
+ BOOST_CHECK_EQUAL( Point( 2.0,3.0,4.0 ).coordinateDimension(), 3 );
+}
+//virtual bool Geometry::isEmpty() const = 0 ;
+BOOST_AUTO_TEST_CASE( testIsEmpty )
+{
+ BOOST_CHECK( Point().isEmpty() );
+ BOOST_CHECK( ! Point( 2.0,3.0 ).isEmpty() );
+}
+//virtual bool Geometry::is3D() const = 0 ;
+BOOST_AUTO_TEST_CASE( testIs3D )
+{
+ BOOST_CHECK( ! Point().is3D() );
+ BOOST_CHECK( ! Point( 2.0,3.0 ).is3D() );
+ BOOST_CHECK( Point( 2.0,3.0,4.0 ).is3D() );
+}
+//virtual bool Geometry::isMeasured() const = 0 ;
+BOOST_AUTO_TEST_CASE( testIsMeasured )
+{
+ BOOST_CHECK( ! Point().isMeasured() );
+ BOOST_CHECK( ! Point( 2.0,3.0 ).isMeasured() );
+ BOOST_CHECK( ! Point( 2.0,3.0,4.0 ).isMeasured() );
+ BOOST_CHECK( Point( 2.0,3.0,4.0,5.0 ).isMeasured() );
+}
+
+//TODO
+//virtual bool Geometry::isSimple() const = 0 ;
+
+//template < typename Derived > inline bool Geometry::is() const
+BOOST_AUTO_TEST_CASE( isPoint )
+{
+ Point g;
+ BOOST_CHECK( g.is< Point >() );
+}
+//template < typename Derived > inline const Derived & Geometry::as() const
+//template < typename Derived > inline Derived & Geometry::as()
+BOOST_AUTO_TEST_CASE( asPoint )
+{
+ std::auto_ptr< Geometry > g( new Point() );
+ BOOST_CHECK( g->as< Point >().isEmpty() );
+}
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/PolygonTest.cpp b/test/unit/SFCGAL/PolygonTest.cpp
new file mode 100644
index 0000000..e0868c2
--- /dev/null
+++ b/test/unit/SFCGAL/PolygonTest.cpp
@@ -0,0 +1,256 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/io/wkt.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_PolygonTest )
+
+//Polygon() ;
+BOOST_AUTO_TEST_CASE( defaultConstructor )
+{
+ Polygon g;
+ BOOST_CHECK( g.isEmpty() );
+ BOOST_CHECK( ! g.is3D() );
+ BOOST_CHECK_EQUAL( g.numInteriorRings(), 0U );
+}
+
+//Polygon( const std::vector< LineString > & rings ) ;
+//Polygon( const LineString & exteriorRing ) ;
+BOOST_AUTO_TEST_CASE( exteriorRingConstructor )
+{
+ LineString exteriorRing ;
+ exteriorRing.addPoint( Point( 0.0,0.0 ) );
+ exteriorRing.addPoint( Point( 1.0,0.0 ) );
+ exteriorRing.addPoint( Point( 1.0,1.0 ) );
+ exteriorRing.addPoint( Point( 0.0,1.0 ) );
+ exteriorRing.addPoint( Point( 0.0,0.0 ) );
+
+ Polygon g( exteriorRing );
+ BOOST_CHECK( ! g.isEmpty() );
+ BOOST_CHECK( ! g.is3D() );
+ BOOST_CHECK_EQUAL( g.numInteriorRings(), 0U );
+ BOOST_CHECK_EQUAL( g.exteriorRing().numPoints(), 5U );
+}
+BOOST_AUTO_TEST_CASE( exteriorRingConstructor3D )
+{
+ Polygon g;
+ g.exteriorRing().addPoint( Point( 0.0,0.0,2.0 ) );
+ g.exteriorRing().addPoint( Point( 1.0,0.0,2.0 ) );
+ g.exteriorRing().addPoint( Point( 1.0,1.0,2.0 ) );
+ g.exteriorRing().addPoint( Point( 0.0,1.0,2.0 ) );
+ g.exteriorRing().addPoint( Point( 0.0,0.0,2.0 ) );
+
+ BOOST_CHECK( ! g.isEmpty() );
+ BOOST_CHECK( g.is3D() );
+ BOOST_CHECK_EQUAL( g.numInteriorRings(), 0U );
+}
+
+
+//Polygon( LineString * exteriorRing ) ;
+//Polygon( const Triangle & triangle ) ;
+BOOST_AUTO_TEST_CASE( testConstructorTriangle )
+{
+ Polygon g(
+ Triangle(
+ Point( 0.0,0.0 ),
+ Point( 0.0,1.0 ),
+ Point( 1.0,1.0 )
+ )
+ );
+ BOOST_CHECK_EQUAL( g.numRings(), 1U );
+ BOOST_CHECK_EQUAL( g.exteriorRing().numPoints(), 4U );
+}
+
+//Polygon( Polygon const& other ) ;
+
+//Polygon( const CGAL::Polygon_2< Kernel >& other );
+//Polygon( const CGAL::Polygon_with_holes_2< Kernel >& poly );
+
+//Polygon& operator = ( const Polygon & other ) ;
+//~Polygon() ;
+
+
+//bool isCounterClockWiseOriented() const;
+
+//void reverse() ;
+BOOST_AUTO_TEST_CASE( testReverse )
+{
+ Polygon g(
+ Triangle(
+ Point( 0.0,0.0 ),
+ Point( 1.0,0.0 ),
+ Point( 1.0,1.0 )
+ )
+ );
+ BOOST_CHECK( g.isCounterClockWiseOriented() );
+ g.reverse();
+ BOOST_CHECK( ! g.isCounterClockWiseOriented() );
+}
+//TODO same with holes
+
+//inline const LineString & exteriorRing() const
+//inline LineString & exteriorRing()
+//inline void setExteriorRing( const LineString& ring )
+//inline void setExteriorRing( LineString* ring )
+//inline bool hasInteriorRings() const
+//inline size_t numInteriorRings() const
+//inline const LineString & interiorRingN( const size_t & n ) const
+//inline LineString & interiorRingN( const size_t & n )
+//inline size_t numRings() const
+//inline const LineString & ringN( const size_t & n ) const
+//inline LineString & ringN( const size_t & n )
+//inline void addInteriorRing( const LineString & ls )
+//inline void addInteriorRing( LineString* ls )
+//inline void addRing( const LineString & ls )
+//inline void addRing( LineString* ls )
+//inline iterator begin() { return _rings.begin() ; }
+//inline const_iterator begin() const { return _rings.begin() ; }
+//inline iterator end() { return _rings.end() ; }
+//inline const_iterator end() const { return _rings.end() ; }
+
+
+
+//CGAL::Polygon_2<Kernel> toPolygon_2( bool fixOrientation = true ) const;
+//CGAL::Polygon_with_holes_2<Kernel> toPolygon_with_holes_2( bool fixOrientation = true ) const;
+
+
+
+//-- Geometry
+
+//virtual Geometry * Geometry::clone() const = 0 ;
+BOOST_AUTO_TEST_CASE( testClone )
+{
+ LineString exteriorRing ;
+ exteriorRing.addPoint( Point( 0.0,0.0 ) );
+ exteriorRing.addPoint( Point( 1.0,0.0 ) );
+ exteriorRing.addPoint( Point( 1.0,1.0 ) );
+ exteriorRing.addPoint( Point( 0.0,1.0 ) );
+ exteriorRing.addPoint( Point( 0.0,0.0 ) );
+
+ Polygon g( exteriorRing );
+ std::auto_ptr< Polygon > copy( g.clone() );
+
+ BOOST_CHECK( ! copy->isEmpty() );
+ BOOST_CHECK( ! copy->is3D() );
+ BOOST_CHECK_EQUAL( copy->numInteriorRings(), 0U );
+ BOOST_CHECK_EQUAL( copy->exteriorRing().numPoints(), 5U );
+}
+
+//virtual Geometry* Geometry::boundary() const ;
+BOOST_AUTO_TEST_CASE( testBoundaryEmpty )
+{
+ std::auto_ptr< Geometry > boundary( Polygon().boundary() );
+ BOOST_CHECK( boundary->isEmpty() );
+ BOOST_CHECK( boundary->is< GeometryCollection >() );
+}
+BOOST_AUTO_TEST_CASE( testBoundaryWithoutHoles )
+{
+ std::string wkt( "POLYGON((0 0,0 1,1 1,0 0))" ) ;
+ std::auto_ptr< Geometry > boundary( io::readWkt( wkt )->boundary() );
+ BOOST_CHECK( ! boundary->isEmpty() );
+ BOOST_CHECK_EQUAL( boundary->asText( 0 ), "LINESTRING(0 0,0 1,1 1,0 0)" );
+}
+BOOST_AUTO_TEST_CASE( testBoundaryWithHoles )
+{
+ std::string wkt( "POLYGON((0 0,0 5,5 5,0 5,0 0),(1 1,2 1,2 2,1 1))" ) ;
+ std::auto_ptr< Geometry > boundary( io::readWkt( wkt )->boundary() );
+ BOOST_CHECK( ! boundary->isEmpty() );
+ BOOST_CHECK_EQUAL( boundary->asText( 0 ), "MULTILINESTRING((0 0,0 5,5 5,0 5,0 0),(1 1,2 1,2 2,1 1))" );
+}
+
+//Envelope Geometry::envelope() const ;
+
+//std::string Geometry::asText( const int & numDecimals = -1 ) const ;
+BOOST_AUTO_TEST_CASE( asTextEmpty )
+{
+ Polygon g;
+ BOOST_CHECK_EQUAL( g.asText( 1 ), "POLYGON EMPTY" );
+}
+BOOST_AUTO_TEST_CASE( asText2d )
+{
+ Polygon g;
+ g.exteriorRing().addPoint( Point( 0.0,0.0 ) );
+ g.exteriorRing().addPoint( Point( 1.0,0.0 ) );
+ g.exteriorRing().addPoint( Point( 1.0,1.0 ) );
+ g.exteriorRing().addPoint( Point( 0.0,1.0 ) );
+ g.exteriorRing().addPoint( Point( 0.0,0.0 ) );
+
+ BOOST_CHECK_EQUAL( g.asText( 1 ), "POLYGON((0.0 0.0,1.0 0.0,1.0 1.0,0.0 1.0,0.0 0.0))" );
+}
+BOOST_AUTO_TEST_CASE( asText3d )
+{
+ Polygon g;
+ g.exteriorRing().addPoint( Point( 0.0,0.0,2.0 ) );
+ g.exteriorRing().addPoint( Point( 1.0,0.0,2.0 ) );
+ g.exteriorRing().addPoint( Point( 1.0,1.0,2.0 ) );
+ g.exteriorRing().addPoint( Point( 0.0,1.0,2.0 ) );
+ g.exteriorRing().addPoint( Point( 0.0,0.0,2.0 ) );
+
+ BOOST_CHECK_EQUAL( g.asText( 1 ), "POLYGON((0.0 0.0 2.0,1.0 0.0 2.0,1.0 1.0 2.0,0.0 1.0 2.0,0.0 0.0 2.0))" );
+}
+//virtual std::string Geometry::geometryType() const = 0 ;
+BOOST_AUTO_TEST_CASE( testGeometryType )
+{
+ Polygon g;
+ BOOST_CHECK_EQUAL( g.geometryType(), "Polygon" );
+}
+//virtual GeometryType Geometry::geometryTypeId() const = 0 ;
+BOOST_AUTO_TEST_CASE( testGeometryTypeId )
+{
+ Polygon g;
+ BOOST_CHECK_EQUAL( g.geometryTypeId(), TYPE_POLYGON );
+}
+//virtual int Geometry::dimension() const = 0 ;
+BOOST_AUTO_TEST_CASE( testDimension )
+{
+ Polygon g;
+ BOOST_CHECK_EQUAL( g.dimension(), 2 );
+}
+//virtual int Geometry::coordinateDimension() const = 0 ;
+//virtual bool Geometry::isEmpty() const = 0 ;
+//virtual bool Geometry::is3D() const = 0 ;
+//virtual bool Geometry::isMeasured() const = 0 ;
+//virtual bool Geometry::isSimple() const = 0 ;
+
+//template < typename Derived > inline bool Geometry::is() const
+BOOST_AUTO_TEST_CASE( isPolygon )
+{
+ Polygon g;
+ BOOST_CHECK( g.is< Polygon >() );
+}
+//template < typename Derived > inline const Derived & Geometry::as() const
+//template < typename Derived > inline Derived & Geometry::as()
+
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/SolidTest.cpp b/test/unit/SFCGAL/SolidTest.cpp
new file mode 100644
index 0000000..3b5a9a4
--- /dev/null
+++ b/test/unit/SFCGAL/SolidTest.cpp
@@ -0,0 +1,114 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <SFCGAL/Kernel.h>
+
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/io/wkt.h>
+
+#include <boost/test/unit_test.hpp>
+using namespace boost::unit_test ;
+
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_SolidTest )
+
+//Solid() ;
+//Solid( const PolyhedralSurface & exteriorShell ) ;
+//Solid( PolyhedralSurface * exteriorShell ) ;
+//Solid( const std::vector< PolyhedralSurface > & shells ) ;
+//Solid( Solid const& other ) ;
+//Solid& operator = ( const Solid & other ) ;
+//~Solid() ;
+
+//inline const PolyhedralSurface & exteriorShell() const { return _shells[0] ; }
+//inline PolyhedralSurface & exteriorShell() { return _shells[0] ; }
+//inline size_t numInteriorShells() const { return _shells.size() - 1 ; }
+//inline const PolyhedralSurface & interiorShellN( size_t const& n ) const { return _shells[n+1]; }
+//inline PolyhedralSurface & interiorShellN( size_t const& n ) { return _shells[n+1]; }
+//inline void addInteriorShell( const PolyhedralSurface & shell )
+//inline void addInteriorShell( PolyhedralSurface * shell )
+//inline size_t numShells() const {
+//inline const PolyhedralSurface & shellN( const size_t & n ) const {
+//inline PolyhedralSurface & shellN( const size_t & n ) {
+
+//-- iterators
+
+//inline iterator begin() { return _shells.begin() ; }
+//inline const_iterator begin() const { return _shells.begin() ; }
+//inline iterator end() { return _shells.end() ; }
+//inline const_iterator end() const { return _shells.end() ; }
+
+
+//-- helpers
+
+//template < typename K > CGAL::Nef_polyhedron_3<K> toNef_polyhedron_3() const
+
+
+
+//virtual Geometry * Geometry::clone() const = 0 ;
+//virtual Geometry* Geometry::boundary() const ;
+//Envelope Geometry::envelope() const ;
+//std::string Geometry::asText( const int & numDecimals = -1 ) const ;
+//virtual std::string Geometry::geometryType() const = 0 ;
+//virtual GeometryType Geometry::geometryTypeId() const = 0 ;
+//virtual int Geometry::dimension() const = 0 ;
+//virtual int Geometry::coordinateDimension() const = 0 ;
+//virtual bool Geometry::isEmpty() const = 0 ;
+//virtual bool Geometry::is3D() const = 0 ;
+//virtual bool Geometry::isMeasured() const = 0 ;
+//virtual bool Geometry::isSimple() const = 0 ;
+//template < typename Derived > inline bool Geometry::is() const
+//template < typename Derived > inline const Derived & Geometry::as() const
+//template < typename Derived > inline Derived & Geometry::as()
+
+
+
+//-- other tests
+
+BOOST_AUTO_TEST_CASE( solidReadTest )
+{
+ // the unit cube where half of a cube has been substracted
+ std::string gstr = "SOLID("
+ // exterior shell
+ "("
+ "((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0))," // front face
+ "((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0))," // right face
+ "((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0))," // top face
+ "((0 0 1,0 1 1,0 1 0,0 0 0,0 0 1))," // left face
+ "((1 0 1,1 1 1,0 1 1,0 0 1,1 0 1))," // back face
+ "((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0))" // bottom face
+ "),"
+ // interior shell, a.k.a. a hole
+ "("
+ "((0 0 0,0 0.5 0,0.5 0.5 0,0.5 0 0,0 0 0))," // front face
+ "((0.5 0 0,0.5 0.5 0,0.5 0.5 0.5,0.5 0 0.5,0.5 0 0))," // right face
+ "((0 0.5 0,0 0.5 0.5,0.5 0.5 0.5,0.5 0.5 0,0 0.5 0))," // top face
+ "((0 0 0.5,0 0.5 0.5,0 0.5 0,0 0 0,0 0 0.5))," // left face
+ "((0.5 0 0.5,0.5 0.5 0.5,0 0.5 0.5,0 0 0.5,0.5 0 0.5))," // back face
+ "((0.5 0 0,0.5 0 0.5,0 0 0.5,0 0 0,0.5 0 0))" // bottom face
+ ")"
+ ")";
+
+ std::auto_ptr<Geometry> g( io::readWkt( gstr ) );
+ BOOST_CHECK_EQUAL( g->as< Solid >().numShells(),2U );
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/unit/SFCGAL/TriangleTest.cpp b/test/unit/SFCGAL/TriangleTest.cpp
new file mode 100644
index 0000000..a94e07a
--- /dev/null
+++ b/test/unit/SFCGAL/TriangleTest.cpp
@@ -0,0 +1,247 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <SFCGAL/Kernel.h>
+
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/Envelope.h>
+#include <SFCGAL/GeometryCollection.h>
+
+#include <boost/test/unit_test.hpp>
+using namespace boost::unit_test ;
+
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_TriangleTest )
+
+//Triangle();
+BOOST_AUTO_TEST_CASE( testDefaultConstructor )
+{
+ Triangle g ;
+ BOOST_CHECK( g.isEmpty() );
+}
+//Triangle( const Kernel::Triangle_2 & triangle ) ;
+BOOST_AUTO_TEST_CASE( testConstructorTriangle_2 )
+{
+ Kernel::Point_2 a( 0.0,0.0 );
+ Kernel::Point_2 b( 1.0,0.0 );
+ Kernel::Point_2 c( 1.0,1.0 );
+
+ Triangle g( Kernel::Triangle_2( a,b,c ) ) ;
+ BOOST_CHECK( ! g.isEmpty() );
+ BOOST_CHECK( ! g.is3D() ) ;
+
+ BOOST_CHECK_EQUAL( g.vertex( 0 ).toPoint_2(), a );
+ BOOST_CHECK_EQUAL( g.vertex( 1 ).toPoint_2(), b );
+ BOOST_CHECK_EQUAL( g.vertex( 2 ).toPoint_2(), c );
+}
+//Triangle( const Kernel::Triangle_3 & triangle ) ;
+BOOST_AUTO_TEST_CASE( testConstructorTriangle_3 )
+{
+ Kernel::Point_3 a( 0.0,0.0,1.0 );
+ Kernel::Point_3 b( 1.0,0.0,2.0 );
+ Kernel::Point_3 c( 1.0,1.0,3.0 );
+
+ Triangle g( Kernel::Triangle_3( a,b,c ) ) ;
+ BOOST_CHECK( ! g.isEmpty() );
+ BOOST_CHECK( g.is3D() ) ;
+
+ BOOST_CHECK_EQUAL( g.vertex( 0 ).toPoint_3(), a );
+ BOOST_CHECK_EQUAL( g.vertex( 1 ).toPoint_3(), b );
+ BOOST_CHECK_EQUAL( g.vertex( 2 ).toPoint_3(), c );
+}
+//Triangle( const Point & p, const Point & q, const Point & r );
+//Triangle( const Triangle & other );
+//Triangle& operator = ( const Triangle & other );
+//~Triangle();
+
+//void reverse() ;
+BOOST_AUTO_TEST_CASE( testReverse )
+{
+ Kernel::Point_3 a( 0.0,0.0,1.0 );
+ Kernel::Point_3 b( 1.0,0.0,2.0 );
+ Kernel::Point_3 c( 1.0,1.0,3.0 );
+
+ Triangle g( Kernel::Triangle_3( a,b,c ) ) ;
+ g.reverse();
+
+ BOOST_CHECK_EQUAL( g.vertex( 0 ).toPoint_3(), a );
+ BOOST_CHECK_EQUAL( g.vertex( 1 ).toPoint_3(), c );
+ BOOST_CHECK_EQUAL( g.vertex( 2 ).toPoint_3(), b );
+}
+
+//Polygon toPolygon() const ;
+
+//inline const Point & vertex( const int & i ) const
+//inline Point & vertex( const int & i )
+//inline Kernel::Triangle_2 toTriangle_2() const
+//inline Kernel::Triangle_3 toTriangle_3() const
+
+//template < int D > inline typename TypeForDimension<D>::Triangle toTriangle_d() const
+
+
+//-- Geometry tests
+
+//virtual Geometry * Geometry::clone() const = 0 ;
+BOOST_AUTO_TEST_CASE( testClone )
+{
+ Kernel::Point_3 a( 0.0,0.0,1.0 );
+ Kernel::Point_3 b( 1.0,0.0,2.0 );
+ Kernel::Point_3 c( 1.0,1.0,3.0 );
+
+ Triangle g( Kernel::Triangle_3( a,b,c ) ) ;
+
+ std::auto_ptr< Geometry > copy( g.clone() );
+ BOOST_REQUIRE( copy->is< Triangle >() );
+ BOOST_CHECK_EQUAL( copy->asText( 0 ), "TRIANGLE((0 0 1,1 0 2,1 1 3,0 0 1))" );
+}
+
+//virtual Geometry* Geometry::boundary() const ;
+BOOST_AUTO_TEST_CASE( testBoundary )
+{
+ Kernel::Point_2 a( 0.0,0.0 );
+ Kernel::Point_2 b( 1.0,0.0 );
+ Kernel::Point_2 c( 1.0,1.0 );
+
+ Triangle g( Kernel::Triangle_2( a,b,c ) ) ;
+
+ std::auto_ptr< Geometry > boundary( g.boundary() );
+ BOOST_CHECK_EQUAL( boundary->asText( 0 ), "LINESTRING(0 0,1 0,1 1,0 0)" );
+}
+
+//Envelope Geometry::envelope() const ;
+BOOST_AUTO_TEST_CASE( testEnvelope_empty )
+{
+ Triangle g ;
+
+ Envelope bbox = g.envelope() ;
+ BOOST_CHECK( bbox.isEmpty() );
+}
+BOOST_AUTO_TEST_CASE( testEnvelope_2d )
+{
+ Kernel::Point_2 a( 0.0,-1.0 );
+ Kernel::Point_2 b( 0.5,0.2 );
+ Kernel::Point_2 c( 1.0,1.5 );
+
+ Triangle g( Kernel::Triangle_2( a,b,c ) ) ;
+
+ Envelope bbox = g.envelope() ;
+ BOOST_CHECK( ! bbox.isEmpty() );
+ BOOST_CHECK( ! bbox.is3D() );
+
+ BOOST_CHECK_EQUAL( bbox.xMin(), 0.0 );
+ BOOST_CHECK_EQUAL( bbox.xMax(), 1.0 );
+ BOOST_CHECK_EQUAL( bbox.yMin(), -1.0 );
+ BOOST_CHECK_EQUAL( bbox.yMax(), 1.5 );
+}
+BOOST_AUTO_TEST_CASE( testEnvelope_3d )
+{
+ Kernel::Point_3 a( 0.0,-1.0,2.0 );
+ Kernel::Point_3 b( 0.5,0.2,4.0 );
+ Kernel::Point_3 c( 1.0,1.5,8.0 );
+
+ Triangle g( Kernel::Triangle_3( a,b,c ) ) ;
+
+ Envelope bbox = g.envelope() ;
+ BOOST_CHECK( ! bbox.isEmpty() );
+ BOOST_CHECK( bbox.is3D() );
+ BOOST_CHECK_EQUAL( bbox.xMin(), 0.0 );
+ BOOST_CHECK_EQUAL( bbox.xMax(), 1.0 );
+ BOOST_CHECK_EQUAL( bbox.yMin(), -1.0 );
+ BOOST_CHECK_EQUAL( bbox.yMax(), 1.5 );
+ BOOST_CHECK_EQUAL( bbox.zMin(), 2.0 );
+ BOOST_CHECK_EQUAL( bbox.zMax(), 8.0 );
+}
+
+//std::string Geometry::asText( const int & numDecimals = -1 ) const ;
+BOOST_AUTO_TEST_CASE( asTextEmpty )
+{
+ Triangle g;
+ BOOST_CHECK_EQUAL( g.asText( 1 ), "TRIANGLE EMPTY" );
+}
+BOOST_AUTO_TEST_CASE( asText2d )
+{
+ Triangle g(
+ Point( 0.0,0.0 ),
+ Point( 1.0,0.0 ),
+ Point( 1.0,1.0 )
+ );
+ BOOST_CHECK_EQUAL( g.asText( 1 ), "TRIANGLE((0.0 0.0,1.0 0.0,1.0 1.0,0.0 0.0))" );
+}
+BOOST_AUTO_TEST_CASE( asText3d )
+{
+ Triangle g(
+ Point( 0.0,0.0,2.0 ),
+ Point( 1.0,0.0,3.0 ),
+ Point( 1.0,1.0,4.0 )
+ );
+ BOOST_CHECK_EQUAL( g.asText( 1 ), "TRIANGLE((0.0 0.0 2.0,1.0 0.0 3.0,1.0 1.0 4.0,0.0 0.0 2.0))" );
+}
+
+
+//virtual std::string Geometry::geometryType() const = 0 ;
+BOOST_AUTO_TEST_CASE( testGeometryType )
+{
+ BOOST_CHECK_EQUAL( Triangle().geometryType(), "Triangle" );
+}
+//virtual GeometryType Geometry::geometryTypeId() const = 0 ;
+BOOST_AUTO_TEST_CASE( testGeometryTypeId )
+{
+ BOOST_CHECK_EQUAL( Triangle().geometryTypeId(), TYPE_TRIANGLE );
+}
+
+//virtual int Geometry::dimension() const = 0 ;
+//virtual int Geometry::coordinateDimension() const = 0 ;
+//virtual bool Geometry::isEmpty() const = 0 ;
+BOOST_AUTO_TEST_CASE( testIsEmpty )
+{
+ BOOST_CHECK( Point().isEmpty() );
+ BOOST_CHECK( ! Triangle(
+ Point( 0.0,0.0,2.0 ),
+ Point( 1.0,0.0,3.0 ),
+ Point( 1.0,1.0,4.0 )
+ ).isEmpty() );
+}
+//virtual bool Geometry::is3D() const = 0 ;
+//virtual bool Geometry::isMeasured() const = 0 ;
+//virtual bool Geometry::isSimple() const = 0 ;
+
+//template < typename Derived > inline bool Geometry::is() const
+BOOST_AUTO_TEST_CASE( isTriangle )
+{
+ Triangle g;
+ BOOST_CHECK( g.is< Triangle >() );
+}
+
+//template < typename Derived > inline const Derived & Geometry::as() const
+//template < typename Derived > inline Derived & Geometry::as()
+BOOST_AUTO_TEST_CASE( asTriangle )
+{
+ std::auto_ptr< Geometry > g( new Triangle() );
+ BOOST_CHECK( g->as< Triangle >().isEmpty() );
+}
+
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/TriangulatedSurfaceTest.cpp b/test/unit/SFCGAL/TriangulatedSurfaceTest.cpp
new file mode 100644
index 0000000..d41b078
--- /dev/null
+++ b/test/unit/SFCGAL/TriangulatedSurfaceTest.cpp
@@ -0,0 +1,221 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Envelope.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/triangulate/triangulatePolygon.h>
+#include <SFCGAL/io/wkt.h>
+
+#include <boost/test/unit_test.hpp>
+using namespace boost::unit_test ;
+
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_TriangulatedSurfaceTest )
+
+//TriangulatedSurface() ;
+BOOST_AUTO_TEST_CASE( defaultConstructor )
+{
+ TriangulatedSurface g ;
+ BOOST_CHECK( g.isEmpty() ) ;
+ BOOST_CHECK_EQUAL( g.numTriangles(), 0U ) ;
+}
+//TriangulatedSurface( const std::vector< Triangle > & triangle ) ;
+BOOST_AUTO_TEST_CASE( constructorWithTriangles )
+{
+ std::vector< Triangle > triangles ;
+ triangles.push_back( Triangle( Point( 0.0,0.0 ), Point( 1.0,0.0 ), Point( 1.0,1.0 ) ) ) ;
+ triangles.push_back( Triangle( Point( 0.0,0.0 ), Point( 1.0,1.0 ), Point( 0.0,1.0 ) ) ) ;
+
+ TriangulatedSurface g( triangles ) ;
+ BOOST_CHECK( ! g.isEmpty() ) ;
+ BOOST_CHECK_EQUAL( g.numTriangles(), 2U ) ;
+}
+
+//TriangulatedSurface( TriangulatedSurface const& other ) ;
+//TriangulatedSurface& operator = ( const TriangulatedSurface & other ) ;
+//~TriangulatedSurface() ;
+
+//inline size_t numTriangles() const { return _triangles.size(); }
+//inline const Triangle & triangleN( size_t const& n ) const {
+//inline Triangle & triangleN( size_t const& n ) {
+//inline void addTriangle( const Triangle & triangle )
+//inline void addTriangle( Triangle * triangle )
+//void addTriangles( const TriangulatedSurface & other ) ;
+
+
+//virtual size_t numGeometries() const ;
+//virtual const Triangle & geometryN( size_t const& n ) const ;
+//virtual Triangle & geometryN( size_t const& n ) ;
+
+
+//void reserve( const size_t & n ) ;
+
+//-- iterators
+
+//inline iterator begin() {
+//inline const_iterator begin() const {
+//inline iterator end() {
+//inline const_iterator end() const {
+
+
+
+//-- helpers
+
+//template < typename K, typename Polyhedron > std::auto_ptr<Polyhedron> toPolyhedron_3() const;
+// TODO
+
+
+//-- Geometry tests
+
+//virtual Geometry * Geometry::clone() const = 0 ;
+BOOST_AUTO_TEST_CASE( testClone )
+{
+ std::vector< Triangle > triangles ;
+ triangles.push_back( Triangle( Point( 0.0,0.0 ), Point( 1.0,0.0 ), Point( 1.0,1.0 ) ) ) ;
+ triangles.push_back( Triangle( Point( 0.0,0.0 ), Point( 1.0,1.0 ), Point( 0.0,1.0 ) ) ) ;
+
+ TriangulatedSurface g( triangles ) ;
+
+ std::auto_ptr< Geometry > copy( g.clone() );
+ BOOST_REQUIRE( copy->is< TriangulatedSurface >() );
+ BOOST_CHECK_EQUAL( copy->as< TriangulatedSurface >().numTriangles(), 2U );
+}
+
+//virtual Geometry* Geometry::boundary() const ;
+BOOST_AUTO_TEST_CASE( testBoundary )
+{
+ std::vector< Triangle > triangles ;
+ triangles.push_back( Triangle( Point( 0.0,0.0 ), Point( 1.0,0.0 ), Point( 1.0,1.0 ) ) ) ;
+ triangles.push_back( Triangle( Point( 0.0,0.0 ), Point( 1.0,1.0 ), Point( 0.0,1.0 ) ) ) ;
+
+ TriangulatedSurface g( triangles ) ;
+ std::auto_ptr< Geometry > boundary( g.boundary() );
+ // TODO add algorithm::lineMerge and update
+ BOOST_CHECK_EQUAL( boundary->asText( 0 ), "MULTILINESTRING((0 0,1 0),(1 0,1 1),(1 1,0 1),(0 1,0 0))" );
+}
+BOOST_AUTO_TEST_CASE( testBoundaryClosed )
+{
+ Point a( 0.0, 0.0, 0.0 );
+ Point b( 1.0, 0.0, 0.0 );
+ Point c( 0.0, 1.0, 0.0 );
+ Point d( 0.0, 0.0, 1.0 );
+
+ std::vector< Triangle > triangles ;
+ triangles.push_back( Triangle( a, c, b ) ) ;
+ triangles.push_back( Triangle( a, b, d ) ) ;
+ triangles.push_back( Triangle( b, c, d ) ) ;
+ triangles.push_back( Triangle( c, a, d ) ) ;
+
+ TriangulatedSurface g( triangles ) ;
+ std::auto_ptr< Geometry > boundary( g.boundary() );
+ BOOST_CHECK( boundary->isEmpty() );
+}
+
+
+//Envelope Geometry::envelope() const ;
+BOOST_AUTO_TEST_CASE( testEnvelope )
+{
+ Point a( 0.0, 0.0, 0.0 );
+ Point b( 1.0, 0.0, 0.0 );
+ Point c( 0.0, 1.0, 0.0 );
+ Point d( 0.0, 0.0, 1.0 );
+
+ std::vector< Triangle > triangles ;
+ triangles.push_back( Triangle( a, c, b ) ) ;
+ triangles.push_back( Triangle( a, b, d ) ) ;
+ triangles.push_back( Triangle( b, c, d ) ) ;
+ triangles.push_back( Triangle( c, a, d ) ) ;
+
+ TriangulatedSurface g( triangles ) ;
+ Envelope bbox = g.envelope() ;
+ BOOST_CHECK_EQUAL( bbox.xMin(), 0.0 );
+ BOOST_CHECK_EQUAL( bbox.xMax(), 1.0 );
+ BOOST_CHECK_EQUAL( bbox.yMin(), 0.0 );
+ BOOST_CHECK_EQUAL( bbox.yMax(), 1.0 );
+ BOOST_CHECK_EQUAL( bbox.zMin(), 0.0 );
+ BOOST_CHECK_EQUAL( bbox.zMax(), 1.0 );
+}
+//std::string Geometry::asText( const int & numDecimals = -1 ) const ;
+//TODO
+
+//virtual std::string Geometry::geometryType() const = 0 ;
+BOOST_AUTO_TEST_CASE( testGeometryType )
+{
+ TriangulatedSurface g;
+ BOOST_CHECK_EQUAL( g.geometryType(), "TriangulatedSurface" );
+}
+//virtual GeometryType Geometry::geometryTypeId() const = 0 ;
+BOOST_AUTO_TEST_CASE( testGeometryTypeId )
+{
+ TriangulatedSurface g;
+ BOOST_CHECK_EQUAL( g.geometryTypeId(), TYPE_TRIANGULATEDSURFACE );
+}
+
+//virtual int Geometry::dimension() const = 0 ;
+BOOST_AUTO_TEST_CASE( testDimension )
+{
+ TriangulatedSurface g;
+ BOOST_CHECK_EQUAL( g.dimension(), 2 ); //surface
+}
+
+//virtual int Geometry::coordinateDimension() const = 0 ;
+//virtual bool Geometry::isEmpty() const = 0 ;
+//virtual bool Geometry::is3D() const = 0 ;
+//virtual bool Geometry::isMeasured() const = 0 ;
+//virtual bool Geometry::isSimple() const = 0 ;
+//template < typename Derived > inline bool Geometry::is() const
+BOOST_AUTO_TEST_CASE( isTriangulatedSurface )
+{
+ TriangulatedSurface g;
+ BOOST_CHECK( g.is< TriangulatedSurface >() );
+}
+//template < typename Derived > inline const Derived & Geometry::as() const
+//template < typename Derived > inline Derived & Geometry::as()
+
+
+
+//-- other tests
+
+BOOST_AUTO_TEST_CASE( polyhedronConversionTest )
+{
+ // two unit squares sharing a common edge (1,0)-(1,1)
+ std::string gstr = "POLYHEDRALSURFACE(((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),"
+ "((1 0 0,1 1 0,2 1 0,2 0 0,1 0 0)))";
+ // the following surface would generate an exception, since the two polygons have opposite orientations
+ // "POLYHEDRALSURFACE(((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),((2 0 0,2 1 0,1 1 0,1 0 0,2 0 0)))";
+ std::auto_ptr<Geometry> g( io::readWkt( gstr ) );
+
+ TriangulatedSurface tri;
+ triangulate::triangulatePolygon3D( *g, tri );
+
+ std::auto_ptr<CGAL::Polyhedron_3<Kernel> > poly( tri.toPolyhedron_3<Kernel, CGAL::Polyhedron_3<Kernel> >() );
+ // we check the two squares share a common edge
+ BOOST_CHECK_EQUAL( poly->size_of_facets(), 4U );
+ BOOST_CHECK_EQUAL( poly->size_of_vertices(), 6U );
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/algorithm/AreaTest.cpp b/test/unit/SFCGAL/algorithm/AreaTest.cpp
new file mode 100644
index 0000000..d804b64
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/AreaTest.cpp
@@ -0,0 +1,197 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/area.h>
+
+#include <SFCGAL/detail/tools/Registry.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_AreaTest )
+
+
+BOOST_AUTO_TEST_CASE( testEmpty2D3D )
+{
+ tools::Registry& registry = tools::Registry::instance() ;
+ std::vector< std::string > typeNames = tools::Registry::instance().getGeometryTypes();
+
+ for ( size_t i = 0; i < typeNames.size(); i++ ) {
+ BOOST_TEST_MESSAGE( typeNames[i] ) ;
+
+ std::auto_ptr< Geometry > g( registry.newGeometryByTypeName( typeNames[i] ) ) ;
+ BOOST_REQUIRE( g.get() != NULL ) ;
+ BOOST_CHECK_EQUAL( algorithm::area( *g ), 0.0 );
+ BOOST_CHECK_EQUAL( algorithm::area3D( *g ), 0.0 );
+ }
+}
+
+
+
+BOOST_AUTO_TEST_CASE( testSignedArea2D_lineString )
+{
+ LineString lineString ;
+ lineString.addPoint( Point( 0.0,0.0 ) );
+ lineString.addPoint( Point( 1.0,0.0 ) );
+ lineString.addPoint( Point( 1.0,1.0 ) );
+ lineString.addPoint( Point( 0.0,1.0 ) );
+ lineString.addPoint( lineString.startPoint() );
+
+ BOOST_CHECK_EQUAL( algorithm::signedArea( lineString ), 1.0 );
+ lineString.reverse() ;
+ BOOST_CHECK_EQUAL( algorithm::signedArea( lineString ), -1.0 );
+}
+
+BOOST_AUTO_TEST_CASE( testSignedArea2D_triangle )
+{
+ Triangle triangle(
+ Point( 0.0,0.0 ),
+ Point( 1.0,0.0 ),
+ Point( 1.0,1.0 )
+ ) ;
+
+ BOOST_CHECK_EQUAL( algorithm::signedArea( triangle ), 0.5 );
+ triangle.reverse() ;
+ BOOST_CHECK_EQUAL( algorithm::signedArea( triangle ), -0.5 );
+}
+
+
+
+
+// must return 0.0
+BOOST_AUTO_TEST_CASE( testPoint2D3D )
+{
+ BOOST_CHECK_EQUAL( algorithm::area( Point( 3.0,4.0 ) ), 0.0 );
+ BOOST_CHECK_EQUAL( algorithm::area3D( Point( 3.0,4.0,5.0 ) ), 0.0 );
+}
+// must return 0.0
+BOOST_AUTO_TEST_CASE( testLineString2D3D )
+{
+ BOOST_CHECK_EQUAL( algorithm::area( LineString( Point( 0.0,0.0 ),Point( 1.0,1.0 ) ) ), 0.0 );
+ BOOST_CHECK_EQUAL( algorithm::area3D( LineString( Point( 0.0,0.0,0.0 ),Point( 1.0,1.0,1.0 ) ) ), 0.0 );
+}
+
+// must return 0.0
+BOOST_AUTO_TEST_CASE( testArea2D_PolygonWithHoleWithBadOrientation )
+{
+ Polygon polygon ;
+
+ // exterior ring
+ {
+ LineString ring ;
+ ring.addPoint( Point( 0.0,0.0 ) );
+ ring.addPoint( Point( 5.0,0.0 ) );
+ ring.addPoint( Point( 5.0,5.0 ) );
+ ring.addPoint( Point( 0.0,5.0 ) );
+ ring.addPoint( ring.startPoint() );
+
+ polygon.setExteriorRing( ring );
+ }
+
+ // hole 1
+ {
+ LineString ring ;
+ ring.addPoint( Point( 1.0,1.0 ) );
+ ring.addPoint( Point( 2.0,1.0 ) );
+ ring.addPoint( Point( 2.0,2.0 ) );
+ ring.addPoint( Point( 1.0,2.0 ) );
+ ring.addPoint( ring.startPoint() );
+
+ polygon.addRing( ring );
+ }
+
+ // hole 2
+ {
+ LineString ring ;
+ ring.addPoint( Point( 3.0,3.0 ) );
+ ring.addPoint( Point( 4.0,3.0 ) );
+ ring.addPoint( Point( 4.0,4.0 ) );
+ ring.addPoint( Point( 3.0,4.0 ) );
+ ring.addPoint( ring.startPoint() );
+
+ polygon.addRing( ring );
+ }
+
+ // 5x5 - 1 - 1 = 23
+ BOOST_CHECK_EQUAL( algorithm::area3D( polygon ), 23.0 );
+}
+
+
+
+BOOST_AUTO_TEST_CASE( testArea3D_Triangle1 )
+{
+ Triangle triangle( Point( 0.0,0.0,0.0 ), Point( 0.0,0.0,1.0 ), Point( 0.0,1.0, 0.0 ) );
+ BOOST_CHECK_EQUAL( algorithm::area3D( triangle ), 0.5 );
+}
+
+BOOST_AUTO_TEST_CASE( testArea3D_Triangle2 )
+{
+ Triangle triangle( Point( 0.0,0.0,0.0 ), Point( 0.0,0.0,4.0 ), Point( 0.0,4.0, 0.0 ) );
+ BOOST_CHECK_EQUAL( algorithm::area3D( triangle ), 8.0 );
+}
+
+BOOST_AUTO_TEST_CASE( testArea2D_Triangle )
+{
+ Triangle triangle1( Point( 0.0,0.0 ), Point( 4.0,0.0 ), Point( 4.0,4.0 ) );
+ // the same, inverted
+ Triangle triangle2( Point( 0.0,0.0 ), Point( 0.0,4.0 ), Point( 4.0,4.0 ) );
+ BOOST_CHECK_EQUAL( algorithm::area( triangle1 ), 8.0 );
+ BOOST_CHECK_EQUAL( algorithm::area( triangle2 ), 8.0 );
+}
+
+BOOST_AUTO_TEST_CASE( testArea3D_Square1x1 )
+{
+ std::auto_ptr< Geometry > g( io::readWkt( "POLYGON((0.0 0.0 0.0,0.0 0.0 1.0,0.0 1.0 1.0,0.0 1.0 0.0,0.0 0.0 0.0))" ) );
+ BOOST_CHECK_EQUAL( g->asText( 1 ), "POLYGON((0.0 0.0 0.0,0.0 0.0 1.0,0.0 1.0 1.0,0.0 1.0 0.0,0.0 0.0 0.0))" );
+ BOOST_CHECK_CLOSE( algorithm::area3D( *g ), 1.0, 1e-10 );
+}
+
+BOOST_AUTO_TEST_CASE( testArea3D_Square4X4 )
+{
+ std::string wkt( "POLYGON((0.0 0.0 0.0,0.0 0.0 4.0,0.0 4.0 4.0,0.0 4.0 0.0,0.0 0.0 0.0))" );
+ std::auto_ptr< Geometry > g( io::readWkt( wkt ) );
+ BOOST_CHECK_CLOSE( algorithm::area3D( *g ), 16.0, 1e-10 );
+}
+
+BOOST_AUTO_TEST_CASE( testArea3D_Square4X4WithHole )
+{
+ std::string wkt( "POLYGON((0.0 0.0 0.0,0.0 0.0 4.0,0.0 4.0 4.0,0.0 4.0 0.0,0.0 0.0 0.0),(0.0 2.0 2.0,0.0 3.0 2.0,0.0 3.0 3.0,0.0 2.0 3.0,0.0 2.0 2.0))" );
+ std::auto_ptr< Geometry > g( io::readWkt( wkt ) );
+ BOOST_CHECK_CLOSE( algorithm::area3D( *g ), 15.0, 1e-10 );
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/BoundaryTest.cpp b/test/unit/SFCGAL/algorithm/BoundaryTest.cpp
new file mode 100644
index 0000000..fbc94bd
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/BoundaryTest.cpp
@@ -0,0 +1,173 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_BoundaryTest )
+
+//-- Point
+
+BOOST_AUTO_TEST_CASE( emptyPoint )
+{
+ Point g;
+ std::auto_ptr< Geometry > boundary( g.boundary() );
+
+ BOOST_CHECK( boundary->is< GeometryCollection >() );
+ BOOST_CHECK( boundary->isEmpty() );
+}
+BOOST_AUTO_TEST_CASE( pointXY )
+{
+ Point g( 2.0,3.0 );
+ std::auto_ptr< Geometry > boundary( g.boundary() );
+
+ BOOST_CHECK( boundary->is< GeometryCollection >() );
+ BOOST_CHECK( boundary->isEmpty() );
+}
+
+//-- LineString
+
+BOOST_AUTO_TEST_CASE( emptyLineString )
+{
+ LineString g;
+ std::auto_ptr< Geometry > boundary( g.boundary() );
+
+ BOOST_CHECK( boundary->is< GeometryCollection >() );
+ BOOST_CHECK( boundary->isEmpty() );
+}
+
+BOOST_AUTO_TEST_CASE( lineStringSegment )
+{
+ BOOST_TEST_MESSAGE( "check that a LineSegment has a MultiPoint boundary composed of 2 points" );
+
+ LineString g;
+ g.addPoint( Point( 0.0,0.0 ) );
+ g.addPoint( Point( 1.0,1.0 ) );
+ std::auto_ptr< Geometry > boundary( g.boundary() );
+
+ BOOST_CHECK( boundary->is< MultiPoint >() );
+ BOOST_CHECK_EQUAL( boundary->as< MultiPoint >().numGeometries(), 2U );
+}
+
+BOOST_AUTO_TEST_CASE( lineStringWithThreePoints )
+{
+ BOOST_TEST_MESSAGE( "check that a LineString with 3 points has a MultiPoint boundary composed of 2 points" );
+
+ LineString g;
+ g.addPoint( Point( 0.0,0.0 ) );
+ g.addPoint( Point( 1.0,1.0 ) );
+ g.addPoint( Point( 2.0,2.0 ) );
+ std::auto_ptr< Geometry > boundary( g.boundary() );
+
+ BOOST_CHECK( boundary->is< MultiPoint >() );
+ BOOST_CHECK_EQUAL( boundary->as< MultiPoint >().numGeometries(), 2U );
+}
+
+BOOST_AUTO_TEST_CASE( lineStringClosed )
+{
+ BOOST_TEST_MESSAGE( "check that a closed LineString has empty boundary" );
+
+ LineString g;
+ g.addPoint( Point( 0.0,0.0 ) );
+ g.addPoint( Point( 1.0,1.0 ) );
+ g.addPoint( Point( 2.0,2.0 ) );
+ g.addPoint( Point( 0.0,0.0 ) );
+
+ std::auto_ptr< Geometry > boundary( g.boundary() );
+
+ BOOST_CHECK( boundary->isEmpty() );
+ BOOST_CHECK( boundary->is< GeometryCollection >() );
+}
+
+//-- MultiLineString
+
+BOOST_AUTO_TEST_CASE( multiLineStringSimple )
+{
+ BOOST_TEST_MESSAGE( "check common point between two LineStrings" );
+
+ MultiLineString g ;
+ g.addGeometry( LineString( Point( 0.0,0.0 ), Point( 1.0,1.0 ) ) );
+ g.addGeometry( LineString( Point( 0.0,0.0 ), Point( 1.0,2.0 ) ) );
+
+ g.addGeometry( LineString( Point( 1.0,1.0 ), Point( 1.0,2.0 ) ) );
+
+ std::auto_ptr< Geometry > boundary( g.boundary() );
+
+ BOOST_CHECK( boundary->isEmpty() );
+ BOOST_CHECK( boundary->is< GeometryCollection >() );
+}
+
+
+
+//-- MultiPolygon
+
+//TODO TDD
+
+BOOST_AUTO_TEST_CASE( multiPolygonSimple )
+{
+ BOOST_TEST_MESSAGE( "check common point between two LineStrings" );
+
+ MultiPolygon g ;
+ {
+ LineString ring;
+ ring.addPoint( Point( 0.0, 0.0 ) );
+ ring.addPoint( Point( 1.0, 0.0 ) );
+ ring.addPoint( Point( 1.0, 1.0 ) );
+ ring.addPoint( Point( 0.0, 1.0 ) );
+ ring.addPoint( Point( 0.0, 0.0 ) );
+
+ g.addGeometry( Polygon( ring ) );
+ }
+ {
+ LineString ring;
+ ring.addPoint( Point( 1.0, 0.0 ) );
+ ring.addPoint( Point( 2.0, 0.0 ) );
+ ring.addPoint( Point( 2.0, 1.0 ) );
+ ring.addPoint( Point( 1.0, 1.0 ) );
+ ring.addPoint( Point( 1.0, 0.0 ) );
+
+ g.addGeometry( Polygon( ring ) );
+ }
+
+ std::auto_ptr< Geometry > boundary( g.boundary() );
+
+ BOOST_CHECK( ! boundary->isEmpty() );
+ BOOST_CHECK( boundary->is< MultiLineString >() );
+}
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/ConnectedTest.cpp b/test/unit/SFCGAL/algorithm/ConnectedTest.cpp
new file mode 100644
index 0000000..6f38687
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/ConnectedTest.cpp
@@ -0,0 +1,88 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/connection.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+using namespace SFCGAL::algorithm ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_Connected )
+
+BOOST_AUTO_TEST_CASE( allFine )
+{
+ std::auto_ptr< Geometry > geom ( io::readWkt(
+ "POLYHEDRALSURFACE(((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)),\
+ ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),\
+ ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),\
+ ((1 1 1, 0 1 1, 0 0 1, 1 0 1, 1 1 1)),\
+ ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)),\
+ ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1)))" ) );
+
+ SurfaceGraph graph( geom->as< PolyhedralSurface >() );
+ BOOST_CHECK_MESSAGE( isConnected( graph ) , "not connected" );
+ BOOST_CHECK_MESSAGE( isClosed( graph ) , "not closed" );
+}
+
+BOOST_AUTO_TEST_CASE( notConnected )
+{
+ std::auto_ptr< Geometry > geom ( io::readWkt(
+ "POLYHEDRALSURFACE(((0 0 -1, 0 1 -1, 1 1 -1, 1 0 -1, 0 0 -1)),\
+ ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),\
+ ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),\
+ ((1 1 1, 0 1 1, 0 0 1, 1 0 1, 1 1 1)),\
+ ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)),\
+ ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1)))" ) );
+
+ SurfaceGraph graph( geom->as< PolyhedralSurface >() );
+ BOOST_CHECK_MESSAGE( !isConnected( graph ) , "connected" );
+ BOOST_CHECK_MESSAGE( !isClosed( graph ) , "closed" );
+}
+
+BOOST_AUTO_TEST_CASE( notClosed )
+{
+ std::auto_ptr< Geometry > geom ( io::readWkt(
+ "POLYHEDRALSURFACE(((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)),\
+ ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),\
+ ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),\
+ ((1 1 1, 0 1 1, 0 0 1, 1 0 1, 1 1 1)),\
+ ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)))" ) );
+
+ SurfaceGraph graph( geom->as< PolyhedralSurface >() );
+ BOOST_CHECK_MESSAGE( isConnected( graph ) , "not connected" );
+ BOOST_CHECK_MESSAGE( !isClosed( graph ) , "closed" );
+
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/unit/SFCGAL/algorithm/ConsistentOrientationBuilderTest.cpp b/test/unit/SFCGAL/algorithm/ConsistentOrientationBuilderTest.cpp
new file mode 100644
index 0000000..9c13a7a
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/ConsistentOrientationBuilderTest.cpp
@@ -0,0 +1,105 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/ConsistentOrientationBuilder.h>
+#include <SFCGAL/algorithm/orientation.h>
+
+
+using namespace SFCGAL ;
+using namespace boost::unit_test ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_ConsistentOrientationBuilderTest )
+
+BOOST_AUTO_TEST_CASE( testOppositeTriangle )
+{
+ algorithm::ConsistentOrientationBuilder builder ;
+ builder.addTriangle(
+ Triangle(
+ Point( 0.0, 0.0, 0.0 ),
+ Point( 1.0, 0.0, 0.0 ),
+ Point( 0.0, 1.0, 0.0 )
+ )
+ );
+ builder.addTriangle(
+ Triangle(
+ Point( 0.0, 0.0, 0.0 ),
+ Point( -1.0, 0.0, 0.0 ),
+ Point( 0.0, 1.0, 0.0 )
+ )
+ );
+ TriangulatedSurface triangulatedSurface = builder.buildTriangulatedSurface();
+ BOOST_CHECK_EQUAL( triangulatedSurface.numGeometries(), 2U );
+ BOOST_CHECK( algorithm::hasConsistentOrientation3D( triangulatedSurface ) );
+}
+
+BOOST_AUTO_TEST_CASE( testFourTriangle )
+{
+ algorithm::ConsistentOrientationBuilder builder ;
+ builder.addTriangle(
+ Triangle(
+ Point( 0.0, 0.0, 0.0 ),
+ Point( 1.0, 0.0, 0.0 ),
+ Point( 0.0, 1.0, 0.0 )
+ )
+ );
+ builder.addTriangle(
+ Triangle(
+ Point( 0.0, 0.0, 0.0 ),
+ Point( -1.0, 0.0, 0.0 ),
+ Point( 0.0, 1.0, 0.0 )
+ )
+ );
+ builder.addTriangle(
+ Triangle(
+ Point( 0.0, 0.0, 0.0 ),
+ Point( 1.0, 0.0, 0.0 ),
+ Point( 0.0,-1.0, 0.0 )
+ )
+ );
+ builder.addTriangle(
+ Triangle(
+ Point( 0.0, 0.0, 0.0 ),
+ Point( -1.0, 0.0, 0.0 ),
+ Point( 0.0,-1.0, 0.0 )
+ )
+ );
+ TriangulatedSurface triangulatedSurface = builder.buildTriangulatedSurface();
+ BOOST_CHECK_EQUAL( triangulatedSurface.numGeometries(), 4U );
+ BOOST_CHECK( algorithm::hasConsistentOrientation3D( triangulatedSurface ) );
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/ConvexHullTest.cpp b/test/unit/SFCGAL/algorithm/ConvexHullTest.cpp
new file mode 100644
index 0000000..720e413
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/ConvexHullTest.cpp
@@ -0,0 +1,177 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/convexHull.h>
+
+using namespace SFCGAL ;
+
+// always after CGAL
+using namespace boost::unit_test ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_ConvexHullTest )
+
+// algorithm::convexHull
+
+BOOST_AUTO_TEST_CASE( testConvexHull2D_Empty )
+{
+ GeometryCollection collect;
+ collect.addGeometry( Polygon() );
+ collect.addGeometry( Polygon() );
+ std::auto_ptr< Geometry > hull( algorithm::convexHull( collect ) );
+ BOOST_CHECK( hull->isEmpty() );
+}
+
+
+BOOST_AUTO_TEST_CASE( testConvexHull2D_ColinearProduceLineString )
+{
+ LineString lineString ;
+ lineString.addPoint( Point( 0.0,0.0 ) );
+ lineString.addPoint( Point( 1.0,1.0 ) );
+ lineString.addPoint( Point( 2.0,2.0 ) );
+
+ std::auto_ptr< Geometry > hull( algorithm::convexHull( lineString ) );
+ BOOST_REQUIRE( hull->is< LineString >() );
+ BOOST_CHECK_EQUAL( hull->as< LineString >().numPoints(), 2U );
+
+ std::string hullWKT = hull->asText( 1 ) ;
+ BOOST_CHECK(
+ ( hullWKT == "LINESTRING(0.0 0.0,2.0 2.0)" )
+ || ( hullWKT == "LINESTRING(2.0 2.0,0.0 0.0)" )
+ );
+}
+
+BOOST_AUTO_TEST_CASE( testConvexHull2D_Triangle )
+{
+ std::vector< Point > points ;
+ points.push_back( Point( 0.0,0.0 ) );
+ points.push_back( Point( 0.5,0.5 ) );
+ points.push_back( Point( 1.0,0.0 ) );
+ points.push_back( Point( 0.0,1.0 ) );
+
+ LineString lineString( points ) ;
+ std::auto_ptr< Geometry > hull( algorithm::convexHull( lineString ) );
+ BOOST_CHECK( hull->is<Triangle>() );
+}
+
+BOOST_AUTO_TEST_CASE( testConvexHull2D_Polygon )
+{
+ std::vector< Point > points ;
+ points.push_back( Point( 0.0,0.0 ) );
+ points.push_back( Point( 1.0,0.0 ) );
+ points.push_back( Point( 1.0,1.0 ) );
+ points.push_back( Point( 0.0,1.0 ) );
+
+ LineString lineString( points ) ;
+ std::auto_ptr< Geometry > hull( algorithm::convexHull( lineString ) );
+ BOOST_CHECK( hull->is<Polygon>() );
+}
+
+
+
+// algorithm::convexHull3D
+
+BOOST_AUTO_TEST_CASE( testConvexHull3D_Empty )
+{
+ GeometryCollection collect;
+ collect.addGeometry( Polygon() );
+ collect.addGeometry( Polygon() );
+ std::auto_ptr< Geometry > hull( algorithm::convexHull3D( collect ) );
+ BOOST_CHECK( hull->isEmpty() );
+}
+
+
+BOOST_AUTO_TEST_CASE( testConvexHull3D_Point )
+{
+ Point p( 1.0,2.0,3.0 );
+ std::auto_ptr< Geometry > hull( algorithm::convexHull3D( p ) );
+ BOOST_CHECK( hull->is< Point >() );
+ BOOST_CHECK_EQUAL( hull->as< Point >().x(), 1.0 ) ;
+ BOOST_CHECK_EQUAL( hull->as< Point >().y(), 2.0 ) ;
+ BOOST_CHECK_EQUAL( hull->as< Point >().z(), 3.0 ) ;
+}
+
+/*
+ * @todo Test if points are collinear
+ */
+BOOST_AUTO_TEST_CASE( testConvexHull3D_LineStringCollinear )
+{
+ std::vector< Point > points ;
+ points.push_back( Point( 0.0,0.0,0.0 ) );
+ points.push_back( Point( 1.0,1.0,1.0 ) );
+ points.push_back( Point( 2.0,2.0,2.0 ) );
+ points.push_back( Point( 3.0,3.0,3.0 ) );
+
+ LineString lineString( points ) ;
+ std::auto_ptr< Geometry > hull( algorithm::convexHull3D( lineString ) );
+ BOOST_CHECK( hull->is< LineString >() );
+}
+
+BOOST_AUTO_TEST_CASE( testConvexHull3D_LineStringCoplanar )
+{
+ std::vector< Point > points ;
+ points.push_back( Point( 0.0,0.0,1.0 ) );
+ points.push_back( Point( 1.0,0.0,1.0 ) );
+ points.push_back( Point( 1.0,1.0,1.0 ) );
+ points.push_back( Point( 0.0,1.0,1.0 ) );
+
+ LineString lineString( points ) ;
+ std::auto_ptr< Geometry > hull( algorithm::convexHull3D( lineString ) );
+ BOOST_CHECK( hull->is< PolyhedralSurface >() );
+ BOOST_CHECK_EQUAL( hull->as< PolyhedralSurface >().numPolygons(), 1U );
+}
+
+
+
+
+BOOST_AUTO_TEST_CASE( testConvexHull3D_Tetrahedron )
+{
+ std::vector< Point > points ;
+ points.push_back( Point( 0.0,0.0,0.0 ) );
+ points.push_back( Point( 1.0,0.0,0.0 ) );
+ points.push_back( Point( 0.0,1.0,0.0 ) );
+ points.push_back( Point( 0.0,0.0,1.0 ) );
+
+ LineString lineString( points ) ;
+ std::auto_ptr< Geometry > hull( algorithm::convexHull3D( lineString ) );
+ BOOST_CHECK( hull->is< PolyhedralSurface >() );
+ BOOST_CHECK_EQUAL( hull->as< PolyhedralSurface >().numPolygons(), 4U );
+
+}
+
+
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/CoversPointsTest.cpp b/test/unit/SFCGAL/algorithm/CoversPointsTest.cpp
new file mode 100644
index 0000000..0b589ee
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/CoversPointsTest.cpp
@@ -0,0 +1,99 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <cmath>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/detail/algorithm/coversPoints.h>
+
+using namespace SFCGAL ;
+using namespace SFCGAL::detail ;
+using namespace boost::unit_test ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_CoversPointsTest )
+
+BOOST_AUTO_TEST_CASE( testPointPointCoversPoints )
+{
+ Point pta( 0.0, 1.0, 0.0 );
+ Point ptb( 0.0, 1.0, 0.0 );
+ Point ptc( 0.0, 0.0, 0.0 );
+ BOOST_CHECK_EQUAL( algorithm::coversPoints( pta, ptb ), true );
+ BOOST_CHECK_EQUAL( algorithm::coversPoints( pta, ptc ), false );
+ BOOST_CHECK_EQUAL( algorithm::coversPoints3D( pta, ptb ), true );
+ BOOST_CHECK_EQUAL( algorithm::coversPoints3D( pta, ptc ), false );
+}
+
+BOOST_AUTO_TEST_CASE( testPolygonPolygonCoversPoints )
+{
+ {
+ std::auto_ptr<Geometry> p1 = io::readWkt( "POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0))" );
+ std::auto_ptr<Geometry> p2 = io::readWkt( "POLYGON((-0.5 -0.5,-0.5 0.5,0.5 0.5,0.5 -0.5,-0.5 -0.5))" );
+
+ BOOST_CHECK_EQUAL( algorithm::coversPoints( *p1, *p2 ), true );
+ BOOST_CHECK_EQUAL( algorithm::coversPoints3D( *p1, *p2 ), true );
+ }
+
+ {
+ // a square with a substracted triangle => concave shape
+ std::auto_ptr<Geometry> p1 = io::readWkt( "POLYGON((0.4 0,0 0,0 1,1 1,1 0,0.6 0,0.5 0.4,0.4 0))" );
+ // a smaller square
+ std::auto_ptr<Geometry> p2 = io::readWkt( "POLYGON((0.2 0.2,0.8 0.2,0.8 0.8,0.2 0.8,0.2 0.2))" );
+
+ // ST_covers would answer false
+ BOOST_CHECK_EQUAL( algorithm::coversPoints( *p1, *p2 ), true );
+ BOOST_CHECK_EQUAL( algorithm::coversPoints3D( *p1, *p2 ), true );
+ }
+}
+
+BOOST_AUTO_TEST_CASE( testCollectionCoversPoints )
+{
+#if 0
+ {
+ std::auto_ptr<Geometry> p1 = io::readWkt( "GEOMETRYCOLLECTION(LINESTRING(0 0 0,0 0 1),LINESTRING(0 0 0,0 1 0),LINESTRING(0 1 1,0 0 1),LINESTRING(0 1 1,0 1 0))" );
+ std::auto_ptr<Geometry> p2 = io::readWkt( "TIN(((0 0.5 0.5,0 0 1,0 0 0,0 0.5 0.5)),((0 0 1,0 0.5 0.5,0 1 1,0 0 1)),((0 0.5 0.5,0 0 0,0 1 0,0 0.5 0.5)),((0 0.5 0.5,0 1 0,0 1 1,0 0.5 0.5)))" );
+ std::cout << "p1 covers p2 ? " << algorithm::coversPoints3D( *p1, *p2 ) << std::endl;
+ std::cout << "p2 covers p1 ? " << algorithm::coversPoints3D( *p2, *p1 ) << std::endl;
+ }
+
+ {
+ std::auto_ptr<Geometry> p1 = io::readWkt( "GEOMETRYCOLLECTION(TRIANGLE((1 1,0.5 0.5,0 1,1 1)),TRIANGLE((1 0,0.5 0.5,1 1,1 0)),TRIANGLE((0.5 0.5,0 0,0 1,0.5 0.5)))" );
+ std::auto_ptr<Geometry> p2 = io::readWkt( "TRIANGLE((1 0, 0 0,0.5 0.5,1 0))" );
+ std::cout << "p1 covers p2 ? " << algorithm::coversPoints3D( *p1, *p2 ) << std::endl;
+ std::cout << "p2 covers p1 ? " << algorithm::coversPoints3D( *p2, *p1 ) << std::endl;
+ }
+#endif
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/CoversTest.cpp b/test/unit/SFCGAL/algorithm/CoversTest.cpp
new file mode 100644
index 0000000..080c091
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/CoversTest.cpp
@@ -0,0 +1,129 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <cmath>
+#include <fstream>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/covers.h>
+
+#include "../../../test_config.h"
+
+using namespace SFCGAL ;
+using namespace boost::unit_test ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_CoversTest )
+
+/**
+ * Perform tests in test/data/CoversTest.txt
+ */
+BOOST_AUTO_TEST_CASE( testFileCoversTest )
+{
+ int argc = framework::master_test_suite().argc;
+ char** argv = framework::master_test_suite().argv;
+
+ // look for options
+ int test_one_line = -1;
+
+ for ( int i = 0; i < argc; ++i ) {
+ std::string argi( argv[i] );
+
+ if ( argi == "--line" ) {
+ // only test one line
+ if ( argc >= i+1 ) {
+ sscanf( argv[i+1], "%d", &test_one_line );
+ ++i;
+ continue;
+ }
+ }
+ }
+
+ std::string filename( SFCGAL_TEST_DIRECTORY );
+ filename += "/data/CoversTest.txt" ;
+
+ std::ifstream ifs( filename.c_str() );
+ BOOST_REQUIRE( ifs.good() ) ;
+
+ int numLine = 0 ;
+ std::string line;
+
+ while ( std::getline( ifs, line ) ) {
+ numLine++;
+
+ if ( test_one_line != -1 && test_one_line != numLine ) {
+ continue;
+ }
+
+ if ( line[0] == '#' || line.empty() ) {
+ continue ;
+ }
+
+ BOOST_TEST_MESSAGE( boost::format( "line#%s:%s" ) % numLine % line );
+
+ std::istringstream iss( line );
+
+ std::string distanceDimension ;
+ std::string wktGA, wktGB ;
+ std::string trueOrFalse ;
+
+ std::getline( iss, distanceDimension, '|' ) ;
+ std::getline( iss, wktGA, '|' ) ;
+ std::getline( iss, wktGB, '|' ) ;
+ std::getline( iss, trueOrFalse, '|' ) ;
+
+ bool expected = ( trueOrFalse == "true" ) ? true : false ;
+
+ std::auto_ptr< Geometry > gA( io::readWkt( wktGA ) );
+ std::auto_ptr< Geometry > gB( io::readWkt( wktGB ) );
+
+ try {
+ if ( distanceDimension == "2" ) {
+ BOOST_CHECK_MESSAGE( algorithm::covers( *gA,*gB ) == expected, numLine << ": covers(" << gA->asText() << ", " << gB->asText() << ") should be " << ( expected ? "TRUE" : "FALSE" ) );
+ }
+ else if ( distanceDimension == "3" ) {
+ bool got = algorithm::covers3D( *gA,*gB );
+ BOOST_CHECK_MESSAGE( got == expected, numLine << ": covers3D(" << gA->asText() << ", " << gB->asText() << ") should be " << ( expected ? "TRUE" : "FALSE" ) );
+ }
+ else {
+ BOOST_CHECK( false );
+ }
+ }
+ catch ( std::exception& e ) {
+ BOOST_CHECK_MESSAGE( false, numLine << ": " << e.what() );
+ }
+ }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/DifferenceTest.cpp b/test/unit/SFCGAL/algorithm/DifferenceTest.cpp
new file mode 100644
index 0000000..c20830c
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/DifferenceTest.cpp
@@ -0,0 +1,368 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <SFCGAL/Exception.h>
+#include <SFCGAL/algorithm/isValid.h>
+#include <SFCGAL/algorithm/difference.h>
+#include <SFCGAL/algorithm/volume.h>
+#include <SFCGAL/algorithm/covers.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/detail/tools/Registry.h>
+
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/io/vtk.h>
+
+#include <boost/test/unit_test.hpp>
+
+using namespace SFCGAL;
+using namespace boost::unit_test ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_DifferenceTest )
+
+BOOST_AUTO_TEST_CASE( testDifferenceXPoint )
+{
+ // The same point
+ BOOST_CHECK( algorithm::difference( Point( 0,0 ), Point( 0,0 ) )->isEmpty() );
+ // A different point
+ BOOST_CHECK( *algorithm::difference( Point( 1,0 ), Point( 0,0 ) ) == Point( 1,0 ) );
+
+ // check difference(X, point) == X
+ std::vector<std::string> typeNames;
+
+ for ( size_t i = 0; i < typeNames.size(); ++i ) {
+ std::auto_ptr<Geometry> newGeo( tools::Registry::instance().newGeometryByTypeName( typeNames[i] ) );
+ std::auto_ptr<Geometry> diffGeo = algorithm::difference( *newGeo, Point( 0, 0 ) );
+ BOOST_CHECK( *newGeo == *diffGeo );
+ }
+}
+
+BOOST_AUTO_TEST_CASE( testDifferenceXLineString )
+{
+ // Point x Linestring intersecting
+ BOOST_CHECK( algorithm::difference( Point( 0,0 ), *io::readWkt( "LINESTRING(0 0,1 1)" ) )->isEmpty() );
+ // Point x linestring not intersecting
+ BOOST_CHECK( *algorithm::difference( Point( 0,0 ), *io::readWkt( "LINESTRING(0 1,1 1)" ) ) == Point( 0, 0 ) );
+
+ // two linestrings with two segments overlapping
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "LINESTRING(0 0,1 0)" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt( "LINESTRING(0.5 0,0.7 0)" );
+ std::auto_ptr<Geometry> diff = algorithm::difference( *ls1, *ls2 );
+ BOOST_CHECK( *diff == *io::readWkt( "MULTILINESTRING((0 0,0.5 0),(0.7 0,1 0))" ) );
+ }
+ // two linestrings with two opposite segments overlapping
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "LINESTRING(0 0,1 0)" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt( "LINESTRING(0.7 0,0.5 0)" );
+ std::auto_ptr<Geometry> diff = algorithm::difference( *ls1, *ls2 );
+ BOOST_CHECK( *diff == *io::readWkt( "MULTILINESTRING((0 0,0.5 0),(0.7 0,1 0))" ) );
+ }
+ // two linestrings with two segments crossing
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "LINESTRING(-1 0,1 0)" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt( "LINESTRING(0 -1,0 1)" );
+ std::auto_ptr<Geometry> diff = algorithm::difference( *ls1, *ls2 );
+ BOOST_CHECK( *diff == *ls1 );
+ }
+ // two linestrings with two segments partly overlapping
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "LINESTRING(0 0,1 0)" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt( "LINESTRING(-1 0,0.7 0)" );
+ std::auto_ptr<Geometry> diff = algorithm::difference( *ls1, *ls2 );
+ BOOST_CHECK( *diff == *io::readWkt( "LINESTRING(0.7 0,1 0)" ) );
+ }
+ // two linestrings with a segment covering another one
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "LINESTRING(0 0,1 0)" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt( "LINESTRING(-1 0,2 0)" );
+ std::auto_ptr<Geometry> diff = algorithm::difference( *ls1, *ls2 );
+ BOOST_CHECK( diff->isEmpty() );
+ }
+ // two linestrings that do not intersect
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "LINESTRING(0 0,1 0)" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt( "LINESTRING(0 1,1 1)" );
+ std::auto_ptr<Geometry> diff = algorithm::difference( *ls1, *ls2 );
+ BOOST_CHECK( *diff == *ls1 );
+ }
+ // two linestrings with more than one segment
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "LINESTRING(0 0,1 0,1 1)" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt( "LINESTRING(0.3 0,1 0,1 0.4)" );
+ std::auto_ptr<Geometry> diff = algorithm::difference( *ls1, *ls2 );
+ BOOST_CHECK( *diff == *io::readWkt( "MULTILINESTRING((0 0,0.3 0),(1 0.4,1 1))" ) );
+ }
+
+ // check difference(X, linestring) == X, with dimension(X) > 1
+ // TODO: add generators of random geometries to avoid empty geometries here ?
+ std::vector<std::string> typeNames;
+
+ for ( size_t i = 0; i < typeNames.size(); ++i ) {
+ std::auto_ptr<Geometry> newGeo( tools::Registry::instance().newGeometryByTypeName( typeNames[i] ) );
+
+ if ( newGeo->dimension() > 1 ) {
+ std::auto_ptr<Geometry> diffGeo = algorithm::difference( *newGeo, Point( 0, 0 ) );
+ BOOST_CHECK( *newGeo == *diffGeo );
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE( testDifferencePolygonPolygon2D )
+{
+ // two identical polygons
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "POLYGON((-1 -1,1 -1,1 1,-1 1,-1 -1))" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt( "POLYGON((-1 -1,1 -1,1 1,-1 1,-1 -1))" );
+ std::auto_ptr<Geometry> diff = algorithm::difference( *ls1, *ls2 );
+ BOOST_CHECK( *diff == *io::readWkt( "GEOMETRYCOLLECTION EMPTY" ) );
+ }
+
+ // two polygons, one of wich is invalid for CGAL but valid for SFS
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "POLYGON((-1 -1,1 -1,1 1,-1 1,-1 -1))" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt( "POLYGON((-1 -1,1 -1,1 1,-1 1,-1 -1),(-0.5 -0.5,-0.5 0.5,0.5 0.5,1 -0.5,-0.5 -0.5))" );
+ std::auto_ptr<Geometry> diff = algorithm::difference( *ls1, *ls2 );
+ BOOST_CHECK( *diff == *io::readWkt( "POLYGON((-0.5 -0.5,1 -0.5,0.5 0.5,-0.5 0.5,-0.5 -0.5))" ) );
+ BOOST_CHECK( algorithm::isValid( *diff ) );
+ }
+
+ // two polygons the result has a hole touching the outer boundary
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "POLYGON((-1 -1,1 -1,1 1,-1 1,-1 -1))" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt( "POLYGON((-0.5 -0.5,1 -0.5,0.5 0.5,-0.5 0.5,-0.5 -0.5))" );
+ std::auto_ptr<Geometry> diff = algorithm::difference( *ls1, *ls2 );
+ BOOST_CHECK( algorithm::isValid( *diff ) );
+ BOOST_CHECK( *diff == *io::readWkt( "POLYGON((-1 -1,1 -1,1 -0.5,1 1,-1 1,-1 -1),(1 -0.5,-0.5 -0.5,-0.5 0.5,0.5 0.5,1 -0.5))" ) );
+ }
+}
+
+BOOST_AUTO_TEST_CASE( testDifferenceVolumeVolume )
+{
+
+ // two cubes
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt(
+ "SOLID((((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)),\
+ ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),\
+ ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),\
+ ((1 1 1, 0 1 1, 0 0 1, 1 0 1, 1 1 1)),\
+ ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)),\
+ ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1))))" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt(
+ "SOLID((((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)),\
+ ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),\
+ ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),\
+ ((1 1 1, 0 1 1, 0 0 1, 1 0 1, 1 1 1)),\
+ ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)),\
+ ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1))))" );
+ std::auto_ptr<Geometry> diff = algorithm::difference3D( *ls1, *ls2 );
+ BOOST_CHECK( *diff == *io::readWkt( "GEOMETRYCOLLECTION EMPTY" ) );
+ }
+ // two cubes
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt(
+ "SOLID((((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)),\
+ ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),\
+ ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),\
+ ((1 1 1, 0 1 1, 0 0 1, 1 0 1, 1 1 1)),\
+ ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)),\
+ ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1))))" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt(
+ "SOLID((((0 0 0.5, 0 1 0.5, 1 1 0.5, 1 0 0.5, 0 0 0.5)),\
+ ((0 0 0.5, 0 0 1, 0 1 1, 0 1 0.5, 0 0 0.5)),\
+ ((0 0 0.5, 1 0 0.5, 1 0 1, 0 0 1, 0 0 0.5)),\
+ ((1 1 1, 0 1 1, 0 0 1, 1 0 1, 1 1 1)),\
+ ((1 1 1, 1 0 1, 1 0 0.5, 1 1 0.5, 1 1 1)),\
+ ((1 1 1, 1 1 0.5, 0 1 0.5, 0 1 1, 1 1 1))))" );
+ std::auto_ptr<Geometry> diff = algorithm::difference3D( *ls1, *ls2 );
+ BOOST_CHECK( algorithm::volume( *diff ) == Kernel::FT( 0.5 ) );
+ }
+
+
+}
+
+BOOST_AUTO_TEST_CASE( testDifferenceLinePolygon )
+{
+
+ // segment - polygon in 2D
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "LINESTRING(-10 0,10 0)" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt( "POLYGON((-1 -1,1 -1,1 1,-1 1,-1 -1),(-0.5 -0.5,-0.5 0.5,0 0,-0.5 -0.5),(0.5 0.5,0.5 -0.5,0 0,0.5 0.5))" );
+ std::auto_ptr<Geometry> diff = algorithm::difference( *ls1, *ls2 );
+ BOOST_CHECK( *diff == *io::readWkt( "MULTILINESTRING((-10 0,-1 0),(-0.5 0,0 0,0.5 0),(1 0,10 0))" ) );
+ }
+
+ // segment - polygon in 2D, with sement lying on hole border
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "LINESTRING(-10 0,10 0)" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt( "POLYGON((-1 -1,1 -1,1 1,-1 1,-1 -1),(-0.5 -0.5,-0.5 0.5,0 0,-0.5 -0.5),(0.5 0,0.5 -0.5,0 0,0.5 0))" );
+ std::auto_ptr<Geometry> diff = algorithm::difference( *ls1, *ls2 );
+ BOOST_CHECK( *diff == *io::readWkt( "MULTILINESTRING((-10 0,-1 0),(-0.5 0,0 0),(1 0,10 0))" ) );
+ }
+
+}
+
+BOOST_AUTO_TEST_CASE( testDifferencePoinLine )
+{
+ // point - segment in 3D
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "POINT(0.5 0.5 0.6)" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt( "LINESTRING(0 0 0,1 1 1)" );
+ std::auto_ptr<Geometry> diff = algorithm::difference3D( *ls1, *ls2 );
+ BOOST_CHECK( *diff == *io::readWkt( "POINT(0.5 0.5 0.6)" ) );
+ }
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "POINT(0.5 0.5 0.5)" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt( "LINESTRING(0 0 0,1 1 1)" );
+ std::auto_ptr<Geometry> diff = algorithm::difference3D( *ls1, *ls2 );
+ BOOST_CHECK( *diff == *io::readWkt( "GEOMETRYCOLLECTION EMPTY" ) );
+ }
+
+}
+
+BOOST_AUTO_TEST_CASE( testDifferencePoinPolygon2D )
+{
+ // point - triangle in 3D
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "POINT(0.5 0.5 0.6)" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt( "POLYGON((0 0 0,1 1 1,1 0 1,0 0 0))" );
+ std::auto_ptr<Geometry> diff = algorithm::difference3D( *ls1, *ls2 );
+ BOOST_CHECK( *diff == *io::readWkt( "POINT(0.5 0.5 0.6)" ) );
+ }
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "POINT(0.5 0.5 0.5)" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt( "POLYGON((0 0 0,1 1 1,1 0 1,0 0 0))" );
+ std::auto_ptr<Geometry> diff = algorithm::difference3D( *ls1, *ls2 );
+ BOOST_CHECK( *diff == *io::readWkt( "GEOMETRYCOLLECTION EMPTY" ) );
+ }
+}
+
+BOOST_AUTO_TEST_CASE( testDifferencePoinVolume )
+{
+
+ // point - volume
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "POINT(0.5 0.5 0.5)" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt(
+ "SOLID((((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)),\
+ ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),\
+ ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),\
+ ((1 1 1, 0 1 1, 0 0 1, 1 0 1, 1 1 1)),\
+ ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)),\
+ ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1))))" );
+ std::auto_ptr<Geometry> diff = algorithm::difference3D( *ls1, *ls2 );
+ BOOST_CHECK( *diff == *io::readWkt( "GEOMETRYCOLLECTION EMPTY" ) );
+ }
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "POINT(1.001 0.5 0.5)" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt(
+ "SOLID((((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)),\
+ ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),\
+ ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),\
+ ((1 1 1, 0 1 1, 0 0 1, 1 0 1, 1 1 1)),\
+ ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)),\
+ ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1))))" );
+ std::auto_ptr<Geometry> diff = algorithm::difference3D( *ls1, *ls2 );
+ BOOST_CHECK( *diff == *io::readWkt( "POINT(1.001 0.5 0.5)" ) );
+ }
+
+}
+
+BOOST_AUTO_TEST_CASE( testDifferenceTriangleTriangle3D )
+{
+ // triangle - trangle in 3D don't share the same plane
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "TRIANGLE((0 0 0,0 1 1,1 0 0,0 0 0))" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt( "TRIANGLE((0 0 0,0 1 1.01,1 0 0,0 0 0))" );
+ std::auto_ptr<Geometry> diff = algorithm::difference3D( *ls1, *ls2 );
+ BOOST_CHECK( *diff == *io::readWkt( "TRIANGLE((0 0 0,0 1 1,1 0 0,0 0 0))" ) );
+ }
+ // triangle - trangle in 3D don't intersect
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "TRIANGLE((0 0 0,0 1 1,1 0 0,0 0 0))" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt( "TRIANGLE((.6 .6 .6,1.6 1.6 1.6,1.6 .6 .6,.6 .6 .6))" );
+ std::auto_ptr<Geometry> diff = algorithm::difference3D( *ls1, *ls2 );
+ BOOST_CHECK( *diff == *io::readWkt( "TRIANGLE((0 0 0,0 1 1,1 0 0,0 0 0))" ) );
+ }
+ // triangle - triangle in 3D do intersect
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "TRIANGLE((0 0 0,0 1 1,1 0 0,0 0 0))" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt( "TRIANGLE((.1 .1 .1,1.6 1.6 1.6,1.6 .6 .6,.1 .1 .1))" );
+ std::auto_ptr<Geometry> diff = algorithm::difference3D( *ls1, *ls2 );
+ BOOST_CHECK( *diff == *io::readWkt( "TIN(((0 1 1,.5 .5 .5,.1 .1 .1,0 1 1)),((0 0 0,0 1 1,.1 .1 .1,0 0 0)),((.7 .3 .3,1 0 0,.1 .1 .1,.7 .3 .3)),((1 0 0,0 0 0,.1 .1 .1,1 0 0)))" ) );
+ }
+
+}
+
+BOOST_AUTO_TEST_CASE( testDifferenceTriangleVolume )
+{
+ // triangle - volume in 3D
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "TRIANGLE((0 0 .5,10 0 .5,0 10 .5,0 0 .5))" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt(
+ "SOLID((((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)),\
+ ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),\
+ ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),\
+ ((1 1 1, 0 1 1, 0 0 1, 1 0 1, 1 1 1)),\
+ ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)),\
+ ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1))))" );
+ std::auto_ptr<Geometry> diff = algorithm::difference3D( *ls1, *ls2 );
+ std::auto_ptr<Geometry> ref = io::readWkt( "TIN(((0/1 10/1 1/2,9/20 1/1 1/2,1/2 1/1 1/2,0/1 10/1 1/2)),((0/1 10/1 1/2,1/2 1/1 1/2,18/19 1/1 1/2,0/1 10/1 1/2)),((0/1 10/1 1/2,0/1 1/1 1/2,9/20 1/1 1/2,0/1 10/1 1/2)),((1/1 0/1 1/2,10/1 0/1 1/2,1/1 1/2 1/2,1/1 0/1 1/2)),((1/1 1/1 1/2,0/1 10/1 1/2,18/19 1/1 1/2,1/1 1/1 1/2)),((10/1 0/1 1/2,0/1 10/1 1/2,1/1 1/1 1/2,10/1 0/1 1/2)),((1/1 1/2 1/2,10/1 0/1 1/2,1/1 1/1 1/2,1/1 1/2 1/2)))" );
+ BOOST_CHECK( algorithm::covers( *diff, *ref ) && algorithm::covers( *ref, *diff ) );
+ }
+}
+
+BOOST_AUTO_TEST_CASE( testDifferenceLineVolume )
+{
+ // segment - volume in 3D
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "LINESTRING(-3 -3 .5,3 3 .5,1 1.1 .5,1 .1 .5,.1 .1 .5)" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt(
+ "SOLID((((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)),\
+ ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),\
+ ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),\
+ ((1 1 1, 0 1 1, 0 0 1, 1 0 1, 1 1 1)),\
+ ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)),\
+ ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1))))" );
+ std::auto_ptr<Geometry> diff = algorithm::difference3D( *ls1, *ls2 );
+ BOOST_CHECK( *diff == *io::readWkt( "MULTILINESTRING((-3 -3 .5,0 0 .5),(1 1 .5,3 3 .5,1 1.1 .5,1 1 .5))" ) );
+ }
+
+}
+
+BOOST_AUTO_TEST_CASE( testDifferencePolygonVolume )
+{
+
+ // polygon - volume crashing the algo in garden
+ {
+ std::auto_ptr<Geometry> ls1 = io::readWkt( "POLYGON((1 -1 -1,1 1 -1,1 1 1,1 -1 1,1 -1 -1))" );
+ std::auto_ptr<Geometry> ls2 = io::readWkt(
+ "SOLID((((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),\
+ ((0 0 0,0 0 1,0 1 1,0 1 0,0 0 0)),\
+ ((0 0 0,1 0 0,1 0 1,0 0 1,0 0 0)),\
+ ((1 1 1,0 1 1,0 0 1,1 0 1,1 1 1)),\
+ ((1 1 1,1 0 1,1 0 0,1 1 0,1 1 1)),\
+ ((1 1 1,1 1 0,0 1 0,0 1 1,1 1 1))))" );
+ std::auto_ptr<Geometry> diff = algorithm::difference3D( *ls1, *ls2 );
+ }
+
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/DistanceTest.cpp b/test/unit/SFCGAL/algorithm/DistanceTest.cpp
new file mode 100644
index 0000000..1b0acdd
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/DistanceTest.cpp
@@ -0,0 +1,247 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/distance.h>
+
+#include <SFCGAL/detail/tools/Registry.h>
+#include <SFCGAL/detail/tools/Log.h>
+
+using namespace SFCGAL ;
+
+// always after CGAL
+using namespace boost::unit_test ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_DistanceTest )
+
+/*
+ * check that distance between empty points is infinity
+ */
+BOOST_AUTO_TEST_CASE( testDistanceBetweenEmptyPointsIsInfinity )
+{
+ BOOST_CHECK_EQUAL( Point().distance( Point() ), std::numeric_limits< double >::infinity() );
+}
+
+//TODO enable when implement is complete
+#if 0
+
+/*
+ * check that distance between all kinds of empty geometry is infinity
+ */
+BOOST_AUTO_TEST_CASE( testDistanceBetweenEmptyGeometriesIsDefined )
+{
+ tools::Registry& registry = tools::Registry::instance() ;
+
+ std::vector< std::string > geometryTypes = tools::Registry::instance().getGeometryTypes() ;
+
+ for ( size_t i = 0; i < geometryTypes.size(); i++ ) {
+ for ( size_t j = 0; j < geometryTypes.size(); j++ ) {
+ BOOST_TEST_MESSAGE( boost::format( "distance(%s,%s)" ) % geometryTypes[i] % geometryTypes[j] );
+
+ std::auto_ptr< Geometry > gA( registry.newGeometryByTypeName( geometryTypes[i] ) );
+ std::auto_ptr< Geometry > gB( registry.newGeometryByTypeName( geometryTypes[j] ) );
+
+ double dAB ;
+ BOOST_CHECK_NO_THROW( dAB = gA->distance( *gB ) ) ;
+ BOOST_CHECK_EQUAL( dAB, std::numeric_limits< double >::infinity() );
+ }
+ }
+}
+/*
+ * check that distance3D between all kinds of empty geometry is infinity
+ */
+BOOST_AUTO_TEST_CASE( testDistance3DBetweenEmptyGeometriesIsDefined )
+{
+ tools::Registry& registry = tools::Registry::instance() ;
+
+ std::vector< std::string > geometryTypes = tools::Registry::instance().getGeometryTypes() ;
+
+ for ( size_t i = 0; i < geometryTypes.size(); i++ ) {
+ for ( size_t j = 0; j < geometryTypes.size(); j++ ) {
+ BOOST_TEST_MESSAGE( boost::format( "distance3D(%s,%s)" ) % geometryTypes[i] % geometryTypes[j] );
+
+ std::auto_ptr< Geometry > gA( registry.newGeometryByTypeName( geometryTypes[i] ) );
+ std::auto_ptr< Geometry > gB( registry.newGeometryByTypeName( geometryTypes[j] ) );
+
+ double dAB ;
+ BOOST_CHECK_NO_THROW( dAB = gA->distance3D( *gB ) ) ;
+ BOOST_CHECK_EQUAL( dAB, std::numeric_limits< double >::infinity() );
+ }
+ }
+}
+
+#endif
+
+
+BOOST_AUTO_TEST_CASE( testDistancePointPoint )
+{
+ BOOST_CHECK_EQUAL( Point( 0.0,0.0 ).distance( Point( 0.0,0.0 ) ), 0.0 );
+ BOOST_CHECK_EQUAL( Point( 1.0,1.0 ).distance( Point( 4.0,5.0 ) ), 5.0 );
+}
+BOOST_AUTO_TEST_CASE( testDistancePointPoint3D )
+{
+ BOOST_CHECK_EQUAL( Point( 0.0,0.0,0.0 ).distance3D( Point( 0.0,0.0,0.0 ) ), 0.0 );
+ BOOST_CHECK_EQUAL( Point( 1.0,1.0,1.0 ).distance3D( Point( 4.0,1.0,5.0 ) ), 5.0 );
+}
+
+
+//testPointLineString
+BOOST_AUTO_TEST_CASE( testDistancePointLineString_pointOnLineString )
+{
+ Point point( 1.0,1.0 );
+ LineString lineString(
+ Point( 0.0,0.0 ),
+ Point( 2.0,2.0 )
+ );
+ BOOST_CHECK_EQUAL( point.distance( lineString ), 0.0 );
+}
+BOOST_AUTO_TEST_CASE( testDistancePointLineString_pointOnLineString_badLineStringDefinition )
+{
+ Point point( 3.0,4.0 );
+ LineString lineString ;
+ lineString.addPoint( Point( 0.0,0.0 ) );
+ BOOST_CHECK_THROW( point.distance( lineString ), GeometryInvalidityException );
+}
+BOOST_AUTO_TEST_CASE( testDistancePointLineString_pointOnLineString_collapsedSegments )
+{
+ Point point( 3.0,4.0 );
+ LineString lineString ;
+ lineString.addPoint( Point( 0.0,0.0 ) );
+ lineString.addPoint( Point( 0.0,0.0 ) );
+ BOOST_CHECK_THROW( point.distance( lineString ), GeometryInvalidityException );
+}
+BOOST_AUTO_TEST_CASE( testDistancePointLineString3D_pointOnLineString_collapsedSegments )
+{
+ Point point( 0.0,3.0,4.0 );
+ LineString lineString ;
+ lineString.addPoint( Point( 0.0,0.0,0.0 ) );
+ lineString.addPoint( Point( 0.0,-1.0,-1.0 ) );
+ BOOST_CHECK_EQUAL( point.distance3D( lineString ), 5.0 );
+}
+
+
+
+BOOST_AUTO_TEST_CASE( testDistancePointLineString_pointOutOfLineString )
+{
+ Point point( 0.0,1.0 );
+ LineString lineString(
+ Point( 0.0,0.0 ),
+ Point( 2.0,2.0 )
+ );
+ BOOST_CHECK_EQUAL( point.distance( lineString ), sqrt( 2.0 )/2.0 );
+}
+
+//testPointPolygon
+BOOST_AUTO_TEST_CASE( testDistancePointPolygon_pointInPolygon )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "POINT(0.5 0.5)" ) );
+ std::auto_ptr< Geometry > gB( io::readWkt( "POLYGON((0.0 0.0,1.0 0.0,1.0 1.0,0.0 1.0,0.0 0.0))" ) );
+ BOOST_CHECK_EQUAL( gA->distance( *gB ), 0.0 );
+}
+BOOST_AUTO_TEST_CASE( testDistancePointPolygon_pointOutOfPolygon )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "POINT(0.0 1.0)" ) );
+ std::auto_ptr< Geometry > gB( io::readWkt( "POLYGON((0.0 0.0,2.0 2.0,2.0 0.0,0.0 0.0))" ) );
+ BOOST_CHECK_EQUAL( gA->distance( *gB ), sqrt( 2.0 )/2.0 );
+}
+
+// LineString / LineString 2D
+BOOST_AUTO_TEST_CASE( testDistanceLineStringLineString_zeroLengthSegments )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "LINESTRING(0.0 0.0,-1.0 -1.0)" ) );
+ std::auto_ptr< Geometry > gB( io::readWkt( "LINESTRING(3.0 4.0,4.0 5.0)" ) );
+ BOOST_CHECK_EQUAL( gA->distance( *gB ), 5.0 );
+}
+// LineString / LineString 3D
+BOOST_AUTO_TEST_CASE( testDistanceLineStringLineString3D_zeroLengthSegments )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "LINESTRING(0.0 0.0 0.0,-1.0 -1.0 -1.0)" ) );
+ std::auto_ptr< Geometry > gB( io::readWkt( "LINESTRING(0.0 3.0 4.0,0.0 4.0 5.0)" ) );
+ BOOST_CHECK_EQUAL( gA->distance3D( *gB ), 5.0 );
+}
+
+// LineString / Triangle
+BOOST_AUTO_TEST_CASE( testDistance3DLineStringTriangle_lineStringInTriangle )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "LINESTRING(-1.0 0.0 1.0,1.0 0.0 1.0)" ) );
+ std::auto_ptr< Geometry > gB( io::readWkt( "TRIANGLE((-4.0 0.0 1.0,4.0 0.0 1.0,0.0 4.0 1.0,-4.0 0.0 1.0))" ) );
+ BOOST_CHECK_EQUAL( gA->distance3D( *gB ), 0.0 );
+}
+BOOST_AUTO_TEST_CASE( testDistance3DLineStringTriangle_lineStringStartPointIsNearest )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "LINESTRING(-1.0 0.0 2.0,1.0 0.0 3.0)" ) );
+ std::auto_ptr< Geometry > gB( io::readWkt( "TRIANGLE((-4.0 0.0 1.0,4.0 0.0 1.0,0.0 4.0 1.0,-4.0 0.0 1.0))" ) );
+ BOOST_CHECK_EQUAL( gA->distance3D( *gB ), 1.0 );
+}
+
+// Triangle / Triangle
+BOOST_AUTO_TEST_CASE( testDistance3DTriangleTriangle_contained )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "TRIANGLE((-3.0 0.0 1.0,3.0 0.0 1.0,0.0 3.0 1.0,-3.0 0.0 1.0))" ) );
+ std::auto_ptr< Geometry > gB( io::readWkt( "TRIANGLE((-4.0 0.0 1.0,4.0 0.0 1.0,0.0 4.0 1.0,-4.0 0.0 1.0))" ) );
+ BOOST_CHECK_EQUAL( gA->distance3D( *gB ), 0.0 );
+}
+BOOST_AUTO_TEST_CASE( testDistance3DTriangleTriangle_parallel )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "TRIANGLE((-3.0 0.0 1.0,3.0 0.0 1.0,0.0 3.0 1.0,-3.0 0.0 1.0))" ) );
+ std::auto_ptr< Geometry > gB( io::readWkt( "TRIANGLE((-4.0 0.0 2.0,4.0 0.0 2.0,0.0 4.0 2.0,-4.0 0.0 2.0))" ) );
+ BOOST_CHECK_EQUAL( gA->distance3D( *gB ), 1.0 );
+}
+
+// Polygon / Polygon
+
+BOOST_AUTO_TEST_CASE( testDistancePolygonPolygon_disjoint )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "POLYGON((0.0 0.0,1.0 0.0,1.0 1.0,0.0 1.0,0.0 0.0))" ) );
+ std::auto_ptr< Geometry > gB( io::readWkt( "POLYGON((2.0 0.0,3.0 0.0,3.0 1.0,2.0 1.0,2.0 0.0))" ) );
+ BOOST_CHECK_EQUAL( gA->distance( *gB ), 1.0 );
+}
+
+BOOST_AUTO_TEST_CASE( testDistanceMultiPointMultiPoint_disjoint )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "MULTIPOINT((0.0 0.0),(1.0 0.0),(1.0 1.0),(0.0 1.0)))" ) );
+ std::auto_ptr< Geometry > gB( io::readWkt( "MULTIPOINT((8.0 8.0),(4.0 5.0))" ) );
+ BOOST_CHECK_EQUAL( gA->distance( *gB ), 5.0 );
+}
+
+// Polygon / Solid
+BOOST_AUTO_TEST_CASE( testDistancePolygonSolid )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "POLYGON((1 -1 -1,1 1 -1,1 1 1,1 -1 1,1 -1 -1))" ) );
+ std::auto_ptr< Geometry > gB( io::readWkt( "SOLID((((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),((0 0 0,0 0 1,0 1 1,0 1 0,0 0 0)),((0 0 0,1 0 0,1 0 1,0 0 1,0 0 0)),((1 1 1,0 1 1,0 0 1,1 0 1,1 1 1)),((1 1 1,1 0 1,1 0 0,1 1 0,1 1 1)),((1 1 1,1 1 0,0 1 0,0 1 1,1 1 1))))" ) );
+ BOOST_CHECK_EQUAL( gA->distance3D( *gB ), 0 );
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/ExtrudeTest.cpp b/test/unit/SFCGAL/algorithm/ExtrudeTest.cpp
new file mode 100644
index 0000000..f574077
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/ExtrudeTest.cpp
@@ -0,0 +1,174 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/extrude.h>
+#include <SFCGAL/detail/transform/ForceZ.h>
+#include <SFCGAL/io/wkt.h>
+
+using namespace SFCGAL ;
+
+// always after CGAL
+using namespace boost::unit_test ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_ExtrudeTest )
+
+
+BOOST_AUTO_TEST_CASE( testExtrudePoint )
+{
+ Point g( 0.0,0.0,0.0 );
+ std::auto_ptr< Geometry > ext( algorithm::extrude( g, 0.0, 0.0, 1.0 ) );
+ BOOST_CHECK( ext->is< LineString >() );
+ BOOST_CHECK( ext->as< LineString >().is3D() );
+ BOOST_CHECK_EQUAL( ext->asText( 1 ), "LINESTRING(0.0 0.0 0.0,0.0 0.0 1.0)" );
+}
+
+
+BOOST_AUTO_TEST_CASE( testExtrudeLineString )
+{
+ LineString g(
+ Point( 0.0,0.0,0.0 ),
+ Point( 1.0,0.0,0.0 )
+ );
+ std::auto_ptr< Geometry > ext( algorithm::extrude( g, 0.0, 0.0, 1.0 ) );
+ BOOST_CHECK( ext->is< PolyhedralSurface >() );
+ BOOST_CHECK( ext->as< PolyhedralSurface >().is3D() );
+ BOOST_CHECK_EQUAL( ext->asText( 1 ), "POLYHEDRALSURFACE(((0.0 0.0 0.0,1.0 0.0 0.0,1.0 0.0 1.0,0.0 0.0 1.0,0.0 0.0 0.0)))" );
+}
+
+
+
+BOOST_AUTO_TEST_CASE( testExtrudeSquare )
+{
+ std::vector< Point > points;
+ points.push_back( Point( 0.0,0.0,0.0 ) );
+ points.push_back( Point( 1.0,0.0,0.0 ) );
+ points.push_back( Point( 1.0,1.0,0.0 ) );
+ points.push_back( Point( 0.0,1.0,0.0 ) );
+ points.push_back( Point( 0.0,0.0,0.0 ) );
+
+ LineString exteriorRing( points ) ;
+ Polygon g( exteriorRing );
+ std::auto_ptr< Geometry > ext( algorithm::extrude( g, 0.0, 0.0, 1.0 ) );
+ BOOST_CHECK( ext->is< Solid >() );
+ BOOST_CHECK_EQUAL( ext->as< Solid >().numShells(), 1U );
+ BOOST_CHECK_EQUAL( ext->as< Solid >().exteriorShell().numPolygons(), 6U );
+}
+
+BOOST_AUTO_TEST_CASE( testExtrudePolyhedral )
+{
+ std::auto_ptr<Geometry> g = io::readWkt( "POLYHEDRALSURFACE(((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)))" );
+
+ std::auto_ptr< Geometry > ext = algorithm::extrude( *g, 0.0, 0.0, 1.0 );
+ BOOST_CHECK( ext->is< Solid >() );
+ BOOST_CHECK_EQUAL( ext->as< Solid >().numShells(), 1U );
+}
+
+BOOST_AUTO_TEST_CASE( testExtrudeMultiPolygon )
+{
+ std::vector< Point > points;
+ points.push_back( Point( 0.0,0.0,0.0 ) );
+ points.push_back( Point( 1.0,0.0,0.0 ) );
+ points.push_back( Point( 1.0,1.0,0.0 ) );
+ points.push_back( Point( 0.0,1.0,0.0 ) );
+ points.push_back( Point( 0.0,0.0,0.0 ) );
+
+ std::vector< Point > points2;
+ points2.push_back( Point( 2.0,0.0,0.0 ) );
+ points2.push_back( Point( 3.0,0.0,0.0 ) );
+ points2.push_back( Point( 3.0,1.0,0.0 ) );
+ points2.push_back( Point( 2.0,1.0,0.0 ) );
+ points2.push_back( Point( 2.0,0.0,0.0 ) );
+
+ LineString exteriorRing( points ) ;
+ LineString exteriorRing2( points2 ) ;
+ Polygon g1( exteriorRing );
+ Polygon g2( exteriorRing2 );
+ MultiPolygon mp;
+ mp.addGeometry( g1 );
+ mp.addGeometry( g2 );
+
+ std::auto_ptr< Geometry > ext( algorithm::extrude( mp, 0.0, 0.0, 1.0 ) );
+ BOOST_CHECK( ext->is< MultiSolid >() );
+ BOOST_CHECK_EQUAL( ext->as<MultiSolid>().numGeometries(), 2U );
+}
+
+
+BOOST_AUTO_TEST_CASE( testExtrudeSquareWithHole )
+{
+ std::vector< LineString > rings;
+ {
+ std::vector< Point > points;
+ points.push_back( Point( 0.0,0.0,0.0 ) );
+ points.push_back( Point( 1.0,0.0,0.0 ) );
+ points.push_back( Point( 1.0,1.0,0.0 ) );
+ points.push_back( Point( 0.0,1.0,0.0 ) );
+ points.push_back( Point( 0.0,0.0,0.0 ) );
+ rings.push_back( LineString( points ) );
+ }
+ {
+ std::vector< Point > points;
+ points.push_back( Point( 0.2,0.2,0.0 ) );
+ points.push_back( Point( 0.8,0.2,0.0 ) );
+ points.push_back( Point( 0.8,0.8,0.0 ) );
+ points.push_back( Point( 0.2,0.8,0.0 ) );
+ points.push_back( Point( 0.2,0.2,0.0 ) );
+
+ std::reverse( points.begin(), points.end() );
+
+ rings.push_back( LineString( points ) );
+ }
+
+ Polygon g( rings );
+ std::auto_ptr< Geometry > ext( algorithm::extrude( g, 0.0, 0.0, 1.0 ) );
+ BOOST_CHECK( ext->is< Solid >() );
+ BOOST_CHECK_EQUAL( ext->as< Solid >().numShells(), 1U );
+ BOOST_CHECK_EQUAL( ext->as< Solid >().exteriorShell().numPolygons(), 10U );
+}
+
+
+//SELECT ST_AsText(ST_Extrude(ST_Extrude(ST_Extrude('POINT(0 0)', 1, 0, 0), 0, 1, 0), 0, 0, 1));
+BOOST_AUTO_TEST_CASE( testChainingExtrude )
+{
+ std::auto_ptr< Geometry > g( new Point( 0.0,0.0 ) );
+ g = algorithm::extrude( *g, 1.0, 0.0, 0.0 ) ;
+ BOOST_CHECK_EQUAL( g->asText( 0 ), "LINESTRING(0 0 0,1 0 0)" ) ;
+ g = algorithm::extrude( *g, 0.0, 1.0, 0.0 ) ;
+ BOOST_CHECK_EQUAL( g->asText( 0 ), "POLYHEDRALSURFACE(((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0)))" ) ;
+ g = algorithm::extrude( *g, 0.0, 0.0, 1.0 ) ;
+ BOOST_CHECK_EQUAL( g->asText( 0 ), "SOLID((((0 1 0,1 1 0,1 0 0,0 1 0)),((0 1 1,1 0 1,1 1 1,0 1 1)),((0 1 0,1 0 0,0 0 0,0 1 0)),((0 1 1,0 0 1,1 0 1,0 1 1)),((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)),((1 1 0,0 1 0,0 1 1,1 1 1,1 1 0)),((0 1 0,0 0 0,0 0 1,0 1 1,0 1 0)),((0 0 0,1 0 0,1 0 1,0 0 1,0 0 0))))" ) ;
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/Force3DTest.cpp b/test/unit/SFCGAL/algorithm/Force3DTest.cpp
new file mode 100644
index 0000000..e60d2e8
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/Force3DTest.cpp
@@ -0,0 +1,91 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/force3D.h>
+
+#include <SFCGAL/detail/tools/Registry.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+// note that it relies on a visitor
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_Force3DTest )
+
+BOOST_AUTO_TEST_CASE( testIgnoreEmpty )
+{
+ tools::Registry& registry = tools::Registry::instance() ;
+ std::vector< std::string > typeNames = tools::Registry::instance().getGeometryTypes();
+
+ for ( size_t i = 0; i < typeNames.size(); i++ ) {
+ BOOST_TEST_MESSAGE( typeNames[i] ) ;
+
+ std::auto_ptr< Geometry > g( registry.newGeometryByTypeName( typeNames[i] ) ) ;
+ BOOST_REQUIRE( g.get() != NULL ) ;
+ algorithm::force3D( *g ) ;
+ BOOST_CHECK( g->isEmpty() ) ;
+ }
+}
+
+BOOST_AUTO_TEST_CASE( testPointForceZ )
+{
+ Point p( 3.0,4.0 );
+ algorithm::force3D( p );
+ BOOST_CHECK_EQUAL( p.asText( 1 ), "POINT(3.0 4.0 0.0)" );
+}
+BOOST_AUTO_TEST_CASE( testPointForceZWithValue )
+{
+ Point p( 3.0,4.0 );
+ algorithm::force3D( p,-9999.0 );
+ BOOST_CHECK_EQUAL( p.asText( 1 ), "POINT(3.0 4.0 -9999.0)" );
+}
+
+
+BOOST_AUTO_TEST_CASE( test_MixedLineString2D3D )
+{
+ LineString lineString ;
+ lineString.addPoint( Point( 1.0,1.0 ) );
+ lineString.addPoint( Point( 2.0,2.0,1.0 ) );
+ lineString.addPoint( Point( 3.0,3.0 ) );
+ algorithm::force3D( lineString );
+ // should keep 1.0 for the second point
+ BOOST_CHECK_EQUAL( lineString.asText( 1 ), "LINESTRING(1.0 1.0 0.0,2.0 2.0 1.0,3.0 3.0 0.0)" );
+}
+
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/IntersectionTest.cpp b/test/unit/SFCGAL/algorithm/IntersectionTest.cpp
new file mode 100644
index 0000000..ca93d13
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/IntersectionTest.cpp
@@ -0,0 +1,243 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <fstream>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/algorithm/intersection.h>
+#include <SFCGAL/detail/GetPointsVisitor.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/io/GeometryStreams.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/detail/transform/AffineTransform3.h>
+
+#include "../../../test_config.h"
+
+#include <boost/test/unit_test.hpp>
+#include <boost/ptr_container/ptr_map.hpp>
+
+using namespace SFCGAL;
+using namespace boost::unit_test ;
+//namespace SFCGAL{
+//inline Geometry* new_clone( const Geometry& g )
+//{
+// return g.clone();
+//}
+//}
+
+void insertOrReplace( boost::ptr_map<std::string, Geometry >& map, std::string key, Geometry* value )
+{
+ boost::ptr_map<std::string, Geometry >::iterator found = map.find( key );
+
+ if ( found != map.end() ) {
+ map.erase( found );
+ }
+
+ map.insert( key, value );
+}
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_IntersectionTest )
+
+BOOST_AUTO_TEST_CASE( testFileIntersectionTest )
+{
+ int argc = framework::master_test_suite().argc;
+ char** argv = framework::master_test_suite().argv;
+
+ // look for options
+ int test_one_line = -1;
+ bool print_line_number = false;
+
+ for ( int i = 0; i < argc; ++i ) {
+ std::string argi( argv[i] );
+
+ if ( argi == "--line" ) {
+ // only test one line
+ if ( argc >= i+1 ) {
+ sscanf( argv[i+1], "%d", &test_one_line );
+ ++i;
+ continue;
+ }
+ }
+
+ if ( argi == "--line-number" ) {
+ print_line_number = true;
+ }
+ }
+
+ boost::ptr_map<std::string, Geometry > storedGeom;
+
+ //logger().setLogLevel( Logger::Debug );
+
+ std::string filename( SFCGAL_TEST_DIRECTORY );
+ filename += "/data/IntersectionTest.txt" ;
+
+ std::ifstream ifs( filename.c_str() );
+ BOOST_REQUIRE( ifs.good() ) ;
+
+ int numLine = 0 ;
+ std::string line;
+
+ while ( std::getline( ifs, line ) ) {
+ numLine++;
+
+ if ( line[0] == '#' || line.empty() ) {
+ continue ;
+ }
+
+ if ( print_line_number ) {
+ std::cout << numLine << std::endl;
+ }
+
+ if ( test_one_line == -1 ) {
+ BOOST_TEST_MESSAGE( boost::format( "line#%s:%s" ) % numLine % line );
+ }
+
+ std::istringstream iss( line );
+
+ std::string dimension ;
+ std::string wktGA, wktGB ;
+ std::string wktOut ;
+
+ std::getline( iss, dimension, '|' ) ;
+
+ if ( dimension == "S" ) {
+ // store the geometry
+ std::string geomName;
+ std::getline( iss, geomName, '|' );
+ std::getline( iss, wktGA, '|' );
+ insertOrReplace( storedGeom, geomName, io::readWkt( wktGA ).release() );
+ continue;
+ }
+
+ // we need to read the lines until here to store reference
+ if ( test_one_line != -1 ) {
+ if ( numLine != test_one_line ) {
+ continue;
+ }
+ else {
+ BOOST_TEST_MESSAGE( boost::format( "line#%s:%s" ) % numLine % line );
+ }
+ }
+
+ std::auto_ptr< Geometry > gA( 0 );
+ std::auto_ptr< Geometry > gB( 0 );
+ std::auto_ptr< Geometry > gOut( 0 );
+
+ std::getline( iss, wktGA, '|' ) ;
+
+ if ( wktGA[0] == '@' ) {
+ // stored geometry reference
+ std::string name = wktGA.substr( 1 );
+ const boost::ptr_map<std::string, Geometry >::const_iterator found = storedGeom.find( name );
+
+ if ( found == storedGeom.end() ) {
+ BOOST_REQUIRE_MESSAGE( false, numLine << ": can't find the geometry named " << name );
+ }
+
+ gA.reset( found->second->clone() );
+ }
+ else {
+ gA = io::readWkt( wktGA );
+ }
+
+ insertOrReplace( storedGeom, "A", gA->clone() );
+
+ std::getline( iss, wktGB, '|' ) ;
+
+ if ( wktGB[0] == '@' ) {
+ // stored geometry reference
+ std::string name = wktGB.substr( 1 );
+ const boost::ptr_map<std::string, Geometry >::const_iterator found = storedGeom.find( name );
+
+ if ( found == storedGeom.end() ) {
+ BOOST_REQUIRE_MESSAGE( false, numLine << ": can't find the geometry named " << name );
+ }
+
+ gB.reset( found->second->clone() );
+ }
+ else {
+ gB = io::readWkt( wktGB );
+ }
+
+ insertOrReplace( storedGeom, "B", gB->clone() );
+
+ // exception management
+ bool expectException = false;
+ bool expectNotImplemented = false;
+
+ std::getline( iss, wktOut, '|' ) ;
+
+ if ( wktOut[0] == '@' ) {
+ // stored geometry reference
+ std::string name = wktOut.substr( 1 );
+ const boost::ptr_map<std::string, Geometry >::const_iterator found = storedGeom.find( name );
+
+ if ( found == storedGeom.end() ) {
+ BOOST_CHECK_MESSAGE( false, numLine << ": can't find the geometry named " << name );
+ }
+
+ gOut.reset( found->second->clone() );
+ }
+ // expect an exception
+ else if ( wktOut[0] == '!' ) {
+ if ( wktOut == "!NotImplemented" ) {
+ expectNotImplemented = true;
+ }
+
+ expectException = true;
+ }
+ else {
+ gOut = io::readWkt( wktOut );
+ }
+
+
+ try {
+ if ( dimension == "2" ) {
+ std::auto_ptr<Geometry> result = algorithm::intersection( *gA,*gB );
+ BOOST_CHECK_MESSAGE( *result == *gOut, numLine << ": intersection(" << gA->asText() << ", " << gB->asText() << ") is " << result->asText() << " and should be " << gOut->asText() );
+ }
+ else if ( dimension == "3" ) {
+ std::auto_ptr<Geometry> result = algorithm::intersection3D( *gA,*gB );
+ BOOST_CHECK_MESSAGE( *result == *gOut, numLine << ": intersection3D(" << gA->asText() << ", " << gB->asText() << ") is " << result->asText() << " and should be " << gOut->asText() );
+ }
+ else {
+ BOOST_CHECK( false );
+ }
+ }
+ catch ( SFCGAL::NotImplementedException& e ) {
+ BOOST_CHECK_MESSAGE( expectNotImplemented, numLine << ": " << e.what() );
+ }
+ catch ( std::exception& e ) {
+ BOOST_CHECK_MESSAGE( expectException, numLine << ": " << e.what() );
+ }
+ }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/IntersectsTest.cpp b/test/unit/SFCGAL/algorithm/IntersectsTest.cpp
new file mode 100644
index 0000000..8687da2
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/IntersectsTest.cpp
@@ -0,0 +1,115 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <cmath>
+#include <fstream>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/detail/io/WktWriter.h>
+#include <SFCGAL/algorithm/intersects.h>
+#include <SFCGAL/detail/transform/AffineTransform3.h>
+
+#include "../../../test_config.h"
+
+using namespace SFCGAL ;
+using namespace boost::unit_test ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_IntersectsTest )
+
+/**
+ * Perform tests in test/data/IntersectsTest.txt
+ */
+BOOST_AUTO_TEST_CASE( testFileIntersectsTest )
+{
+ //logger().setLogLevel( Logger::Debug );
+
+ std::string filename( SFCGAL_TEST_DIRECTORY );
+ filename += "/data/IntersectsTest.txt" ;
+
+ std::ifstream ifs( filename.c_str() );
+ BOOST_REQUIRE( ifs.good() ) ;
+
+ int numLine = 0 ;
+ std::string line;
+
+ while ( std::getline( ifs, line ) ) {
+ numLine++;
+
+ if ( line[0] == '#' || line.empty() ) {
+ continue ;
+ }
+
+ BOOST_TEST_MESSAGE( boost::format( "line#%s:%s" ) % numLine % line );
+
+ std::istringstream iss( line );
+
+ std::string distanceDimension ;
+ std::string wktGA, wktGB ;
+ std::string trueOrFalse ;
+
+ std::getline( iss, distanceDimension, '|' ) ;
+ std::getline( iss, wktGA, '|' ) ;
+ std::getline( iss, wktGB, '|' ) ;
+ std::getline( iss, trueOrFalse, '|' ) ;
+
+ bool expected = ( trueOrFalse == "true" ) ? true : false ;
+
+ std::auto_ptr< Geometry > gA( io::readWkt( wktGA ) );
+ std::auto_ptr< Geometry > gB( io::readWkt( wktGB ) );
+
+ try {
+ if ( distanceDimension == "2" ) {
+ BOOST_CHECK_MESSAGE( algorithm::intersects( *gA,*gB ) == expected, numLine << ": intersects(" << gA->asText() << ", " << gB->asText() << ") should be " << ( expected ? "TRUE" : "FALSE" ) );
+ // test symmetric call
+ BOOST_CHECK_MESSAGE( algorithm::intersects( *gB,*gA ) == expected, numLine << ": intersects(" << gB->asText() << ", " << gA->asText() << ") should be " << ( expected ? "TRUE" : "FALSE" ) );
+ }
+ else if ( distanceDimension == "3" ) {
+ bool got = algorithm::intersects3D( *gA,*gB );
+ BOOST_CHECK_MESSAGE( got == expected, numLine << ": intersects3D(" << gA->asText() << ", " << gB->asText() << ") should be " << ( expected ? "TRUE" : "FALSE" ) );
+ // test symmetric call
+ got = algorithm::intersects3D( *gB,*gA );
+ BOOST_CHECK_MESSAGE( got == expected, numLine << ": intersects3D(" << gB->asText() << ", " << gA->asText() << ") should be " << ( expected ? "TRUE" : "FALSE" ) );
+ }
+ else {
+ BOOST_CHECK( false );
+ }
+ }
+ catch ( std::exception& e ) {
+ BOOST_CHECK_MESSAGE( false, numLine << ": " << e.what() );
+ }
+ }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/IsValidTest.cpp b/test/unit/SFCGAL/algorithm/IsValidTest.cpp
new file mode 100644
index 0000000..df80ab0
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/IsValidTest.cpp
@@ -0,0 +1,84 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/isValid.h>
+#include <SFCGAL/detail/TestGeometry.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_IsValid )
+
+BOOST_AUTO_TEST_CASE( geometryIsValid )
+{
+ const std::vector< TestGeometry > testGeometry( createTestGeometries() );
+ const std::size_t nbOfTest = testGeometry.size();
+
+ for ( std::size_t t=0; t<nbOfTest; t++ ) {
+ const TestGeometry& tg = testGeometry[t];
+ //std::cerr << t << ":" << tg.wkt << "\n";
+ std::auto_ptr< Geometry > g;
+
+ try {
+ g = io::readWkt( tg.wkt );
+ }
+ catch ( WktParseException ) {
+ BOOST_CHECK_MESSAGE( !tg.isValid, ( boost::format( "%d: parse error on valid geometry %s" ) % t % tg.wkt ) );
+ continue;
+ }
+
+ Validity v = algorithm::isValid( *g );
+ BOOST_CHECK_MESSAGE( v == tg.isValid, ( boost::format( "%d:%s should be %s (%s)%s%s : %s" ) % t % g->geometryType() % ( tg.isValid?"valid":"invalid" ) % tg.comment % ( v?".":", reason: " ) % v.reason() % tg.wkt ) );
+ }
+
+}
+
+BOOST_AUTO_TEST_CASE( geometryWithNan )
+{
+ const double inf = std::numeric_limits<double>::infinity();
+ const double quietNaN = std::numeric_limits<double>::quiet_NaN();
+ const double sigNaN = std::numeric_limits<double>::signaling_NaN();
+
+ BOOST_CHECK_THROW( Coordinate( quietNaN ,1.0,2.0 ), NonFiniteValueException );
+ BOOST_CHECK_THROW( Coordinate( inf,1.0,2.0 ), NonFiniteValueException );
+ BOOST_CHECK_THROW( Coordinate( sigNaN,1.0,2.0 ), NonFiniteValueException );
+}
+
+BOOST_AUTO_TEST_CASE( disconnectedTIN )
+{
+ std::auto_ptr< Geometry > g( io::readWkt( "TIN(((0 0,1 0,0 1,0 0)),((2 0,3 0,2 1,2 0)))" ) );
+ Validity v = algorithm::isValid( *g );
+ BOOST_CHECK( !v );
+}
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/unit/SFCGAL/algorithm/LengthTest.cpp b/test/unit/SFCGAL/algorithm/LengthTest.cpp
new file mode 100644
index 0000000..0fb2030
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/LengthTest.cpp
@@ -0,0 +1,103 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/length.h>
+
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_LengthTest )
+
+BOOST_AUTO_TEST_CASE( testZeroLength )
+{
+ BOOST_CHECK_EQUAL( algorithm::length( *io::readWkt( "POINT(0.0 0.0)" ) ), 0.0 );
+ BOOST_CHECK_EQUAL( algorithm::length( *io::readWkt( "LINESTRING EMPTY" ) ), 0.0 );
+ BOOST_CHECK_EQUAL( algorithm::length( *io::readWkt( "POLYGON((0 0,0 1,1 1,1 0,0 0))" ) ), 0.0 );
+}
+
+BOOST_AUTO_TEST_CASE( testZeroLengthVertical )
+{
+ BOOST_CHECK_EQUAL( algorithm::length( *io::readWkt( "LINESTRING(0.0 0.0 0.0,0.0 0.0 1.0)" ) ), 0.0 );
+}
+
+BOOST_AUTO_TEST_CASE( testLengthLineString )
+{
+ BOOST_CHECK_EQUAL( algorithm::length( *io::readWkt( "LINESTRING(0.0 0.0,3.0 4.0)" ) ), 5.0 );
+ BOOST_CHECK_EQUAL( algorithm::length( *io::readWkt( "LINESTRING(0.0 0.0,0.0 1.0,1.0 1.0)" ) ), 2.0 );
+}
+
+//-- 3D
+
+
+BOOST_AUTO_TEST_CASE( test3DZeroLength )
+{
+ BOOST_CHECK_EQUAL( algorithm::length3D( *io::readWkt( "POINT(0.0 0.0)" ) ), 0.0 );
+ BOOST_CHECK_EQUAL( algorithm::length3D( *io::readWkt( "LINESTRING EMPTY" ) ), 0.0 );
+ BOOST_CHECK_EQUAL( algorithm::length3D( *io::readWkt( "POLYGON((0 0,0 1,1 1,1 0,0 0))" ) ), 0.0 );
+}
+BOOST_AUTO_TEST_CASE( test3DLengthVertical )
+{
+ BOOST_CHECK_EQUAL( algorithm::length3D( *io::readWkt( "LINESTRING(0.0 0.0 0.0,0.0 0.0 1.0)" ) ), 1.0 );
+}
+BOOST_AUTO_TEST_CASE( test3DLengthLineString )
+{
+ BOOST_CHECK_EQUAL( algorithm::length3D( *io::readWkt( "LINESTRING(0.0 0.0 0.0,0.0 1.0 0.0,0.0 1.0 1.0)" ) ), 2.0 );
+}
+
+
+//-- invalid type 2D
+
+BOOST_AUTO_TEST_CASE( testLength_invalidType )
+{
+ std::vector< std::string > wkts ;
+ wkts.push_back( "POINT(3.0 4.0)" );
+ wkts.push_back( "TRIANGLE((0.0 0.0,1.0 0.0,1.0 1.0,0.0 0.0))" );
+ wkts.push_back( "POLYGON((0.0 0.0,1.0 0.0,1.0 1.0,0.0 0.0))" );
+
+ for ( size_t i = 0; i < wkts.size(); i++ ) {
+ BOOST_TEST_MESSAGE( wkts[i] );
+ BOOST_CHECK_EQUAL( algorithm::length( *io::readWkt( wkts[i] ) ), 0.0 );
+ BOOST_CHECK_EQUAL( algorithm::length3D( *io::readWkt( wkts[i] ) ), 0.0 );
+ }
+
+}
+//-- invalid type 3D
+
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/MinkowskiSumTest.cpp b/test/unit/SFCGAL/algorithm/MinkowskiSumTest.cpp
new file mode 100644
index 0000000..e47306b
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/MinkowskiSumTest.cpp
@@ -0,0 +1,137 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/minkowskiSum.h>
+#include <SFCGAL/detail/generator/hoch.h>
+
+#include <SFCGAL/detail/tools/Registry.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_MinkowskiTest )
+
+BOOST_AUTO_TEST_CASE( testEmpty )
+{
+ std::auto_ptr< Geometry > gB( io::readWkt( "POLYGON((0 0,1 0,1 1,0 1,0 0))" ) );
+
+ tools::Registry& registry = tools::Registry::instance() ;
+ std::vector< std::string > typeNames = tools::Registry::instance().getGeometryTypes();
+
+ for ( size_t i = 0; i < typeNames.size(); i++ ) {
+ std::auto_ptr< Geometry > g( registry.newGeometryByTypeName( typeNames[i] ) ) ;
+ BOOST_CHECK( algorithm::minkowskiSum( *g, gB->as< Polygon >() )->isEmpty() );
+ }
+}
+
+BOOST_AUTO_TEST_CASE( testEmptyPoint )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "MULTIPOINT EMPTY" ) );
+ std::auto_ptr< Geometry > gB( io::readWkt( "POLYGON((0 0,1 0,1 1,0 1,0 0))" ) );
+
+ std::auto_ptr< Geometry > sum( algorithm::minkowskiSum( *gA, gB->as< Polygon >() ) );
+ BOOST_CHECK_EQUAL( sum->asText( 0 ), "MULTIPOLYGON EMPTY" );
+}
+
+BOOST_AUTO_TEST_CASE( testPoint )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "POINT(0 0)" ) );
+ std::auto_ptr< Geometry > gB( io::readWkt( "POLYGON((0 0,1 0,1 1,0 1,0 0))" ) );
+
+ std::auto_ptr< Geometry > sum( algorithm::minkowskiSum( *gA, gB->as< Polygon >() ) );
+ BOOST_CHECK_EQUAL( sum->asText( 0 ), "MULTIPOLYGON(((0 0,1 0,1 1,0 1,0 0)))" );
+}
+BOOST_AUTO_TEST_CASE( testLineString )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "LINESTRING(0 0,5 0)" ) );
+ std::auto_ptr< Geometry > gB( io::readWkt( "POLYGON((-1 0,0 -1,1 0,0 1,-1 0))" ) );
+
+ std::auto_ptr< Geometry > sum( algorithm::minkowskiSum( *gA, gB->as< Polygon >() ) );
+ BOOST_CHECK_EQUAL( sum->asText( 0 ), "MULTIPOLYGON(((5 1,0 1,-1 0,0 -1,5 -1,6 0,5 1)))" );
+}
+/*
+ * check that CGAL doesn't use the center of the polygon gB
+ */
+BOOST_AUTO_TEST_CASE( testLineString2 )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "LINESTRING(0 0,5 0)" ) );
+ std::auto_ptr< Geometry > gB( io::readWkt( "POLYGON((0 0,1 -1,2 0,1 1,0 0))" ) );
+
+ std::auto_ptr< Geometry > sum( algorithm::minkowskiSum( *gA, gB->as< Polygon >() ) );
+ BOOST_CHECK_EQUAL( sum->asText( 0 ), "MULTIPOLYGON(((6 1,1 1,0 0,1 -1,6 -1,7 0,6 1)))" );
+}
+
+
+
+BOOST_AUTO_TEST_CASE( testLineString3 )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "LINESTRING(5 5,0 5,5 0,0 0)" ) );
+ std::auto_ptr< Geometry > gB( io::readWkt( "POLYGON((-1 0,0 -1,1 0,0 1,-1 0))" ) );
+
+ std::auto_ptr< Geometry > sum( algorithm::minkowskiSum( *gA, gB->as< Polygon >() ) );
+ BOOST_CHECK_EQUAL( sum->asText( 0 ), "MULTIPOLYGON(((5 1,2 4,5 4,6 5,5 6,0 6,-1 5,0 4,3 1,0 1,-1 0,0 -1,5 -1,6 0,5 1)))" );
+}
+
+BOOST_AUTO_TEST_CASE( testPolygonWithHole )
+{
+ std::string wkt = "POLYGON((11.966308 -10.211022,18.007885 1.872133,39.364158 2.434140,53.554839 -6.557975,43.438710 -22.856183,20.396416 -28.476254,5.643728 -25.525717,13.090323 -20.889158,32.479570 -21.310663,38.521147 -15.831093,46.248746 -9.087007,34.446595 -1.359409,22.784946 -14.988082,11.966308 -10.211022),(20.396416 -1.640412,15.900358 -7.260484,18.007885 -9.508513,22.644444 -9.368011,25.173477 -2.342921,20.396416 -1.640412),(41.050179 -0.797401,40.207168 -2.202419,47.934767 [...]
+ std::auto_ptr< Geometry > gA( io::readWkt( wkt ) );
+
+ std::auto_ptr< Geometry > gB( io::readWkt( "POLYGON((-1 0,0 -1,1 0,0 1,-1 0))" ) );
+
+ std::auto_ptr< Geometry > sum( algorithm::minkowskiSum( *gA, gB->as< Polygon >() ) );
+ BOOST_CHECK_EQUAL( sum->asText( 6 ), "MULTIPOLYGON(((53.554839 -5.557975,39.364158 3.434140,18.007885 2.872133,17.007885 1.872133,10.966308 -10.211022,11.966308 -11.211022,22.784946 -15.988082,23.784946 -14.988082,34.539099 -2.419977,44.939408 -9.229702,38.521147 -14.831093,32.479570 -20.310663,13.090323 -19.889158,5.643728 -24.525717,4.643728 -25.525717,5.643728 -26.525717,20.396416 -29.476254,43.438710 -23.856183,44.438710 -22.856183,54.554839 -6.557975,53.554839 -5.557975),(23.881 [...]
+
+ // reverse orientation
+ gA->as< Polygon >().reverse() ;
+ sum = algorithm::minkowskiSum( *gA, gB->as< Polygon >() ) ;
+ BOOST_CHECK_EQUAL( sum->asText( 6 ), "MULTIPOLYGON(((53.554839 -5.557975,39.364158 3.434140,18.007885 2.872133,17.007885 1.872133,10.966308 -10.211022,11.966308 -11.211022,22.784946 -15.988082,23.784946 -14.988082,34.539099 -2.419977,44.939408 -9.229702,38.521147 -14.831093,32.479570 -20.310663,13.090323 -19.889158,5.643728 -24.525717,4.643728 -25.525717,5.643728 -26.525717,20.396416 -29.476254,43.438710 -23.856183,44.438710 -22.856183,54.554839 -6.557975,53.554839 -5.557975),(23.881 [...]
+}
+
+BOOST_AUTO_TEST_CASE( testMultiPoint )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "MULTIPOINT(0 0,5 5)" ) );
+ std::auto_ptr< Geometry > gB( io::readWkt( "POLYGON((-1 0,0 -1,1 0,0 1,-1 0))" ) );
+
+ std::auto_ptr< Geometry > sum( algorithm::minkowskiSum( *gA, gB->as< Polygon >() ) );
+ BOOST_CHECK_EQUAL( sum->asText( 0 ), "MULTIPOLYGON(((0 1,-1 0,0 -1,1 0,0 1)),((5 6,4 5,5 4,6 5,5 6)))" );
+}
+
+
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/NormalTest.cpp b/test/unit/SFCGAL/algorithm/NormalTest.cpp
new file mode 100644
index 0000000..663918a
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/NormalTest.cpp
@@ -0,0 +1,117 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/normal.h>
+
+using namespace SFCGAL ;
+using namespace boost::unit_test ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_NormalTest )
+
+BOOST_AUTO_TEST_CASE( testNormal1 )
+{
+ typedef CGAL::Vector_3< Kernel > Vector_3 ;
+ typedef CGAL::Point_3< Kernel > Point_3 ;
+
+ Point_3 a( 0.0, 0.0, 0.0 );
+ Point_3 b( 1.0, 0.0, 0.0 );
+ Point_3 c( 1.0, 1.0, 0.0 );
+
+ Vector_3 normal = algorithm::normal3D( a, b, c );
+ BOOST_CHECK_EQUAL( normal.x(), 0.0 );
+ BOOST_CHECK_EQUAL( normal.y(), 0.0 );
+ BOOST_CHECK_EQUAL( normal.z(), 1.0 );
+}
+
+BOOST_AUTO_TEST_CASE( testNormal2 )
+{
+ // a square ccw
+ std::auto_ptr<Geometry> gA( io::readWkt( "POLYGON((0 0,1 0,1 1,0 1,0 0))" ) );
+ // a square cw oriented
+ std::auto_ptr<Geometry> gB( io::readWkt( "POLYGON((0 0,0 1,1 1,1 0,0 0))" ) );
+
+ // a pseudo-square ccw oriented, with a concave part
+ std::auto_ptr<Geometry> gC( io::readWkt( "POLYGON((0 0,0.5 0.5,1 0,1 1,0 1,0 0))" ) );
+
+ {
+ CGAL::Vector_3<Kernel> normal = algorithm::normal3D<Kernel>( gA->as<Polygon>() );
+ BOOST_CHECK_EQUAL( normal.x(), 0.0 );
+ BOOST_CHECK_EQUAL( normal.y(), 0.0 );
+ BOOST_CHECK_EQUAL( normal.z(), 2.0 );
+ }
+
+ {
+ CGAL::Vector_3<Kernel> normal = algorithm::normal3D<Kernel>( gB->as<Polygon>() );
+ BOOST_CHECK_EQUAL( normal.x(), 0.0 );
+ BOOST_CHECK_EQUAL( normal.y(), 0.0 );
+ BOOST_CHECK_EQUAL( normal.z(), -2.0 );
+ }
+
+ {
+ CGAL::Vector_3<Kernel> normal = algorithm::normal3D<Kernel>( gC->as<Polygon>() );
+ BOOST_CHECK_EQUAL( normal.x(), 0.0 );
+ BOOST_CHECK_EQUAL( normal.y(), 0.0 );
+ // ok, the normal is pointing up (z > 0)
+ BOOST_CHECK_EQUAL( normal.z(), 1.5 );
+ }
+}
+
+
+BOOST_AUTO_TEST_CASE( testNormal3 )
+{
+ std::auto_ptr<Geometry> gA( io::readWkt( "POLYGON((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0))" ) );
+ // exact
+ {
+ CGAL::Vector_3<Kernel> normal = algorithm::normal3D<Kernel>( gA->as<Polygon>(), true );
+ //std::cout << CGAL::exact(normal) << std::endl;
+ CGAL::Plane_3<Kernel> plane( gA->as<Polygon>().exteriorRing().startPoint().toPoint_3(), normal );
+ //std::cout << CGAL::exact(plane) << std::endl;
+ BOOST_CHECK( ! plane.is_degenerate() );
+ }
+ // round
+ {
+ CGAL::Vector_3<Kernel> normal = algorithm::normal3D<Kernel>( gA->as<Polygon>(), false );
+ //std::cout << CGAL::exact(normal) << std::endl;
+ CGAL::Plane_3<Kernel> plane( gA->as<Polygon>().exteriorRing().startPoint().toPoint_3(), normal );
+ //std::cout << CGAL::exact(plane) << std::endl;
+ BOOST_CHECK( ! plane.is_degenerate() );
+ }
+
+}
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/OffsetTest.cpp b/test/unit/SFCGAL/algorithm/OffsetTest.cpp
new file mode 100644
index 0000000..7d9aff5
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/OffsetTest.cpp
@@ -0,0 +1,140 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/offset.h>
+#include <SFCGAL/algorithm/area.h>
+
+#include <SFCGAL/detail/tools/Registry.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_OffsetTest )
+
+
+BOOST_AUTO_TEST_CASE( testEmpty )
+{
+ tools::Registry& registry = tools::Registry::instance() ;
+ std::vector< std::string > typeNames = tools::Registry::instance().getGeometryTypes();
+
+ for ( size_t i = 0; i < typeNames.size(); i++ ) {
+ std::auto_ptr< Geometry > g( registry.newGeometryByTypeName( typeNames[i] ) ) ;
+ BOOST_CHECK( algorithm::offset( *g, 1.0 )->isEmpty() );
+ }
+}
+
+
+BOOST_AUTO_TEST_CASE( testSimple )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "POLYGON((0 0,10 0,10 10,0 10,0 0))" ) );
+
+ std::auto_ptr< MultiPolygon > result( algorithm::offset( *gA, 1.0 ) ) ;
+ BOOST_CHECK_EQUAL( result->asText( 7 ), "MULTIPOLYGON(((-1.0000000 10.0000000,-1.0000000 0.0000000,-0.8750000 -0.4841229,-0.7500000 -0.6614378,-0.6250000 -0.7806247,-0.5000000 -0.8660254,-0.3750000 -0.9270248,-0.2500000 -0.9682458,-0.1250000 -0.9921567,0.0000000 -1.0000000,10.0000000 -1.0000000,10.1250000 -0.9921567,10.2500000 -0.9682458,10.3750000 -0.9270248,10.5000000 -0.8660254,10.6250000 -0.7806247,10.7500000 -0.6614378,10.8750000 -0.4841229,11.0000000 0.0000000,11.0000000 10.000 [...]
+}
+
+BOOST_AUTO_TEST_CASE( testHoles )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "POLYGON((13.652901 8.978070,13.921068 13.219992,20.454603 13.268750,18.967492 11.001516,16.432091 11.220926,15.091253 13.024961,14.481782 11.976670,14.676813 10.708970,15.798240 9.392511,16.358954 9.416890,16.870910 10.075119,16.797774 10.952758,17.431624 11.001516,18.162990 10.099498,18.138611 8.368599,14.774328 9.416890,14.530540 8.929313,13.945447 8.441735,13.652901 8.978070))" ) );
+
+ std::auto_ptr< MultiPolygon > result( algorithm::offset( *gA, 1.0 ) ) ;
+ BOOST_REQUIRE( result->is< MultiPolygon >() );
+
+ // @todo works in Release, not in Debug... Something strange with holes?
+ //BOOST_CHECK_EQUAL(result->asText(), "MULTIPOLYGON(((3562035796054625/281474976710656 2544860917657577/281474976710656,7123931396669903/562949953421312 317964373056855/35184372088832,1780947800307639/140737488355328 2542483596591303/281474976710656,890456375723901/70368744177664 2541144291051935/281474976710656,7123510810351861/562949953421312 634915648506851/70368744177664,3561685307456257/281474976710656 2537980476987837/281474976710656,3561615209736583/281474976710656 50719696011 [...]
+
+ //Check area
+ BOOST_CHECK_CLOSE( algorithm::area( *result ), 47.7, 1.0 );
+}
+
+BOOST_AUTO_TEST_CASE( testPoint )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "POINT(1 1)" ) );
+ std::auto_ptr< MultiPolygon > result( algorithm::offset( *gA, 1.0 ) ) ;
+ BOOST_CHECK_EQUAL( result->asText( 2 ), "MULTIPOLYGON(((2.00 1.00,1.75 1.66,1.50 1.87,1.25 1.97,1.00 2.00,0.75 1.97,0.50 1.87,0.25 1.66,0.00 1.00,0.25 0.34,0.50 0.13,0.75 0.03,1.00 0.00,1.25 0.03,1.50 0.13,1.75 0.34,2.00 1.00)))" );
+}
+
+
+BOOST_AUTO_TEST_CASE( testLineString )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "LINESTRING(13.652901 8.978070,13.921068 13.219992,20.454603 13.268750,18.967492 11.001516,16.432091 11.220926,15.091253 13.024961,14.481782 11.976670,14.676813 10.708970,15.798240 9.392511,16.358954 9.416890,16.870910 10.075119,16.797774 10.952758,17.431624 11.001516,18.162990 10.099498,18.138611 8.368599,14.774328 9.416890,14.530540 8.929313,13.945447 8.441735,13.652901 8.978070)" ) );
+ std::auto_ptr< MultiPolygon > result( algorithm::offset( *gA, 0.5 ) ) ;
+ // BOOST_CHECK_EQUAL( result->asText(7), "MULTIPOLYGON(((20.9546030 13.2687500,20.8916366 13.5116525,20.8286702 13.6005236,20.7657038 13.6601785,20.7027374 13.7028345,20.6397710 13.7331989,20.5768046 13.7535869,20.5138382 13.7652288,20.4508718 13.7687361,17.1597259 13.7441753,13.9173367 13.7199781,13.8554277 13.7156646,13.7935186 13.7034495,13.7316095 13.6827073,13.6697004 13.6522123,13.6077914 13.6096813,13.5458823 13.5505002,13.4839732 13.4627844,13.4220642 13.2515382,13.2795207 10 [...]
+ //Check area
+ BOOST_CHECK_CLOSE( algorithm::area( *result ), 29.2515, 1.0 );
+}
+
+BOOST_AUTO_TEST_CASE( testPolygonWithHoles )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "POLYGON((11.966308 -10.211022,18.007885 1.872133,39.364158 2.434140,53.554839 -6.557975,43.438710 -22.856183,20.396416 -28.476254,5.643728 -25.525717,13.090323 -20.889158,32.479570 -21.310663,38.521147 -15.831093,46.248746 -9.087007,34.446595 -1.359409,22.784946 -14.988082,11.966308 -10.211022),(20.396416 -1.640412,15.900358 -7.260484,18.007885 -9.508513,22.644444 -9.368011,25.173477 -2.342921,20.396416 -1.640412),(41.050179 -0.797401,40.20 [...]
+ std::auto_ptr< MultiPolygon > result( algorithm::offset( *gA, 0.5 ) ) ;
+
+ // @todo works in Release, not in Debug... Something strange with holes?
+ //BOOST_CHECK_EQUAL(result->asText(), "MULTIPOLYGON(((3028360385708393/562949953421312 -3532689497542891/140737488355328,3011773017246331/562949953421312 -1767740319401211/70368744177664,2995185648784269/562949953421312 -3538735168852129/140737488355328,5957196560644415/1125899906842624 -885635926734687/35184372088832,5924021823720291/1125899906842624 -3547045526205937/140737488355328,5890847086796167/1125899906842624 -1776237153685471/70368744177664,1464418087468011/281474976710656 [...]
+
+ BOOST_CHECK_CLOSE( algorithm::area( *result ), 696.0, 1.0 );
+}
+
+
+BOOST_AUTO_TEST_CASE( testMultiPoint )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "MULTIPOINT(2 0,1 1,0 2,-1 1,-2 0,-1 -1,0 -2,1 -1)" ) );
+ std::auto_ptr< MultiPolygon > result( algorithm::offset( *gA, 1.0 ) ) ;
+ BOOST_CHECK_EQUAL( result->asText( 7 ), "MULTIPOLYGON(((3.0000000 0.0000000,2.8750000 0.4841229,2.7500000 0.6614378,2.6250000 0.7806247,2.5000000 0.8660254,2.3750000 0.9270248,2.2500000 0.9682458,2.1250000 0.9921567,2.0000000 1.0000000,1.8750000 1.4841229,1.7500000 1.6614378,1.6250000 1.7806247,1.5000000 1.8660254,1.3750000 1.9270248,1.2500000 1.9682458,1.1250000 1.9921567,1.0000000 2.0000000,0.7500000 2.6614378,0.5000000 2.8660254,0.2500000 2.9682458,0.0000000 3.0000000,-0.2500000 2 [...]
+}
+
+BOOST_AUTO_TEST_CASE( testMultiLineString )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "MULTILINESTRING((0.0 0.0,1.0 0.0),(2.0 2.0,3.0 2.0))" ) );
+ std::auto_ptr< MultiPolygon > result( algorithm::offset( *gA, 1.0 ) ) ;
+ BOOST_CHECK_EQUAL( result->asText( 2 ), "MULTIPOLYGON(((2.00 0.00,1.88 0.48,1.75 0.66,1.62 0.78,1.50 0.87,1.38 0.93,1.25 0.97,1.12 0.99,1.00 1.00,0.00 1.00,-0.12 0.99,-0.25 0.97,-0.38 0.93,-0.50 0.87,-0.62 0.78,-0.75 0.66,-0.88 0.48,-1.00 0.00,-0.88 -0.48,-0.75 -0.66,-0.62 -0.78,-0.50 -0.87,-0.38 -0.93,-0.25 -0.97,-0.12 -0.99,0.00 -1.00,1.00 -1.00,1.12 -0.99,1.25 -0.97,1.38 -0.93,1.50 -0.87,1.62 -0.78,1.75 -0.66,1.88 -0.48,2.00 0.00)),((4.00 2.00,3.88 2.48,3.75 2.66,3.62 2.78,3.50 2. [...]
+}
+
+BOOST_AUTO_TEST_CASE( testMultiPolygon )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "MULTIPOLYGON(((0 0,1 0,1 1,0 0)),((2 1,2 0,3 0,2 1)))" ) );
+ std::auto_ptr< MultiPolygon > result( algorithm::offset( *gA, 1. ) ) ;
+ BOOST_CHECK_EQUAL( result->asText( 2 ), "MULTIPOLYGON(((-0.71 0.71,-0.74 0.67,-0.78 0.63,-0.82 0.58,-0.85 0.52,-0.89 0.46,-0.93 0.38,-0.96 0.27,-1.00 0.00,-0.88 -0.48,-0.75 -0.66,-0.62 -0.78,-0.50 -0.87,-0.38 -0.93,-0.25 -0.97,-0.12 -0.99,0.00 -1.00,1.00 -1.00,1.06 -1.00,1.12 -0.99,1.19 -0.98,1.25 -0.97,1.31 -0.95,1.38 -0.93,1.44 -0.90,1.50 -0.87,1.56 -0.90,1.62 -0.93,1.69 -0.95,1.75 -0.97,1.81 -0.98,1.88 -0.99,1.94 -1.00,2.00 -1.00,3.00 -1.00,3.12 -0.99,3.25 -0.97,3.38 -0.93,3.50 -0 [...]
+}
+
+BOOST_AUTO_TEST_CASE( testGeometryCollection )
+{
+ std::auto_ptr< Geometry > gA( io::readWkt( "GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(1 1,2 2))" ) );
+ std::auto_ptr< MultiPolygon > result( algorithm::offset( *gA, 1.0 ) ) ;
+ BOOST_CHECK_EQUAL( result->asText( 2 ), "MULTIPOLYGON(((-0.00 1.00,-0.12 0.99,-0.25 0.97,-0.38 0.93,-0.50 0.87,-0.62 0.78,-0.75 0.66,-0.88 0.48,-1.00 0.00,-0.75 -0.66,-0.50 -0.87,-0.25 -0.97,0.00 -1.00,0.25 -0.97,0.50 -0.87,0.75 -0.66,1.00 0.00,1.09 0.00,1.18 0.02,1.27 0.04,1.35 0.06,1.44 0.10,1.53 0.15,1.62 0.21,1.71 0.29,1.85 0.44,2.71 1.29,2.74 1.33,2.78 1.37,2.82 1.42,2.85 1.48,2.89 1.54,2.93 1.62,2.96 1.73,3.00 2.00,2.79 2.62,2.57 2.82,2.36 2.93,2.15 2.99,1.93 3.00,1.72 2.96,1.5 [...]
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/OrientationTest.cpp b/test/unit/SFCGAL/algorithm/OrientationTest.cpp
new file mode 100644
index 0000000..ff7182d
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/OrientationTest.cpp
@@ -0,0 +1,187 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/orientation.h>
+
+using namespace SFCGAL ;
+
+// always after CGAL
+using namespace boost::unit_test ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_OrientationTest )
+
+//TODO COMPLETE TEST
+
+//void makeValidOrientation( CGAL::Polygon_2< Kernel > & polygon ) ;
+//void makeValidOrientation( CGAL::Polygon_with_holes_2< Kernel > & polygon ) ;
+//void makeValidOrientation( Polygon & polygon ) ;
+
+
+//bool hasConsistentOrientation3D( const TriangulatedSurface & g ) ;
+BOOST_AUTO_TEST_CASE( testHasConsistentOrientation3D_basicTriangles )
+{
+ TriangulatedSurface triangulatedSurface;
+ BOOST_CHECK( algorithm::hasConsistentOrientation3D( triangulatedSurface ) );
+ triangulatedSurface.addTriangle(
+ Triangle(
+ Point( 0.0,0.0,0.0 ),
+ Point( 1.0,0.0,0.0 ),
+ Point( 0.0,1.0,0.0 )
+ )
+ );
+ BOOST_CHECK( algorithm::hasConsistentOrientation3D( triangulatedSurface ) );
+
+ triangulatedSurface.addTriangle(
+ Triangle(
+ Point( 0.0,0.0,0.0 ),
+ Point( 0.0,1.0,0.0 ),
+ Point( -1.0,0.0,0.0 )
+ )
+ );
+ BOOST_CHECK( algorithm::hasConsistentOrientation3D( triangulatedSurface ) );
+
+ triangulatedSurface.addTriangle(
+ Triangle(
+ Point( 0.0, 0.0, 0.0 ),
+ Point( 1.0, 0.0, 0.0 ),
+ Point( 0.0,-1.0, 0.0 )
+ )
+ );
+ BOOST_CHECK( ! algorithm::hasConsistentOrientation3D( triangulatedSurface ) );
+}
+
+
+
+//bool hasConsistentOrientation3D( const PolyhedralSurface & g ) ;
+
+BOOST_AUTO_TEST_CASE( testHasConsistentOrientation3D_basicPolygons )
+{
+ PolyhedralSurface polyhedralSurface ;
+ BOOST_CHECK( algorithm::hasConsistentOrientation3D( polyhedralSurface ) );
+
+ //base polygon
+ {
+ LineString ring ;
+ ring.addPoint( Point( 0.0,0.0,0.0 ) );
+ ring.addPoint( Point( 1.0,0.0,0.0 ) );
+ ring.addPoint( Point( 1.0,1.0,0.0 ) );
+ ring.addPoint( Point( 0.0,1.0,0.0 ) );
+ ring.addPoint( ring.startPoint() ) ;
+
+ polyhedralSurface.addPolygon( Polygon( ring ) );
+ }
+ BOOST_CHECK( algorithm::hasConsistentOrientation3D( polyhedralSurface ) );
+
+ //right polygon
+ {
+ LineString ring ;
+ ring.addPoint( Point( 1.0,0.0,0.0 ) );
+ ring.addPoint( Point( 1.0,0.0,1.0 ) );
+ ring.addPoint( Point( 1.0,1.0,1.0 ) );
+ ring.addPoint( Point( 1.0,1.0,0.0 ) );
+ ring.addPoint( ring.startPoint() ) ;
+
+ polyhedralSurface.addPolygon( Polygon( ring ) );
+ }
+ BOOST_CHECK( algorithm::hasConsistentOrientation3D( polyhedralSurface ) );
+
+ //left polygon (bad orientation)
+ {
+ LineString ring ;
+ ring.addPoint( Point( 0.0,0.0,0.0 ) );
+ ring.addPoint( Point( 0.0,0.0,1.0 ) );
+ ring.addPoint( Point( 0.0,1.0,1.0 ) );
+ ring.addPoint( Point( 0.0,1.0,0.0 ) );
+ ring.addPoint( ring.startPoint() ) ;
+
+ polyhedralSurface.addPolygon( Polygon( ring ) );
+ }
+ BOOST_CHECK( ! algorithm::hasConsistentOrientation3D( polyhedralSurface ) );
+}
+
+
+
+//void makeConsistentOrientation3D( TriangulatedSurface & g ) ;
+
+//bool isCounterClockWiseOriented( const Polygon& );
+BOOST_AUTO_TEST_CASE( testIsCounterClockWiseOriented_Polygon )
+{
+ LineString ring ;
+ ring.addPoint( Point( 0.0,0.0 ) );
+ ring.addPoint( Point( 1.0,0.0 ) );
+ ring.addPoint( Point( 1.0,1.0 ) );
+ ring.addPoint( Point( 0.0,1.0 ) );
+ ring.addPoint( ring.startPoint() ) ;
+
+ Polygon polygon( ring ) ;
+ BOOST_CHECK( algorithm::isCounterClockWiseOriented( polygon ) );
+ polygon.exteriorRing().reverse();
+ BOOST_CHECK( ! algorithm::isCounterClockWiseOriented( polygon ) );
+}
+
+//bool isCounterClockWiseOriented( const Triangle& );
+BOOST_AUTO_TEST_CASE( testIsCounterClockWiseOriented_Triangle )
+{
+ Triangle triangle(
+ Point( 0.0,0.0 ),
+ Point( 1.0,0.0 ),
+ Point( 1.0,1.0 )
+ );
+ BOOST_CHECK( algorithm::isCounterClockWiseOriented( triangle ) );
+ triangle.reverse();
+ BOOST_CHECK( ! algorithm::isCounterClockWiseOriented( triangle ) );
+}
+
+
+//bool isCounterClockWiseOriented( const LineString& );
+BOOST_AUTO_TEST_CASE( testIsCounterClockWiseOriented_LineString )
+{
+ LineString ring ;
+ ring.addPoint( Point( 0.0,0.0 ) ) ;
+ ring.addPoint( Point( 1.0,0.0 ) ) ;
+ ring.addPoint( Point( 1.0,1.0 ) ) ;
+ ring.addPoint( Point( 0.0,1.0 ) ) ;
+ ring.addPoint( ring.startPoint() ) ;
+
+ BOOST_CHECK( algorithm::isCounterClockWiseOriented( ring ) );
+ ring.reverse();
+ BOOST_CHECK( ! algorithm::isCounterClockWiseOriented( ring ) );
+}
+
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/PlaneTest.cpp b/test/unit/SFCGAL/algorithm/PlaneTest.cpp
new file mode 100644
index 0000000..387785f
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/PlaneTest.cpp
@@ -0,0 +1,84 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/plane.h>
+
+using namespace SFCGAL ;
+using namespace boost::unit_test ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_PlaneTest )
+
+BOOST_AUTO_TEST_CASE( testPlane1 )
+{
+ std::auto_ptr<Geometry> gA( io::readWkt( "POLYGON((0 0,1 0,1 1,0 1,0 0))" ) );
+
+ CGAL::Plane_3<Kernel> plane = algorithm::plane3D<Kernel>( gA->as<Polygon>() );
+ BOOST_CHECK_EQUAL( plane.a(), 0.0 );
+ BOOST_CHECK_EQUAL( plane.b(), 0.0 );
+ BOOST_CHECK_EQUAL( plane.c(), 2.0 );
+}
+
+BOOST_AUTO_TEST_CASE( testPlane )
+{
+ struct TestCase {
+ const std::string _wkt;
+ const bool _isPlane;
+ };
+ const TestCase test[] = {
+ {"LINESTRING(1 2 3,4 5 6)", true}, // only two points
+ {"LINESTRING(1 2 3,1 2 3,1 2 3,1 2 3)", true}, // all points in the same place
+ {"LINESTRING(1 2 3,2 4 6,3 6 9,4 8 12)", true}, // all points aliged
+ {"LINESTRING(1 2 3,6 5 4,7 8 9)", true}, // triangle must be plane
+ {"LINESTRING(0 0 0,1 0 0,1 1 0,0 1 0,0 0 0)", true}, // all point in the plane z=0
+ {"LINESTRING(2 1 0,2 0 0,2 1 0,2 1 0,2 0 3)", true}, // all points in the plane x=2
+ {"LINESTRING(2 1 0,2 0 0,2 1 1,2 1 0,1 0 3)", false}, // one point out of plane
+ };
+ const size_t numTest = sizeof( test ) / sizeof( TestCase );
+
+ for ( size_t t=0; t != numTest; ++t ) {
+ //std::cout << "test = " << t << "\n";
+ std::auto_ptr<Geometry> g( io::readWkt( test[t]._wkt ) );
+ const LineString* l = dynamic_cast<LineString*>( g.get() );
+ BOOST_CHECK_MESSAGE(
+ algorithm::isPlane3D< Kernel >( *l, 1.e-9 ) == test[t]._isPlane,
+ ( boost::format( "LineString %d: %s %s" ) % t % test[t]._wkt % ( test[t]._isPlane ? "is plane" : "isn't plane" ) )
+ );
+ }
+}
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/StraightSkeletonTest.cpp b/test/unit/SFCGAL/algorithm/StraightSkeletonTest.cpp
new file mode 100644
index 0000000..7d76ef8
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/StraightSkeletonTest.cpp
@@ -0,0 +1,123 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/straightSkeleton.h>
+
+#include <SFCGAL/detail/tools/Registry.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_StraightSkeletonTest )
+
+
+BOOST_AUTO_TEST_CASE( testTriangle )
+{
+ std::auto_ptr< Geometry > g( io::readWkt( "TRIANGLE((0 0,1 0,1 1,0 0))" ) );
+
+ std::string expectedWKT( "MULTILINESTRING((0.0 0.0,0.7 0.3),(1.0 0.0,0.7 0.3),(1.0 1.0,0.7 0.3))" );
+ {
+ std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ) ;
+ BOOST_CHECK_EQUAL( result->numGeometries(), 3U );
+ BOOST_CHECK_EQUAL( result->asText( 1 ), expectedWKT );
+ }
+ // check orientation insensitive
+ {
+ g->as< Triangle >().reverse() ;
+ std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ) ;
+ BOOST_CHECK_EQUAL( result->numGeometries(), 3U );
+ BOOST_CHECK_EQUAL( result->asText( 1 ), expectedWKT );
+ }
+}
+
+
+BOOST_AUTO_TEST_CASE( testPolygon )
+{
+ std::auto_ptr< Geometry > g( io::readWkt( "POLYGON((0 0,10 0,10 10,0 10,0 0))" ) );
+
+ std::string expectedWKT( "MULTILINESTRING((0 0,5 5),(10 0,5 5),(10 10,5 5),(0 10,5 5))" );
+ {
+ std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ) ;
+ BOOST_CHECK_EQUAL( result->numGeometries(), 4U );
+ BOOST_CHECK_EQUAL( result->asText( 0 ), expectedWKT );
+ }
+ // check orientation insensitive
+ {
+ g->as< Polygon >().exteriorRing().reverse() ;
+ std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ) ;
+ BOOST_CHECK_EQUAL( result->numGeometries(), 4U );
+ BOOST_CHECK_EQUAL( result->asText( 0 ), expectedWKT );
+ }
+}
+BOOST_AUTO_TEST_CASE( testPolygonWithHole )
+{
+ std::auto_ptr< Geometry > g( io::readWkt( "POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,-0.5 0.5,0.5 0.5,1.0 -0.5,-0.5 -0.5))" ) );
+
+ // just for valgrind
+ std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ) ;
+
+}
+
+BOOST_AUTO_TEST_CASE( testPolygonWithTouchingHoles )
+{
+ std::auto_ptr< Geometry > g( io::readWkt( "POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,-0.5 0.5,-0.1 0.5,0.1 -0.5,-0.5 -0.5),(0.1 -0.5,0.1 0.5,0.5 0.5,0.5 -0.5,0.1 -0.5))" ) );
+
+ // just for valgrind
+ BOOST_CHECK_THROW( std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ), NotImplementedException ) ;
+
+}
+
+BOOST_AUTO_TEST_CASE( testMultiPolygon )
+{
+ std::auto_ptr< Geometry > g( io::readWkt( "MULTIPOLYGON(((3.000000 0.000000,2.875000 0.484123,2.750000 0.661438,2.625000 0.780625,2.500000 0.866025,2.375000 0.927025,2.250000 0.968246,2.125000 0.992157,2.000000 1.000000,1.875000 1.484123,1.750000 1.661438,1.625000 1.780625,1.500000 1.866025,1.375000 1.927025,1.250000 1.968246,1.125000 1.992157,1.000000 2.000000,0.750000 2.661438,0.500000 2.866025,0.250000 2.968246,0.000000 3.000000,-0.250000 2.968246,-0.500000 2.866025,-0.750000 2.66 [...]
+ std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ) ;
+ BOOST_CHECK_EQUAL( result->numGeometries(), 220U );
+}
+
+
+BOOST_AUTO_TEST_CASE( testInvalidTypes )
+{
+ std::vector< std::string > wkt;
+ wkt.push_back( "POINT(1 2)" );
+ wkt.push_back( "LINESTRING(0 0,1 1)" );
+
+ std::auto_ptr< Geometry > g( io::readWkt( "MULTIPOLYGON(((3.000000 0.000000,2.875000 0.484123,2.750000 0.661438,2.625000 0.780625,2.500000 0.866025,2.375000 0.927025,2.250000 0.968246,2.125000 0.992157,2.000000 1.000000,1.875000 1.484123,1.750000 1.661438,1.625000 1.780625,1.500000 1.866025,1.375000 1.927025,1.250000 1.968246,1.125000 1.992157,1.000000 2.000000,0.750000 2.661438,0.500000 2.866025,0.250000 2.968246,0.000000 3.000000,-0.250000 2.968246,-0.500000 2.866025,-0.750000 2.66 [...]
+ std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ) ;
+ BOOST_CHECK_EQUAL( result->numGeometries(), 220U );
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/TesselateTest.cpp b/test/unit/SFCGAL/algorithm/TesselateTest.cpp
new file mode 100644
index 0000000..2b514d0
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/TesselateTest.cpp
@@ -0,0 +1,113 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/tesselate.h>
+
+#include <SFCGAL/detail/tools/Registry.h>
+
+using namespace SFCGAL ;
+
+// always after CGAL
+using namespace boost::unit_test ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_TesselateTest )
+
+
+BOOST_AUTO_TEST_CASE( testEmpty )
+{
+ tools::Registry& registry = tools::Registry::instance() ;
+
+ std::vector< std::string > geometryTypes = registry.getGeometryTypes() ;
+
+ for ( size_t i = 0; i < geometryTypes.size(); i++ ) {
+ std::auto_ptr< Geometry > g( registry.newGeometryByTypeName( geometryTypes[i] ) ) ;
+ BOOST_TEST_MESSAGE( boost::format( "tesselate(%s)" ) % g->asText() );
+ std::auto_ptr< Geometry > result = algorithm::tesselate( *g ) ;
+ BOOST_CHECK( result->isEmpty() );
+ }
+}
+
+/*
+ * test invariants (Point,LineString & co)
+ */
+
+BOOST_AUTO_TEST_CASE( testPoint )
+{
+ std::string wkt = "POINT(3.0 4.0)" ;
+ std::auto_ptr< Geometry > g( io::readWkt( wkt ) );
+ BOOST_CHECK_EQUAL( algorithm::tesselate( *g )->asText( 1 ), wkt );
+}
+BOOST_AUTO_TEST_CASE( testLineString )
+{
+ std::string wkt = "LINESTRING(0.0 0.0,1.0 1.0)" ;
+ std::auto_ptr< Geometry > g( io::readWkt( wkt ) );
+ BOOST_CHECK_EQUAL( algorithm::tesselate( *g )->asText( 1 ), wkt );
+}
+BOOST_AUTO_TEST_CASE( testMultiPoint )
+{
+ std::string wkt = "MULTIPOINT((3.0 4.0),(5.0 6.0))" ;
+ std::auto_ptr< Geometry > g( io::readWkt( wkt ) );
+ BOOST_CHECK_EQUAL( algorithm::tesselate( *g )->asText( 1 ), wkt );
+}
+BOOST_AUTO_TEST_CASE( testMultiLineString )
+{
+ std::string wkt = "MULTILINESTRING((0.0 0.0,1.0 1.0),(1.0 1.0,2.0 2.0))" ;
+ std::auto_ptr< Geometry > g( io::readWkt( wkt ) );
+ BOOST_CHECK_EQUAL( algorithm::tesselate( *g )->asText( 1 ), wkt );
+}
+
+
+/*
+ * test with polygon, MultiPolygon & co
+ */
+BOOST_AUTO_TEST_CASE( testPolygon )
+{
+ std::string wkt = "POLYGON((0.0 0.0,1.0 0.0,1.0 1.0,0.0 1.0,0.0 0.0))" ;
+ std::string wktOut = "TIN(((0.0 1.0,1.0 0.0,1.0 1.0,0.0 1.0)),((0.0 1.0,0.0 0.0,1.0 0.0,0.0 1.0)))" ;
+ std::auto_ptr< Geometry > g( io::readWkt( wkt ) );
+ std::auto_ptr< Geometry > result( algorithm::tesselate( *g ) );
+ BOOST_CHECK_EQUAL( result->asText( 1 ), wktOut );
+}
+BOOST_AUTO_TEST_CASE( testMultiPolygon )
+{
+ std::string wkt = "MULTIPOLYGON(((0.0 0.0,1.0 0.0,1.0 1.0,0.0 1.0,0.0 0.0)),((2.0 0.0,3.0 0.0,3.0 1.0,2.0 1.0,2.0 0.0)))" ;
+ std::string wktOut = "GEOMETRYCOLLECTION(TIN(((0.0 1.0,1.0 0.0,1.0 1.0,0.0 1.0)),((0.0 1.0,0.0 0.0,1.0 0.0,0.0 1.0))),TIN(((2.0 1.0,3.0 0.0,3.0 1.0,2.0 1.0)),((2.0 1.0,2.0 0.0,3.0 0.0,2.0 1.0))))" ;
+ std::auto_ptr< Geometry > g( io::readWkt( wkt ) );
+ std::auto_ptr< Geometry > result( algorithm::tesselate( *g ) );
+ BOOST_CHECK_EQUAL( result->asText( 1 ), wktOut );
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/TranslateTest.cpp b/test/unit/SFCGAL/algorithm/TranslateTest.cpp
new file mode 100644
index 0000000..40d1fa6
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/TranslateTest.cpp
@@ -0,0 +1,65 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/algorithm/translate.h>
+
+#include <SFCGAL/detail/tools/Registry.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_TranslateTest )
+
+
+BOOST_AUTO_TEST_CASE( testEmpty )
+{
+ tools::Registry& registry = tools::Registry::instance() ;
+ std::vector< std::string > typeNames = tools::Registry::instance().getGeometryTypes();
+
+ for ( size_t i = 0; i < typeNames.size(); i++ ) {
+ BOOST_TEST_MESSAGE( typeNames[i] ) ;
+
+ std::auto_ptr< Geometry > g( registry.newGeometryByTypeName( typeNames[i] ) ) ;
+ BOOST_REQUIRE( g.get() != NULL ) ;
+ algorithm::translate( *g, 1.0, 1.0, 1.0 );
+ BOOST_CHECK( g->isEmpty() );
+ }
+}
+
+//TODO complete with 2D/3D test after having renamed translate to translate3D
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/UnionTest.cpp b/test/unit/SFCGAL/algorithm/UnionTest.cpp
new file mode 100644
index 0000000..6f29672
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/UnionTest.cpp
@@ -0,0 +1,401 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <SFCGAL/Exception.h>
+#include <SFCGAL/algorithm/isValid.h>
+#include <SFCGAL/algorithm/union.h>
+#include <SFCGAL/algorithm/volume.h>
+#include <SFCGAL/algorithm/translate.h>
+#include <SFCGAL/algorithm/area.h>
+#include <SFCGAL/detail/tools/Registry.h>
+#include <SFCGAL/algorithm/tesselate.h>
+#include <SFCGAL/triangulate/triangulatePolygon.h>
+
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/io/vtk.h>
+
+#include <boost/test/unit_test.hpp>
+
+namespace SFCGAL {
+namespace algorithm {
+void handleLeakTest();
+}
+}
+
+#define DEBUG_OUT if (0) std::cerr << __FILE__ << ":" << __LINE__ << " debug: "
+
+using namespace SFCGAL;
+using namespace boost::unit_test ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_UnionTest )
+
+
+BOOST_AUTO_TEST_CASE( Handle )
+{
+ algorithm::handleLeakTest();
+}
+
+BOOST_AUTO_TEST_CASE( Handle1 )
+{
+ std::auto_ptr<Geometry> a = io::readWkt( "POINT(0 1)" );
+ std::auto_ptr<Geometry> b = io::readWkt( "POINT(0 1)" );
+ std::auto_ptr<Geometry> u = algorithm::union_( *a, *b );
+ DEBUG_OUT << u->asText() <<"\n";
+ BOOST_CHECK( *u == *io::readWkt( "POINT(0 1)" ) );
+}
+
+BOOST_AUTO_TEST_CASE( Handle2 )
+{
+ std::auto_ptr<Geometry> a = io::readWkt( "MULTIPOINT(0 1,0 1,0 1)" );
+ std::auto_ptr<Geometry> b = io::readWkt( "POINT(0 1)" );
+ std::auto_ptr<Geometry> u = algorithm::union_( *a, *b );
+ DEBUG_OUT << u->asText() <<"\n";
+ BOOST_CHECK( *u == *io::readWkt( "POINT(0 1)" ) );
+}
+
+BOOST_AUTO_TEST_CASE( PointPoint )
+{
+ {
+ std::auto_ptr<Geometry> a = io::readWkt( "POINT(0 1)" );
+ std::auto_ptr<Geometry> b = io::readWkt( "POINT(0 1)" );
+ std::auto_ptr<Geometry> u = algorithm::union_( *a, *b );
+ DEBUG_OUT << u->asText() <<"\n";
+ BOOST_CHECK( *u == *io::readWkt( "POINT(0 1)" ) );
+ }
+ {
+ std::auto_ptr<Geometry> a = io::readWkt( "POINT(0 0)" );
+ std::auto_ptr<Geometry> b = io::readWkt( "POINT(0 1)" );
+ std::auto_ptr<Geometry> u = algorithm::union_( *a, *b );
+ DEBUG_OUT << u->asText() <<"\n";
+ BOOST_CHECK( *u == *io::readWkt( "MULTIPOINT(0 0,0 1)" ) );
+ }
+ {
+ std::auto_ptr<Geometry> a = io::readWkt( "POINT(0 1 1)" );
+ std::auto_ptr<Geometry> b = io::readWkt( "POINT(0 1 1)" );
+ std::auto_ptr<Geometry> u = algorithm::union3D( *a, *b );
+ DEBUG_OUT << u->asText() <<"\n";
+ BOOST_CHECK( *u == *io::readWkt( "POINT(0 1 1)" ) );
+ }
+ {
+ std::auto_ptr<Geometry> a = io::readWkt( "POINT(0 0 0)" );
+ std::auto_ptr<Geometry> b = io::readWkt( "POINT(0 0 1)" );
+ std::auto_ptr<Geometry> u = algorithm::union3D( *a, *b );
+ DEBUG_OUT << u->asText() <<"\n";
+ BOOST_CHECK( *u == *io::readWkt( "MULTIPOINT(0 0 0,0 0 1)" ) );
+ }
+}
+
+BOOST_AUTO_TEST_CASE( PointLine )
+{
+ {
+ std::auto_ptr<Geometry> a = io::readWkt( "POINT(.5 0)" );
+ std::auto_ptr<Geometry> b = io::readWkt( "LINESTRING(-1 0,1 0)" );
+ std::auto_ptr<Geometry> u = algorithm::union_( *a, *b );
+ DEBUG_OUT << u->asText() <<"\n";
+ BOOST_CHECK( *u == *io::readWkt( "LINESTRING(-1 0,.5 0,1 0)" ) );
+ }
+ {
+ std::auto_ptr<Geometry> a = io::readWkt( "POINT(0 0 .5)" );
+ std::auto_ptr<Geometry> b = io::readWkt( "LINESTRING(0 0 -1,0 0 1)" );
+ std::auto_ptr<Geometry> u = algorithm::union3D( *a, *b );
+ DEBUG_OUT << u->asText() <<"\n";
+ BOOST_CHECK( *u == *io::readWkt( "LINESTRING(0 0 -1,0 0 .5,0 0 1)" ) );
+ }
+}
+
+BOOST_AUTO_TEST_CASE( LineLine )
+{
+ {
+ std::auto_ptr<Geometry> a = io::readWkt( "LINESTRING(-1 0,1 0)" );
+ std::auto_ptr<Geometry> b = io::readWkt( "LINESTRING(-1 1,1 1)" );
+ std::auto_ptr<Geometry> u = algorithm::union_( *a, *b );
+ DEBUG_OUT << u->asText() <<"\n";
+ BOOST_CHECK( *u == *io::readWkt( "MULTILINESTRING((-1 0,1 0),(-1 1,1 1))" ) );
+ }
+ {
+ std::auto_ptr<Geometry> a = io::readWkt( "LINESTRING(-1 0,1 0)" );
+ std::auto_ptr<Geometry> b = io::readWkt( "LINESTRING(0 -1,0 1)" );
+ std::auto_ptr<Geometry> u = algorithm::union_( *a, *b );
+ DEBUG_OUT << u->asText() <<"\n";
+ BOOST_CHECK( *u == *io::readWkt( "MULTILINESTRING((-1 0,0 0),(0 0,1 0),(0 -1,0 0),(0 0,0 1))" ) );
+ }
+}
+
+BOOST_AUTO_TEST_CASE( LineVolume )
+{
+ std::auto_ptr<Geometry> a = io::readWkt( "LINESTRING(-1 -1 -1,2 2 2)" );
+ std::auto_ptr<Geometry> b = io::readWkt(
+ "SOLID((((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)),\
+ ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),\
+ ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),\
+ ((1 1 1, 0 1 1, 0 0 1, 1 0 1, 1 1 1)),\
+ ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)),\
+ ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1))))" );
+ std::auto_ptr<Geometry> u = algorithm::union3D( *a, *b );
+ BOOST_CHECK( u->geometryTypeId() == TYPE_GEOMETRYCOLLECTION );
+ BOOST_CHECK( u->geometryN( 0 ).geometryTypeId() == TYPE_LINESTRING );
+ BOOST_CHECK( u->geometryN( 1 ).geometryTypeId() == TYPE_LINESTRING );
+ BOOST_CHECK( u->geometryN( 2 ).geometryTypeId() == TYPE_SOLID );
+}
+
+BOOST_AUTO_TEST_CASE( PointSurface )
+{
+ {
+ std::auto_ptr<Geometry> a = io::readWkt( "TRIANGLE((0 0,0 1,1 0,0 0))" );
+ std::auto_ptr<Geometry> b = io::readWkt( "POINT(.1 .1)" );
+ std::auto_ptr<Geometry> u = algorithm::union_( *a, *b );
+ DEBUG_OUT << u->asText() <<"\n";
+ BOOST_CHECK( *u == *io::readWkt( "TRIANGLE((0 0,0 1,1 0,0 0))" ) );
+ }
+ {
+ std::auto_ptr<Geometry> a = io::readWkt( "TRIANGLE((0 0 1,0 1 1,1 0 1,0 0 1))" );
+ std::auto_ptr<Geometry> b = io::readWkt( "POINT(.1 .1 1)" );
+ std::auto_ptr<Geometry> u = algorithm::union3D( *a, *b );
+ DEBUG_OUT << u->asText() <<"\n";
+ BOOST_CHECK( *u == *io::readWkt( "TRIANGLE((0 0 1,0 1 1,1 0 1,0 0 1))" ) );
+ }
+}
+
+BOOST_AUTO_TEST_CASE( PointVolume )
+{
+ std::auto_ptr<Geometry> a = io::readWkt(
+ "SOLID((((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)),\
+ ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),\
+ ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),\
+ ((1 1 1, 0 1 1, 0 0 1, 1 0 1, 1 1 1)),\
+ ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)),\
+ ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1))))" );
+ {
+ std::auto_ptr<Geometry> b = io::readWkt( "POINT(.1 .1 1)" );
+ std::auto_ptr<Geometry> u = algorithm::union3D( *a, *b );
+ BOOST_CHECK( u->geometryTypeId() == TYPE_SOLID );
+ }
+ {
+ std::auto_ptr<Geometry> b = io::readWkt( "POINT(-.1 .1 1)" );
+ std::auto_ptr<Geometry> u = algorithm::union3D( *a, *b );
+ BOOST_CHECK( u->geometryTypeId() == TYPE_GEOMETRYCOLLECTION );
+ }
+}
+
+BOOST_AUTO_TEST_CASE( TriangleTriangle )
+{
+ {
+ std::auto_ptr<Geometry> a = io::readWkt( "TRIANGLE((0 0,1 0,0 1,0 0))" );
+ std::auto_ptr<Geometry> b = io::readWkt( "TRIANGLE((0 0,1 0,0 1,0 0))" );
+ std::auto_ptr<Geometry> u = algorithm::union_( *a, *b );
+ DEBUG_OUT << u->asText() <<"\n";
+ BOOST_CHECK( *u == *io::readWkt( "TRIANGLE((0 0,0 1,1 0,0 0))" ) );
+ }
+}
+
+BOOST_AUTO_TEST_CASE( PolygonPolygon1 )
+{
+ {
+ std::auto_ptr<Geometry> a = io::readWkt( "POLYGON((-1 -1,1 -1,1 1,-1 1,-1 -1))" );
+ std::auto_ptr<Geometry> b = io::readWkt( "POLYGON((-1 -1,1 -1,1 1,-1 1,-1 -1),(-0.5 -0.5,-0.5 0.5,0.5 0.5,0.5 -0.5,-0.5 -0.5))" );
+ std::auto_ptr<Geometry> u = algorithm::union_( *a, *b );
+ BOOST_CHECK( *u == *io::readWkt( "POLYGON((-1 -1,1 -1,1 1,-1 1,-1 -1))" ) );
+ }
+
+ {
+ std::auto_ptr<Geometry> a = io::readWkt( "POLYGON((0 0,1 0,1 1,0 1,0 0))" );
+ std::auto_ptr<Geometry> b = io::readWkt( "POLYGON((1 0,2 0,2 1,1 1,1 0))" );
+ std::auto_ptr<Geometry> u = algorithm::union_( *a, *b );
+ DEBUG_OUT << u->asText() <<"\n";
+ BOOST_CHECK( *u == *io::readWkt( "POLYGON((0 0,1 0,2 0,2 1,1 1,0 1,0 0))" ) );
+ }
+}
+
+BOOST_AUTO_TEST_CASE( PolygonPolygon2 )
+{
+ {
+ std::auto_ptr<Geometry> base = io::readWkt( "POLYGON((0 0,1 0,1 1,0 1,0 0))" );
+ Polygon a( base->as<Polygon>() );
+ algorithm::translate( a, .75, 0, 0 ); //disjoined
+ GeometryCollection b;
+ b.addGeometry( base->as<Polygon>() );
+ b.addGeometry( base->as<Polygon>() );
+ algorithm::translate( b.geometryN( 1 ), 1.5, 0, 0 );
+
+ std::auto_ptr<Geometry> u = algorithm::union_( a, b );
+ DEBUG_OUT << u->asText() << "\n";
+ DEBUG_OUT << "area " << algorithm::area3D( *u ) <<"\n";
+ BOOST_CHECK( u->geometryTypeId() == TYPE_POLYGON );
+ BOOST_CHECK( algorithm::area3D( *u ) == 2.5 );
+
+ u = algorithm::union3D( a, b );
+ DEBUG_OUT << u->asText() <<"\n";
+ DEBUG_OUT << "area " << algorithm::area3D( *u ) <<"\n";
+ BOOST_CHECK( u->geometryTypeId() == TYPE_TRIANGULATEDSURFACE );
+ BOOST_CHECK( algorithm::area3D( *u ) == 2.5 );
+ }
+}
+
+BOOST_AUTO_TEST_CASE( PolygonPolygon3 )
+{
+ std::auto_ptr<Geometry> base = io::readWkt( "POLYGON((0 0,1 0,1 1,0 1,0 0))" );
+ GeometryCollection a;
+ GeometryCollection b;
+
+ for ( unsigned i = 0; i<4; ++i ) {
+ for ( unsigned j = 0; j<4; ++j ) {
+ Polygon p( base->as<Polygon>() );
+ algorithm::translate( p, std::pow( i, 1.3 ), std::pow( j, 1.3 ), 0 );
+ a.addGeometry( p );
+ algorithm::translate( p, .5, .5, 0 );
+ b.addGeometry( p );
+ }
+ }
+
+ std::auto_ptr<Geometry> u = algorithm::union_( a, b );
+ DEBUG_OUT << "surface " << algorithm::area( *u ) << "\n";
+ BOOST_CHECK( std::abs( algorithm::area( *u ) - 25.56 ) < .01 );
+ //TriangulatedSurface ts;
+ //triangulate::triangulatePolygon3D( *u, ts );
+ //io::vtk( ts, "out.vtk" );
+ u = algorithm::union3D( a, b );
+ BOOST_CHECK( std::abs( algorithm::area3D( *u ) - 25.56 ) < .01 );
+ //io::vtk( *u, "out.vtk" );
+}
+
+BOOST_AUTO_TEST_CASE( GardenFailures1 )
+{
+ // cgal precondition violation
+ {
+ std::auto_ptr<Geometry> a = io::readWkt( "POLYGON((0 0,10 0,10 0,10 10,0 10,0 0),(2 2,2 5,5 5,5 2,2 2))" );
+ std::auto_ptr<Geometry> b = io::readWkt( "TRIANGLE((-1 -1,1 -1,-1 1,-1 -1))" );
+ std::auto_ptr<Geometry> u = algorithm::union_( *a, *b );
+ DEBUG_OUT << u->asText() <<"\n";
+ BOOST_CHECK( algorithm::area( *a ) + algorithm::area( *b ) == algorithm::area( *u ) );
+ }
+}
+
+BOOST_AUTO_TEST_CASE( GardenFailures2 )
+{
+ // cgal assertion
+ {
+ std::auto_ptr<Geometry> a = io::readWkt( "POLYGON((-1 -1,1 -1,1 1,-1 1,-1 -1),(-.5 -.5,-.5 .5,.5 .5,.5 -.5,-.5 -.5))" );
+ std::auto_ptr<Geometry> b = io::readWkt( "POLYGON((-1 -1,1 -1,1 1,-1 1,-1 -1),(-.5 -.5,-.5 .5,.5 .5,.5 -.5,-.5 -.5))" );
+ std::auto_ptr<Geometry> u = algorithm::union3D( *a, *b );
+ DEBUG_OUT << u->asText() <<"\n";
+ }
+}
+
+BOOST_AUTO_TEST_CASE( GardenFailures3 )
+{
+ // crash (valgrind err) with invalidated iterator after push_back
+ {
+ std::auto_ptr<Geometry> a = io::readWkt( "LINESTRING(-1 -1,1 1)" );
+ std::auto_ptr<Geometry> b = io::readWkt( "MULTILINESTRING((1/1 -1/1 -1/1,1/1 1/1 1/1),(1/1 1/1 1/1,1/1 1/1 -1/1))" );
+ std::auto_ptr<Geometry> u = algorithm::union3D( *a, *b );
+ DEBUG_OUT << u->asText() <<"\n";
+ }
+}
+
+BOOST_AUTO_TEST_CASE( GardenFailures4 )
+{
+ // infinite loop
+ {
+ std::auto_ptr<Geometry> a = io::readWkt( "POLYGON((-1 -1,1 -1,1 1,-1 1,-1 -1))" );
+ std::auto_ptr<Geometry> b = io::readWkt( "POLYGON((0 0,10 0,10 0,10 10,0 10,0 0))" );
+ std::auto_ptr<Geometry> u = algorithm::union3D( *a, *b );
+ DEBUG_OUT << u->asText() <<"\n";
+ }
+}
+
+BOOST_AUTO_TEST_CASE( GardenFailures5 )
+{
+ // infinite loop
+ {
+ std::auto_ptr<Geometry> a = io::readWkt( "MULTIPOLYGON(((-3 -1,-1 -1,-1 1,-3 1,-3 -1)),((1 -1,3 -1,3 1,1 1,1 -1)))" );
+ std::auto_ptr<Geometry> b = io::readWkt( "MULTIPOLYGON(((-3 -1,-1 -1,-1 1,-3 1,-3 -1)),((1 -1,3 -1,3 1,1 1,1 -1)))" );
+ std::auto_ptr<Geometry> u = algorithm::union_( *a, *b );
+ DEBUG_OUT << u->asText() <<"\n";
+ }
+}
+
+BOOST_AUTO_TEST_CASE( GardenFailures6 )
+{
+ // segfault
+ {
+ std::auto_ptr<Geometry> a = io::readWkt( "POLYGON((-1 -1,1 -1,1 1,-1 1,-1 -1))" );
+ std::auto_ptr<Geometry> b = io::readWkt( "POLYGON((-1 -1,1 -1,1 1,-1 1,-1 -1),(-0.5 -0.5,-0.5 0.5,0.5 0.5,0.5 -0.5,-0.5 -0.5))" );
+ std::auto_ptr<Geometry> u = algorithm::union3D( *a, *b );
+ DEBUG_OUT << u->asText() <<"\n";
+ }
+}
+
+BOOST_AUTO_TEST_CASE( GardenFailures7 )
+{
+ std::auto_ptr<Geometry> a = io::readWkt( "LINESTRING(-1 -1,1 1)" );
+ std::auto_ptr<Geometry> b = io::readWkt( "POLYGON((-1 -1,1 -1,1 1,-1 1,-1 -1),(-.5 -.5,-.5 .5,.5 .5,1 -.5,-.5 -.5))" );
+ std::auto_ptr<Geometry> u = algorithm::union3D( *a, *b );
+ DEBUG_OUT << u->asText() <<"\n";
+}
+
+BOOST_AUTO_TEST_CASE( VolumeVolume )
+{
+ std::auto_ptr<Geometry> a = io::readWkt(
+ "SOLID((((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)),\
+ ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),\
+ ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),\
+ ((1 1 1, 0 1 1, 0 0 1, 1 0 1, 1 1 1)),\
+ ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)),\
+ ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1))))" );
+ {
+ Solid b = a->as<Solid>();
+ algorithm::translate( b, 2, 0, 0 ); //disjoined
+ std::auto_ptr<Geometry> u = algorithm::union3D( *a, b );
+ BOOST_CHECK( u->geometryTypeId() == TYPE_MULTISOLID );
+ BOOST_CHECK( algorithm::volume( *u ) == 2 );
+ }
+ {
+ Solid b = a->as<Solid>();
+ algorithm::translate( b, .5, 0, 0 );
+ std::auto_ptr<Geometry> u = algorithm::union3D( *a, b );
+ BOOST_CHECK( u->geometryTypeId() == TYPE_SOLID );
+ BOOST_CHECK( algorithm::volume( *u ) == 1.5 );
+ }
+ {
+ Solid b = a->as<Solid>();
+ algorithm::translate( b, 1, 0, 0 );
+ std::auto_ptr<Geometry> u = algorithm::union3D( *a, b );
+ BOOST_CHECK( u->geometryTypeId() == TYPE_SOLID );
+ BOOST_CHECK( algorithm::volume( *u ) == 2 );
+ }
+
+ {
+ Solid b = a->as<Solid>();
+ algorithm::translate( b, 1, 1, 0 );
+ std::auto_ptr<Geometry> u = algorithm::union3D( *a, b );
+ BOOST_CHECK( u->geometryTypeId() == TYPE_MULTISOLID );
+ BOOST_CHECK( algorithm::volume( *u ) == 2 );
+ }
+
+ {
+ Solid b = a->as<Solid>();
+ algorithm::translate( b, 1, 1, 1 ); // share a corner
+ std::auto_ptr<Geometry> u = algorithm::union3D( *a, b );
+ BOOST_CHECK( u->geometryTypeId() == TYPE_MULTISOLID );
+ BOOST_CHECK( algorithm::volume( *u ) == 2 );
+ }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/algorithm/VolumeTest.cpp b/test/unit/SFCGAL/algorithm/VolumeTest.cpp
new file mode 100644
index 0000000..fe600c8
--- /dev/null
+++ b/test/unit/SFCGAL/algorithm/VolumeTest.cpp
@@ -0,0 +1,79 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SFCGAL/algorithm/volume.h>
+#include <SFCGAL/algorithm/isValid.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/io/vtk.h>
+
+#include <boost/test/unit_test.hpp>
+
+using namespace SFCGAL;
+using namespace boost::unit_test ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_VolumeTest )
+
+
+BOOST_AUTO_TEST_CASE( cubeVolume )
+{
+ std::auto_ptr<Geometry> s = io::readWkt( "SOLID((((0 0 0,0 0 1,0 1 1,0 1 0,0 0 0)),\
+ ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),\
+ ((0 0 0,1 0 0,1 0 1,0 0 1,0 0 0)),\
+ ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)),\
+ ((0 0 1,1 0 1,1 1 1,0 1 1,0 0 1)),\
+ ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0))))" );
+ BOOST_CHECK_EQUAL( algorithm::volume( *s ), 1 );
+}
+
+BOOST_AUTO_TEST_CASE( cubeWithHoleVolume )
+{
+ std::auto_ptr<Geometry> s = io::readWkt(
+ "SOLID((((0 0 0,0 0 1,0 1 1,0 1 0,0 0 0)),\
+ ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),\
+ ((0 0 0,1 0 0,1 0 1,0 0 1,0 0 0)),\
+ ((1 0 0,1 1 0,1 1 1,1 0 1,1 0 0)),\
+ ((0 0 1,1 0 1,1 1 1,0 1 1,0 0 1)),\
+ ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0))),\
+ (((.2 .2 .2,.2 .8 .2,.2 .8 .8,.2 .2 .8,.2 .2 .2)),\
+ ((.2 .2 .2,.8 .2 .2,.8 .8 .2,.2 .8 .2,.2 .2 .2)),\
+ ((.2 .2 .2,.2 .2 .8,.8 .2 .8,.8 .2 .2,.2 .2 .2)),\
+ ((.8 .2 .2,.8 .2 .8,.8 .8 .8,.8 .8 .2,.8 .2 .2)),\
+ ((.2 .2 .8,.2 .8 .8,.8 .8 .8,.8 .2 .8,.2 .2 .8)),\
+ ((.2 .8 .2,.8 .8 .2,.8 .8 .8,.2 .8 .8,.2 .8 .2))))" );
+ const Kernel::FT c( .6 );
+ const Kernel::FT ref = 1 - c*c*c;
+ BOOST_CHECK_EQUAL( CGAL::to_double( algorithm::volume( s->as<Solid>(), algorithm::NoValidityCheck() ) ), CGAL::to_double( ref ) );
+}
+
+BOOST_AUTO_TEST_CASE( invertedCubeVolume )
+{
+ std::auto_ptr<Geometry> s = io::readWkt( "SOLID((((0 0 0,0 1 0,0 1 1,0 0 1,0 0 0)),\
+ ((0 0 0,1 0 0,1 1 0,0 1 0,0 0 0)),\
+ ((0 0 0,0 0 1,1 0 1,1 0 0,0 0 0)),\
+ ((1 0 0,1 0 1,1 1 1,1 1 0,1 0 0)),\
+ ((0 0 1,0 1 1,1 1 1,1 0 1,0 0 1)),\
+ ((0 1 0,1 1 0,1 1 1,0 1 1,0 1 0))))" );
+ BOOST_CHECK_EQUAL( algorithm::volume( *s ), -1 );
+
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/capi/sfcgal_cTest.cpp b/test/unit/SFCGAL/capi/sfcgal_cTest.cpp
new file mode 100644
index 0000000..26b642a
--- /dev/null
+++ b/test/unit/SFCGAL/capi/sfcgal_cTest.cpp
@@ -0,0 +1,81 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <SFCGAL/capi/sfcgal_c.h>
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_sfcgal_cTest )
+
+bool hasError = false;
+
+int on_error( const char* /*msg*/, ... )
+{
+ hasError = true;
+ return 0;
+}
+
+/// Coordinate() ;
+BOOST_AUTO_TEST_CASE( testErrorOnBadGeometryType )
+{
+ sfcgal_set_error_handlers( printf, on_error );
+
+ std::auto_ptr<Geometry> l( io::readWkt( "LINESTRING(0 0, 0 1)" ) );
+ std::auto_ptr<Geometry> p( io::readWkt( "POINT(0 2)" ) );
+ sfcgal_geometry_t* gl = l.get();
+
+ hasError = false;
+ BOOST_CHECK_EQUAL( 2, sfcgal_linestring_num_points( gl ) ); // should succeed
+ BOOST_CHECK( hasError == false );
+
+ hasError = false;
+ BOOST_CHECK( sfcgal_triangle_vertex( gl, 0 ) == 0 ); // should fail
+ BOOST_CHECK( hasError == true );
+
+ sfcgal_geometry_t* gp = p.release();
+ hasError = false;
+ sfcgal_linestring_add_point( gl, gp ); // should succeed
+ BOOST_CHECK( hasError == false );
+
+ hasError = false;
+ sfcgal_linestring_add_point( gl, gl ); // should fail
+ BOOST_CHECK( hasError == true );
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/detail/ComplexComparatorTest.cpp b/test/unit/SFCGAL/detail/ComplexComparatorTest.cpp
new file mode 100644
index 0000000..977b8ca
--- /dev/null
+++ b/test/unit/SFCGAL/detail/ComplexComparatorTest.cpp
@@ -0,0 +1,45 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/detail/ComplexComparator.h>
+#include <SFCGAL/numeric.h>
+
+using namespace SFCGAL ;
+using namespace SFCGAL::detail ;
+
+// always after CGAL
+using namespace boost::unit_test ;
+
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_detail_ComplexComparatorTest )
+
+BOOST_AUTO_TEST_CASE( testComparator )
+{
+ ComplexComparator less ;
+
+ BOOST_CHECK( ! less( std::complex< double >( 1.0,0.0 ), std::complex< double >( 0.0,0.0 ) ) );
+ BOOST_CHECK( ! less( std::complex< double >( 0.0,0.0 ), std::complex< double >( 0.0,0.0 ) ) );
+ BOOST_CHECK( less( std::complex< double >( 0.0,0.0 ), std::complex< double >( 1.0,0.0 ) ) );
+ BOOST_CHECK( less( std::complex< double >( 0.0,0.0 ), std::complex< double >( 0.0,1.0 ) ) );
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/detail/IntervalTest.cpp b/test/unit/SFCGAL/detail/IntervalTest.cpp
new file mode 100644
index 0000000..65a5a4e
--- /dev/null
+++ b/test/unit/SFCGAL/detail/IntervalTest.cpp
@@ -0,0 +1,160 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/detail/Interval.h>
+#include <SFCGAL/numeric.h>
+
+using namespace SFCGAL ;
+using namespace SFCGAL::detail ;
+
+// always after CGAL
+using namespace boost::unit_test ;
+
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_detail_IntervalTest )
+
+//Interval() ;
+BOOST_AUTO_TEST_CASE( testDefaultConstructor )
+{
+ Interval bound;
+ BOOST_CHECK( isNaN( bound.lower() ) );
+ BOOST_CHECK( isNaN( bound.upper() ) );
+}
+
+//Interval( const double & value ) ;
+BOOST_AUTO_TEST_CASE( testConstructorWithValue )
+{
+ Interval bound( 5.0 );
+ BOOST_CHECK_EQUAL( bound.lower(), 5.0 );
+ BOOST_CHECK_EQUAL( bound.upper(), 5.0 );
+}
+
+//Interval( const double & v1, const double & v2 ) ;
+BOOST_AUTO_TEST_CASE( testConstructorWithTwoValues )
+{
+ Interval bound( 5.0,3.0 );
+ BOOST_CHECK_EQUAL( bound.lower(), 3.0 );
+ BOOST_CHECK_EQUAL( bound.upper(), 5.0 );
+}
+
+
+//Interval( const Interval & other ) ;
+//Interval& operator = ( const Interval & other ) ;
+//~Interval() ;
+
+//bool isEmpty() const ;
+BOOST_AUTO_TEST_CASE( testEmpty )
+{
+ Interval bound ;
+ BOOST_CHECK( bound.isEmpty() );
+}
+BOOST_AUTO_TEST_CASE( testNotEmpty )
+{
+ Interval bound( 5.0 );
+ BOOST_CHECK( ! bound.isEmpty() );
+}
+
+//inline const double & lower() const { return _lower; }
+//inline const double & upper() const { return _upper; }
+//inline double width() const { return _upper - _lower ; }
+BOOST_AUTO_TEST_CASE( testWidth )
+{
+ Interval bound( 4.0,5.0 );
+ BOOST_CHECK_EQUAL( bound.width(), 1.0 );
+}
+
+//void expandBy( const double & d ) ;
+BOOST_AUTO_TEST_CASE( testExpandByEmpty )
+{
+ Interval bound ;
+ bound.expandBy( 5.0 ) ;
+ BOOST_CHECK( bound.isEmpty() );
+}
+
+//void expandToInclude( const Interval & other ) ;
+BOOST_AUTO_TEST_CASE( testExpandToIncludeInterval_emptyExpanded )
+{
+ Interval bound ;
+ bound.expandToInclude( Interval( 0.0,1.0 ) );
+ BOOST_CHECK_EQUAL( bound.lower(), 0.0 );
+ BOOST_CHECK_EQUAL( bound.upper(), 1.0 );
+}
+BOOST_AUTO_TEST_CASE( testExpandToIncludeInterval_expandByEmpty )
+{
+ Interval bound( 0.0,1.0 );
+ bound.expandToInclude( Interval() );
+ BOOST_CHECK_EQUAL( bound.lower(), 0.0 );
+ BOOST_CHECK_EQUAL( bound.upper(), 1.0 );
+}
+BOOST_AUTO_TEST_CASE( testExpandToIncludeInterval_classic )
+{
+ Interval bound( 0.0,1.0 );
+ bound.expandToInclude( Interval( -1.0,2.0 ) );
+ BOOST_CHECK_EQUAL( bound.lower(),-1.0 );
+ BOOST_CHECK_EQUAL( bound.upper(), 2.0 );
+}
+
+
+//void expandToInclude( const double & value ) ;
+BOOST_AUTO_TEST_CASE( testExpandToIncludeValue_classic1 )
+{
+ Interval bound( 0.0,1.0 );
+ bound.expandToInclude( 2.0 );
+ BOOST_CHECK_EQUAL( bound.lower(), 0.0 );
+ BOOST_CHECK_EQUAL( bound.upper(), 2.0 );
+}
+BOOST_AUTO_TEST_CASE( testExpandToIncludeValue_classic2 )
+{
+ Interval bound( 0.0,1.0 );
+ bound.expandToInclude( -2.0 );
+ BOOST_CHECK_EQUAL( bound.lower(), -2.0 );
+ BOOST_CHECK_EQUAL( bound.upper(), 1.0 );
+}
+
+//bool intersects( const Interval & other ) const ;
+BOOST_AUTO_TEST_CASE( testIntersects_emptyBehavior )
+{
+ BOOST_CHECK( ! Interval().intersects( Interval() ) );
+ BOOST_CHECK( ! Interval( 0.0,1.0 ).intersects( Interval() ) );
+ BOOST_CHECK( ! Interval().intersects( Interval( 0.0,1.0 ) ) );
+}
+
+BOOST_AUTO_TEST_CASE( testIntersects_normalBehavior )
+{
+ BOOST_CHECK( Interval( 0.0,1.0 ).intersects( Interval( -1.0,0.5 ) ) );
+ BOOST_CHECK( Interval( 0.0,1.0 ).intersects( Interval( 0.3,0.5 ) ) );
+ BOOST_CHECK( Interval( 0.0,1.0 ).intersects( Interval( 0.5,2.0 ) ) );
+
+ BOOST_CHECK( ! Interval( 0.0,1.0 ).intersects( Interval( 2.0,3.0 ) ) );
+ BOOST_CHECK( ! Interval( 2.0,3.0 ).intersects( Interval( 0.0,1.0 ) ) );
+}
+BOOST_AUTO_TEST_CASE( testIntersects_limitBehavior )
+{
+ BOOST_CHECK( Interval( 0.0,1.0 ).intersects( Interval( 1.0,2.0 ) ) );
+ BOOST_CHECK( Interval( 0.0,1.0 ).intersects( Interval( -1.0,0.0 ) ) );
+
+ BOOST_CHECK( Interval( 1.0,2.0 ).intersects( Interval( 0.0,1.0 ) ) );
+ BOOST_CHECK( Interval( -1.0,0.0 ).intersects( Interval( 0.0,1.0 ) ) );
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/unit/SFCGAL/graph/GeometryGraphBuilderTest.cpp b/test/unit/SFCGAL/graph/GeometryGraphBuilderTest.cpp
new file mode 100644
index 0000000..60cb4ee
--- /dev/null
+++ b/test/unit/SFCGAL/graph/GeometryGraphBuilderTest.cpp
@@ -0,0 +1,90 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+
+#include <SFCGAL/detail/graph/GeometryGraph.h>
+#include <SFCGAL/detail/graph/GeometryGraphBuilder.h>
+
+using namespace boost::unit_test ;
+
+using namespace SFCGAL ;
+using namespace SFCGAL::graph ;
+
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_GeometryGraphBuilderTest )
+
+BOOST_AUTO_TEST_CASE( addPoint )
+{
+ typedef GeometryGraph::vertex_descriptor vertex_descriptor ;
+ //typedef GeometryGraph::edge_descriptor edge_descriptor ;
+ GeometryGraph graph;
+ GeometryGraphBuilder graphBuilder( graph );
+
+ vertex_descriptor a = graphBuilder.addPoint( Point( 0.0,0.0,0.0 ) );
+ vertex_descriptor b = graphBuilder.addPoint( Point( 1.0,1.0,1.0 ) );
+ vertex_descriptor c = graphBuilder.addPoint( Point( 2.0,2.0,2.0 ) );
+
+ //b duplicate
+ vertex_descriptor d = graphBuilder.addPoint( Point( 1.0,1.0,1.0 ) );
+
+ BOOST_CHECK_EQUAL( graph.numVertices(), 3U );
+ BOOST_CHECK_EQUAL( graph.numEdges(), 0U );
+ BOOST_CHECK_EQUAL( b, d );
+
+ BOOST_CHECK( graph[ a ].coordinate == Coordinate( 0.0,0.0,0.0 ) );
+ BOOST_CHECK( graph[ b ].coordinate == Coordinate( 1.0,1.0,1.0 ) );
+ BOOST_CHECK( graph[ c ].coordinate == Coordinate( 2.0,2.0,2.0 ) );
+}
+
+
+
+BOOST_AUTO_TEST_CASE( addLineString )
+{
+ //typedef GeometryGraph::vertex_descriptor vertex_descriptor ;
+ typedef GeometryGraph::edge_descriptor edge_descriptor ;
+ GeometryGraph graph;
+ GeometryGraphBuilder graphBuilder( graph );
+
+ std::vector< Point > points ;
+ points.push_back( Point( 0.0,0.0,0.0 ) );
+ points.push_back( Point( 1.0,0.0,0.0 ) );
+ points.push_back( Point( 1.0,1.0,0.0 ) );
+ points.push_back( Point( 0.0,1.0,0.0 ) );
+ points.push_back( Point( 0.0,0.0,0.0 ) );
+
+ LineString lineString( points );
+ std::vector< edge_descriptor > sharedLineString = graphBuilder.addLineString( lineString );
+
+ BOOST_CHECK_EQUAL( graph.numVertices(), 4U );
+ BOOST_CHECK_EQUAL( graph.numEdges(), 4U );
+
+ //check closed
+ for ( size_t i = 0; i < sharedLineString.size(); i++ ) {
+ BOOST_CHECK( graph.target( sharedLineString[ i ] ) == graph.source( sharedLineString[ ( i+1 ) % 4 ] ) ) ;
+ }
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/graph/GeometryGraphTest.cpp b/test/unit/SFCGAL/graph/GeometryGraphTest.cpp
new file mode 100644
index 0000000..60bb3f9
--- /dev/null
+++ b/test/unit/SFCGAL/graph/GeometryGraphTest.cpp
@@ -0,0 +1,117 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+
+#include <SFCGAL/detail/graph/GeometryGraph.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+using namespace SFCGAL::graph ;
+
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_GeometryGraphTest )
+
+BOOST_AUTO_TEST_CASE( addVertexAndEdges )
+{
+ GeometryGraph graph;
+ typedef GeometryGraph::vertex_descriptor vertex_descriptor ;
+ typedef GeometryGraph::edge_descriptor edge_descriptor ;
+
+ vertex_descriptor a = graph.addVertex( Coordinate( 0.0,0.0 ) );
+ vertex_descriptor b = graph.addVertex( Coordinate( 1.0,1.0 ) );
+
+ edge_descriptor ab = graph.addEdge( a, b );
+ BOOST_CHECK_EQUAL( graph.source( ab ), a );
+ BOOST_CHECK_EQUAL( graph.target( ab ), b );
+
+ BOOST_CHECK_EQUAL( graph.numVertices(), 2U );
+ BOOST_CHECK_EQUAL( graph.numEdges(), 1U );
+}
+
+
+
+BOOST_AUTO_TEST_CASE( adjacentVertices )
+{
+ GeometryGraph graph;
+ typedef GeometryGraph::vertex_descriptor vertex_descriptor ;
+ //typedef GeometryGraph::edge_descriptor edge_descriptor ;
+
+ vertex_descriptor a = graph.addVertex( Coordinate( 0.0,0.0 ) );
+ vertex_descriptor b = graph.addVertex( Coordinate( 1.0,1.0 ) );
+ vertex_descriptor c = graph.addVertex( Coordinate( 2.0,2.0 ) );
+ vertex_descriptor d = graph.addVertex( Coordinate( 2.0,2.0 ) );
+
+ graph.addEdge( a, b );
+ graph.addEdge( b, c );
+ graph.addEdge( c, d );
+
+ std::set< vertex_descriptor > bAjacentVertices = graph.adjacentVertices( b );
+ BOOST_CHECK_EQUAL( bAjacentVertices.size(), 2U );
+ BOOST_CHECK_EQUAL( bAjacentVertices.count( a ), 1U );
+ BOOST_CHECK_EQUAL( bAjacentVertices.count( c ), 1U );
+}
+
+
+
+BOOST_AUTO_TEST_CASE( inOutEdges )
+{
+ GeometryGraph graph;
+ typedef GeometryGraph::vertex_descriptor vertex_descriptor ;
+ typedef GeometryGraph::edge_descriptor edge_descriptor ;
+ typedef GeometryGraph::directed_edge_descriptor directed_edge_descriptor ;
+
+ vertex_descriptor a = graph.addVertex( Coordinate( 0.0,0.0 ) );
+ vertex_descriptor b = graph.addVertex( Coordinate( 1.0,1.0 ) );
+ vertex_descriptor c = graph.addVertex( Coordinate( 2.0,2.0 ) );
+ vertex_descriptor d = graph.addVertex( Coordinate( 2.0,2.0 ) );
+
+ edge_descriptor ab = graph.addEdge( a, b );
+ edge_descriptor bc = graph.addEdge( b, c );
+ /*edge_descriptor cd =*/
+ graph.addEdge( c, d );
+
+ std::vector< edge_descriptor > inEdges = graph.inEdges( b );
+ std::vector< edge_descriptor > outEdges = graph.outEdges( b );
+ std::vector< directed_edge_descriptor > inOutEdges = graph.inOutEdges( b );
+
+ BOOST_REQUIRE_EQUAL( inEdges.size(), 1U );
+ BOOST_CHECK_EQUAL( inEdges[0], ab );
+
+ BOOST_REQUIRE_EQUAL( outEdges.size(), 1U );
+ BOOST_CHECK_EQUAL( outEdges[0], bc );
+
+ BOOST_REQUIRE_EQUAL( inOutEdges.size(), 2U );
+ //ab is in inOutEdges
+ BOOST_CHECK( ( inOutEdges[0].first == ab && inOutEdges[0].second == REVERSE )
+ || ( inOutEdges[1].first == ab && inOutEdges[1].second == REVERSE ) );
+ //bc is in inOutEdges
+ BOOST_CHECK( ( inOutEdges[0].first == bc && inOutEdges[0].second == DIRECT )
+ || ( inOutEdges[1].first == bc && inOutEdges[1].second == DIRECT ) );
+}
+
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/graph/algorithm/IsHalfEdgeTest.cpp b/test/unit/SFCGAL/graph/algorithm/IsHalfEdgeTest.cpp
new file mode 100644
index 0000000..b400b2d
--- /dev/null
+++ b/test/unit/SFCGAL/graph/algorithm/IsHalfEdgeTest.cpp
@@ -0,0 +1,80 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/detail/graph/GeometryGraph.h>
+#include <SFCGAL/detail/graph/algorithm/isHalfEdge.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+using namespace SFCGAL::graph ;
+
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_graph_algorithm_IsHalfEdgeTest )
+
+
+BOOST_AUTO_TEST_CASE( basicTestCase )
+{
+ GeometryGraph graph;
+ typedef GeometryGraph::vertex_descriptor vertex_descriptor ;
+
+ /*
+ d c f h
+
+ a b e g
+ */
+
+ vertex_descriptor a = graph.addVertex( Coordinate( 0.0,0.0 ) ) ;
+ vertex_descriptor b = graph.addVertex( Coordinate( 1.0,0.0 ) ) ;
+ vertex_descriptor c = graph.addVertex( Coordinate( 1.0,1.0 ) ) ;
+ vertex_descriptor d = graph.addVertex( Coordinate( 0.0,1.0 ) ) ;
+
+ vertex_descriptor e = graph.addVertex( Coordinate( 2.0,0.0 ) ) ;
+ vertex_descriptor f = graph.addVertex( Coordinate( 2.0,1.0 ) ) ;
+
+ vertex_descriptor g = graph.addVertex( Coordinate( 3.0,0.0 ) ) ;
+ vertex_descriptor h = graph.addVertex( Coordinate( 3.0,1.0 ) ) ;
+
+
+ graph.addEdge( a, b );
+ graph.addEdge( b, c );
+ graph.addEdge( c, d );
+ graph.addEdge( d, a );
+ BOOST_CHECK( algorithm::isHalfEdge( graph ) );
+ graph.addEdge( c, b );
+ graph.addEdge( c, f );
+ graph.addEdge( f, e );
+ graph.addEdge( e, b );
+ BOOST_CHECK( algorithm::isHalfEdge( graph ) );
+
+ graph.addEdge( e, g );
+ graph.addEdge( g, h );
+ graph.addEdge( h, f );
+ BOOST_CHECK( algorithm::isHalfEdge( graph ) );
+ graph.addEdge( f, e );
+ BOOST_CHECK( ! algorithm::isHalfEdge( graph ) );
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/io/SerializationTest.cpp b/test/unit/SFCGAL/io/SerializationTest.cpp
new file mode 100644
index 0000000..5be8ce5
--- /dev/null
+++ b/test/unit/SFCGAL/io/SerializationTest.cpp
@@ -0,0 +1,157 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <memory>
+#include <string>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/detail/io/Serialization.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/io/ewkt.h>
+
+#include <boost/test/unit_test.hpp>
+using namespace boost::unit_test ;
+
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_io_SerializationTest )
+
+BOOST_AUTO_TEST_CASE( textTest )
+{
+ Coordinate pt1( 2.3, 8.9 );
+ Coordinate rpt1;
+ // 2/3
+ CGAL::Gmpq q1( 2, 3 );
+ CGAL::Gmpq rq1;
+
+ std::ostringstream ostr;
+ boost::archive::text_oarchive arc( ostr );
+ arc << pt1;
+ arc << q1;
+
+ std::string str = ostr.str();
+
+ std::istringstream istr( str );
+ boost::archive::text_iarchive iarc( istr );
+ iarc >> rpt1;
+ iarc >> rq1;
+
+ BOOST_CHECK( pt1 == rpt1 );
+ BOOST_CHECK( q1 == rq1 );
+}
+
+BOOST_AUTO_TEST_CASE( binaryTest )
+{
+ Coordinate pt( 2.3, 4.5 );
+ Coordinate rpt;
+
+ std::ostringstream ostr;
+ io::BinarySerializer arc( ostr );
+ arc << pt;
+
+ std::string str = ostr.str();
+
+ std::istringstream istr( str );
+ io::BinaryUnserializer iarc( istr );
+ iarc >> rpt;
+
+ BOOST_CHECK( pt == rpt );
+}
+
+BOOST_AUTO_TEST_CASE( geometryTest )
+{
+ std::auto_ptr<Geometry> g1 = io::readWkt( "POINT( 3.4 4.5 5.6 )" );
+ std::auto_ptr<Geometry> g2 = io::readWkt( "LINESTRING( 3.4 4.5 5.6, 5 6 8 )" );
+ std::auto_ptr<Geometry> g3 = io::readWkt( "TRIANGLE(( 0 0 0, 3.4 5.6 6.7,2 3 4, 0 0 0))" );
+ std::auto_ptr<Geometry> g4 = io::readWkt( "POLYGON(( 0 0 0, 1 1 1, 3.4 5.6 6.7,2 3 4, 0 0 0))" );
+ std::auto_ptr<Geometry> g5 = io::readWkt( "TIN((( 0 0 0, 3.4 5.6 6.7,2 3 4, 0 0 0)), ((0 0 0,0 1 0,1 1 0,0 0 0)))" );
+ std::auto_ptr<Geometry> g6 = io::readWkt( "POLYHEDRALSURFACE((( 0 0 0, 3.4 5.6 6.7,2 3 4, 0 0 0)), ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)))" );
+ std::auto_ptr<Geometry> g7 = io::readWkt( "SOLID(((( 0 0 0, 3.4 5.6 6.7,2 3 4, 0 0 0)), ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0))))" );
+ std::auto_ptr<Geometry> g8 = io::readWkt( "MULTIPOINT(( 3.4 4.5 5.6 ))" );
+ std::auto_ptr<Geometry> g9 = io::readWkt( "MULTILINESTRING(( 3.4 4.5 5.6, 5 6 8 ))" );
+ std::auto_ptr<Geometry> g10 = io::readWkt( "MULTIPOLYGON((( 0 0 0, 1 1 1, 3.4 5.6 6.7,2 3 4, 0 0 0)))" );
+ std::auto_ptr<Geometry> g11 = io::readWkt( "MULTISOLID((((( 0 0 0, 3.4 5.6 6.7,2 3 4, 0 0 0)), ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)))))" );
+
+ BOOST_CHECK( io::readBinaryGeometry( io::writeBinaryGeometry( *g1 ) )->asText() == g1->asText() );
+ BOOST_CHECK( io::readBinaryGeometry( io::writeBinaryGeometry( *g2 ) )->asText() == g2->asText() );
+ BOOST_CHECK( io::readBinaryGeometry( io::writeBinaryGeometry( *g3 ) )->asText() == g3->asText() );
+ BOOST_CHECK( io::readBinaryGeometry( io::writeBinaryGeometry( *g4 ) )->asText() == g4->asText() );
+ BOOST_CHECK( io::readBinaryGeometry( io::writeBinaryGeometry( *g5 ) )->asText() == g5->asText() );
+ BOOST_CHECK( io::readBinaryGeometry( io::writeBinaryGeometry( *g6 ) )->asText() == g6->asText() );
+ BOOST_CHECK( io::readBinaryGeometry( io::writeBinaryGeometry( *g7 ) )->asText() == g7->asText() );
+ BOOST_CHECK( io::readBinaryGeometry( io::writeBinaryGeometry( *g8 ) )->asText() == g8->asText() );
+ BOOST_CHECK( io::readBinaryGeometry( io::writeBinaryGeometry( *g9 ) )->asText() == g9->asText() );
+ BOOST_CHECK( io::readBinaryGeometry( io::writeBinaryGeometry( *g10 ) )->asText() == g10->asText() );
+ BOOST_CHECK( io::readBinaryGeometry( io::writeBinaryGeometry( *g11 ) )->asText() == g11->asText() );
+
+}
+
+BOOST_AUTO_TEST_CASE( caseTest )
+{
+ std::auto_ptr<Geometry> g1 = io::readWkt( "PoInT( 3.4 4.5 5.6 )" );
+ BOOST_CHECK( io::readBinaryGeometry( io::writeBinaryGeometry( *g1 ) )->asText() == g1->asText() );
+}
+
+BOOST_AUTO_TEST_CASE( extBinaryTest )
+{
+ std::auto_ptr<Geometry> ng1 = io::readWkt( "POLYGON((9.70065196277574 -2.37991360574961,3.74221071600914 5.33515858836472,-4.30443822173402 -2.37991360574961,3.74221071600914 -12.1891073728912,9.70065196277574 -2.37991360574961))" );
+ SFCGAL::Geometry* mg1 = ng1.release();
+ SFCGAL::Geometry* ng2;
+
+ std::string str;
+ std::ostringstream ostr( str );
+ io::BinarySerializer arc( ostr );
+ arc << mg1;
+
+ std::istringstream istr( ostr.str() );
+ io::BinaryUnserializer iarc( istr );
+ iarc >> ng2;
+
+ BOOST_CHECK( mg1->asText() == ng2->asText() );
+ delete mg1;
+ delete ng2;
+}
+
+BOOST_AUTO_TEST_CASE( preparedGeometryTest )
+{
+ std::auto_ptr<PreparedGeometry> g1 = io::readEwkt( "POINT( 3.4 4.5 5.6 )" );
+ std::auto_ptr<PreparedGeometry> g2 = io::readEwkt( "srid=0;POINT( 3.4 4.5 5.6 )" );
+ std::auto_ptr<PreparedGeometry> g3 = io::readEwkt( "srid=4326;POINT( 3.4 4.5 5.6 )" );
+
+ BOOST_CHECK( io::readBinaryPrepared( io::writeBinaryPrepared( *g1 ) )->asEWKT() == g1->asEWKT() );
+ BOOST_CHECK( io::readBinaryPrepared( io::writeBinaryPrepared( *g2 ) )->asEWKT() == g2->asEWKT() );
+ BOOST_CHECK( io::readBinaryPrepared( io::writeBinaryPrepared( *g3 ) )->asEWKT() == g3->asEWKT() );
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
diff --git a/test/unit/SFCGAL/io/WktReaderTest.cpp b/test/unit/SFCGAL/io/WktReaderTest.cpp
new file mode 100644
index 0000000..8bf190e
--- /dev/null
+++ b/test/unit/SFCGAL/io/WktReaderTest.cpp
@@ -0,0 +1,268 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <memory>
+#include <string>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+
+#include <boost/test/unit_test.hpp>
+using namespace boost::unit_test ;
+
+using namespace SFCGAL ;
+using namespace SFCGAL::io ;
+
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_io_WktReaderTest )
+
+//-- WKT POINT
+
+BOOST_AUTO_TEST_CASE( pointEmpty )
+{
+ std::auto_ptr< Geometry > g( readWkt( "POINT EMPTY" ) );
+ BOOST_CHECK( g->is< Point >() );
+ BOOST_CHECK( g->isEmpty() );
+}
+
+
+BOOST_AUTO_TEST_CASE( pointXY )
+{
+ std::auto_ptr< Geometry > g( readWkt( "POINT(4.0 6.0)" ) );
+ BOOST_CHECK( g->is< Point >() );
+ BOOST_CHECK( ! g->isEmpty() );
+
+ BOOST_CHECK_EQUAL( g->as< Point >().x(), 4.0 );
+ BOOST_CHECK_EQUAL( g->as< Point >().y(), 6.0 );
+}
+
+BOOST_AUTO_TEST_CASE( pointXYZ_implicit )
+{
+ std::auto_ptr< Geometry > g( readWkt( "POINT(4.0 5.0 6.0)" ) );
+ BOOST_CHECK( g->is< Point >() );
+ BOOST_CHECK( ! g->isEmpty() );
+
+ BOOST_CHECK( g->is3D() );
+ BOOST_CHECK( ! g->isMeasured() );
+
+ BOOST_CHECK_EQUAL( g->as< Point >().x(), 4.0 );
+ BOOST_CHECK_EQUAL( g->as< Point >().y(), 5.0 );
+ BOOST_CHECK_EQUAL( g->as< Point >().z(), 6.0 );
+}
+
+BOOST_AUTO_TEST_CASE( pointXYZ_explicit )
+{
+ std::auto_ptr< Geometry > g( readWkt( "POINT Z(4.0 5.0 6.0)" ) );
+ BOOST_CHECK( g->is< Point >() );
+ BOOST_CHECK( ! g->isEmpty() );
+
+ BOOST_CHECK( g->is3D() );
+ BOOST_CHECK( ! g->isMeasured() );
+
+ BOOST_CHECK_EQUAL( g->as< Point >().x(), 4.0 );
+ BOOST_CHECK_EQUAL( g->as< Point >().y(), 5.0 );
+ BOOST_CHECK_EQUAL( g->as< Point >().z(), 6.0 );
+}
+
+
+BOOST_AUTO_TEST_CASE( pointXYM_explicit )
+{
+ std::auto_ptr< Geometry > g( readWkt( "POINT M(4.0 5.0 6.0)" ) );
+ BOOST_CHECK( g->is< Point >() );
+ BOOST_CHECK( ! g->isEmpty() );
+
+ BOOST_CHECK( ! g->is3D() );
+ BOOST_CHECK( g->isMeasured() );
+
+ BOOST_CHECK_EQUAL( g->as< Point >().x(), 4.0 );
+ BOOST_CHECK_EQUAL( g->as< Point >().y(), 5.0 );
+ BOOST_CHECK_EQUAL( g->as< Point >().m(), 6.0 );
+}
+
+//-- WKT LINESTRING
+
+
+BOOST_AUTO_TEST_CASE( lineStringEmpty )
+{
+ std::auto_ptr< Geometry > g( readWkt( "LINESTRING EMPTY" ) );
+ BOOST_CHECK( g->is< LineString >() );
+ BOOST_CHECK( g->isEmpty() );
+}
+
+BOOST_AUTO_TEST_CASE( lineString_twoPoints )
+{
+ std::auto_ptr< Geometry > g( readWkt( "LINESTRING(0.0 0.0,1.0 1.0)" ) );
+ BOOST_CHECK( g->is< LineString >() );
+ BOOST_CHECK( ! g->isEmpty() );
+ BOOST_CHECK_EQUAL( g->as< LineString >().numPoints(), 2U );
+}
+
+BOOST_AUTO_TEST_CASE( lineString_twoPoints3D )
+{
+ std::auto_ptr< Geometry > g( readWkt( "LINESTRING(0.0 0.0 0.0,1.0 1.0 1.0)" ) );
+ BOOST_CHECK( g->is< LineString >() );
+ BOOST_CHECK( ! g->isEmpty() );
+ BOOST_REQUIRE_EQUAL( g->as< LineString >().numPoints(), 2U );
+ BOOST_CHECK( g->as< LineString >().pointN( 0 ).is3D() );
+ BOOST_CHECK( g->as< LineString >().pointN( 1 ).is3D() );
+}
+
+//-- WKT POLYGON
+
+
+BOOST_AUTO_TEST_CASE( polygonEmpty )
+{
+ std::auto_ptr< Geometry > g( readWkt( "POLYGON EMPTY" ) );
+ BOOST_CHECK( g->is< Polygon >() );
+ BOOST_CHECK( g->isEmpty() );
+}
+
+
+// 4 points polygon (triangle)
+BOOST_AUTO_TEST_CASE( polygonWithFourPoints )
+{
+ std::auto_ptr< Geometry > g( readWkt( "POLYGON((0 0,1 0,1 1,0 0))" ) );
+ BOOST_CHECK( g->is< Polygon >() );
+ BOOST_CHECK( ! g->isEmpty() );
+ BOOST_CHECK_EQUAL( g->as< Polygon >().exteriorRing().numPoints(), 4U );
+}
+
+
+
+
+//-- WKT MULTIPOINT
+
+BOOST_AUTO_TEST_CASE( multiPointEmpty )
+{
+ std::auto_ptr< Geometry > g( readWkt( "MULTIPOINT EMPTY" ) );
+ BOOST_CHECK( g->is< MultiPoint >() );
+ BOOST_CHECK( g->isEmpty() );
+}
+
+BOOST_AUTO_TEST_CASE( multiPointEmpty2 )
+{
+ std::auto_ptr< Geometry > g( readWkt( "MULTIPOINT(0 0,1 1,EMPTY)" ) );
+ BOOST_CHECK( g->asText() == "MULTIPOINT((0/1 0/1),(1/1 1/1),EMPTY)" );
+ BOOST_CHECK( g->is< MultiPoint >() );
+ BOOST_CHECK( g->numGeometries() == 3 );
+}
+
+BOOST_AUTO_TEST_CASE( multiPointEmpty3 )
+{
+ std::auto_ptr< Geometry > g( readWkt( "MULTIPOINT(EMPTY,EMPTY)" ) );
+ BOOST_CHECK( g->asText() == "MULTIPOINT(EMPTY,EMPTY)" );
+ BOOST_CHECK( g->is< MultiPoint >() );
+ BOOST_CHECK( g->numGeometries() == 2 );
+}
+
+//-- WKT MULTILINESTRING
+
+BOOST_AUTO_TEST_CASE( multiLineStringEmpty )
+{
+ std::auto_ptr< Geometry > g( readWkt( "MULTILINESTRING EMPTY" ) );
+ BOOST_CHECK( g->is< MultiLineString >() );
+ BOOST_CHECK( g->isEmpty() );
+}
+
+
+//-- WKT MULTIPOLYGON
+
+BOOST_AUTO_TEST_CASE( multiPolygonEmpty )
+{
+ std::auto_ptr< Geometry > g( readWkt( "MULTIPOLYGON EMPTY" ) );
+ BOOST_CHECK( g->is< MultiPolygon >() );
+ BOOST_CHECK( g->isEmpty() );
+}
+
+
+
+//-- WKT GEOMETRYCOLLECTION
+
+BOOST_AUTO_TEST_CASE( geometryCollectionEmpty )
+{
+ std::auto_ptr< Geometry > g( readWkt( "GEOMETRYCOLLECTION EMPTY" ) );
+ BOOST_CHECK( g->is< GeometryCollection >() );
+ BOOST_CHECK( g->isEmpty() );
+}
+
+
+
+//-- WKT TRIANGULATEDSURFACE
+
+BOOST_AUTO_TEST_CASE( triangulatedSurface_Empty )
+{
+ std::auto_ptr< Geometry > g( readWkt( "TIN EMPTY" ) );
+ BOOST_CHECK( g->is< TriangulatedSurface >() );
+ BOOST_CHECK( g->isEmpty() );
+}
+
+BOOST_AUTO_TEST_CASE( triangulatedSurface_fourTriangles )
+{
+ std::string wkt = "TIN("
+ "((0 0 0, 0 0 1, 0 1 0, 0 0 0)),"
+ "((0 0 0, 0 1 0, 1 0 0, 0 0 0)),"
+ "((0 0 0, 1 0 0, 0 0 1, 0 0 0)),"
+ "((1 0 0, 0 1 0, 0 0 1, 1 0 0))"
+ ")";
+ std::auto_ptr< Geometry > g( readWkt( wkt ) );
+ BOOST_CHECK( g->is< TriangulatedSurface >() );
+ BOOST_CHECK( ! g->isEmpty() );
+
+ BOOST_CHECK_EQUAL( g->as< TriangulatedSurface >().numGeometries(), 4U );
+}
+
+BOOST_AUTO_TEST_CASE( wkt_exactTest )
+{
+ std::auto_ptr< Geometry > g( readWkt( "LINESTRING(2/3 3/2,5/4 2/3)" ) );
+ BOOST_CHECK( g->is< LineString >() );
+ BOOST_CHECK( ! g->isEmpty() );
+ BOOST_REQUIRE_EQUAL( g->as< LineString >().numPoints(), 2U );
+ Kernel::Exact_kernel::FT x = CGAL::exact( g->as<LineString>().pointN( 0 ).x() );
+ Kernel::Exact_kernel::FT y = CGAL::exact( g->as<LineString>().pointN( 0 ).y() );
+ BOOST_CHECK_EQUAL( x.numerator(), 2 );
+ BOOST_CHECK_EQUAL( x.denominator(), 3 );
+ BOOST_CHECK_EQUAL( y.numerator(), 3 );
+ BOOST_CHECK_EQUAL( y.denominator(), 2 );
+}
+
+BOOST_AUTO_TEST_CASE( charArrayRead )
+{
+ char str[] = "LINESTRING(0.0 0.0,1.0 1.0)";
+ std::auto_ptr< Geometry > g( readWkt( str, strlen( str ) ) );
+ BOOST_CHECK( g->is< LineString >() );
+ BOOST_CHECK( ! g->isEmpty() );
+ BOOST_CHECK_EQUAL( g->as< LineString >().numPoints(), 2U );
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
diff --git a/test/unit/SFCGAL/transform/AffineTransform2Test.cpp b/test/unit/SFCGAL/transform/AffineTransform2Test.cpp
new file mode 100644
index 0000000..dbd2950
--- /dev/null
+++ b/test/unit/SFCGAL/transform/AffineTransform2Test.cpp
@@ -0,0 +1,53 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/detail/transform/AffineTransform2.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_transform_AffineTransform2Test )
+
+BOOST_AUTO_TEST_CASE( simpleTranslate )
+{
+ LineString g( Point( 0.0,0.0 ), Point( 1.0,1.0 ) ) ;
+
+ CGAL::Aff_transformation_2< Kernel > affine(
+ CGAL::TRANSLATION,
+ CGAL::Vector_2< Kernel >( 1.0,2.0 )
+ );
+
+ transform::AffineTransform2 transform( affine ) ;
+ g.accept( transform );
+
+ BOOST_CHECK_EQUAL( g.pointN( 0 ).asText( 5 ), "POINT(1.00000 2.00000)" );
+ BOOST_CHECK_EQUAL( g.pointN( 1 ).asText( 5 ), "POINT(2.00000 3.00000)" );
+}
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/transform/ForceZOrderPointsTest.cpp b/test/unit/SFCGAL/transform/ForceZOrderPointsTest.cpp
new file mode 100644
index 0000000..da6866b
--- /dev/null
+++ b/test/unit/SFCGAL/transform/ForceZOrderPointsTest.cpp
@@ -0,0 +1,53 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Kernel.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/detail/io/WktWriter.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/detail/transform/ForceZOrderPoints.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_transform_ForceZOrderPointsTest )
+
+BOOST_AUTO_TEST_CASE( simple )
+{
+ std::auto_ptr<Geometry> g1 = io::readWkt( "POLYGON((0 0,0 1,1 1,1 0,0 0))" );
+
+ const Polygon& p = g1->as<Polygon>();
+ BOOST_CHECK( ! p.isCounterClockWiseOriented() );
+
+ transform::ForceZOrderPoints forceZ;
+ g1->accept( forceZ );
+
+ BOOST_CHECK( g1->is3D() );
+ BOOST_CHECK( g1->as<Polygon>().isCounterClockWiseOriented() );
+}
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/transform/RoundTest.cpp b/test/unit/SFCGAL/transform/RoundTest.cpp
new file mode 100644
index 0000000..b5a4aa1
--- /dev/null
+++ b/test/unit/SFCGAL/transform/RoundTest.cpp
@@ -0,0 +1,59 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/io/wkt.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_CoordinateTest )
+
+BOOST_AUTO_TEST_CASE( testRoundPoint )
+{
+ std::auto_ptr< Geometry > g( io::readWkt( "POINT(1.5 2.6 3.4)" ) );
+ g->round();
+ BOOST_CHECK_EQUAL( g->asText(), "POINT(2/1 3/1 3/1)" );
+}
+
+BOOST_AUTO_TEST_CASE( testRoundLineString )
+{
+ std::auto_ptr< Geometry > g( io::readWkt( "LINESTRING(0.5 0.5,1.5 1.5)" ) );
+ g->round( 10 );
+ BOOST_CHECK_EQUAL( g->asText(), "LINESTRING(1/2 1/2,3/2 3/2)" );
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/triangulate/ConstraintDelaunayTriangulationTest.cpp b/test/unit/SFCGAL/triangulate/ConstraintDelaunayTriangulationTest.cpp
new file mode 100644
index 0000000..e3ec716
--- /dev/null
+++ b/test/unit/SFCGAL/triangulate/ConstraintDelaunayTriangulationTest.cpp
@@ -0,0 +1,114 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Exception.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/detail/triangulate/ConstraintDelaunayTriangulation.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+using namespace SFCGAL::triangulate ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_triangulate_ConstraintDelaunayTriangulationTest )
+
+/// Coordinate() ;
+BOOST_AUTO_TEST_CASE( testDefaultConstructor )
+{
+ ConstraintDelaunayTriangulation triangulation ;
+ BOOST_CHECK_EQUAL( triangulation.numVertices(), 0U );
+ BOOST_CHECK_EQUAL( triangulation.numTriangles(), 0U );
+}
+
+BOOST_AUTO_TEST_CASE( testTriangulateSquare )
+{
+ ConstraintDelaunayTriangulation triangulation ;
+ typedef ConstraintDelaunayTriangulation::Vertex_handle Vertex_handle ;
+ typedef ConstraintDelaunayTriangulation::Face_handle Face_handle ;
+ typedef ConstraintDelaunayTriangulation::All_faces_iterator All_faces_iterator ;
+ //typedef ConstraintDelaunayTriangulation::Finite_faces_iterator Finite_faces_iterator ;
+
+ Vertex_handle a = triangulation.addVertex( Coordinate( 0.0,0.0 ) ) ;
+ Vertex_handle b = triangulation.addVertex( Coordinate( 1.0,0.0 ) ) ;
+ Vertex_handle c = triangulation.addVertex( Coordinate( 1.0,1.0 ) ) ;
+ Vertex_handle d = triangulation.addVertex( Coordinate( 0.0,1.0 ) ) ;
+
+ BOOST_CHECK_EQUAL( triangulation.numVertices(), 4U );
+ BOOST_CHECK_EQUAL( triangulation.numTriangles(), 2U );
+
+ triangulation.addConstraint( a, b );
+ triangulation.addConstraint( b, c );
+ triangulation.addConstraint( c, d );
+ triangulation.addConstraint( d, a );
+
+ // constraint have no impact
+ BOOST_CHECK_EQUAL( triangulation.numVertices(), 4U );
+ BOOST_CHECK_EQUAL( triangulation.numTriangles(), 2U );
+
+
+ /*
+ * nesting level
+ */
+ for ( All_faces_iterator it = triangulation.all_faces_begin(); it != triangulation.all_faces_end(); ++it ) {
+ BOOST_CHECK_EQUAL( it->info().nestingLevel, -1 );
+ }
+
+ // check mark domains
+ triangulation.markDomains();
+
+ for ( All_faces_iterator it = triangulation.all_faces_begin(); it != triangulation.all_faces_end(); ++it ) {
+ Face_handle face = it ;
+
+ if ( triangulation.isInfinite( face ) ) {
+ BOOST_CHECK_EQUAL( it->info().nestingLevel, 0 );
+ }
+ else {
+ BOOST_CHECK_EQUAL( it->info().nestingLevel, 1 );
+ }
+ }
+}
+
+
+
+
+BOOST_AUTO_TEST_CASE( testProjectionPlane )
+{
+ ConstraintDelaunayTriangulation triangulation ;
+ //typedef ConstraintDelaunayTriangulation::Vertex_handle Vertex_handle ;
+ //typedef ConstraintDelaunayTriangulation::Face_handle Face_handle ;
+
+ triangulation.setProjectionPlane( Kernel::Plane_3( Kernel::RT( 1 ), Kernel::RT( 0 ), Kernel::RT( 0 ), Kernel::RT( 0 ) ) );
+
+ triangulation.addVertex( Coordinate( 1.0,0.0,0.0 ) ) ;
+ triangulation.addVertex( Coordinate( 1.0,1.0,0.0 ) ) ;
+ triangulation.addVertex( Coordinate( 1.0,1.0,1.0 ) ) ;
+ triangulation.addVertex( Coordinate( 1.0,0.0,1.0 ) ) ;
+
+ BOOST_CHECK_EQUAL( triangulation.numVertices(), 4U );
+ BOOST_CHECK_EQUAL( triangulation.numTriangles(), 2U );
+}
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/SFCGAL/triangulate/Triangulate2DZTest.cpp b/test/unit/SFCGAL/triangulate/Triangulate2DZTest.cpp
new file mode 100644
index 0000000..a95d91a
--- /dev/null
+++ b/test/unit/SFCGAL/triangulate/Triangulate2DZTest.cpp
@@ -0,0 +1,104 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/test/unit_test.hpp>
+
+#include <SFCGAL/Exception.h>
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/triangulate/triangulate2DZ.h>
+
+using namespace boost::unit_test ;
+using namespace SFCGAL ;
+using namespace SFCGAL::triangulate ;
+
+BOOST_AUTO_TEST_SUITE( SFCGAL_triangulate_Triangulate2DZTest )
+
+BOOST_AUTO_TEST_CASE( testPoint )
+{
+ std::auto_ptr< Geometry > g( io::readWkt( "POINT(1.0 2.0 3.0)" ) ) ;
+ ConstraintDelaunayTriangulation triangulation = triangulate2DZ( *g );
+ BOOST_CHECK_EQUAL( triangulation.numVertices(), 1U );
+ BOOST_CHECK_EQUAL( triangulation.numTriangles(), 0U );
+}
+
+BOOST_AUTO_TEST_CASE( testLineString )
+{
+ std::auto_ptr< Geometry > g( io::readWkt( "LINESTRING(0.0 0.0,1.0 0.0,1.0 1.0,2.0 1.0)" ) ) ;
+ ConstraintDelaunayTriangulation triangulation = triangulate2DZ( *g );
+ BOOST_CHECK_EQUAL( triangulation.numVertices(), 4U );
+ BOOST_CHECK_EQUAL( triangulation.numTriangles(), 2U );
+}
+
+BOOST_AUTO_TEST_CASE( testPolygonWithHole )
+{
+ std::auto_ptr< Geometry > g( io::readWkt( "POLYGON((0.0 0.0,1.0 0.0,1.0 1.0,0.0 1.0,0.0 0.0),(0.2 0.2,0.2 0.8,0.8 0.8,0.8 0.2,0.2 0.2))" ) ) ;
+ ConstraintDelaunayTriangulation triangulation = triangulate2DZ( *g );
+ BOOST_CHECK_EQUAL( triangulation.numVertices(), 8U );
+ BOOST_CHECK_EQUAL( triangulation.numTriangles(), 10U );
+}
+
+
+BOOST_AUTO_TEST_CASE( testMultiPoint )
+{
+ std::auto_ptr< Geometry > g( io::readWkt( "MULTIPOINT((1.0 2.0 3.0),(2.0 3.0 6.0),(8.0 6.0 7.0),(2.0 1.0 6.0))" ) ) ;
+ ConstraintDelaunayTriangulation triangulation = triangulate2DZ( *g );
+ BOOST_CHECK_EQUAL( triangulation.numVertices(), 4U );
+ BOOST_CHECK_EQUAL( triangulation.numTriangles(), 2U );
+}
+
+//MultiLineString
+//MultiPolygon
+//GeometryCollection
+BOOST_AUTO_TEST_CASE( testMultiPolygon )
+{
+ std::auto_ptr< Geometry > g( io::readWkt( "GEOMETRYCOLLECTION(LINESTRING(-1.52451708766716 0.583952451708767,-1.5408618127786 0.361069836552749,-1.47251114413076 0.317979197622586,-1.30163447251114 0.398216939078752,-1.32095096582467 0.482912332838039,-1.08320950965825 0.598811292719168,-0.809806835066865 0.570579494799406,-0.517087667161962 0.662704309063893),POLYGON((-1.46508172362556 0.615156017830609,-1.35215453194651 0.806835066864785,-1.08320950965825 0.754829123328381,-1.10401 [...]
+ ConstraintDelaunayTriangulation triangulation = triangulate2DZ( *g );
+ BOOST_CHECK_EQUAL( triangulation.numVertices(), 41U );
+ BOOST_CHECK_EQUAL( triangulation.numTriangles(), 72U );
+// std::cout << triangulation.getTriangulatedSurface()->asText(5) << std::endl ;
+}
+
+//Solid
+
+BOOST_AUTO_TEST_CASE( testSolid )
+{
+
+ std::auto_ptr< Geometry > g( io::readWkt( "SOLID((((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)),\
+ ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),\
+ ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),\
+ ((1 1 1, 0 1 1, 0 0 1, 1 0 1, 1 1 1)),\
+ ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)),\
+ ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1))))" ) );
+
+#ifndef SFCGAL_NEVER_CHECK_VALIDITY
+ BOOST_CHECK_THROW( triangulate2DZ( *g ), GeometryInvalidityException );
+#else
+ BOOST_CHECK_THROW( triangulate2DZ( *g ), InappropriateGeometryException );
+#endif
+}
+
+
+//MultiSolid
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+
+
diff --git a/test/unit/TestModule.cpp b/test/unit/TestModule.cpp
new file mode 100644
index 0000000..9b1f7c8
--- /dev/null
+++ b/test/unit/TestModule.cpp
@@ -0,0 +1,41 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#define BOOST_TEST_MODULE UnitTestSFCGAL
+
+#define BOOST_TEST_ALTERNATIVE_INIT_API
+
+#include <boost/test/unit_test.hpp>
+using namespace boost::unit_test ;
+
+#include <SFCGAL/detail/tools/Log.h>
+
+test_suite* init_unit_test_suite( int, char** const )
+{
+// std::cerr << "init test suite" << std::endl;
+ SFCGAL::Logger::get()->setLogLevel( SFCGAL::Logger::Info );
+ return 0;
+}
+
+
+
+
+
+
+
diff --git a/viewer/CMakeLists.txt b/viewer/CMakeLists.txt
new file mode 100644
index 0000000..581831b
--- /dev/null
+++ b/viewer/CMakeLists.txt
@@ -0,0 +1,40 @@
+find_package( Qt4 COMPONENTS QtGui QtCore REQUIRED )
+find_package( OpenSceneGraph COMPONENTS osgQt osgViewer osgGA osgDB osgUtil REQUIRED )
+find_package( PostgreSQL REQUIRED )
+
+include_directories(
+ include
+ # postgresql
+ ${POSTGRESQL_INCLUDE_DIR}
+ ${QT_INCLUDES}
+ ${OPENSCENEGRAPH_INCLUDE_DIRS}
+)
+
+file( GLOB_RECURSE VIEWER_SFCGAL_HEADERS ./*.h )
+file( GLOB_RECURSE VIEWER_SFCGAL_HEADERS_MOC ./include/SFCGAL/*.h )
+file( GLOB_RECURSE VIEWER_SFCGAL_SOURCES ./*.cpp )
+
+QT4_WRAP_CPP(VIEWER_SFCGAL_MOC ${VIEWER_SFCGAL_HEADERS_MOC})
+
+add_executable( viewer-SFCGAL
+ ${VIEWER_SFCGAL_HEADERS}
+ ${VIEWER_SFCGAL_SOURCES}
+ ${VIEWER_SFCGAL_MOC}
+)
+
+set(QT_LIBRARIES QtCore QtGui)
+set_target_properties( viewer-SFCGAL PROPERTIES DEBUG_POSTFIX "d" )
+target_link_libraries( viewer-SFCGAL
+ SFCGAL
+ ${OPENSCENEGRAPH_LIBRARIES}
+ ${QT_LIBRARIES}
+ ${CGAL_LIBRARIES}
+ ${Boost_LIBRARIES}
+ ${MPFR_LIBRARIES}
+ ${GMP_LIBRARIES}
+ # Postgresql
+ pq
+)
+install( TARGETS viewer-SFCGAL DESTINATION bin )
+
+
diff --git a/viewer/cmake/Modules/FindosgQt.cmake b/viewer/cmake/Modules/FindosgQt.cmake
new file mode 100644
index 0000000..658a7bd
--- /dev/null
+++ b/viewer/cmake/Modules/FindosgQt.cmake
@@ -0,0 +1,50 @@
+# This is part of the Findosg* suite used to find OpenSceneGraph components.
+# Each component is separate and you must opt in to each module. You must
+# also opt into OpenGL and OpenThreads (and Producer if needed) as these
+# modules won't do it for you. This is to allow you control over your own
+# system piece by piece in case you need to opt out of certain components
+# or change the Find behavior for a particular module (perhaps because the
+# default FindOpenGL.cmake module doesn't work with your system as an
+# example).
+# If you want to use a more convenient module that includes everything,
+# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+#
+# Locate osgQt
+# This module defines
+#
+# OSGQT_FOUND - Was osgQt found?
+# OSGQT_INCLUDE_DIR - Where to find the headers
+# OSGQT_LIBRARIES - The libraries to link for osgQt (use this)
+#
+# OSGQT_LIBRARY - The osgQt library
+# OSGQT_LIBRARY_DEBUG - The osgQt debug library
+#
+# $OSGDIR is an environment variable that would
+# correspond to the ./configure --prefix=$OSGDIR
+# used in building osg.
+#
+# Created by Eric Wing.
+# Modified to work with osgQt by Robert Osfield, January 2012.
+
+#=============================================================================
+# Copyright 2007-2009 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# Header files are presumed to be included like
+# #include <osg/PositionAttitudeTransform>
+# #include <osgQt/GraphicsWindowQt>
+
+OSG_FIND_PATH (OSGQT osgQt/GraphicsWindowQt)
+OSG_FIND_LIBRARY(OSGQT osgQt)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(osgQt DEFAULT_MSG
+ OSGQT_LIBRARY OSGQT_INCLUDE_DIR)
diff --git a/viewer/include/SFCGAL/viewer/GISManipulator.h b/viewer/include/SFCGAL/viewer/GISManipulator.h
new file mode 100644
index 0000000..00da55f
--- /dev/null
+++ b/viewer/include/SFCGAL/viewer/GISManipulator.h
@@ -0,0 +1,44 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _SFCGAL_VIEWER_GISMANIPULATOR_H_
+#define _SFCGAL_VIEWER_GISMANIPULATOR_H_
+
+#include <osgGA/FirstPersonManipulator>
+
+namespace SFCGAL {
+namespace viewer {
+
+class GISManipulator : public osgGA::FirstPersonManipulator {
+public:
+ GISManipulator();
+
+ void init ( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );
+
+protected:
+ bool performMovementLeftMouseButton( const double eventTimeDelta, const double dx, const double dy );
+
+ bool handleMouseWheel( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );
+};
+
+}//viewer
+}//SFCGAL
+
+
+#endif
diff --git a/viewer/include/SFCGAL/viewer/ViewerPlugin.h b/viewer/include/SFCGAL/viewer/ViewerPlugin.h
new file mode 100644
index 0000000..fe88cc4
--- /dev/null
+++ b/viewer/include/SFCGAL/viewer/ViewerPlugin.h
@@ -0,0 +1,74 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _SFCGAL_VIEWER_VIEWERPLUGIN_H_
+#define _SFCGAL_VIEWER_VIEWERPLUGIN_H_
+
+#include <QtCore/QObject>
+
+namespace SFCGAL {
+namespace viewer {
+
+class ViewerWindow ;
+class ViewerWidget ;
+
+/**
+ * osgViewer::Viewer wrapped in a QWidget
+ */
+class ViewerPlugin : public QObject {
+ Q_OBJECT
+
+ friend class ViewerWindow ;
+public:
+ /**
+ * Default constructor
+ */
+ ViewerPlugin() ;
+
+ /**
+ * Returns the plugin name
+ */
+ virtual QString pluginName() const = 0 ;
+
+ /**
+ * returns the window
+ */
+ ViewerWindow* viewerWindow() ;
+ /**
+ * returns the window
+ */
+ ViewerWidget* viewer() ;
+protected:
+ /**
+ * Load plugin
+ */
+ virtual void load() = 0 ;
+ /**
+ * Unload plugin
+ */
+ virtual void unload() ;
+private:
+ ViewerWindow* _viewerWindow ;
+};
+
+}//viewer
+}//SFCGAL
+
+
+#endif
diff --git a/viewer/include/SFCGAL/viewer/ViewerWidget.h b/viewer/include/SFCGAL/viewer/ViewerWidget.h
new file mode 100644
index 0000000..4d76006
--- /dev/null
+++ b/viewer/include/SFCGAL/viewer/ViewerWidget.h
@@ -0,0 +1,102 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _SFCGAL_VIEWER_VIEWERWIDGET_H_
+#define _SFCGAL_VIEWER_VIEWERWIDGET_H_
+
+#include <QtCore/QTimer>
+#include <QtGui/QWidget>
+
+#include <osgViewer/Viewer>
+#include <osgQt/GraphicsWindowQt>
+
+namespace SFCGAL {
+namespace viewer {
+
+/**
+ * osgViewer::Viewer wrapped in a QWidget
+ */
+class ViewerWidget : public QWidget, public osgViewer::Viewer {
+ Q_OBJECT
+public:
+ /**
+ * Constructor with a threadingModel
+ */
+ ViewerWidget() ;
+ /**
+ * Constructor with a threadingModel
+ */
+ ViewerWidget( osg::ArgumentParser& arguments ) ;
+
+ /**
+ * returns the scene node
+ */
+ osg::Group* getScene() ;
+
+ /**
+ * Get GraphicsWindows
+ */
+ osgQt::GraphicsWindowQt* getGraphicsWindowQt() ;
+
+
+ //-- [QWidget]
+ virtual void paintEvent( QPaintEvent* event ) ;
+
+ /**
+ * [factory]create viewer from command line arguments
+ */
+ static ViewerWidget* createFromArguments( osg::ArgumentParser& arguments ) ;
+
+ /**
+ * Save image to file
+ */
+ void saveImageToFile() ;
+
+
+ void setCameraToExtent( const osg::BoundingBox& );
+public slots :
+ /**
+ * start animation
+ */
+ void startAnimation() ;
+ /**
+ * stop animation
+ */
+ void stopAnimation() ;
+
+protected:
+ QTimer _timer;
+ osg::Camera* _camera ;
+ osg::Group* _scene ;
+
+
+ /**
+ * [helper]create a camera with the given parameters
+ */
+ osg::Camera* createCamera( int x, int y, int w, int h, const std::string& name="", bool windowDecoration=false ) ;
+
+private:
+ void initViewer() ;
+};
+
+}//viewer
+}//SFCGAL
+
+
+#endif
diff --git a/viewer/include/SFCGAL/viewer/ViewerWindow.h b/viewer/include/SFCGAL/viewer/ViewerWindow.h
new file mode 100644
index 0000000..35195cb
--- /dev/null
+++ b/viewer/include/SFCGAL/viewer/ViewerWindow.h
@@ -0,0 +1,112 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _SFCGAL_VIEWER_VIEWERWINDOW_H_
+#define _SFCGAL_VIEWER_VIEWERWINDOW_H_
+
+#include <QtGui/QMainWindow>
+
+
+namespace SFCGAL {
+namespace viewer {
+
+class ViewerPlugin ;
+class ViewerWidget ;
+
+/**
+ * osgViewer::Viewer wrapped in a QWidget
+ */
+class ViewerWindow : public QMainWindow {
+ Q_OBJECT
+public:
+ /**
+ * constructor with a viewer
+ */
+ ViewerWindow( ViewerWidget* viewer = 0 );
+
+ /**
+ * destructor
+ */
+ ~ViewerWindow() ;
+
+ /**
+ * get viewer
+ */
+ ViewerWidget* viewer() ;
+ /**
+ * get viewer
+ */
+ void setViewer( ViewerWidget* viewer ) ;
+
+ /**
+ * add a plugin to the window
+ */
+ void addPlugin( ViewerPlugin* plugin ) ;
+
+public slots:
+
+ /**
+ * load a file
+ */
+ void loadFile() ;
+ /**
+ * save to a file
+ */
+ void saveFile() ;
+
+ /**
+ * display about message
+ */
+ void about() ;
+
+ /**
+ * take a screen shot
+ */
+ void screenShot() ;
+
+ /**
+ * switch to a GIS-oriented manipulator
+ */
+ void toGISView();
+
+ /**
+ * switch to a free view manipulator
+ */
+ void toFreeView();
+protected:
+ /**
+ * create default menus
+ */
+ void createMenus() ;
+
+protected:
+ ViewerWidget* _viewer ;
+
+ QMenu* _menuFile ;
+ QMenu* _menuData ;
+ QMenu* _menuHelp ;
+
+ std::vector< ViewerPlugin* > _plugins ;
+};
+
+}//viewer
+}//SFCGAL
+
+
+#endif
diff --git a/viewer/include/SFCGAL/viewer/plugins/DataPlugin.h b/viewer/include/SFCGAL/viewer/plugins/DataPlugin.h
new file mode 100644
index 0000000..05f7975
--- /dev/null
+++ b/viewer/include/SFCGAL/viewer/plugins/DataPlugin.h
@@ -0,0 +1,70 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _SFCGAL_VIEWER_PLUGINS_DATAPLUGIN_H_
+#define _SFCGAL_VIEWER_PLUGINS_DATAPLUGIN_H_
+
+#include <SFCGAL/viewer/ViewerPlugin.h>
+
+namespace osg {
+class Node ;
+}
+
+namespace SFCGAL {
+namespace viewer {
+namespace plugins {
+
+/**
+ * data management plugin
+ */
+class DataPlugin : public ViewerPlugin {
+ Q_OBJECT
+public:
+ /**
+ * Default constructor
+ */
+ DataPlugin() ;
+
+ /**
+ * Returns the plugin name
+ */
+ virtual QString pluginName() const ;
+
+
+ static void displayNodeInformation( osg::Node* node, std::ostream& s, const size_t& depth = 0 ) ;
+
+public slots :
+ /**
+ * display data information
+ */
+ void displayInformations();
+protected:
+ /**
+ * init plugin
+ */
+ virtual void load() ;
+};
+
+}//plugins
+}//viewer
+}//SFCGAL
+
+
+#endif
+
diff --git a/viewer/include/SFCGAL/viewer/plugins/DemoPlugin.h b/viewer/include/SFCGAL/viewer/plugins/DemoPlugin.h
new file mode 100644
index 0000000..c23b6e0
--- /dev/null
+++ b/viewer/include/SFCGAL/viewer/plugins/DemoPlugin.h
@@ -0,0 +1,76 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _SFCGAL_VIEWER_PLUGINS_DEMOPLUGIN_H_
+#define _SFCGAL_VIEWER_PLUGINS_DEMOPLUGIN_H_
+
+#include <SFCGAL/viewer/ViewerPlugin.h>
+
+
+namespace SFCGAL {
+namespace viewer {
+namespace plugins {
+
+/**
+ * demo plugin
+ */
+class DemoPlugin : public ViewerPlugin {
+ Q_OBJECT
+public:
+ /**
+ * Default constructor
+ */
+ DemoPlugin() ;
+
+ /**
+ * Returns the plugin name
+ */
+ virtual QString pluginName() const ;
+
+public slots :
+ /**
+ * demo extrude
+ */
+ void demoSpiral();
+ /**
+ * demo extrude
+ */
+ void demoWkt();
+ /**
+ * demo extrude
+ */
+ void demoExtrude();
+ /**
+ * demo convexHull
+ */
+ void demoConvexhull();
+protected:
+ /**
+ * init plugin
+ */
+ virtual void load() ;
+};
+
+}//plugins
+}//viewer
+}//SFCGAL
+
+
+#endif
+
diff --git a/viewer/include/SFCGAL/viewer/plugins/GridPlugin.h b/viewer/include/SFCGAL/viewer/plugins/GridPlugin.h
new file mode 100644
index 0000000..c3307eb
--- /dev/null
+++ b/viewer/include/SFCGAL/viewer/plugins/GridPlugin.h
@@ -0,0 +1,67 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _SFCGAL_VIEWER_PLUGINS_GRIDPLUGIN_H_
+#define _SFCGAL_VIEWER_PLUGINS_GRIDPLUGIN_H_
+
+#include <SFCGAL/viewer/ViewerPlugin.h>
+
+namespace osg {
+class Node ;
+}
+
+namespace SFCGAL {
+namespace viewer {
+namespace plugins {
+
+/**
+ * data management plugin
+ */
+class GridPlugin : public ViewerPlugin {
+ Q_OBJECT
+public:
+ /**
+ * Default constructor
+ */
+ GridPlugin() ;
+
+ /**
+ * Returns the plugin name
+ */
+ virtual QString pluginName() const ;
+
+public slots :
+ /**
+ * display data information
+ */
+ void loadGridXYZ();
+protected:
+ /**
+ * init plugin
+ */
+ virtual void load() ;
+};
+
+}//plugins
+}//viewer
+}//SFCGAL
+
+
+#endif
+
diff --git a/viewer/include/SFCGAL/viewer/plugins/PSQLPlugin.h b/viewer/include/SFCGAL/viewer/plugins/PSQLPlugin.h
new file mode 100644
index 0000000..521569d
--- /dev/null
+++ b/viewer/include/SFCGAL/viewer/plugins/PSQLPlugin.h
@@ -0,0 +1,160 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _SFCGAL_VIEWER_PLUGINS_PSQLPLUGIN_H_
+#define _SFCGAL_VIEWER_PLUGINS_PSQLPLUGIN_H_
+
+#ifndef Q_MOC_RUN
+#include <boost/scoped_ptr.hpp>
+#include <osg/Geode>
+#endif
+
+#include <QtGui/QDockWidget>
+#include <QtGui/QPlainTextEdit>
+#include <QtGui/QPushButton>
+#include <QtGui/QListWidget>
+#include <QtGui/QLineEdit>
+
+#include <SFCGAL/viewer/ViewerPlugin.h>
+
+namespace SFCGAL {
+namespace viewer {
+namespace plugins {
+
+class PSQLPluginImpl;
+/**
+ * data management plugin
+ */
+class PSQLPlugin : public ViewerPlugin {
+ Q_OBJECT
+public:
+ /**
+ * Default constructor
+ */
+ PSQLPlugin() ;
+
+ ~PSQLPlugin();
+
+ /**
+ * Returns the plugin name
+ */
+ virtual QString pluginName() const ;
+
+ /**
+ * Connect to the database
+ */
+ void connect( const std::string& dbOptions );
+
+ void disconnect();
+
+ /**
+ * Do the PostGIS query and returns an osg::Geode
+ */
+ osg::Geode* doQuery( const std::string& );
+
+ /**
+ * Do the PostGIS queries for all layers
+ */
+ void computeGeometries();
+
+ /**
+ * Display all visible layers
+ */
+ void display();
+public slots :
+ /**
+ * display data information
+ */
+ void launchConsole();
+
+ void saveLayers();
+ void loadLayers();
+ void onRefresh();
+protected:
+ /**
+ * init plugin
+ */
+ virtual void load() ;
+
+private:
+ PSQLPluginImpl* impl_;
+};
+
+
+///
+/// SQL editor for a layer
+class SQLConsole : public QDockWidget {
+ Q_OBJECT
+public:
+ SQLConsole( PSQLPlugin* plugin );
+
+ //
+ // connect to a QListWidgetItem storing the sql query and the resulting geometry
+ void connectItem( QListWidgetItem* );
+
+ //
+ //
+ void disconnectItem();
+
+public slots:
+ void onQuery();
+ void onReconnect();
+private:
+ QPlainTextEdit* sqlEdit_;
+ QPushButton* okBtn_;
+ QPushButton* connectBtn_;
+ QLineEdit* dbOptions_;
+
+ QListWidgetItem* item_;
+
+ PSQLPlugin* plugin_;
+};
+
+class LayersWidget : public QDockWidget {
+ Q_OBJECT
+public:
+ LayersWidget( PSQLPlugin* plugin, SQLConsole* );
+
+ QListWidget* widget() {
+ return listWidget_;
+ }
+
+ void addLayer( const QString& name, bool visible, const QString& dbOptions, const QString& query );
+public slots:
+ void onAdd();
+ void onClick( const QModelIndex& idx );
+
+ void onEdit();
+ void onRemove();
+ void onZoomToLayer();
+private:
+ QListWidget* listWidget_;
+ QPushButton* addBtn_;
+ SQLConsole* console_;
+
+ PSQLPlugin* plugin_;
+};
+
+}//plugins
+}//viewer
+}//SFCGAL
+
+
+#endif
+
diff --git a/viewer/include/db.h b/viewer/include/db.h
new file mode 100644
index 0000000..dcde09b
--- /dev/null
+++ b/viewer/include/db.h
@@ -0,0 +1,274 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+// Database access classes
+// (c) 2012 Oslandia
+// MIT License
+
+#ifndef POSTGRESQL_CONNECTION_HH
+#define POSTGRESQL_CONNECTION_HH
+
+/**
+ Database access is modeled by means of the following classes, inspired by pqxx:
+ * A Db::Connection objet represents a connection to a database. It is a lightweighted objet that is reference-counted and thus can be copied safely.
+ * A Db::Result objet represents result of a query. It is a lightweighted objet that is reference-counted and thus can be copied safely.
+ * A Db::RowValue object represents a row of a result and is obtained by Db::Result::operator[]
+ * A Db::Value object represent a basic value. It is obtained by Db::RowValue::operator[]. It has templated conversion operators for common data types.
+
+ These classes throw std::runtime_error on problem.
+ */
+
+#include <libpq-fe.h>
+
+#include <string>
+#include <stdexcept>
+
+#include <boost/assert.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace Db {
+///
+/// Class representing an atomic value stored in a database.
+class Value {
+public:
+ Value( const char* value, size_t len, bool isnull ) : value_( value ), len_( len ), isnull_( isnull ) {
+ }
+
+ ///
+ /// This is the generic conversion operator.
+ /// It calls stringstream conversion operators (slow!).
+ /// Specialization can be introduced, or via a specialization of the stringstream::operator>>()
+ template <class T>
+ T as() {
+ T obj;
+ std::istringstream istr( value_ );
+ istr >> obj;
+ return obj;
+ }
+
+ ///
+ /// Conversion operator. Does nothing if the underlying object is null (which is a special value in a database)
+ template <class T>
+ void operator >> ( T& obj ) {
+ if ( !isnull_ ) {
+ obj = as<T>();
+ }
+ }
+
+ ///
+ /// Tests if the underlying object is null
+ bool is_null() {
+ return isnull_;
+ }
+protected:
+ const char* value_;
+ size_t len_;
+ bool isnull_;
+};
+
+//
+// List of conversion specializations
+template <>
+bool Value::as<bool>();
+template <>
+std::string Value::as<std::string>();
+template <>
+long long Value::as<long long>();
+template <>
+int Value::as<int>();
+template <>
+float Value::as<float>();
+template <>
+double Value::as<double>();
+
+///
+/// Class used to represent a row in a result.
+class RowValue {
+public:
+ RowValue( PGresult* res, size_t nrow ) : res_( res ), nrow_( nrow ) {
+ }
+
+ ///
+ /// Access to a value by column number
+ Value operator [] ( size_t fn ) {
+ BOOST_ASSERT( fn < ( size_t )PQnfields( res_ ) );
+ return Value( PQgetvalue( res_, nrow_, fn ),
+ PQgetlength( res_, nrow_, fn ),
+ PQgetisnull( res_, nrow_, fn ) != 0 ? true : false
+ );
+ }
+protected:
+ PGresult* res_;
+ size_t nrow_;
+};
+
+///
+/// Class representing result of a query
+class Result {
+public:
+ Result() : res_( 0 ) {}
+
+ Result( PGresult* res ) : res_( res ) {
+ BOOST_ASSERT( res_ );
+ nrefs_ = 1;
+ }
+ ///
+ /// Copy constructor
+ Result( const Result& r ) {
+ r.inc_refs();
+ dec_refs();
+ nrefs_ = r.nrefs_;
+ res_ = r.res_;
+ }
+ ///
+ /// Assignment operator. Deals with reference counting
+ Result& operator = ( const Result& r ) {
+ r.inc_refs();
+ dec_refs();
+ nrefs_ = r.nrefs_;
+ res_ = r.res_;
+ return *this;
+ }
+
+ virtual ~Result() {
+ dec_refs();
+ }
+
+ ///
+ /// Number of rows
+ size_t size() {
+ return res_ == 0 ? 0 : PQntuples( res_ );
+ }
+
+ ///
+ /// Number of columns
+ size_t columns() {
+ return res_ == 0 ? 0 : PQnfields( res_ );
+ }
+
+ ///
+ /// Access to a row of a result, by row number
+ RowValue operator [] ( size_t idx ) {
+ BOOST_ASSERT( idx < size() );
+ return RowValue( res_, idx );
+ }
+
+ PGresult* result() const {
+ return res_;
+ }
+protected:
+ PGresult* res_;
+
+ void dec_refs() const {
+ if ( res_ == 0 ) {
+ return;
+ }
+
+ if ( --nrefs_ == 0 ) {
+ PQclear( res_ );
+ }
+ }
+ void inc_refs() const {
+ nrefs_++;
+ }
+ mutable int nrefs_;
+};
+
+///
+/// Class representing connection to a database.
+class Connection {
+public:
+ Connection() : conn_( 0 ) {
+ nrefs_ = 0;
+ }
+
+ Connection( const std::string& db_options ) : conn_( 0 ) {
+ nrefs_ = 0;
+ connect( db_options );
+ }
+
+ void connect( const std::string& db_options ) {
+ dec_refs();
+ conn_ = PQconnectdb( db_options.c_str() );
+
+ if ( conn_ == NULL || PQstatus( conn_ ) != CONNECTION_OK ) {
+ std::string msg = "Database connection problem: ";
+ msg += PQerrorMessage( conn_ );
+ throw std::runtime_error( msg.c_str() );
+ }
+
+ nrefs_ = 1;
+ }
+
+ virtual ~Connection() {
+ dec_refs();
+ }
+
+ Connection( const Connection& r ) {
+ r.inc_refs();
+ dec_refs();
+ nrefs_ = r.nrefs_;
+ conn_ = r.conn_;
+ }
+ Connection& operator = ( const Connection& r ) {
+ r.inc_refs();
+ dec_refs();
+ nrefs_ = r.nrefs_;
+ conn_ = r.conn_;
+ return *this;
+ }
+
+ ///
+ /// Query execution. Returns a Db::Result. Throws a std::runtime_error on problem
+ Result exec( const std::string& query ) const throw ( std::runtime_error ) {
+ PGresult* res = PQexec( conn_, query.c_str() );
+ ExecStatusType ret = PQresultStatus( res );
+
+ if ( ( ret != PGRES_COMMAND_OK ) && ( ret != PGRES_TUPLES_OK ) ) {
+ std::string msg = "Problem on database query: ";
+ msg += PQresultErrorMessage( res );
+ PQclear( res );
+ throw std::runtime_error( msg.c_str() );
+ }
+
+ return res;
+ }
+ PGconn* connection() const {
+ return conn_;
+ }
+protected:
+ PGconn* conn_;
+
+ void dec_refs() const {
+ if ( nrefs_ == 0 ) {
+ return;
+ }
+
+ if ( --nrefs_ == 0 ) {
+ PQfinish( conn_ );
+ }
+ }
+ void inc_refs() const {
+ nrefs_++;
+ }
+ mutable int nrefs_;
+};
+}
+
+#endif
diff --git a/viewer/main.cpp b/viewer/main.cpp
new file mode 100644
index 0000000..48b1bd7
--- /dev/null
+++ b/viewer/main.cpp
@@ -0,0 +1,105 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <iostream>
+
+#include <QtGui/QApplication>
+
+#include <osgDB/ReadFile>
+#include <osgUtil/SmoothingVisitor>
+
+#include <osg/Material>
+#include <osgDB/Registry>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+#include <SFCGAL/detail/tools/Log.h>
+
+#include <SFCGAL/viewer/ViewerWidget.h>
+#include <SFCGAL/viewer/ViewerWindow.h>
+#include <SFCGAL/viewer/plugins/DemoPlugin.h>
+#include <SFCGAL/viewer/plugins/DataPlugin.h>
+#include <SFCGAL/viewer/plugins/GridPlugin.h>
+#include <SFCGAL/viewer/plugins/PSQLPlugin.h>
+#include <QtGui/QFileDialog>
+
+
+
+using namespace SFCGAL ;
+using namespace SFCGAL::viewer ;
+
+
+int main( int argc, char** argv )
+{
+ Logger::get()->setLogLevel( Logger::Debug );
+
+ // use an ArgumentParser object to manage the program arguments.
+ osg::ArgumentParser arguments( &argc,argv );
+
+ QApplication app( argc, argv );
+
+ ViewerWidget* viewer = ViewerWidget::createFromArguments( arguments );
+// osg::Geode* geode = new osg::Geode;
+// //osg::StateSet* status = geode->getOrCreateStateSet();
+// //status->setMode(GL_LIGHTING, osg::StateAttribute::ON);
+//
+//
+// std::auto_ptr< Geometry > g( io::readWkt("POLYGON((0.0 0.0 0.0,1.0 0.0 0.0,1.0 1.0 0.0,0.0 1.0 0.0,0.0 0.0 0.0),(0.2 0.2 0.0,0.8 0.2 0.0,0.8 0.8 0.0,0.2 0.8 0.0,0.2 0.2 0.0))") );
+// g->as< Polygon >().ringN(1).reverse();
+// std::auto_ptr< Geometry > ext( algorithm::extrude(*g,0.0,0.0,1.0) );
+//
+// detail::io::OsgFactory factory ;
+//
+// osg::Geometry * osgGeometry = factory.createGeometry( *ext ) ;
+//
+
+// */
+//
+// /*
+// * provide a material
+// */
+// osg::ref_ptr<osg::StateSet> stateSet( geode->getOrCreateStateSet() );
+// osg::ref_ptr<osg::Material> material( new osg::Material );
+// material->setDiffuse(osg::Material::FRONT,osg::Vec4(1.0f,0.0f,0.0f,1.0f));
+// stateSet->setAttribute( material.release() );
+//
+//
+// geode->addDrawable( osgGeometry );
+// viewer->getScene()->addChild( geode ) ;
+
+
+ ViewerWindow window( viewer );
+ window.addPlugin( new plugins::DataPlugin ) ;
+ window.addPlugin( new plugins::DemoPlugin ) ;
+ window.addPlugin( new plugins::GridPlugin ) ;
+ window.addPlugin( new plugins::PSQLPlugin ) ;
+ window.show();
+
+ return app.exec();
+}
diff --git a/viewer/src/SFCGAL/viewer/GISManipulator.cpp b/viewer/src/SFCGAL/viewer/GISManipulator.cpp
new file mode 100644
index 0000000..804e139
--- /dev/null
+++ b/viewer/src/SFCGAL/viewer/GISManipulator.cpp
@@ -0,0 +1,82 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <iostream>
+
+#include <osg/io_utils>
+
+#include <SFCGAL/viewer/GISManipulator.h>
+
+namespace SFCGAL {
+namespace viewer {
+
+GISManipulator::GISManipulator() : osgGA::FirstPersonManipulator()
+{
+}
+
+void GISManipulator::init ( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us )
+{
+ std::cout << "init" << std::endl;
+ osgGA::FirstPersonManipulator::init( ea, us );
+ setTransformation( /*eye*/ osg::Vec3f( 0.0, 0.0, 100.0 ), /*center*/ osg::Vec3f( 0.0, 0.0, 0.0 ), /* up */ osg::Vec3f( 0.0, 0.0, 1.0 ) );
+}
+
+bool GISManipulator::performMovementLeftMouseButton( const double /*eventTimeDelta*/, const double dx, const double dy )
+{
+ // TODO: compute the right amount in order for one mouse's pixel movement to correspond to a movement of one object's pixel
+ osg::Vec3d eye, center, up;
+ getTransformation( eye, center, up );
+
+ double altitude = eye[2];
+
+ moveRight( -dx * altitude / 8.0 );
+ moveUp( -dy * altitude / 8.0 );
+
+ return true;
+}
+
+bool GISManipulator::handleMouseWheel( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us )
+{
+ osgGA::GUIEventAdapter::ScrollingMotion sm = ea.getScrollingMotion();
+
+ osg::Vec3d eye, center, up;
+ getTransformation( eye, center, up );
+ double altitude = eye[2];
+
+ if ( sm == osgGA::GUIEventAdapter::SCROLL_UP ) {
+ altitude /= 1.41;
+ }
+ else if ( sm == osgGA::GUIEventAdapter::SCROLL_DOWN ) {
+ altitude *= 1.41;
+ }
+ else {
+ return false;
+ }
+
+ eye[2] = altitude;
+ center[2] = eye[2] - 1.0;
+ setTransformation( eye, center, up );
+
+ us.requestRedraw();
+ us.requestContinuousUpdate( isAnimating() );
+ return true;
+}
+
+} // namespace viewer
+} // namespace SFCGAL
diff --git a/viewer/src/SFCGAL/viewer/ViewerPlugin.cpp b/viewer/src/SFCGAL/viewer/ViewerPlugin.cpp
new file mode 100644
index 0000000..3734547
--- /dev/null
+++ b/viewer/src/SFCGAL/viewer/ViewerPlugin.cpp
@@ -0,0 +1,67 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <SFCGAL/viewer/ViewerPlugin.h>
+#include <SFCGAL/viewer/ViewerWidget.h>
+#include <SFCGAL/viewer/ViewerWindow.h>
+
+#include <iostream>
+
+namespace SFCGAL {
+namespace viewer {
+
+///
+///
+///
+ViewerPlugin::ViewerPlugin():
+ _viewerWindow( 0 )
+{
+
+}
+
+
+///
+///
+///
+ViewerWindow* ViewerPlugin::viewerWindow()
+{
+ return _viewerWindow ;
+}
+
+///
+///
+///
+ViewerWidget* ViewerPlugin::viewer()
+{
+ return _viewerWindow->viewer() ;
+}
+
+///
+///
+///
+void ViewerPlugin::unload()
+{
+
+}
+
+
+}//viewer
+}//SFCGAL
+
+
diff --git a/viewer/src/SFCGAL/viewer/ViewerWidget.cpp b/viewer/src/SFCGAL/viewer/ViewerWidget.cpp
new file mode 100644
index 0000000..31883d7
--- /dev/null
+++ b/viewer/src/SFCGAL/viewer/ViewerWidget.cpp
@@ -0,0 +1,353 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <SFCGAL/viewer/ViewerWidget.h>
+
+#include <iostream>
+#include <memory>
+
+#include <QtGui/QVBoxLayout>
+
+
+#include <osgViewer/ViewerEventHandlers>
+#include <osgGA/CameraManipulator>
+#include <osgGA/TrackballManipulator>
+
+
+#include <osgDB/Registry>
+#include <osgDB/ReadFile>
+#include <osgDB/WriteFile>
+
+#include <osgViewer/Viewer>
+#include <osgViewer/ViewerEventHandlers>
+
+#include <osgGA/TrackballManipulator>
+#include <osgGA/FlightManipulator>
+#include <osgGA/DriveManipulator>
+#include <osgGA/KeySwitchMatrixManipulator>
+#include <osgGA/StateSetManipulator>
+#include <osgGA/AnimationPathManipulator>
+#include <osgGA/TerrainManipulator>
+#include <osgGA/SphericalManipulator>
+#include <osgGA/FirstPersonManipulator>
+
+
+#include <osgUtil/Optimizer>
+#include <osg/CoordinateSystemNode>
+
+#include <osg/Switch>
+#include <osgText/Text>
+
+#include <osg/io_utils>
+
+#include <SFCGAL/viewer/GISManipulator.h>
+
+namespace SFCGAL {
+namespace viewer {
+
+///
+///
+///
+ViewerWidget::ViewerWidget():
+ QWidget(),
+ osgViewer::Viewer()
+{
+ initViewer();
+}
+
+///
+///
+///
+ViewerWidget::ViewerWidget( osg::ArgumentParser& arguments ) :
+ QWidget(),
+ osgViewer::Viewer( arguments )
+{
+ initViewer();
+}
+
+///
+///
+///
+void ViewerWidget::initViewer()
+{
+ _camera = createCamera( 0,0,100,100 ) ;
+ setCamera( _camera );
+
+ _scene = new osg::Group();
+ setSceneData( _scene );
+
+ osgQt::GraphicsWindowQt* gw = dynamic_cast<osgQt::GraphicsWindowQt*>( _camera->getGraphicsContext() );
+
+ QVBoxLayout* layout = new QVBoxLayout;
+ layout->addWidget( gw ? gw->getGLWidget() : NULL );
+ setLayout( layout );
+
+ setMinimumSize( 700,300 );
+
+ connect( &_timer, SIGNAL( timeout() ), this, SLOT( update() ) );
+ startAnimation();
+}
+
+
+///
+///
+///
+osg::Group* ViewerWidget::getScene()
+{
+ return _scene ;
+}
+
+///
+///
+///
+osgQt::GraphicsWindowQt* ViewerWidget::getGraphicsWindowQt()
+{
+ return dynamic_cast<osgQt::GraphicsWindowQt*>( _camera->getGraphicsContext() ) ;
+}
+
+
+
+///
+///
+///
+osg::Camera* ViewerWidget::createCamera( int x, int y, int w, int h, const std::string& name, bool windowDecoration )
+{
+ osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();
+ osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
+ traits->windowName = name;
+ traits->windowDecoration = windowDecoration;
+ traits->x = x;
+ traits->y = y;
+ traits->width = w;
+ traits->height = h;
+ traits->doubleBuffer = true;
+ traits->alpha = ds->getMinimumNumAlphaBits();
+ traits->stencil = ds->getMinimumNumStencilBits();
+ traits->sampleBuffers = ds->getMultiSamples();
+ traits->samples = ds->getNumMultiSamples();
+
+ osg::ref_ptr<osg::Camera> camera = new osg::Camera;
+ camera->setGraphicsContext( new osgQt::GraphicsWindowQt( traits.get() ) );
+
+ camera->setClearColor( osg::Vec4( 0.2, 0.2, 0.6, 1.0 ) );
+ camera->setViewport( new osg::Viewport( 0, 0, traits->width, traits->height ) );
+
+ osg::Matrixd persp;
+ persp.makePerspective( 30.0f,
+ static_cast<double>( traits->width )/static_cast<double>( traits->height ),
+ 1.0f,
+ 1000000000.0f
+ );
+ camera->setProjectionMatrix( persp );
+
+ camera->setComputeNearFarMode( osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR );
+ return camera.release();
+}
+
+void ViewerWidget::setCameraToExtent( const osg::BoundingBox& bbox )
+{
+ // translate to the center of the bbox
+ osgGA::CameraManipulator* manip = getCameraManipulator();
+ osg::Vec3d eye, center, up;
+ osg::Matrixd m = manip->getMatrix();
+ m.getLookAt( eye, center, up );
+ center[0] = bbox.center()[0];
+ center[1] = bbox.center()[1];
+ eye = center;
+ eye[2] = center[2] + 1.0;
+ m.makeLookAt( eye, center, up );
+ manip->setByMatrix( m );
+
+ // TODO: compute the right amount of zoom (use the inverse projection matrix ?)
+}
+///
+///
+///
+void ViewerWidget::paintEvent( QPaintEvent* /*event*/ )
+{
+ frame();
+}
+
+///
+///
+///
+ViewerWidget* ViewerWidget::createFromArguments( osg::ArgumentParser& arguments )
+{
+ arguments.getApplicationUsage()->setApplicationName( arguments.getApplicationName() );
+ arguments.getApplicationUsage()->setDescription( arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models." );
+ arguments.getApplicationUsage()->setCommandLineUsage( arguments.getApplicationName()+" [options] filename ..." );
+ arguments.getApplicationUsage()->addCommandLineOption( "--image <filename>","Load an image and render it on a quad" );
+ arguments.getApplicationUsage()->addCommandLineOption( "--dem <filename>","Load an image/DEM and render it on a HeightField" );
+ arguments.getApplicationUsage()->addCommandLineOption( "--login <url> <username> <password>","Provide authentication information for http file access." );
+
+ std::auto_ptr< ViewerWidget > viewer( new ViewerWidget( arguments ) );
+
+ unsigned int helpType = 0;
+
+ if ( ( helpType = arguments.readHelpType() ) ) {
+ arguments.getApplicationUsage()->write( std::cout, helpType );
+ return NULL ;
+ }
+
+ // report any errors if they have occurred when parsing the program arguments.
+ if ( arguments.errors() ) {
+ arguments.writeErrorMessages( std::cout );
+ return NULL ;
+ }
+
+
+ std::string url, username, password;
+
+ while( arguments.read( "--login",url, username, password ) ) {
+ if ( !osgDB::Registry::instance()->getAuthenticationMap() ) {
+ osgDB::Registry::instance()->setAuthenticationMap( new osgDB::AuthenticationMap );
+ osgDB::Registry::instance()->getAuthenticationMap()->addAuthenticationDetails(
+ url,
+ new osgDB::AuthenticationDetails( username, password )
+ );
+ }
+ }
+
+ // set up the camera manipulators.
+ {
+ osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
+
+ keyswitchManipulator->addMatrixManipulator( '0', "GIS", new GISManipulator() );
+ keyswitchManipulator->addMatrixManipulator( '1', "Orbit", new osgGA::OrbitManipulator() );
+ keyswitchManipulator->addMatrixManipulator( '2', "Trackball", new osgGA::TrackballManipulator() );
+ keyswitchManipulator->addMatrixManipulator( '3', "Flight", new osgGA::FlightManipulator() );
+ keyswitchManipulator->addMatrixManipulator( '4', "Drive", new osgGA::DriveManipulator() );
+ keyswitchManipulator->addMatrixManipulator( '5', "Terrain", new osgGA::TerrainManipulator() );
+ keyswitchManipulator->addMatrixManipulator( '6', "FirstPerson", new osgGA::FirstPersonManipulator() );
+ keyswitchManipulator->addMatrixManipulator( '7', "Spherical", new osgGA::SphericalManipulator() );
+
+ std::string pathfile;
+ double animationSpeed = 1.0;
+
+ while( arguments.read( "--speed",animationSpeed ) ) {}
+
+ char keyForAnimationPath = '9';
+
+ while ( arguments.read( "-p",pathfile ) ) {
+ osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator( pathfile );
+
+ if ( apm || !apm->valid() ) {
+ apm->setTimeScale( animationSpeed );
+
+ unsigned int num = keyswitchManipulator->getNumMatrixManipulators();
+ keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm );
+ keyswitchManipulator->selectMatrixManipulator( num );
+ ++keyForAnimationPath;
+ }
+ }
+
+ viewer->setCameraManipulator( keyswitchManipulator.get() );
+ }
+
+ // add the state manipulator
+ viewer->addEventHandler( new osgGA::StateSetManipulator( viewer->getCamera()->getOrCreateStateSet() ) );
+
+ // add the thread model handler
+ viewer->addEventHandler( new osgViewer::ThreadingHandler );
+
+ // add the window size toggle handler
+ //viewer->addEventHandler(new osgViewer::WindowSizeHandler);
+
+ // add the stats handler
+ viewer->addEventHandler( new osgViewer::StatsHandler );
+
+ // add the help handler
+ viewer->addEventHandler( new osgViewer::HelpHandler( arguments.getApplicationUsage() ) );
+
+ // add the record camera path handler
+ viewer->addEventHandler( new osgViewer::RecordCameraPathHandler );
+
+ // add the LOD Scale handler
+ viewer->addEventHandler( new osgViewer::LODScaleHandler );
+
+ // add the screen capture handler
+ viewer->addEventHandler( new osgViewer::ScreenCaptureHandler );
+
+ // load the data
+ osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles( arguments );
+
+ if ( !loadedModel ) {
+ std::cout << arguments.getApplicationName() << ": No data loaded" << std::endl;
+ }
+ else {
+ osgUtil::Optimizer optimizer;
+ optimizer.optimize( loadedModel.get() );
+ viewer->setSceneData( loadedModel.get() );
+ }
+
+ // any option left unread are converted into errors to write out later.
+ arguments.reportRemainingOptionsAsUnrecognized();
+
+ // report any errors if they have occurred when parsing the program arguments.
+ if ( arguments.errors() ) {
+ arguments.writeErrorMessages( std::cerr );
+ }
+
+
+ /// TODO remove
+ viewer->setThreadingModel( osgViewer::Viewer::SingleThreaded ) ;
+ viewer->realize();
+
+
+ //viewer->setThreadingModel( osgViewer::Viewer::ThreadPerCamera );
+ //viewer->setThreadingModel( osgViewer::Viewer::DrawThreadPerContext ) ;
+
+ //viewer->run();
+ return viewer.release() ;
+}
+
+
+///
+///
+///
+void ViewerWidget::saveImageToFile()
+{
+ osgViewer::ScreenCaptureHandler::WriteToFile* writeToFileOperation = new osgViewer::ScreenCaptureHandler::WriteToFile(
+ "screenshot",
+ "png",
+ osgViewer::ScreenCaptureHandler::WriteToFile::SEQUENTIAL_NUMBER
+ );
+
+ osgViewer::ScreenCaptureHandler* captureHandler = new osgViewer::ScreenCaptureHandler( writeToFileOperation );
+ captureHandler->captureNextFrame( *this );
+}
+
+///
+///
+///
+void ViewerWidget::startAnimation()
+{
+ _timer.start( 20 ) ;
+}
+
+///
+///
+///
+void ViewerWidget::stopAnimation()
+{
+ _timer.stop();
+}
+
+}//viewer
+}//SFCGAL
diff --git a/viewer/src/SFCGAL/viewer/ViewerWindow.cpp b/viewer/src/SFCGAL/viewer/ViewerWindow.cpp
new file mode 100644
index 0000000..01028dd
--- /dev/null
+++ b/viewer/src/SFCGAL/viewer/ViewerWindow.cpp
@@ -0,0 +1,259 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <SFCGAL/viewer/ViewerWindow.h>
+#include <SFCGAL/viewer/ViewerWidget.h>
+#include <SFCGAL/viewer/ViewerPlugin.h>
+
+#include <SFCGAL/detail/tools/Log.h>
+
+#include <iostream>
+
+#include <QtGui/QApplication>
+#include <QtGui/QVBoxLayout>
+
+#include <QtGui/QFileDialog>
+
+
+#include <QtGui/QMenu>
+#include <QtGui/QMenuBar>
+#include <QtGui/QPixmap>
+#include <QtGui/QPainter>
+#include <QtGui/QImage>
+#include <QtGui/QMessageBox>
+
+
+#include <QtOpenGL/QGLFramebufferObject>
+#include <QtOpenGL/QGLWidget>
+
+#include <osgDB/ReadFile>
+#include <osgDB/WriteFile>
+
+#include <osgGA/OrbitManipulator>
+#include <SFCGAL/viewer/GISManipulator.h>
+
+namespace SFCGAL {
+namespace viewer {
+
+///
+///
+///
+ViewerWindow::ViewerWindow( ViewerWidget* viewer )
+{
+ setViewer( viewer );
+
+ createMenus();
+}
+
+///
+///
+///
+ViewerWindow::~ViewerWindow()
+{
+ for ( std::vector< ViewerPlugin* >::iterator it = _plugins.begin(); it != _plugins.end(); ++it ) {
+ ( *it )->unload();
+ delete *it ;
+ }
+
+ _plugins.clear();
+}
+
+///
+///
+///
+ViewerWidget* ViewerWindow::viewer()
+{
+ return _viewer ;
+}
+
+///
+///
+///
+void ViewerWindow::setViewer( ViewerWidget* viewer )
+{
+ _viewer = viewer ;
+
+ QWidget* centralWidget = new QWidget ;
+ QVBoxLayout* layout = new QVBoxLayout ;
+
+ if ( _viewer ) {
+ layout->addWidget( _viewer );
+ }
+
+ centralWidget->setLayout( layout );
+ setCentralWidget( centralWidget );
+}
+
+
+///
+///
+///
+void ViewerWindow::addPlugin( ViewerPlugin* plugin )
+{
+ BOOST_ASSERT( plugin != NULL );
+
+ SFCGAL_INFO( boost::format( "loading ViewerPlugin %1%..." ) % plugin->pluginName().toStdString() );
+
+ _plugins.push_back( plugin );
+ plugin->_viewerWindow = this ;
+ plugin->load() ;
+}
+
+
+
+///
+///
+///
+//void ViewerWindow::screenShot()
+//{
+// QImage image( viewer()->size(), QImage::Format_ARGB32 );
+// QPainter painter( &image );
+// centralWidget()->render( &painter ) ;
+// image.save("test.png","PNG");
+//}
+
+
+///
+///
+///
+void ViewerWindow::screenShot()
+{
+ viewer()->stopAnimation();
+ viewer()->saveImageToFile();
+ viewer()->startAnimation();
+}
+
+
+
+///
+///
+///
+void ViewerWindow::about()
+{
+ QApplication::aboutQt();
+}
+
+///
+///
+///
+void ViewerWindow::loadFile()
+{
+ viewer()->stopAnimation();
+
+ QString filename = QFileDialog::getOpenFileName( NULL,"select a file to open", QDir::currentPath() ) ;
+
+ osg::Node* node = osgDB::readNodeFile( filename.toStdString() );
+
+ if ( ! node ) {
+ QMessageBox::warning( this, "load file error", QString( "can't read file..." ) );
+ }
+ else {
+ node->setName( filename.toStdString() );
+ viewer()->getScene()->addChild( node );
+ }
+
+ viewer()->startAnimation();
+}
+
+
+///
+///
+///
+void ViewerWindow::saveFile()
+{
+ viewer()->stopAnimation();
+
+ QString filename = QFileDialog::getOpenFileName( NULL,"select save file name", QDir::currentPath() ) ;
+
+ if ( ! filename.isEmpty() ) {
+ osgDB::writeNodeFile( *viewer()->getScene(), filename.toStdString() );
+ }
+
+ viewer()->startAnimation();
+}
+
+///
+///
+///
+void ViewerWindow::toGISView()
+{
+ viewer()->setCameraManipulator( new GISManipulator(), /* resetPosition = */ true );
+}
+
+///
+///
+///
+void ViewerWindow::toFreeView()
+{
+ viewer()->setCameraManipulator( new osgGA::OrbitManipulator(), /* resetPosition = */ true );
+}
+
+///
+///
+///
+void ViewerWindow::createMenus()
+{
+ /*
+ * File menu
+ */
+ _menuFile = menuBar()->addMenu( "&File" ) ;
+
+ //-- load a file
+ QAction* actionLoadFile = _menuFile->addAction( "&Load a file..." );
+ connect( actionLoadFile, SIGNAL( triggered() ), this, SLOT( loadFile() ) );
+
+ //-- save as file
+ QAction* actionSaveFile = _menuFile->addAction( "&save to file..." );
+ connect( actionSaveFile, SIGNAL( triggered() ), this, SLOT( saveFile() ) );
+
+
+ //-- screenshot
+ QAction* actionSaveAsImage = _menuFile->addAction( "&Save as image..." );
+ connect( actionSaveAsImage, SIGNAL( triggered() ), this, SLOT( screenShot() ) );
+
+ _menuFile->addSeparator();
+ //-- exit
+ QAction* actionExit = _menuFile->addAction( "&Exit" );
+ connect( actionExit, SIGNAL( triggered() ), qApp, SLOT( quit() ) );
+
+ /*
+ * Display menu
+ */
+ QMenu* displayMenu = menuBar()->addMenu( "&Display" );
+ QAction* gisView = displayMenu->addAction( "GIS view\t0" );
+ connect( gisView, SIGNAL( triggered() ), this, SLOT( toGISView() ) );
+
+ QAction* freeView = displayMenu->addAction( "Free view\t1" );
+ connect( freeView, SIGNAL( triggered() ), this, SLOT( toFreeView() ) );
+
+ /*
+ * Help menu
+ */
+ _menuHelp = menuBar()->addMenu( "&Help" ) ;
+
+ //-- about
+ QAction* actionAbout = _menuHelp->addAction( "&About" );
+ connect( actionAbout, SIGNAL( triggered() ), this, SLOT( about() ) );
+}
+
+
+
+}//viewer
+}//SFCGAL
+
diff --git a/viewer/src/SFCGAL/viewer/plugins/DataPlugin.cpp b/viewer/src/SFCGAL/viewer/plugins/DataPlugin.cpp
new file mode 100644
index 0000000..b9122ef
--- /dev/null
+++ b/viewer/src/SFCGAL/viewer/plugins/DataPlugin.cpp
@@ -0,0 +1,103 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <SFCGAL/viewer/plugins/DataPlugin.h>
+#include <SFCGAL/viewer/ViewerWindow.h>
+#include <SFCGAL/viewer/ViewerWidget.h>
+
+#include <iostream>
+
+#include <QtGui/QMenu>
+#include <QtGui/QMenuBar>
+#include <QtGui/QInputDialog>
+
+
+namespace SFCGAL {
+namespace viewer {
+namespace plugins {
+
+///
+///
+///
+DataPlugin::DataPlugin()
+{
+
+}
+
+///
+///
+///
+QString DataPlugin::pluginName() const
+{
+ return QString( "DataPlugin" );
+}
+
+///
+///
+///
+void DataPlugin::displayNodeInformation( osg::Node* node, std::ostream& s, const size_t& depth )
+{
+ std::string indent ;
+
+ for ( size_t i = 0; i < depth; i++ ) {
+ indent += ' ';
+ }
+
+ s << indent << "Node[" << node->getName() << "]" << std::endl;
+ osg::Group* group = node->asGroup() ;
+
+ if ( group ) {
+ for ( size_t i = 0; i < group->getNumChildren(); i++ ) {
+ s << indent << "child[" << i << "]" << std::endl;
+ displayNodeInformation( group->getChild( i ), s, depth + 1 ) ;
+ }
+ }
+ else {
+ osg::Geode* geode = dynamic_cast< osg::Geode* >( node ) ;
+ s << indent << "Geode[" << geode->getBoundingBox().xMin() << " " << geode->getBoundingBox().xMax() << " " ;
+ s << geode->getBoundingBox().yMin() << " " << geode->getBoundingBox().yMax() << " " ;
+ s << geode->getBoundingBox().zMin() << " " << geode->getBoundingBox().zMax() << "]" << std::endl;
+ }
+}
+
+///
+///
+///
+void DataPlugin::displayInformations()
+{
+ displayNodeInformation( viewerWindow()->viewer()->getScene(), std::cout );
+}
+
+///
+///
+///
+void DataPlugin::load()
+{
+ QMenu* pluginMenu = viewerWindow()->menuBar()->addMenu( "Data" ) ;
+
+ QAction* actionDisplayInformations = pluginMenu->addAction( QString( "&display informations" ) );
+ connect( actionDisplayInformations, SIGNAL( triggered() ), this, SLOT( displayInformations() ) );
+}
+
+
+
+}//plugins
+}//viewer
+}//SFCGAL
+
diff --git a/viewer/src/SFCGAL/viewer/plugins/DemoPlugin.cpp b/viewer/src/SFCGAL/viewer/plugins/DemoPlugin.cpp
new file mode 100644
index 0000000..6775d57
--- /dev/null
+++ b/viewer/src/SFCGAL/viewer/plugins/DemoPlugin.cpp
@@ -0,0 +1,231 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <SFCGAL/viewer/plugins/DemoPlugin.h>
+#include <SFCGAL/viewer/ViewerWindow.h>
+#include <SFCGAL/viewer/ViewerWidget.h>
+
+#include <iostream>
+
+#include <QtGui/QMenu>
+#include <QtGui/QMenuBar>
+#include <QtGui/QInputDialog>
+
+#include <osg/Geode>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/LineString.h>
+#include <SFCGAL/Polygon.h>
+#include <SFCGAL/Triangle.h>
+#include <SFCGAL/PolyhedralSurface.h>
+#include <SFCGAL/TriangulatedSurface.h>
+#include <SFCGAL/Solid.h>
+#include <SFCGAL/GeometryCollection.h>
+#include <SFCGAL/MultiPoint.h>
+#include <SFCGAL/MultiLineString.h>
+#include <SFCGAL/MultiPolygon.h>
+#include <SFCGAL/MultiSolid.h>
+
+#include <SFCGAL/io/wkt.h>
+#include <SFCGAL/detail/io/OsgFactory.h>
+#include <SFCGAL/algorithm/extrude.h>
+#include <SFCGAL/algorithm/convexHull.h>
+
+
+namespace SFCGAL {
+namespace viewer {
+namespace plugins {
+
+///
+///
+///
+DemoPlugin::DemoPlugin():
+ ViewerPlugin()
+{
+
+}
+
+///
+///
+///
+QString DemoPlugin::pluginName() const
+{
+ return QString( "DemoPlugin" );
+}
+
+///
+///
+///
+void DemoPlugin::demoExtrude()
+{
+ QString wkt = QInputDialog::getText( NULL, QString( "Read WKT" ), QString( "Type WKT" ) );
+
+ if ( wkt.isEmpty() ) {
+ return ;
+ }
+
+ //parse wkt
+ std::auto_ptr< Geometry > g( io::readWkt( wkt.toStdString() ) );
+
+ //extrude
+ double h = QInputDialog::getDouble( NULL,"Height","Type height" );
+ std::auto_ptr< Geometry > ext( algorithm::extrude( *g,0.,0.,h ) );
+
+ //create osg::Geode
+ detail::io::OsgFactory factory ;
+ osg::Geometry* osgGeometry = factory.createGeometry( *ext );
+ osg::Geode* geode = new osg::Geode;
+ geode->setName( wkt.toStdString() );
+ geode->addDrawable( osgGeometry );
+
+ viewerWindow()->viewer()->getScene()->addChild( geode );
+}
+
+
+///
+///
+///
+void DemoPlugin::demoConvexhull()
+{
+ QString wkt = QInputDialog::getText( NULL, QString( "Read WKT" ), QString( "Type WKT" ) );
+
+ if ( wkt.isEmpty() ) {
+ return ;
+ }
+
+ //parse wkt
+ std::auto_ptr< Geometry > g( io::readWkt( wkt.toStdString() ) );
+
+ //build convexhull
+ std::auto_ptr< Geometry > hull( algorithm::convexHull3D( *g ) );
+
+ //create osg::Geode
+ detail::io::OsgFactory factory ;
+ osg::Geometry* osgGeometry = factory.createGeometry( *hull );
+ osg::Geode* geode = new osg::Geode;
+ geode->setName( wkt.toStdString() );
+ geode->addDrawable( osgGeometry );
+
+ viewerWindow()->viewer()->getScene()->addChild( geode );
+}
+
+///
+///
+///
+void DemoPlugin::demoSpiral()
+{
+ std::vector< Point > points ;
+
+ double r = 0.0 ;
+ double z = 0.0 ;
+ double theta = 0.0 ;
+
+ for ( size_t i = 0; i < 1000; i++ ) {
+ Point p( r*cos( theta ), r*sin( theta ), z );
+ points.push_back( p );
+
+ if ( i < 500 ) {
+ r += 0.01 ;
+ }
+ else {
+ r -= 0.01 ;
+ }
+
+ z += 0.01 ;
+ theta += 0.1 ;
+ }
+
+ LineString g( points );
+
+ /*
+ * Convert to osg::Geometry
+ */
+ detail::io::OsgFactory factory ;
+ osg::Geometry* osgGeometry = factory.createGeometry( g );
+
+
+ /*
+ * provide a color to osg::Geometry
+ */
+ osg::Vec3Array* colors = new osg::Vec3Array();
+ colors->push_back( osg::Vec3( 1.0f,0.0f,0.0f ) );
+ osgGeometry->setColorArray( colors );
+ osgGeometry->setColorBinding( osg::Geometry::BIND_OVERALL );
+
+ /*
+ * Create a named Geode (Geometric Node)
+ */
+ osg::Geode* geode = new osg::Geode;
+ geode->setName( "DemoPlugin::demoSpiral" );
+ geode->addDrawable( osgGeometry );
+
+ viewerWindow()->viewer()->getScene()->addChild( geode );
+}
+
+///
+///
+///
+void DemoPlugin::demoWkt()
+{
+ QString wkt = QInputDialog::getText( NULL, QString( "Read WKT" ), QString( "Type WKT" ) );
+
+ if ( wkt.isEmpty() ) {
+ return ;
+ }
+
+ //parse
+ std::auto_ptr< Geometry > g( io::readWkt( wkt.toStdString() ) );
+ detail::io::OsgFactory factory ;
+
+ osg::Geometry* osgGeometry = factory.createGeometry( *g );
+ osg::Geode* geode = new osg::Geode;
+ geode->setName( wkt.toStdString() );
+ geode->addDrawable( osgGeometry );
+
+ viewerWindow()->viewer()->getScene()->addChild( geode );
+}
+
+
+///
+///
+///
+void DemoPlugin::load()
+{
+ QMenu* pluginMenu = viewerWindow()->menuBar()->addMenu( "DemoPlugin" ) ;
+
+ QAction* actionExtrude = pluginMenu->addAction( QString( "&extrude" ) );
+ connect( actionExtrude, SIGNAL( triggered() ), this, SLOT( demoExtrude() ) );
+
+ QAction* actionConvexhull = pluginMenu->addAction( QString( "&convexhull" ) );
+ connect( actionConvexhull, SIGNAL( triggered() ), this, SLOT( demoConvexhull() ) );
+
+
+ QAction* actionReadWkt = pluginMenu->addAction( QString( "&read wkt" ) );
+ connect( actionReadWkt, SIGNAL( triggered() ), this, SLOT( demoWkt() ) );
+
+ QAction* actionDemoSpiral = pluginMenu->addAction( QString( "&create a spiral" ) );
+ connect( actionDemoSpiral, SIGNAL( triggered() ), this, SLOT( demoSpiral() ) );
+}
+
+
+
+}//plugins
+}//viewer
+}//SFCGAL
+
diff --git a/viewer/src/SFCGAL/viewer/plugins/GridPlugin.cpp b/viewer/src/SFCGAL/viewer/plugins/GridPlugin.cpp
new file mode 100644
index 0000000..0d64f39
--- /dev/null
+++ b/viewer/src/SFCGAL/viewer/plugins/GridPlugin.cpp
@@ -0,0 +1,122 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <SFCGAL/viewer/plugins/GridPlugin.h>
+
+#include <SFCGAL/Point.h>
+#include <SFCGAL/MultiPoint.h>
+
+#include <SFCGAL/viewer/ViewerWindow.h>
+#include <SFCGAL/viewer/ViewerWidget.h>
+
+#include <fstream>
+
+#include <SFCGAL/detail/io/OsgFactory.h>
+
+#include <QtGui/QMenu>
+#include <QtGui/QMenuBar>
+#include <QtGui/QInputDialog>
+#include <QtGui/QMessageBox>
+#include <QtGui/QFileDialog>
+
+#include <osgUtil/Optimizer>
+
+namespace SFCGAL {
+namespace viewer {
+namespace plugins {
+
+///
+///
+///
+GridPlugin::GridPlugin()
+{
+
+}
+
+///
+///
+///
+QString GridPlugin::pluginName() const
+{
+ return "GridPlugin";
+}
+
+///
+///
+///
+void GridPlugin::loadGridXYZ()
+{
+ viewerWindow()->viewer()->stopAnimation();
+ QString filename = QFileDialog::getOpenFileName( NULL, QString( "Open XYZ grid file" ) );
+
+ std::ifstream ifs( filename.toStdString().c_str() );
+
+ if ( ! ifs.good() ) {
+ QMessageBox::warning( NULL, QString( "load grid XYZ" ), QString( "can't load file" ) ) ;
+ }
+
+ MultiPoint multiPoint ;
+ double x, y, z ;
+
+ while ( ! ifs.eof() && ( ifs >> x >> y >> z ) ) {
+ if ( z == 0.0 ) {
+ continue ;
+ }
+
+ multiPoint.addGeometry( Point( x,y,z ) );
+ }
+
+ ifs.close();
+
+ //create OSG geometry
+ detail::io::OsgFactory factory ;
+ osg::Geode* geode = new osg::Geode();
+ geode->setName( filename.toStdString() );
+
+ geode->addDrawable( factory.createGeometry( multiPoint ) );
+
+ osgUtil::Optimizer optimizer ;
+ optimizer.optimize( geode );
+
+ geode->setCullingActive( false );
+
+ viewerWindow()->viewer()->getScene()->addChild( geode );
+
+
+ viewerWindow()->viewer()->startAnimation();
+}
+
+///
+///
+///
+void GridPlugin::load()
+{
+ QMenu* pluginMenu = viewerWindow()->menuBar()->addMenu( "GridPlugin" ) ;
+
+ QAction* actionLoadXYZ = pluginMenu->addAction( QString( "&load xyz" ) );
+ connect( actionLoadXYZ, SIGNAL( triggered() ), this, SLOT( loadGridXYZ() ) );
+}
+
+
+}//plugins
+}//viewer
+}//SFCGAL
+
+
+
diff --git a/viewer/src/SFCGAL/viewer/plugins/PSQLPlugin.cpp b/viewer/src/SFCGAL/viewer/plugins/PSQLPlugin.cpp
new file mode 100644
index 0000000..f335e47
--- /dev/null
+++ b/viewer/src/SFCGAL/viewer/plugins/PSQLPlugin.cpp
@@ -0,0 +1,553 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <iostream>
+
+#include <SFCGAL/viewer/plugins/PSQLPlugin.h>
+#include <SFCGAL/viewer/ViewerWindow.h>
+#include <SFCGAL/viewer/ViewerWidget.h>
+#include <SFCGAL/detail/io/OsgFactory.h>
+#include <SFCGAL/io/wkt.h>
+
+#include <osg/Geode>
+
+#include <QtGui/QMenu>
+#include <QtGui/QLabel>
+#include <QtGui/QMenuBar>
+#include <QtGui/QInputDialog>
+#include <QtGui/QMessageBox>
+#include <QtGui/QFileDialog>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QApplication>
+
+#include "db.h"
+
+namespace SFCGAL {
+namespace viewer {
+namespace plugins {
+
+struct LayerInfo {
+ LayerInfo() : query( "" ), geode( 0 ) {}
+ std::string dbOptions;
+ std::string query;
+ osg::ref_ptr<osg::Geode> geode;
+};
+
+SQLConsole::SQLConsole( PSQLPlugin* plugin ) : QDockWidget( NULL ), plugin_( plugin )
+{
+ setMinimumSize( QSize( 300, 50 ) );
+ setWindowTitle( "SQL Console" );
+
+ QWidget* dockWidgetContents = new QWidget();
+ dockWidgetContents->setObjectName( QString::fromUtf8( "dockWidgetContents" ) );
+ QVBoxLayout* verticalLayout_2 = new QVBoxLayout( dockWidgetContents );
+ verticalLayout_2->setObjectName( QString::fromUtf8( "verticalLayout_2" ) );
+
+ QLabel* lbl1 = new QLabel( "DB options" );
+ verticalLayout_2->addWidget( lbl1 );
+
+ QHBoxLayout* hbox2 = new QHBoxLayout();
+ dbOptions_ = new QLineEdit( dockWidgetContents );
+ hbox2->addWidget( dbOptions_ );
+
+ connectBtn_ = new QPushButton( dockWidgetContents );
+ connectBtn_->setText( "&Connect" );
+ hbox2->addWidget( connectBtn_ );
+ verticalLayout_2->addItem( hbox2 );
+
+ QLabel* lbl2 = new QLabel( "SQL" );
+ verticalLayout_2->addWidget( lbl2 );
+
+ sqlEdit_ = new QPlainTextEdit( dockWidgetContents );
+ sqlEdit_->setObjectName( QString::fromUtf8( "sqlEdit" ) );
+ sqlEdit_->setMinimumSize( QSize( 200, 0 ) );
+
+ verticalLayout_2->addWidget( sqlEdit_ );
+
+ QHBoxLayout* horizontalLayout = new QHBoxLayout();
+ horizontalLayout->setObjectName( QString::fromUtf8( "horizontalLayout" ) );
+ QSpacerItem* horizontalSpacer = new QSpacerItem( 40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
+
+ horizontalLayout->addItem( horizontalSpacer );
+
+ okBtn_ = new QPushButton( dockWidgetContents );
+ okBtn_->setObjectName( QString::fromUtf8( "okBtn" ) );
+ okBtn_->setText( "&Edit" );
+
+ horizontalLayout->addWidget( okBtn_ );
+
+ verticalLayout_2->addLayout( horizontalLayout );
+
+ setWidget( dockWidgetContents );
+
+ dbOptions_->setEnabled( false );
+ sqlEdit_->setEnabled( false );
+ okBtn_->setEnabled( false );
+
+ // connect signal
+ connect( okBtn_, SIGNAL( clicked() ), this, SLOT( onQuery() ) );
+ connect( connectBtn_, SIGNAL( clicked() ), this, SLOT( onReconnect() ) );
+}
+
+void SQLConsole::connectItem( QListWidgetItem* item )
+{
+ item_ = item;
+ dbOptions_->setEnabled( true );
+ connectBtn_->setEnabled( true );
+ sqlEdit_->setEnabled( true );
+ okBtn_->setText( "&Ok" );
+ okBtn_->setEnabled( true );
+ // disconnect from the db
+ disconnect();
+
+ sqlEdit_->clear();
+ LayerInfo* linfo = ( LayerInfo* )item_->data( Qt::UserRole ).value<void*>();
+
+ dbOptions_->setText( QString::fromStdString( linfo->dbOptions ) );
+ sqlEdit_->appendPlainText( QString::fromStdString( linfo->query ) );
+}
+
+void SQLConsole::disconnectItem()
+{
+ item_ = 0;
+ dbOptions_->setEnabled( false );
+ sqlEdit_->setEnabled( false );
+ okBtn_->setText( "&Edit" );
+ okBtn_->setEnabled( false );
+ connectBtn_->setEnabled( false );
+}
+
+void SQLConsole::onReconnect()
+{
+ plugin_->disconnect();
+ plugin_->connect( dbOptions_->text().toStdString() );
+}
+
+void SQLConsole::onQuery()
+{
+ plugin_->connect( dbOptions_->text().toStdString() );
+ osg::Geode* geode = plugin_->doQuery( sqlEdit_->toPlainText().toStdString() );
+
+ // store the query and its result
+ LayerInfo* linfo = ( LayerInfo* )item_->data( Qt::UserRole ).value<void*>();
+ linfo->query = sqlEdit_->toPlainText().toStdString();
+ linfo->dbOptions = dbOptions_->text().toStdString();
+ linfo->geode = osg::ref_ptr<osg::Geode>( geode );
+
+ // refresh the display
+ plugin_->display();
+}
+
+LayersWidget::LayersWidget( PSQLPlugin* plugin, SQLConsole* console ) : console_( console ), plugin_( plugin )
+{
+ setMinimumSize( QSize( 100, 50 ) );
+
+ QWidget* dockWidgetContents = new QWidget();
+ dockWidgetContents->setObjectName( QString::fromUtf8( "dockWidgetContents" ) );
+ QVBoxLayout* verticalLayout = new QVBoxLayout( dockWidgetContents );
+ verticalLayout->setObjectName( QString::fromUtf8( "verticalLayout" ) );
+ listWidget_ = new QListWidget( dockWidgetContents );
+ listWidget_->setObjectName( QString::fromUtf8( "listWidget" ) );
+
+ addBtn_ = new QPushButton( dockWidgetContents );
+ addBtn_->setText( "&Add" );
+
+ verticalLayout->addWidget( addBtn_ );
+ verticalLayout->addWidget( listWidget_ );
+
+ setWidget( dockWidgetContents );
+ setWindowTitle( "Layers" );
+
+ // connect signal
+ connect( addBtn_, SIGNAL( clicked() ), this, SLOT( onAdd() ) );
+
+ //
+ connect( listWidget_, SIGNAL( pressed( const QModelIndex& ) ), this, SLOT( onClick( const QModelIndex& ) ) );
+}
+
+void LayersWidget::addLayer( const QString& name, bool visible, const QString& dbOptions, const QString& query )
+{
+ QListWidgetItem* item = new QListWidgetItem( name );
+ item->setFlags( item->flags() | Qt::ItemIsUserCheckable | Qt::ItemIsEditable );
+
+ if ( visible ) {
+ item->setCheckState( Qt::Checked );
+ }
+ else {
+ item->setCheckState( Qt::Unchecked );
+ }
+
+ LayerInfo* linfo = new LayerInfo;
+ linfo->dbOptions = dbOptions.toStdString();
+ linfo->query = query.toStdString();
+ item->setData( Qt::UserRole, qVariantFromValue( ( void* )linfo ) );
+ listWidget_->addItem( item );
+}
+
+void LayersWidget::onAdd()
+{
+ addLayer( "layer", true, "", "" );
+}
+
+void LayersWidget::onClick( const QModelIndex& /*idx*/ )
+{
+ if ( QApplication::mouseButtons() & Qt::RightButton ) {
+ QMenu* menu = new QMenu;
+ QAction* removeAction = menu->addAction( "&Remove" );
+ connect( removeAction, SIGNAL( triggered() ), this, SLOT( onRemove() ) );
+ QAction* zoomAction = menu->addAction( "&Zoom to layer extent" );
+ connect( zoomAction, SIGNAL( triggered() ), this, SLOT( onZoomToLayer() ) );
+
+ menu->popup( QCursor::pos() );
+ }
+ else {
+ // left button
+ onEdit();
+ }
+}
+
+void LayersWidget::onEdit()
+{
+ // std::cout << "edit " << listWidget_->currentRow() << std::endl;
+ console_->connectItem( listWidget_->item( listWidget_->currentRow() ) );
+}
+
+void LayersWidget::onRemove()
+{
+ console_->disconnectItem();
+
+ int current = listWidget_->currentRow();
+ QListWidgetItem* widget = listWidget_->item( current );
+ listWidget_->removeItemWidget( widget );
+ delete widget;
+}
+
+void LayersWidget::onZoomToLayer()
+{
+ int current = listWidget_->currentRow();
+ QListWidgetItem* item = listWidget_->item( current );
+ LayerInfo* linfo = ( LayerInfo* )item->data( Qt::UserRole ).value<void*>();
+
+ if ( linfo->geode ) {
+ const osg::BoundingBox& bbox = linfo->geode->getBoundingBox();
+ std::cout << bbox.xMin() << " ; " << bbox.xMax() << " " << bbox.yMin() << " ; " << bbox.yMax() << " " << bbox.zMin() << " ; " << bbox.zMax() << std::endl;
+ std::cout << bbox.center()[0] << " " << bbox.center()[1] << " " << bbox.center()[2] << std::endl;
+ plugin_->viewerWindow()->viewer()->setCameraToExtent( bbox );
+ }
+}
+
+std::string wkbToWkt( const std::string& wkb, const Db::Connection& db )
+{
+ // wkb is a hex textual representation of a binary array
+ std::string q = "SELECT ST_AsText(ST_GeomFromEWKB('\\x" + wkb + "'))";
+ // temporary : use a PostGIS query to convert from wkb to wkt
+ Db::Result r = db.exec( q );
+
+ if ( r.size() == 1 ) {
+ return r[0][0].as<std::string>();
+ }
+
+ return "";
+}
+
+
+struct Color {
+ Color( float r, float g, float b ) : r( r ), g( g ), b( b ) {}
+ float r, g, b;
+};
+
+//
+// The Pimpl class for this plugin
+struct PSQLPluginImpl {
+ PSQLPluginImpl( PSQLPlugin* super ) : geometry_oid_( 0 ), console( 0 ), layers( 0 ), isConnected( false ), super_( super ) {
+ colors.push_back( Color( 1.0, 0.0, 0.0 ) );
+ colors.push_back( Color( 0.0, 1.0, 0.0 ) );
+ colors.push_back( Color( 0.0, 0.0, 1.0 ) );
+ colors.push_back( Color( 1.0, 1.0, 0.0 ) );
+ colors.push_back( Color( 0.0, 1.0, 1.0 ) );
+ colors.push_back( Color( 1.0, 0.0, 1.0 ) );
+ }
+ unsigned geometry_oid_;
+ std::vector<Color> colors;
+ Db::Connection db;
+ SQLConsole* console;
+ LayersWidget* layers;
+ bool isConnected;
+
+ PSQLPlugin* super_;
+};
+
+///
+///
+///
+PSQLPlugin::PSQLPlugin() : impl_( new PSQLPluginImpl( this ) )
+{
+
+}
+
+
+PSQLPlugin::~PSQLPlugin()
+{
+ delete impl_;
+}
+
+void PSQLPlugin::launchConsole()
+{
+ impl_->console = new SQLConsole( this );
+ viewerWindow()->addDockWidget( Qt::BottomDockWidgetArea, impl_->console );
+ impl_->layers = new LayersWidget( this, impl_->console );
+ viewerWindow()->addDockWidget( Qt::LeftDockWidgetArea, impl_->layers );
+}
+
+void PSQLPlugin::connect( const std::string& db_options )
+{
+ if ( impl_->isConnected ) {
+ return;
+ }
+
+ try {
+ impl_->db.connect( db_options );
+ }
+ catch ( std::exception& e ) {
+ std::cerr << e.what() << std::endl;
+ return;
+ }
+
+ //
+ // get geometry type oid
+ Db::Result r = impl_->db.exec( "SELECT oid FROM pg_type WHERE typname='geometry'" );
+
+ if ( r.size() == 0 ) {
+ std::cerr << "Not a PostGIS database" << std::endl;
+ return;
+ }
+
+ impl_->geometry_oid_ = r[0][0].as<unsigned>();
+ impl_->isConnected = true;
+}
+
+void PSQLPlugin::disconnect()
+{
+ impl_->isConnected = false;
+}
+
+osg::Geode* PSQLPlugin::doQuery( const std::string& query )
+{
+ Db::Result r;
+
+ try {
+ r = impl_->db.exec( query );
+ }
+ catch ( std::runtime_error& e ) {
+ std::cerr << e.what() << std::endl;
+ return 0;
+ }
+
+ detail::io::OsgFactory factory;
+ osg::ref_ptr<osg::Geode> geode( new osg::Geode );
+
+ try {
+
+ std::cout << "# of rows: " << r.size() << std::endl;
+
+ for ( size_t i = 0; i < r.size(); ++i ) {
+ for ( size_t j = 0; j < r.columns(); ++j ) {
+ std::string geomWkt;
+
+ if ( PQftype( r.result(), j ) == impl_->geometry_oid_ ) {
+ geomWkt = wkbToWkt( r[i][j].as<std::string>(), impl_->db );
+ }
+ else {
+ geomWkt = r[i][j].as<std::string>();
+ }
+
+ std::auto_ptr<Geometry> g = ( io::readWkt( geomWkt ) );
+ osg::Geometry* osgGeo = factory.createGeometry( *g );
+
+ osg::Vec4Array* colors = new osg::Vec4Array;
+ // Each column has a color
+ const Color& c = impl_->colors[ j % impl_->colors.size() ];
+ colors->push_back( osg::Vec4( c.r, c.g, c.b, 1.0f ) );
+ osgGeo->setColorArray( colors );
+ osgGeo->setColorBinding( osg::Geometry::BIND_OVERALL );
+
+ geode->addDrawable( osgGeo );
+ }
+ }
+
+ }
+ catch ( std::exception& e ) {
+ std::cerr << e.what() << std::endl;
+ return 0;
+ }
+
+ return geode.release();
+}
+
+void PSQLPlugin::computeGeometries()
+{
+ // iterate through the layers
+ QListWidget* listWidget = impl_->layers->widget();
+
+ for ( int i = 0; i < listWidget->count(); ++i ) {
+ QListWidgetItem* item = listWidget->item( i );
+ LayerInfo* linfo = ( LayerInfo* )item->data( Qt::UserRole ).value<void*>();
+
+ disconnect();
+ connect( linfo->dbOptions );
+ linfo->geode = osg::ref_ptr<osg::Geode>( doQuery( linfo->query ) );
+ }
+}
+
+void PSQLPlugin::display()
+{
+ if ( impl_->layers == 0 ) {
+ return;
+ }
+
+ osg::Group* root = viewerWindow()->viewer()->getScene();
+ // remove all children
+ root->removeChildren( 0, root->getNumChildren() );
+
+ // iterate through the layers
+ QListWidget* listWidget = impl_->layers->widget();
+
+ for ( int i = 0; i < listWidget->count(); ++i ) {
+ QListWidgetItem* item = listWidget->item( i );
+ LayerInfo* linfo = ( LayerInfo* )item->data( Qt::UserRole ).value<void*>();
+ bool visible = item->data( Qt::CheckStateRole ).toBool();
+ std::cout << "visible = " << visible << std::endl;
+
+ if ( visible && linfo->geode != 0 ) {
+ root->addChild( linfo->geode );
+ }
+ }
+}
+
+void PSQLPlugin::onRefresh()
+{
+ display();
+}
+///
+///
+///
+QString PSQLPlugin::pluginName() const
+{
+ return "PSQLPlugin";
+}
+
+void PSQLPlugin::saveLayers()
+{
+ if ( impl_->layers == 0 ) {
+ launchConsole();
+ }
+
+ viewerWindow()->viewer()->stopAnimation();
+ QString filename = QFileDialog::getSaveFileName( NULL, QString( "Choose a layers file to save to" ) );
+
+ QFile file( filename );
+ file.open( QIODevice::ReadWrite );
+ QDataStream stream( &file );
+
+ // iterate through the layers
+ QListWidget* listWidget = impl_->layers->widget();
+
+ // write the number of layers
+ stream << listWidget->count();
+
+ for ( int i = 0; i < listWidget->count(); ++i ) {
+ QListWidgetItem* item = listWidget->item( i );
+ QString name = item->text();
+ LayerInfo* linfo = ( LayerInfo* )item->data( Qt::UserRole ).value<void*>();
+ bool visible = item->data( Qt::CheckStateRole ).toBool();
+
+ // write the layer's data
+ stream << name << visible << QString::fromStdString( linfo->dbOptions ) << QString::fromStdString( linfo->query );
+ }
+
+ file.flush();
+ viewerWindow()->viewer()->startAnimation();
+}
+
+void PSQLPlugin::loadLayers()
+{
+ if ( impl_->layers == 0 ) {
+ launchConsole();
+ }
+
+ viewerWindow()->viewer()->stopAnimation();
+ QString filename = QFileDialog::getOpenFileName( NULL, QString( "Choose file to load layers from" ) );
+ QFile file( filename );
+ file.open( QIODevice::ReadOnly );
+ QDataStream str( &file );
+
+ // iterate through the layers
+ QListWidget* listWidget = impl_->layers->widget();
+
+ // clear the list
+ listWidget->clear();
+
+ // number of layers
+ int count;
+ str >> count;
+
+ for ( int i = 0; i < count; ++i ) {
+ QString name, dbOptions, query;
+ bool visible;
+
+ // read the layer's data
+ str >> name >> visible >> dbOptions >> query;
+ impl_->layers->addLayer( name, visible, dbOptions, query );
+ }
+
+ file.flush();
+
+ //
+ computeGeometries();
+ display();
+
+ impl_->console->disconnectItem();
+ viewerWindow()->viewer()->startAnimation();
+}
+
+void PSQLPlugin::load()
+{
+ QMenu* pluginMenu = viewerWindow()->menuBar()->addMenu( "PostGIS" ) ;
+
+ QAction* action = pluginMenu->addAction( QString( "&SQL console" ) );
+ QObject::connect( action, SIGNAL( triggered() ), this, SLOT( launchConsole() ) );
+
+ QAction* saveAction = pluginMenu->addAction( QString( "&Save layers" ) );
+ QObject::connect( saveAction, SIGNAL( triggered() ), this, SLOT( saveLayers() ) );
+
+ QAction* loadAction = pluginMenu->addAction( QString( "&Load layers" ) );
+ QObject::connect( loadAction, SIGNAL( triggered() ), this, SLOT( loadLayers() ) );
+
+ QAction* refreshAction = pluginMenu->addAction( QString( "&Refresh display\tF5" ) );
+ refreshAction->setShortcut( QKeySequence( "F5" ) );
+ QObject::connect( refreshAction, SIGNAL( triggered() ), this, SLOT( onRefresh() ) );
+}
+
+
+}//plugins
+}//viewer
+}//SFCGAL
+
+
+
diff --git a/viewer/src/db.cpp b/viewer/src/db.cpp
new file mode 100644
index 0000000..bdd0369
--- /dev/null
+++ b/viewer/src/db.cpp
@@ -0,0 +1,66 @@
+/**
+ * SFCGAL
+ *
+ * Copyright (C) 2012-2013 Oslandia <infos at oslandia.com>
+ * Copyright (C) 2012-2013 IGN (http://www.ign.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <iostream>
+
+#include "db.h"
+
+namespace Db {
+template <>
+bool Value::as<bool>()
+{
+ return std::string( value_, len_ ) == "t" ? true : false;
+}
+
+template <>
+std::string Value::as<std::string>()
+{
+ return std::string( value_, len_ );
+}
+
+template <>
+long long Value::as<long long>()
+{
+ long long v;
+ sscanf( value_, "%Ld", &v );
+ return v;
+}
+template <>
+int Value::as<int>()
+{
+ int v;
+ sscanf( value_, "%d", &v );
+ return v;
+}
+template <>
+float Value::as<float>()
+{
+ float v;
+ sscanf( value_, "%f", &v );
+ return v;
+}
+template <>
+double Value::as<double>()
+{
+ double v;
+ sscanf( value_, "%lf", &v );
+ return v;
+}
+
+}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/sfcgal.git
More information about the Pkg-grass-devel
mailing list