diff --git a/Code/redblood/Mesh.cc b/Code/redblood/Mesh.cc index dd129481e..b5fa5ce6f 100644 --- a/Code/redblood/Mesh.cc +++ b/Code/redblood/Mesh.cc @@ -19,6 +19,8 @@ #include "constants.h" #include #include +#include +#include namespace hemelb { @@ -141,7 +143,7 @@ namespace hemelb return result; } - std::shared_ptr readVTKMesh(std::string const &filename) + std::shared_ptr readVTKMesh(std::string const &filename, bool fixFacetOrientation) { log::Logger::Log("Reading red blood cell from %s", filename.c_str()); @@ -149,19 +151,28 @@ namespace hemelb if (!util::file_exists(filename.c_str())) throw Exception() << "Red-blood-cell mesh file '" << filename.c_str() << "' does not exist"; + std::shared_ptr meshData; + vtkSmartPointer polyData; + std::tie(meshData, polyData) = readMeshDataFromVTKPolyData(filename); + + if (fixFacetOrientation) + { + orientFacets(*meshData, *polyData); + } + + return meshData; + } + + std::tuple, vtkSmartPointer > readMeshDataFromVTKPolyData(std::string const &filename) + { + log::Logger::Log("Reading red blood cell from VTK polydata file"); + // Read in VTK polydata object vtkSmartPointer reader = vtkSmartPointer::New(); reader->SetFileName(filename.c_str()); reader->Update(); // TODO: check that the file read succeeded, e.g. wrong format - vtkPolyData* polydata = reader->GetOutput(); - - return readVTKMesh(polydata); - } - - std::shared_ptr readVTKMesh(vtkPolyData* polydata, bool fixFacetOrientation) - { - log::Logger::Log("Reading red blood cell from polydata object"); + vtkSmartPointer polydata(reader->GetOutput()); // Number of vertices unsigned int num_vertices = polydata->GetNumberOfPoints(); @@ -207,12 +218,7 @@ namespace hemelb num_vertices, num_facets); - if (fixFacetOrientation) - { - // TODO: Write new implementation of orientFacets that uses the VTK algorithm to work out what's the outward pointing normal - orientFacets(*result); - } - return result; + return std::make_tuple(result, polydata); } @@ -757,6 +763,8 @@ namespace hemelb } void orientFacets(MeshData &mesh, bool outward) { + log::Logger::Log("orientFacets method for meshes constructed from a .msh file has been deprecated. Consider using VTK input files instead."); + // create a new mesh at slighly smaller scale MeshData smaller(mesh); auto const scale = 0.99; @@ -784,7 +792,44 @@ namespace hemelb std::swap(facet[0], facet[2]); } } + } + unsigned orientFacets(MeshData &mesh, vtkPolyData &polydata, bool outward) + { + vtkSmartPointer normalCalculator = vtkSmartPointer::New(); + normalCalculator->SetInputData(&polydata); + normalCalculator->ComputePointNormalsOff(); + normalCalculator->ComputeCellNormalsOn(); + normalCalculator->SetAutoOrientNormals(1); + normalCalculator->Update(); + auto normals = normalCalculator->GetOutput()->GetCellData()->GetNormals(); + + assert(normals->GetNumberOfComponents() == 3); + assert(normals->GetNumberOfTuples() == mesh.facets.size()); + + // Loop over each facet, checks orientation and modify as appropriate + unsigned normalId = 0; + unsigned numSwapped = 0; + for (auto &facet : mesh.facets) + { + auto const &v0 = mesh.vertices[facet[0]]; + auto const &v1 = mesh.vertices[facet[1]]; + auto const &v2 = mesh.vertices[facet[2]]; + double vtkNormal[3]; + normals->GetTuple(normalId, vtkNormal); + LatticePosition direction(vtkNormal[0], vtkNormal[1], vtkNormal[2]); + + if ( ( (v0 - v1).Cross(v2 - v1).Dot(direction) > 0e0) xor outward) + { + std::swap(facet[0], facet[2]); + ++numSwapped; + } + + ++normalId; + } + + return numSwapped; } + } } // hemelb::redblood diff --git a/Code/redblood/Mesh.h b/Code/redblood/Mesh.h index 062c37672..cf9e936e2 100644 --- a/Code/redblood/Mesh.h +++ b/Code/redblood/Mesh.h @@ -56,8 +56,10 @@ namespace hemelb LatticeVolume volume(MeshData::Vertices const &vertices, MeshData::Facets const &facets); LatticeArea area(MeshData const &mesh); LatticeArea area(MeshData::Vertices const &vertices, MeshData::Facets const &facets); - //! Orients facet inward, or inward + //! DEPRECATED. Orients facets outward, or inward. Algorithm cannot handle case of facet being coplanar with mesh barycenter. void orientFacets(MeshData &mesh, bool outward = true); + //! Orients facets inwards/outwards using VTK algorithm to determining outward facing direction. MeshData object should have been constructed from vtkPolyData object. See readMeshDataFromVTKPolyData. + unsigned orientFacets(MeshData &mesh, vtkPolyData &polydata, bool outward = true); //! Holds raw topology data class MeshTopology @@ -240,8 +242,8 @@ namespace hemelb std::shared_ptr readMesh(std::istream &stream, util::UnitConverter const &); //! Read VTK mesh from file - std::shared_ptr readVTKMesh(std::string const &filename); - std::shared_ptr readVTKMesh(vtkPolyData* polydata, bool fixFacetOrientation=true); + std::shared_ptr readVTKMesh(std::string const &filename, bool fixFacetOrientation=true); + std::tuple, vtkSmartPointer > readMeshDataFromVTKPolyData(std::string const &filename); //! Write mesh from file //! Format is from T. Krueger's thesis diff --git a/Code/unittests/CMakeLists.txt b/Code/unittests/CMakeLists.txt index 34cd46b7d..938d26d03 100644 --- a/Code/unittests/CMakeLists.txt +++ b/Code/unittests/CMakeLists.txt @@ -91,4 +91,5 @@ add_to_resources(resources/four_cube.gmy resources/four_cube.xml resources/rbc_ico_720.msh resources/rbc_ico_720.vtp resources/992Particles_rank3_26_t992.msh + resources/992Particles_rank3_26_t992.vtp ) diff --git a/Code/unittests/redblood/RedBloodMeshVTKDataIOTests.h b/Code/unittests/redblood/RedBloodMeshVTKDataIOTests.h index ef8fe7146..518d7eb56 100644 --- a/Code/unittests/redblood/RedBloodMeshVTKDataIOTests.h +++ b/Code/unittests/redblood/RedBloodMeshVTKDataIOTests.h @@ -17,6 +17,7 @@ #include "resources/Resource.h" #include "util/UnitConverter.h" #include "unittests/redblood/Fixtures.h" +#include namespace hemelb { @@ -31,14 +32,13 @@ namespace hemelb { CPPUNIT_TEST_SUITE (RedBloodMeshVTKDataIOTests); CPPUNIT_TEST (testVTPReadMesh); - //CPPUNIT_TEST (testVTPWriteMesh); + CPPUNIT_TEST (testOrientOriginalRBCMesh); + CPPUNIT_TEST (testOrientTimmSimRBCMesh); CPPUNIT_TEST_SUITE_END(); public: void setUp() { - std::string filename = resources::Resource("rbc_ico_720.vtp").Path(); - mesh = readVTKMesh(filename); } void tearDown() @@ -47,6 +47,9 @@ namespace hemelb void testVTPReadMesh() { + std::string filename = resources::Resource("rbc_ico_720.vtp").Path(); + std::shared_ptr mesh = readVTKMesh(filename); + CPPUNIT_ASSERT(mesh); CPPUNIT_ASSERT_EQUAL(mesh->vertices.size(), 362ul); CPPUNIT_ASSERT_EQUAL(mesh->facets.size(), 720ul); @@ -65,23 +68,33 @@ namespace hemelb CPPUNIT_ASSERT(any(mesh->facets.back(), 157)); } -// void testWriteMesh() -// { -// std::ostringstream output; -// writeMesh(output, *mesh, util::UnitConverter(1, 1, LatticePosition(0, 0, 0))); -// std::istringstream input(output.str()); -// std::shared_ptr other = readMesh(input); -// CPPUNIT_ASSERT(other->vertices.size() == mesh->vertices.size()); -// CPPUNIT_ASSERT(other->facets.size() == mesh->facets.size()); -// CPPUNIT_ASSERT(compare(mesh->vertices.front() - other->vertices.front())); -// CPPUNIT_ASSERT(compare(mesh->vertices.back() - other->vertices.back())); -// -// for (size_t i(0); i < 3; ++i) -// { -// CPPUNIT_ASSERT(mesh->facets.front()[i] == other->facets.front()[i]); -// CPPUNIT_ASSERT(mesh->facets.back()[i] == other->facets.back()[i]); -// } -// } + void testOrientOriginalRBCMesh() + { + // This file has 684 out of 720 faces oriented inwards + std::string filename = resources::Resource("rbc_ico_720.vtp").Path(); + + std::shared_ptr meshData; + vtkSmartPointer polyData; + std::tie(meshData, polyData) = readMeshDataFromVTKPolyData(filename); + + auto numSwaps = orientFacets(*meshData, *polyData); + + CPPUNIT_ASSERT_EQUAL(numSwaps, 684u); + } + + void testOrientTimmSimRBCMesh() + { + // This file has all 720 faces oriented inwards + std::string filename = resources::Resource("992Particles_rank3_26_t992.vtp").Path(); + + std::shared_ptr meshData; + vtkSmartPointer polyData; + std::tie(meshData, polyData) = readMeshDataFromVTKPolyData(filename); + + auto numSwaps = orientFacets(*meshData, *polyData); + + CPPUNIT_ASSERT_EQUAL(numSwaps, 720u); + } static bool compare(util::Vector3D const &in) { @@ -92,8 +105,6 @@ namespace hemelb return vec[0] == value or vec[1] == value or vec[2] == value; } - private: - std::shared_ptr mesh; }; diff --git a/Code/unittests/resources/992Particles_rank3_26_t992.vtp b/Code/unittests/resources/992Particles_rank3_26_t992.vtp new file mode 100644 index 000000000..052e7114d --- /dev/null +++ b/Code/unittests/resources/992Particles_rank3_26_t992.vtp @@ -0,0 +1,20 @@ + + + + + + +0.811695362 4.333258782 -4.176194692 -2.923251842 1.517020378 5.394796825 3.05870464 -1.489493217 -5.19990685 -1.137122844 -4.324765053 4.114080882 -0.32959721 0.301577721 -3.870446706 2.6336787 1.412217293 -2.13639214 -2.631484722 -1.522824135 2.141165233 0.073078419 -0.27688488 3.608213878 -2.565376018 4.032946739 0.298887706 0.156326557 -5.150959816 -1.640450978 0.015339161 5.257842217 1.672430492 2.916397358 -4.0889748 -0.141175771 0.065407063 4.734152947 -3.691911244 -0.660022472 4.93874279 -3.068505788 -1.312858318 4.955489311 -2.307153249 -1.859340404 4.798930321 -1.468110585 -2.269527172 4.477381859 -0.590066457 0.487793232 3.893649254 -4.565408254 0.154800678 3.307524834 -4.81003716 -0.165881847 2.634415779 -4.8860183 -0.382716869 1.897143517 -4.774362111 -0.438239788 1.112242851 -4.440927052 -0.751056408 1.182406578 -3.352273488 -1.239284252 1.95868412 -2.754098439 -1.750480388 2.640870247 -2.091851735 -2.203212475 3.215939675 -1.358994984 -2.487334942 3.674407158 -0.547265553 1.443050648 4.188983116 -4.074830556 2.027115132 3.909091149 -3.818765187 2.508972431 3.484450493 -3.451951527 2.803314472 2.925543938 -3.022920155 2.843071247 2.219063912 -2.585778737 0.649952198 4.933554802 -3.40278008 0.493290211 5.347739372 -2.503915334 0.361694599 5.604178581 -1.523644948 0.243282582 5.696421776 -0.480851674 0.132778431 5.581355248 0.596098399 2.089565541 2.273755226 -1.660821462 1.648567463 3.093838845 -1.057687306 1.29653957 3.854178581 -0.366929555 0.963085438 4.511084709 0.346777415 0.546123768 4.986369286 1.039373851 2.490116383 -1.313769188 -5.493897939 1.828125263 -1.09779438 -5.621560597 1.129440571 -0.833519783 -5.532716298 0.496761585 -0.502329674 -5.231812978 0.008434559 -0.113226738 -4.669976735 2.800483967 -2.399659004 -4.969636464 2.423469807 -3.224337425 -4.581826711 1.953594471 -3.932490196 -4.042993092 1.400329853 -4.490336265 -3.36333611 0.788845326 -4.90185627 -2.558290028 -0.077190136 -0.787333336 -3.725297475 0.032791401 -1.872345772 -3.512048268 0.042240406 -2.904724922 -3.218202138 0.026291157 -3.831868019 -2.832002187 0.050503041 -4.586621132 -2.297448659 3.380337025 -2.18335041 -4.636064076 3.545242573 -2.791239586 -3.902963185 3.590885426 -3.292927589 -3.04882195 3.488842274 -3.678168144 -2.118394399 3.259144093 -3.951481666 -1.137895131 3.443275715 -0.980143394 -4.960748219 3.718147541 -0.445280876 -4.558640981 3.832039143 0.094264183 -4.030557179 3.716167713 0.60122982 -3.430390859 3.310646321 1.040196572 -2.803308034 2.812195088 0.363972817 -2.028626943 3.008281971 -0.648693886 -1.76063683 3.200058247 -1.606249656 -1.380380177 3.28361919 -2.516693916 -0.95305016 3.204368855 -3.34965023 -0.527375722 -3.320716594 0.988902245 5.124090648 -3.577064251 0.45664135 4.666067577 -3.676547741 -0.094843712 4.097815013 -3.5645406 -0.626616325 3.488638377 -3.216327404 -1.12198719 2.85503242 -3.062076305 2.216616783 4.812330699 -3.108356212 2.804820214 4.094946361 -3.015571331 3.2519981 3.256742931 -2.839225506 3.593474541 2.339323497 -2.684829448 3.853614006 1.352682567 -2.637695049 -0.481852379 2.016058421 -2.699939464 0.547761116 1.765730357 -2.810172771 1.546000633 1.435827708 -2.869132732 2.469924126 1.051748729 -2.789481853 3.302622948 0.674246287 -2.514922832 2.43200985 5.192762828 -2.036025738 3.264144097 4.826765514 -1.493873333 4.002291832 4.260817027 -0.93713734 4.590670738 3.538954234 -0.429794048 5.029261742 2.659430003 -2.405746197 1.314185295 5.683256602 -1.778094982 1.052294884 5.762510753 -1.14410374 0.765877876 5.574118114 -0.603801464 0.439088021 5.151861644 -0.209174846 0.093224678 4.496832347 -0.105373119 0.761750374 3.515264964 -0.107856487 1.824381981 3.365393138 0.026203419 2.851815376 3.132452464 0.165191914 3.798728142 2.787649608 0.178459431 4.617285881 2.301306224 -0.995101665 -4.915024605 3.332426524 -0.820392345 -5.326084938 2.431044078 -0.616176342 -5.561013069 1.453711009 -0.391620373 -5.613493767 0.428961253 -0.130088543 -5.467310753 -0.610765004 -1.783694958 -4.25917324 4.056723094 -2.392822002 -4.007471885 3.85428474 -2.838443493 -3.575455513 3.487631297 -3.042476391 -2.988192405 3.082289195 -2.967185711 -2.301541176 2.637648082 -2.239276623 -2.375870552 1.652838206 -1.874934887 -3.163353767 1.021017528 -1.516700481 -3.900677528 0.31673286 -1.091479992 -4.509911384 -0.396188283 -0.529262279 -4.93310627 -1.069039845 -0.814883922 -3.83745655 4.454725719 -0.478591655 -3.235245552 4.6452317 -0.162048076 -2.549961891 4.685873485 0.059894825 -1.817297783 4.548758006 0.131958271 -1.05882534 4.183134532 -0.407466625 -4.648125496 3.576506114 0.32583263 -4.807467308 2.944265819 1.050117756 -4.831364479 2.24716804 1.743629719 -4.727965202 1.488905406 2.380516316 -4.478623237 0.687612987 0.451927449 -1.112967338 3.024809337 0.991100575 -1.886738624 2.463926768 1.629680897 -2.569931831 1.88804481 2.218887593 -3.178612556 1.281652904 2.668182636 -3.676390495 0.602552867 -2.36159489 4.627925072 0.62142036 -2.072654461 5.142790947 0.92710731 -1.668884014 5.509413872 1.17510078 -1.143874859 5.669871483 1.388197398 -0.543483471 5.597876702 1.561285472 0.745014454 -5.40903553 -1.495339894 1.333286549 -5.491471138 -1.271424794 1.859535481 -5.402428474 -1.006364369 2.314640309 -5.128874626 -0.724175954 2.688846852 -4.685509529 -0.424424672 1.339519764 3.549422417 -4.799233937 1.833812977 2.645321999 -5.243867421 2.265087391 1.659472618 -5.513604665 2.623611714 0.624371681 -5.587281728 2.890613819 -0.436673012 -5.484674001 -2.913898205 0.433320198 5.688116527 -2.776496624 -0.656275596 5.760015941 -2.509425853 -1.720431175 5.605146861 -2.127105449 -2.711113777 5.277830577 -1.664344524 -3.602072563 4.778616405 -0.34925053 0.054101143 -2.814675832 -0.337672924 -0.213532295 -1.664735341 -0.536418651 -0.509060707 -0.55436089 -1.08451054 -0.852217521 0.426146007 -1.872115825 -1.214947548 1.311613536 1.865738178 1.083737526 -1.405244374 1.041645313 0.732897911 -0.621285939 0.392860676 0.423987541 0.268270946 0.120662953 0.1872398 1.341726756 0.094143177 -0.03456768 2.499235606 -0.300990795 4.226119194 -4.033296132 -1.044227337 4.348544274 -3.312036061 -1.672214245 4.285926018 -2.457421803 -2.14612553 4.053218041 -1.523225331 -0.650756572 3.577391777 -4.197122121 -1.337836956 3.63160244 -3.374475026 -1.849868511 3.505923424 -2.411767506 -0.892516826 2.837828789 -4.159356618 -1.423988079 2.829272423 -3.206399464 -0.932002758 2.032258187 -3.891099477 1.291958119 4.747874413 -3.216348195 1.858925129 4.388354454 -2.888619923 2.236065174 3.854266319 -2.48632195 2.329670216 3.138419304 -2.072404408 1.135662342 5.105696831 -2.234170461 1.623512532 4.647841606 -1.851884389 1.823951985 3.970832024 -1.449388051 0.959198261 5.273120079 -1.17054131 1.318538929 4.686137352 -0.763429189 0.763195301 5.244155083 -0.071259999 2.163238789 -2.236967888 -5.225022817 1.443920399 -2.001963463 -5.263963246 0.764881397 -1.686920967 -5.043344045 0.246288563 -1.269396629 -4.534280324 1.717247273 -3.058907356 -4.76416924 0.99103954 -2.781338539 -4.670617604 0.3993037 -2.388016548 -4.261949086 1.203148152 -3.731575813 -4.099824452 0.518959309 -3.397744026 -3.845277333 0.639255787 -4.256283607 -3.277574086 3.743316914 -1.661064949 -4.299500966 3.866245533 -2.254431572 -3.472047353 3.804477955 -2.729634132 -2.533967519 3.576565052 -3.106648292 -1.542047047 3.958198811 -1.108086433 -3.80902245 3.952747608 -1.68231472 -2.92357018 3.714771534 -2.160225715 -1.955682301 3.927192951 -0.554594841 -3.237428212 3.692184712 -1.138987388 -2.345071339 3.547233845 -0.063771095 -2.636842275 -3.400520061 1.662699852 4.440451121 -3.571769451 1.085461769 3.909338451 -3.557830547 0.523362313 3.311743236 -3.256076549 -0.018046226 2.693678355 -3.349044536 2.216237221 3.629385448 -3.409881328 1.633687172 3.053762889 -3.243056988 1.06900898 2.436361766 -3.207305645 2.67359272 2.721243358 -3.186942791 2.103232537 2.106756663 -3.002994274 3.033438835 1.738012767 -1.915355419 2.215521965 5.425337291 -1.372539257 3.060197029 4.943060374 -0.798068737 3.742491875 4.232336497 -0.262019848 4.287764702 3.337202525 -1.248107647 1.951087151 5.381964183 -0.732925152 2.727656517 4.729040599 -0.240581249 3.364897881 3.846403575 -0.679156994 1.60297123 5.02942512 -0.298263286 2.322846565 4.196829295 -0.30615971 1.21001545 4.407621837 -1.65777943 -4.801821556 3.176908946 -1.471847271 -5.134623375 2.171606517 -1.22028706 -5.27628788 1.106260753 -0.899654125 -5.203865852 0.015165782 -2.232524608 -4.46863636 2.87935493 -1.950446819 -4.681145515 1.813269115 -1.563594555 -4.710486259 0.715109325 -2.562030529 -3.920470085 2.482222057 -2.096915935 -4.014071312 1.413282848 -2.560508465 -3.210944023 2.089514232 -0.04764912 -4.101425972 3.854841685 0.291797901 -3.43064579 3.971357799 0.547790791 -2.697613563 3.913473582 0.592243458 -1.921982612 3.605520702 0.716877247 -4.202956047 3.156019664 1.029007221 -3.488350715 3.181539989 1.149757649 -2.710867729 2.968962169 1.448463703 -4.170994606 2.369352794 1.680839802 -3.408499565 2.272657848 2.115249897 -4.007859077 1.51494453 -0.125739788 5.293570671 -2.801629567 -0.288444256 5.665904198 -1.796540761 -0.411140178 5.854365502 -0.714631581 -0.490359997 5.838545952 0.418577647 -0.856910442 5.439250145 -2.061685109 -1.008887981 5.735270653 -0.960450673 -1.101718639 5.809783135 0.201925731 -1.50152943 5.373454247 -1.20028069 -1.618327831 5.554404412 -0.024705434 -2.009803509 5.087863121 -0.289376759 -2.659389232 3.167079125 4.530271983 -2.671493267 3.744437371 3.706045604 -2.563358043 4.153037224 2.761702037 -2.451556896 4.447642479 1.727362132 -2.156856273 4.01208416 4.067793346 -2.178493236 4.572653923 3.134191966 -2.13188145 4.937026177 2.071691966 -1.601016735 4.739955101 3.390509105 -1.662891124 5.242045555 2.340597606 -1.053588604 5.278113518 2.54757545 3.068748738 -3.123713341 -4.308068776 2.633358265 -3.941590156 -3.799714589 2.082359577 -4.614523735 -3.152116322 1.435245777 -5.090617027 -2.375192189 3.181724812 -3.727633323 -3.463174367 2.675209309 -4.520674553 -2.861505055 2.041282917 -5.108925667 -2.117455983 3.14740398 -4.20049366 -2.509538197 2.56110027 -4.922327843 -1.819077992 2.977894093 -4.51828846 -1.485833669 -0.204639171 -5.20228466 2.713522411 0.024875904 -5.574658241 1.73721931 0.258152272 -5.732382622 0.67874763 0.500099446 -5.665160026 -0.410073781 0.579311634 -5.319422569 2.006720042 0.840183522 -5.614134636 0.958158946 1.096512104 -5.671946373 -0.148568654 1.338199879 -5.276053276 1.236975169 1.614006306 -5.462448921 0.130583263 2.053077961 -5.0590485 0.420134044 0.09706905 0.733437691 -5.132432484 0.762794758 0.374570046 -5.581994557 1.519783283 0.06157795 -5.767159963 2.255382801 -0.202046242 -5.733193898 0.325340534 1.55322567 -5.357957387 1.124588276 1.219956551 -5.680650258 1.917087818 0.911111031 -5.757073903 0.659969593 2.322444115 -5.364419484 1.497368122 1.99617115 -5.566125417 1.016460682 3.004851494 -5.169435048 3.313347126 1.809508476 -3.344979787 3.062519337 2.453690682 -3.862641835 2.597481037 2.959197197 -4.32389977 2.002556111 3.328772698 -4.648530507 3.513931538 1.299250756 -4.056970143 3.095218922 1.88711277 -4.611032033 2.511207844 2.332875405 -5.030091786 3.474918629 0.733031426 -4.693749928 2.932518269 1.261397515 -5.204583669 3.248741413 0.139519844 -5.18201592 -3.397769665 -1.848307457 3.417669749 -3.596137737 -1.303772774 4.135572887 -3.541114544 -0.716826286 4.801657176 -3.312759136 -0.140818443 5.349104381 -3.311214184 -2.499352302 3.948179698 -3.319236492 -1.900311317 4.713804698 -3.136729931 -1.289643135 5.348074412 -2.92692921 -3.043114509 4.38968513 -2.796615337 -2.40393528 5.105490184 -2.336318706 -3.412159767 4.688421703 -0.335975384 -0.74544033 4.96869514 -0.598010753 -1.556147423 5.226919627 -0.955264782 -2.332451668 5.252981639 -1.323684429 -3.026429024 5.106558299 -0.929416393 -0.433352318 5.523436046 -1.338245128 -1.283120003 5.676794505 -1.76073048 -2.050511207 5.585852122 -1.615890239 -0.134150352 5.842207408 -2.098323559 -0.968275871 5.847006297 -2.310516094 0.172347222 5.888540721 -2.531379436 2.878276024 -0.137246632 -2.352332805 1.956654701 0.308599925 -2.063422893 0.953763161 0.756155467 -1.86588261 -0.116906013 1.109129405 -2.010928844 2.33602253 -0.890382314 -1.578426098 1.348811302 -0.365235829 -1.184848522 0.286957894 0.117216563 -1.354770397 1.67624775 -1.563500905 -0.825938915 0.625321541 -1.002061391 -0.760501598 0.917781029 -2.19789269 -0.512031292 -4.220105018 -1.62631371 -0.366870617 -3.29140171 -2.043214345 -0.194465374 -2.205773201 -2.327127004 -0.145351146 -1.072909202 -2.57704308 -0.89933369 -3.630963173 -0.837136769 -0.567470287 -2.552931633 -1.136010671 -0.292823528 -1.378928032 -1.372193837 -1.162379955 -2.880766716 -0.014939809 -0.72500584 -1.716872062 -0.267457509 -1.446819042 -2.05378231 0.7261338 0.554519917 4.216712151 1.565199351 0.766651417 3.588912163 0.750990367 0.957905079 2.790074501 -0.077836537 1.293327595 1.937207375 -0.827188039 0.342640187 3.259463463 1.941267467 0.387794758 2.497599755 1.000410533 0.54055431 1.612734947 0.093725658 0.064018513 2.185370598 2.177534557 0.077736164 1.337304268 1.158041453 -0.065025066 1.066065941 2.346281505 2.764957691 -2.885437813 0.150579906 2.078834797 -2.323059883 0.752439952 1.25615337 -1.660342064 1.29404304 0.535225178 -0.900679436 1.847502208 2.606071736 -1.985512581 -0.351518178 1.654197956 -1.384745445 0.167311168 0.709774281 -0.67896923 0.671934581 2.279220845 -1.029629555 -0.848397755 1.217457081 -0.379849281 -0.357972646 1.997314717 -0.005341377 -1.23455193 + + + + +17 12 0 162 13 12 163 14 13 164 15 14 165 16 15 26 8 16 18 162 17 166 163 162 167 164 163 168 165 164 25 26 165 19 166 18 169 167 166 170 168 167 24 25 168 20 169 19 171 170 169 23 24 170 21 171 20 22 23 171 4 22 21 162 12 17 163 13 162 164 14 163 165 15 164 26 16 165 166 162 18 167 163 166 168 164 167 25 165 168 169 166 19 170 167 169 24 168 170 171 169 20 23 170 171 22 171 21 32 27 0 172 28 27 173 29 28 174 30 29 175 31 30 37 5 31 33 172 32 176 173 172 177 174 173 178 175 174 38 37 175 34 176 33 179 177 176 180 178 177 39 38 178 35 179 34 181 180 179 40 39 180 36 181 35 41 40 181 10 41 36 172 27 32 173 28 172 174 29 173 175 30 174 37 31 175 176 172 33 177 173 176 178 174 177 38 175 178 179 176 34 180 177 179 39 178 180 181 179 35 40 180 181 41 181 36 47 42 2 182 43 42 183 44 43 184 45 44 185 46 45 52 4 46 48 182 47 186 183 182 187 184 183 188 185 184 53 52 185 49 186 48 189 187 186 190 188 187 54 53 188 50 189 49 191 190 189 55 54 190 51 191 50 56 55 191 9 56 51 182 42 47 183 43 182 184 44 183 185 45 184 52 46 185 186 182 48 187 183 186 188 184 187 53 185 188 189 186 49 190 187 189 54 188 190 191 189 50 55 190 191 56 191 51 62 57 2 192 58 57 193 59 58 194 60 59 195 61 60 71 11 61 63 192 62 196 193 192 197 194 193 198 195 194 70 71 195 64 196 63 199 197 196 200 198 197 69 70 198 65 199 64 201 200 199 68 69 200 66 201 65 67 68 201 5 67 66 192 57 62 193 58 192 194 59 193 195 60 194 71 61 195 196 192 63 197 193 196 198 194 197 70 195 198 199 196 64 200 197 199 69 198 200 201 199 65 68 200 201 67 201 66 77 72 1 202 73 72 203 74 73 204 75 74 205 76 75 82 6 76 78 202 77 206 203 202 207 204 203 208 205 204 83 82 205 79 206 78 209 207 206 210 208 207 84 83 208 80 209 79 211 210 209 85 84 210 81 211 80 86 85 211 8 86 81 202 72 77 203 73 202 204 74 203 205 75 204 82 76 205 206 202 78 207 203 206 208 204 207 83 205 208 209 206 79 210 207 209 84 208 210 211 209 80 85 210 211 86 211 81 92 87 1 212 88 87 213 89 88 214 90 89 215 91 90 101 10 91 93 212 92 216 213 212 217 214 213 218 215 214 100 101 215 94 216 93 219 217 216 220 218 217 99 100 218 95 219 94 221 220 219 98 99 220 96 221 95 97 98 221 7 97 96 212 87 92 213 88 212 214 89 213 215 90 214 101 91 215 216 212 93 217 213 216 218 214 217 100 215 218 219 216 94 220 217 219 99 218 220 221 219 95 98 220 221 97 221 96 107 102 3 222 103 102 223 104 103 224 105 104 225 106 105 116 9 106 108 222 107 226 223 222 227 224 223 228 225 224 115 116 225 109 226 108 229 227 226 230 228 227 114 115 228 110 229 109 231 230 229 113 114 230 111 231 110 112 113 231 6 112 111 222 102 107 223 103 222 224 104 223 225 105 224 116 106 225 226 222 108 227 223 226 228 224 227 115 225 228 229 226 109 230 227 229 114 228 230 231 229 110 113 230 231 112 231 111 122 117 3 232 118 117 233 119 118 234 120 119 235 121 120 127 7 121 123 232 122 236 233 232 237 234 233 238 235 234 128 127 235 124 236 123 239 237 236 240 238 237 129 128 238 125 239 124 241 240 239 130 129 240 126 241 125 131 130 241 11 131 126 232 117 122 233 118 232 234 119 233 235 120 234 127 121 235 236 232 123 237 233 236 238 234 237 128 235 238 239 236 124 240 237 239 129 238 240 241 239 125 130 240 241 131 241 126 12 32 0 242 33 32 243 34 33 244 35 34 245 36 35 136 10 36 13 242 12 246 243 242 247 244 243 248 245 244 135 136 245 14 246 13 249 247 246 250 248 247 134 135 248 15 249 14 251 250 249 133 134 250 16 251 15 132 133 251 8 132 16 242 32 12 243 33 242 244 34 243 245 35 244 136 36 245 246 242 13 247 243 246 248 244 247 135 245 248 249 246 14 250 247 249 134 248 250 251 249 15 133 250 251 132 251 16 87 77 1 252 78 77 253 79 78 254 80 79 255 81 80 132 8 81 88 252 87 256 253 252 257 254 253 258 255 254 133 132 255 89 256 88 259 257 256 260 258 257 134 133 258 90 259 89 261 260 259 135 134 260 91 261 90 136 135 261 10 136 91 252 77 87 253 78 252 254 79 253 255 80 254 132 81 255 256 252 88 257 253 256 258 254 257 133 255 258 259 256 89 260 257 259 134 258 260 261 259 90 135 260 261 136 261 91 57 47 2 262 48 47 263 49 48 264 50 49 265 51 50 137 9 51 58 262 57 266 263 262 267 264 263 268 265 264 138 137 265 59 266 58 269 267 266 270 268 267 139 138 268 60 269 59 271 270 269 140 139 270 61 271 60 141 140 271 11 141 61 262 47 57 263 48 262 264 49 263 265 50 264 137 51 265 266 262 58 267 263 266 268 264 267 138 265 268 269 266 59 270 267 269 139 268 270 271 269 60 140 270 271 141 271 61 3 102 122 102 103 272 103 104 273 104 105 274 105 106 275 106 9 137 122 272 123 272 273 276 273 274 277 274 275 278 275 137 138 123 276 124 276 277 279 277 278 280 278 138 139 124 279 125 279 280 281 280 139 140 125 281 126 281 140 141 126 141 11 122 102 272 272 103 273 273 104 274 274 105 275 275 106 137 123 272 276 276 273 277 277 274 278 278 275 138 124 276 279 279 277 280 280 278 139 125 279 281 281 280 140 126 281 141 21 46 4 282 45 46 283 44 45 284 43 44 285 42 43 146 2 42 20 282 21 286 283 282 287 284 283 288 285 284 145 146 285 19 286 20 289 287 286 290 288 287 144 145 288 18 289 19 291 290 289 143 144 290 17 291 18 142 143 291 0 142 17 282 46 21 283 45 282 284 44 283 285 43 284 146 42 285 286 282 20 287 283 286 288 284 287 145 285 288 289 286 19 290 287 289 144 288 290 291 289 18 143 290 291 142 291 17 66 31 5 292 30 31 293 29 30 294 28 29 295 27 28 142 0 27 65 292 66 296 293 292 297 294 293 298 295 294 143 142 295 64 296 65 299 297 296 300 298 297 144 143 298 63 299 64 301 300 299 145 144 300 62 301 63 146 145 301 2 146 62 292 31 66 293 30 292 294 29 293 295 28 294 142 27 295 296 292 65 297 293 296 298 294 297 143 295 298 299 296 64 300 297 299 144 298 300 301 299 63 145 300 301 146 301 62 111 76 6 302 75 76 303 74 75 304 73 74 305 72 73 147 1 72 110 302 111 306 303 302 307 304 303 308 305 304 148 147 305 109 306 110 309 307 306 310 308 307 149 148 308 108 309 109 311 310 309 150 149 310 107 311 108 151 150 311 3 151 107 302 76 111 303 75 302 304 74 303 305 73 304 147 72 305 306 302 110 307 303 306 308 304 307 148 305 308 309 306 109 310 307 309 149 308 310 311 309 108 150 310 311 151 311 107 96 121 7 312 120 121 313 119 120 314 118 119 315 117 118 151 3 117 95 312 96 316 313 312 317 314 313 318 315 314 150 151 315 94 316 95 319 317 316 320 318 317 149 150 318 93 319 94 321 320 319 148 149 320 92 321 93 147 148 321 1 147 92 312 121 96 313 120 312 314 119 313 315 118 314 151 117 315 316 312 95 317 313 316 318 314 317 150 315 318 319 316 94 320 317 319 149 318 320 321 319 93 148 320 321 147 321 92 26 86 8 322 85 86 323 84 85 324 83 84 325 82 83 156 6 82 25 322 26 326 323 322 327 324 323 328 325 324 155 156 325 24 326 25 329 327 326 330 328 327 154 155 328 23 329 24 331 330 329 153 154 330 22 331 23 152 153 331 4 152 22 322 86 26 323 85 322 324 84 323 325 83 324 156 82 325 326 322 25 327 323 326 328 324 327 155 325 328 329 326 24 330 327 329 154 328 330 331 329 23 153 330 331 152 331 22 116 56 9 332 55 56 333 54 55 334 53 54 335 52 53 152 4 52 115 332 116 336 333 332 337 334 333 338 335 334 153 152 335 114 336 115 339 337 336 340 338 337 154 153 338 113 339 114 341 340 339 155 154 340 112 341 113 156 155 341 6 156 112 332 56 116 333 55 332 334 54 333 335 53 334 152 52 335 336 332 115 337 333 336 338 334 337 153 335 338 339 336 114 340 337 339 154 338 340 341 339 113 155 340 341 156 341 112 101 41 10 342 40 41 343 39 40 344 38 39 345 37 38 157 5 37 100 342 101 346 343 342 347 344 343 348 345 344 158 157 345 99 346 100 349 347 346 350 348 347 159 158 348 98 349 99 351 350 349 160 159 350 97 351 98 161 160 351 7 161 97 342 41 101 343 40 342 344 39 343 345 38 344 157 37 345 346 342 100 347 343 346 348 344 347 158 345 348 349 346 99 350 347 349 159 348 350 351 349 98 160 350 351 161 351 97 71 131 11 352 130 131 353 129 130 354 128 129 355 127 128 161 7 127 70 352 71 356 353 352 357 354 353 358 355 354 160 161 355 69 356 70 359 357 356 360 358 357 159 160 358 68 359 69 361 360 359 158 159 360 67 361 68 157 158 361 5 157 67 352 131 71 353 130 352 354 129 353 355 128 354 161 127 355 356 352 70 357 353 356 358 354 357 160 355 358 359 356 69 360 357 359 159 358 360 361 359 68 158 360 361 157 361 67 + + +3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 159 162 165 168 171 174 177 180 183 186 189 192 195 198 201 204 207 210 213 216 219 222 225 228 231 234 237 240 243 246 249 252 255 258 261 264 267 270 273 276 279 282 285 288 291 294 297 300 303 306 309 312 315 318 321 324 327 330 333 336 339 342 345 348 351 354 357 360 363 366 369 372 375 378 381 384 387 390 393 396 399 402 405 408 411 414 417 420 423 426 429 432 435 438 441 444 447 450 453 456 459 462 465 468 471 474 477 480 483 486 489 492 495 498 501 504 507 510 513 516 519 522 525 528 531 534 537 540 543 546 549 552 555 558 561 564 567 570 573 576 579 582 585 588 591 594 597 600 603 606 609 612 615 618 621 624 627 630 633 636 639 642 645 648 651 654 657 660 663 666 669 672 675 678 681 684 687 690 693 696 699 702 705 708 711 714 717 720 723 726 729 732 735 738 741 744 747 750 753 756 759 762 765 768 771 774 777 780 783 786 789 792 795 798 801 804 807 810 813 816 819 822 825 828 831 834 837 840 843 846 849 852 855 858 861 864 867 870 873 876 879 882 885 888 891 894 897 900 903 906 909 912 915 918 921 924 927 930 933 936 939 942 945 948 951 954 957 960 963 966 969 972 975 978 981 984 987 990 993 996 999 1002 1005 1008 1011 1014 1017 1020 1023 1026 1029 1032 1035 1038 1041 1044 1047 1050 1053 1056 1059 1062 1065 1068 1071 1074 1077 1080 1083 1086 1089 1092 1095 1098 1101 1104 1107 1110 1113 1116 1119 1122 1125 1128 1131 1134 1137 1140 1143 1146 1149 1152 1155 1158 1161 1164 1167 1170 1173 1176 1179 1182 1185 1188 1191 1194 1197 1200 1203 1206 1209 1212 1215 1218 1221 1224 1227 1230 1233 1236 1239 1242 1245 1248 1251 1254 1257 1260 1263 1266 1269 1272 1275 1278 1281 1284 1287 1290 1293 1296 1299 1302 1305 1308 1311 1314 1317 1320 1323 1326 1329 1332 1335 1338 1341 1344 1347 1350 1353 1356 1359 1362 1365 1368 1371 1374 1377 1380 1383 1386 1389 1392 1395 1398 1401 1404 1407 1410 1413 1416 1419 1422 1425 1428 1431 1434 1437 1440 1443 1446 1449 1452 1455 1458 1461 1464 1467 1470 1473 1476 1479 1482 1485 1488 1491 1494 1497 1500 1503 1506 1509 1512 1515 1518 1521 1524 1527 1530 1533 1536 1539 1542 1545 1548 1551 1554 1557 1560 1563 1566 1569 1572 1575 1578 1581 1584 1587 1590 1593 1596 1599 1602 1605 1608 1611 1614 1617 1620 1623 1626 1629 1632 1635 1638 1641 1644 1647 1650 1653 1656 1659 1662 1665 1668 1671 1674 1677 1680 1683 1686 1689 1692 1695 1698 1701 1704 1707 1710 1713 1716 1719 1722 1725 1728 1731 1734 1737 1740 1743 1746 1749 1752 1755 1758 1761 1764 1767 1770 1773 1776 1779 1782 1785 1788 1791 1794 1797 1800 1803 1806 1809 1812 1815 1818 1821 1824 1827 1830 1833 1836 1839 1842 1845 1848 1851 1854 1857 1860 1863 1866 1869 1872 1875 1878 1881 1884 1887 1890 1893 1896 1899 1902 1905 1908 1911 1914 1917 1920 1923 1926 1929 1932 1935 1938 1941 1944 1947 1950 1953 1956 1959 1962 1965 1968 1971 1974 1977 1980 1983 1986 1989 1992 1995 1998 2001 2004 2007 2010 2013 2016 2019 2022 2025 2028 2031 2034 2037 2040 2043 2046 2049 2052 2055 2058 2061 2064 2067 2070 2073 2076 2079 2082 2085 2088 2091 2094 2097 2100 2103 2106 2109 2112 2115 2118 2121 2124 2127 2130 2133 2136 2139 2142 2145 2148 2151 2154 2157 2160 + + + + + \ No newline at end of file