diff --git a/CMakeLists.txt b/CMakeLists.txt index ca5452fd0..c4397af37 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -396,6 +396,10 @@ list(APPEND draco_io_sources "${draco_src_root}/io/ply_property_writer.h" "${draco_src_root}/io/ply_reader.cc" "${draco_src_root}/io/ply_reader.h" + "${draco_src_root}/io/stl_decoder.cc" + "${draco_src_root}/io/stl_decoder.h" + "${draco_src_root}/io/stl_encoder.cc" + "${draco_src_root}/io/stl_encoder.h" "${draco_src_root}/io/point_cloud_io.cc" "${draco_src_root}/io/point_cloud_io.h" "${draco_src_root}/io/stdio_file_reader.cc" diff --git a/cmake/draco_tests.cmake b/cmake/draco_tests.cmake index 1633d7522..d3e43251c 100644 --- a/cmake/draco_tests.cmake +++ b/cmake/draco_tests.cmake @@ -60,6 +60,8 @@ list( "${draco_src_root}/io/obj_encoder_test.cc" "${draco_src_root}/io/ply_decoder_test.cc" "${draco_src_root}/io/ply_reader_test.cc" + "${draco_src_root}/io/stl_decoder_test.cc" + "${draco_src_root}/io/stl_encoder_test.cc" "${draco_src_root}/io/point_cloud_io_test.cc" "${draco_src_root}/mesh/mesh_are_equivalent_test.cc" "${draco_src_root}/mesh/mesh_cleanup_test.cc" diff --git a/src/draco/io/mesh_io.cc b/src/draco/io/mesh_io.cc index 0bba9a787..13bebcb42 100644 --- a/src/draco/io/mesh_io.cc +++ b/src/draco/io/mesh_io.cc @@ -20,6 +20,7 @@ #include "draco/io/file_utils.h" #include "draco/io/obj_decoder.h" #include "draco/io/ply_decoder.h" +#include "draco/io/stl_decoder.h" #ifdef DRACO_TRANSCODER_SUPPORTED #include "draco/compression/draco_compression_options.h" #include "draco/compression/encode.h" @@ -71,11 +72,16 @@ StatusOr> ReadMeshFromFile( return std::move(mesh); } if (extension == "ply") { - // Wavefront PLY file format. + // Stanford PLY file format. PlyDecoder ply_decoder; DRACO_RETURN_IF_ERROR(ply_decoder.DecodeFromFile(file_name, mesh.get())); return std::move(mesh); } + if (extension == "stl") { + // STL file format. + StlDecoder stl_decoder; + return stl_decoder.DecodeFromFile(file_name); + } #ifdef DRACO_TRANSCODER_SUPPORTED if (extension == "gltf" || extension == "glb") { GltfDecoder gltf_decoder; diff --git a/src/draco/io/stl_decoder.cc b/src/draco/io/stl_decoder.cc new file mode 100644 index 000000000..954aba06b --- /dev/null +++ b/src/draco/io/stl_decoder.cc @@ -0,0 +1,74 @@ +// Copyright 2022 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/io/stl_decoder.h" + +#include "draco/core/macros.h" +#include "draco/core/status.h" +#include "draco/core/status_or.h" +#include "draco/io/file_utils.h" +#include "draco/mesh/triangle_soup_mesh_builder.h" + +namespace draco { + +StatusOr> StlDecoder::DecodeFromFile( + const std::string &file_name) { + std::vector data; + if (!ReadFileToBuffer(file_name, &data)) { + return Status(Status::IO_ERROR, "Unable to read input file."); + } + DecoderBuffer buffer; + buffer.Init(data.data(), data.size()); + return DecodeFromBuffer(&buffer); +} + +StatusOr> StlDecoder::DecodeFromBuffer( + DecoderBuffer *buffer) { + if (!strncmp(buffer->data_head() , "solid ", 6)) { + return Status(Status::IO_ERROR, + "Currently only binary STL files are supported."); + } + buffer->Advance(80); + uint32_t face_count; + buffer->Decode(&face_count, 4); + + TriangleSoupMeshBuilder builder; + builder.Start(face_count); + + const int32_t pos_att_id = builder.AddAttribute(GeometryAttribute::POSITION, + 3, DT_FLOAT32); + const int32_t norm_att_id = builder.AddAttribute(GeometryAttribute::NORMAL, + 3, DT_FLOAT32); + + for (uint32_t i = 0; i < face_count; i++) { + float data[48]; + buffer->Decode(data, 48); + uint16_t unused; + buffer->Decode(&unused, 2); + + builder.SetPerFaceAttributeValueForFace(norm_att_id, draco::FaceIndex(i), + draco::Vector3f(data[0], data[1], data[2]).data()); + + builder.SetAttributeValuesForFace(pos_att_id, draco::FaceIndex(i), + draco::Vector3f(data[3], data[4], data[5]).data(), + draco::Vector3f(data[6], data[7], data[8]).data(), + draco::Vector3f(data[9], data[10], data[11]).data()); + + } + + std::unique_ptr mesh = builder.Finalize(); + return mesh; +} + +} // namespace draco diff --git a/src/draco/io/stl_decoder.h b/src/draco/io/stl_decoder.h new file mode 100644 index 000000000..44b35d849 --- /dev/null +++ b/src/draco/io/stl_decoder.h @@ -0,0 +1,38 @@ +// Copyright 2022 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_IO_STL_DECODER_H_ +#define DRACO_IO_STL_DECODER_H_ + +#include + +#include "draco/core/decoder_buffer.h" +#include "draco/core/status.h" +#include "draco/core/status_or.h" +#include "draco/draco_features.h" +#include "draco/mesh/mesh.h" + +namespace draco { + +// Decodes an STL file into draco::Mesh (or draco::PointCloud if the +// connectivity data is not needed). +class StlDecoder { + public: + StatusOr> DecodeFromFile(const std::string &file_name); + StatusOr> DecodeFromBuffer(DecoderBuffer *buffer); +}; + +} // namespace draco + +#endif // DRACO_IO_STL_DECODER_H_ diff --git a/src/draco/io/stl_decoder_test.cc b/src/draco/io/stl_decoder_test.cc new file mode 100644 index 000000000..cb32d4d7d --- /dev/null +++ b/src/draco/io/stl_decoder_test.cc @@ -0,0 +1,47 @@ +// Copyright 2022 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/io/stl_decoder.h" +#include "draco/core/draco_test_base.h" +#include "draco/core/draco_test_utils.h" + +namespace draco { + +class StlDecoderTest : public ::testing::Test { + protected: + + void test_decoding(const std::string &file_name) { + const std::string path = GetTestFileFullPath(file_name); + StlDecoder decoder; + DRACO_ASSIGN_OR_ASSERT(std::unique_ptr mesh, + decoder.DecodeFromFile(path)); + ASSERT_GT(mesh->num_faces(), 0); + ASSERT_GT(mesh->num_points(), 0); + } + + void test_decoding_should_fail(const std::string &file_name) { + StlDecoder decoder; + StatusOr> statusOrMesh = + decoder.DecodeFromFile(GetTestFileFullPath(file_name)); + ASSERT_FALSE(statusOrMesh.ok()); + } +}; + +TEST_F(StlDecoderTest, TestStlDecoding) { + test_decoding("STL/bunny.stl"); + test_decoding("STL/test_sphere.stl"); + test_decoding_should_fail("STL/test_sphere_ascii.stl"); +} + +} // namespace draco diff --git a/src/draco/io/stl_encoder.cc b/src/draco/io/stl_encoder.cc new file mode 100644 index 000000000..784e9281c --- /dev/null +++ b/src/draco/io/stl_encoder.cc @@ -0,0 +1,111 @@ +// Copyright 2022 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/io/stl_encoder.h" + +#include +#include +#include + +#include "draco/io/file_writer_factory.h" +#include "draco/io/file_writer_interface.h" + +namespace draco { + +StlEncoder::StlEncoder() + : out_buffer_(nullptr), in_point_cloud_(nullptr), in_mesh_(nullptr) {} + +Status StlEncoder::EncodeToFile(const Mesh &mesh, const std::string &file_name) { + in_mesh_ = &mesh; + std::unique_ptr file = + FileWriterFactory::OpenWriter(file_name); + if (!file) { + return Status(Status::IO_ERROR, "File couldn't be opened"); + } + // Encode the mesh into a buffer. + EncoderBuffer buffer; + DRACO_RETURN_IF_ERROR(EncodeToBuffer(mesh, &buffer)); + // Write the buffer into the file. + file->Write(buffer.data(), buffer.size()); + return OkStatus(); +} + +Status StlEncoder::EncodeToBuffer(const Mesh &mesh, EncoderBuffer *out_buffer) { + in_mesh_ = &mesh; + out_buffer_ = out_buffer; + Status s = EncodeInternal(); + in_mesh_ = nullptr; // cleanup + in_point_cloud_ = nullptr; + out_buffer_ = nullptr; + return s; +} + +Status StlEncoder::EncodeInternal() { + // Write STL header. + std::stringstream out; + out << std::left << std::setw(80) << "generated using Draco"; // header is 80 bytes fixed size. + const std::string header_str = out.str(); + buffer()->Encode(header_str.data(), header_str.length()); + + uint32_t num_faces = in_mesh_->num_faces(); + buffer()->Encode(&num_faces, 4); + + std::vector stl_face; + + const int pos_att_id = + in_mesh_->GetNamedAttributeId(GeometryAttribute::POSITION); + + if (pos_att_id < 0) { + return ErrorStatus("Mesh is missing the position attribute."); + } + + if (in_mesh_->attribute(pos_att_id)->data_type() != + DT_FLOAT32) { + return ErrorStatus("Mesh position attribute is not of type float32."); + } + + uint16_t unused = 0; + + if (in_mesh_) { + for (FaceIndex i(0); i < in_mesh_->num_faces(); ++i) { + + const auto &f = in_mesh_->face(i); + const auto *const pos_att = in_mesh_->attribute(pos_att_id); + + // The normal attribute can contain arbitrary normals that may not + // correspond to the winding of the face. + // Therefor we simply always calculate them + // using the points of the triangle face: norm(cross(p2-p1, p3-p1)) + + Vector3f pos[3]; + pos_att->GetMappedValue(f[0], &pos[0][0]); + pos_att->GetMappedValue(f[1], &pos[1][0]); + pos_att->GetMappedValue(f[2], &pos[2][0]); + Vector3f norm = CrossProduct(pos[1] - pos[0], pos[2] - pos[0]); + norm.Normalize(); + buffer()->Encode(norm.data(), sizeof(float) * 3); + + for (int c = 0; c < 3; ++c) { + buffer()->Encode(pos_att->GetAddress(pos_att->mapped_index(f[c])), + pos_att->byte_stride()); + } + + buffer()->Encode(&unused, 2); + + } + } + return OkStatus(); +} + +} // namespace draco diff --git a/src/draco/io/stl_encoder.h b/src/draco/io/stl_encoder.h new file mode 100644 index 000000000..77a04f306 --- /dev/null +++ b/src/draco/io/stl_encoder.h @@ -0,0 +1,50 @@ +// Copyright 2022 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_IO_STL_ENCODER_H_ +#define DRACO_IO_STL_ENCODER_H_ + +#include "draco/core/encoder_buffer.h" +#include "draco/mesh/mesh.h" + +namespace draco { + +// Class for encoding draco::Mesh into the STL file format. +class StlEncoder { + public: + StlEncoder(); + + // Encodes the mesh and saves it into a file. + // Returns false when either the encoding failed or when the file couldn't be + // opened. + Status EncodeToFile(const Mesh &mesh, const std::string &file_name); + + // Encodes the mesh into a buffer. + Status EncodeToBuffer(const Mesh &mesh, EncoderBuffer *out_buffer); + + protected: + Status EncodeInternal(); + EncoderBuffer *buffer() const { return out_buffer_; } + + private: + + EncoderBuffer *out_buffer_; + + const PointCloud *in_point_cloud_; + const Mesh *in_mesh_; +}; + +} // namespace draco + +#endif // DRACO_IO_STL_ENCODER_H_ diff --git a/src/draco/io/stl_encoder_test.cc b/src/draco/io/stl_encoder_test.cc new file mode 100644 index 000000000..0525dc605 --- /dev/null +++ b/src/draco/io/stl_encoder_test.cc @@ -0,0 +1,75 @@ +// Copyright 2022 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include + +#include "draco/core/draco_test_base.h" +#include "draco/core/draco_test_utils.h" +#include "draco/io/file_reader_factory.h" +#include "draco/io/file_reader_interface.h" +#include "draco/io/stl_decoder.h" +#include "draco/io/stl_encoder.h" + +namespace draco { + +class StlEncoderTest : public ::testing::Test { + protected: + void CompareMeshes(const Mesh *mesh0, const Mesh *mesh1) { + ASSERT_EQ(mesh0->num_faces(), mesh1->num_faces()); + ASSERT_EQ(mesh0->num_attributes(), mesh1->num_attributes()); + for (size_t att_id = 0; att_id < mesh0->num_attributes(); ++att_id) { + ASSERT_EQ(mesh0->attribute(att_id)->size(), + mesh1->attribute(att_id)->size()); + } + } + + // Encode a mesh using the StlEncoder and then decode to verify the encoding. + std::unique_ptr EncodeAndDecodeMesh(const Mesh *mesh) { + EncoderBuffer encoder_buffer; + StlEncoder encoder; + Status status = encoder.EncodeToBuffer(*mesh, &encoder_buffer); + if (!status.ok()) { + return nullptr; + } + + DecoderBuffer decoder_buffer; + decoder_buffer.Init(encoder_buffer.data(), encoder_buffer.size()); + StlDecoder decoder; + StatusOr> status_or_mesh = + decoder.DecodeFromBuffer(&decoder_buffer); + if (!status_or_mesh.ok()) { + return nullptr; + } + std::unique_ptr decoded_mesh = std::move(status_or_mesh).value(); + return decoded_mesh; + } + + void test_encoding(const std::string &file_name) { + const std::unique_ptr mesh(ReadMeshFromTestFile(file_name, true)); + + ASSERT_NE(mesh, nullptr) << "Failed to load test model " << file_name; + ASSERT_GT(mesh->num_faces(), 0); + + const std::unique_ptr decoded_mesh = EncodeAndDecodeMesh(mesh.get()); + CompareMeshes(mesh.get(), decoded_mesh.get()); + } +}; + +TEST_F(StlEncoderTest, TestStlEncoding) { + // Test decoded mesh from encoded stl file stays the same. + test_encoding("STL/bunny.stl"); + test_encoding("STL/test_sphere.stl"); +} + +} // namespace draco diff --git a/src/draco/tools/draco_decoder.cc b/src/draco/tools/draco_decoder.cc index e7ffb2061..4deb63cc0 100644 --- a/src/draco/tools/draco_decoder.cc +++ b/src/draco/tools/draco_decoder.cc @@ -20,6 +20,7 @@ #include "draco/io/obj_encoder.h" #include "draco/io/parser_utils.h" #include "draco/io/ply_encoder.h" +#include "draco/io/stl_encoder.h" namespace { @@ -157,8 +158,20 @@ int main(int argc, char **argv) { return -1; } } + } else if (extension == ".stl") { + draco::StlEncoder stl_encoder; + if (mesh) { + draco::Status s = stl_encoder.EncodeToFile(*mesh, options.output); + if (s.code() != draco::Status::OK) { + printf("Failed to store the decoded mesh as STL.\n"); + return -1; + } + } else { + printf("Can't store a point cloud as STL.\n"); + return -1; + } } else { - printf("Invalid extension of the output file. Use either .ply or .obj.\n"); + printf("Invalid extension of the output file. Use either .ply, .stl or .obj.\n"); return -1; } printf("Decoded geometry saved to %s (%" PRId64 " ms to decode)\n", diff --git a/testdata/STL/bunny.stl b/testdata/STL/bunny.stl new file mode 100644 index 000000000..af54b9daf Binary files /dev/null and b/testdata/STL/bunny.stl differ diff --git a/testdata/STL/test_sphere.stl b/testdata/STL/test_sphere.stl new file mode 100644 index 000000000..12570635f Binary files /dev/null and b/testdata/STL/test_sphere.stl differ diff --git a/testdata/STL/test_sphere_ascii.stl b/testdata/STL/test_sphere_ascii.stl new file mode 100644 index 000000000..b79326aaf --- /dev/null +++ b/testdata/STL/test_sphere_ascii.stl @@ -0,0 +1,1570 @@ +solid Exported from Blender-3.0.1 +facet normal 0.552209 -0.109841 0.826438 +outer loop +vertex 0.382683 -0.000000 0.923880 +vertex 0.653281 -0.270598 0.707107 +vertex 0.707107 -0.000000 0.707107 +endloop +endfacet +facet normal 0.552208 0.109841 0.826439 +outer loop +vertex 0.382683 -0.000000 0.923880 +vertex 0.653281 0.270598 0.707107 +vertex 0.353553 0.146446 0.923880 +endloop +endfacet +facet normal 0.194944 -0.038777 0.980048 +outer loop +vertex 0.382683 -0.000000 0.923880 +vertex 0.000000 -0.000000 1.000000 +vertex 0.353553 -0.146447 0.923880 +endloop +endfacet +facet normal 0.552209 -0.109841 0.826438 +outer loop +vertex 0.353553 -0.146447 0.923880 +vertex 0.653281 -0.270598 0.707107 +vertex 0.382683 -0.000000 0.923880 +endloop +endfacet +facet normal 0.165265 -0.110427 0.980048 +outer loop +vertex 0.353553 -0.146447 0.923880 +vertex 0.000000 -0.000000 1.000000 +vertex 0.270598 -0.270598 0.923879 +endloop +endfacet +facet normal 0.468140 -0.312801 0.826438 +outer loop +vertex 0.270598 -0.270598 0.923879 +vertex 0.653281 -0.270598 0.707107 +vertex 0.353553 -0.146447 0.923880 +endloop +endfacet +facet normal 0.312801 -0.468140 0.826439 +outer loop +vertex 0.270598 -0.270598 0.923879 +vertex 0.270598 -0.653282 0.707107 +vertex 0.500000 -0.500000 0.707107 +endloop +endfacet +facet normal 0.110427 -0.165265 0.980048 +outer loop +vertex 0.270598 -0.270598 0.923879 +vertex 0.000000 -0.000000 1.000000 +vertex 0.146447 -0.353554 0.923879 +endloop +endfacet +facet normal 0.312801 -0.468140 0.826438 +outer loop +vertex 0.146447 -0.353554 0.923879 +vertex 0.270598 -0.653282 0.707107 +vertex 0.270598 -0.270598 0.923879 +endloop +endfacet +facet normal 0.038776 -0.194944 0.980048 +outer loop +vertex 0.146447 -0.353554 0.923879 +vertex 0.000000 -0.000000 1.000000 +vertex 0.000000 -0.382684 0.923879 +endloop +endfacet +facet normal 0.109841 -0.552208 0.826439 +outer loop +vertex 0.000000 -0.382684 0.923879 +vertex 0.270598 -0.653282 0.707107 +vertex 0.146447 -0.353554 0.923879 +endloop +endfacet +facet normal -0.109841 -0.552209 0.826438 +outer loop +vertex 0.000000 -0.382684 0.923879 +vertex -0.270598 -0.653282 0.707107 +vertex 0.000000 -0.707107 0.707107 +endloop +endfacet +facet normal -0.038776 -0.194944 0.980048 +outer loop +vertex 0.000000 -0.382684 0.923879 +vertex 0.000000 -0.000000 1.000000 +vertex -0.146447 -0.353554 0.923879 +endloop +endfacet +facet normal -0.109841 -0.552208 0.826439 +outer loop +vertex -0.146447 -0.353554 0.923879 +vertex -0.270598 -0.653282 0.707107 +vertex 0.000000 -0.382684 0.923879 +endloop +endfacet +facet normal -0.110427 -0.165265 0.980047 +outer loop +vertex -0.146447 -0.353554 0.923879 +vertex 0.000000 -0.000000 1.000000 +vertex -0.270598 -0.270598 0.923879 +endloop +endfacet +facet normal -0.312801 -0.468140 0.826438 +outer loop +vertex -0.270598 -0.270598 0.923879 +vertex -0.270598 -0.653282 0.707107 +vertex -0.146447 -0.353554 0.923879 +endloop +endfacet +facet normal -0.468140 -0.312801 0.826439 +outer loop +vertex -0.270598 -0.270598 0.923879 +vertex -0.653281 -0.270598 0.707107 +vertex -0.500000 -0.500000 0.707107 +endloop +endfacet +facet normal -0.165265 -0.110427 0.980048 +outer loop +vertex -0.270598 -0.270598 0.923879 +vertex 0.000000 -0.000000 1.000000 +vertex -0.353553 -0.146447 0.923880 +endloop +endfacet +facet normal -0.468140 -0.312801 0.826438 +outer loop +vertex -0.353553 -0.146447 0.923880 +vertex -0.653281 -0.270598 0.707107 +vertex -0.270598 -0.270598 0.923879 +endloop +endfacet +facet normal -0.194944 -0.038777 0.980048 +outer loop +vertex -0.353553 -0.146447 0.923880 +vertex 0.000000 -0.000000 1.000000 +vertex -0.382683 -0.000000 0.923880 +endloop +endfacet +facet normal -0.552209 -0.109841 0.826438 +outer loop +vertex -0.382683 -0.000000 0.923880 +vertex -0.653281 -0.270598 0.707107 +vertex -0.353553 -0.146447 0.923880 +endloop +endfacet +facet normal -0.552208 0.109841 0.826439 +outer loop +vertex -0.382683 -0.000000 0.923880 +vertex -0.653281 0.270598 0.707107 +vertex -0.707107 -0.000000 0.707107 +endloop +endfacet +facet normal -0.194944 0.038777 0.980048 +outer loop +vertex -0.382683 -0.000000 0.923880 +vertex 0.000000 -0.000000 1.000000 +vertex -0.353553 0.146446 0.923880 +endloop +endfacet +facet normal -0.552208 0.109841 0.826439 +outer loop +vertex -0.353553 0.146446 0.923880 +vertex -0.653281 0.270598 0.707107 +vertex -0.382683 -0.000000 0.923880 +endloop +endfacet +facet normal -0.165265 0.110426 0.980048 +outer loop +vertex -0.353553 0.146446 0.923880 +vertex 0.000000 -0.000000 1.000000 +vertex -0.270598 0.270598 0.923880 +endloop +endfacet +facet normal -0.468140 0.312800 0.826439 +outer loop +vertex -0.270598 0.270598 0.923880 +vertex -0.653281 0.270598 0.707107 +vertex -0.353553 0.146446 0.923880 +endloop +endfacet +facet normal -0.312801 0.468140 0.826439 +outer loop +vertex -0.270598 0.270598 0.923880 +vertex -0.270598 0.653281 0.707107 +vertex -0.500000 0.500000 0.707107 +endloop +endfacet +facet normal -0.110427 0.165265 0.980048 +outer loop +vertex -0.270598 0.270598 0.923880 +vertex 0.000000 -0.000000 1.000000 +vertex -0.146447 0.353553 0.923880 +endloop +endfacet +facet normal -0.312801 0.468140 0.826438 +outer loop +vertex -0.146447 0.353553 0.923880 +vertex -0.270598 0.653281 0.707107 +vertex -0.270598 0.270598 0.923880 +endloop +endfacet +facet normal -0.038777 0.194944 0.980048 +outer loop +vertex -0.146447 0.353553 0.923880 +vertex 0.000000 -0.000000 1.000000 +vertex -0.000000 0.382683 0.923880 +endloop +endfacet +facet normal -0.109841 0.552209 0.826439 +outer loop +vertex -0.000000 0.382683 0.923880 +vertex -0.270598 0.653281 0.707107 +vertex -0.146447 0.353553 0.923880 +endloop +endfacet +facet normal 0.109841 0.552208 0.826439 +outer loop +vertex -0.000000 0.382683 0.923880 +vertex 0.270598 0.653281 0.707107 +vertex -0.000000 0.707107 0.707107 +endloop +endfacet +facet normal 0.038777 0.194944 0.980048 +outer loop +vertex -0.000000 0.382683 0.923880 +vertex 0.000000 -0.000000 1.000000 +vertex 0.146447 0.353553 0.923880 +endloop +endfacet +facet normal 0.109841 0.552209 0.826439 +outer loop +vertex 0.146447 0.353553 0.923880 +vertex 0.270598 0.653281 0.707107 +vertex -0.000000 0.382683 0.923880 +endloop +endfacet +facet normal 0.110427 0.165265 0.980048 +outer loop +vertex 0.146447 0.353553 0.923880 +vertex 0.000000 -0.000000 1.000000 +vertex 0.270598 0.270598 0.923880 +endloop +endfacet +facet normal 0.312801 0.468140 0.826439 +outer loop +vertex 0.270598 0.270598 0.923880 +vertex 0.270598 0.653281 0.707107 +vertex 0.146447 0.353553 0.923880 +endloop +endfacet +facet normal 0.468140 0.312801 0.826438 +outer loop +vertex 0.270598 0.270598 0.923880 +vertex 0.653281 0.270598 0.707107 +vertex 0.500000 0.500000 0.707107 +endloop +endfacet +facet normal 0.165265 0.110426 0.980048 +outer loop +vertex 0.270598 0.270598 0.923880 +vertex 0.000000 -0.000000 1.000000 +vertex 0.353553 0.146446 0.923880 +endloop +endfacet +facet normal 0.468140 0.312800 0.826439 +outer loop +vertex 0.353553 0.146446 0.923880 +vertex 0.653281 0.270598 0.707107 +vertex 0.270598 0.270598 0.923880 +endloop +endfacet +facet normal 0.194944 0.038777 0.980048 +outer loop +vertex 0.353553 0.146446 0.923880 +vertex 0.000000 -0.000000 1.000000 +vertex 0.382683 -0.000000 0.923880 +endloop +endfacet +facet normal 0.552208 0.109841 0.826439 +outer loop +vertex 0.707107 -0.000000 0.707107 +vertex 0.653281 0.270598 0.707107 +vertex 0.382683 -0.000000 0.923880 +endloop +endfacet +facet normal 0.820326 0.163172 0.548124 +outer loop +vertex 0.707107 -0.000000 0.707107 +vertex 0.923880 -0.000000 0.382683 +vertex 0.653281 0.270598 0.707107 +endloop +endfacet +facet normal 0.820326 -0.163173 0.548124 +outer loop +vertex 0.653281 -0.270598 0.707107 +vertex 0.923880 -0.000000 0.382683 +vertex 0.707107 -0.000000 0.707107 +endloop +endfacet +facet normal 0.695438 -0.464677 0.548124 +outer loop +vertex 0.653281 -0.270598 0.707107 +vertex 0.653281 -0.653282 0.382683 +vertex 0.853553 -0.353553 0.382683 +endloop +endfacet +facet normal 0.468140 -0.312801 0.826439 +outer loop +vertex 0.500000 -0.500000 0.707107 +vertex 0.653281 -0.270598 0.707107 +vertex 0.270598 -0.270598 0.923879 +endloop +endfacet +facet normal 0.695439 -0.464677 0.548124 +outer loop +vertex 0.500000 -0.500000 0.707107 +vertex 0.653281 -0.653282 0.382683 +vertex 0.653281 -0.270598 0.707107 +endloop +endfacet +facet normal 0.464677 -0.695439 0.548124 +outer loop +vertex 0.270598 -0.653282 0.707107 +vertex 0.653281 -0.653282 0.382683 +vertex 0.500000 -0.500000 0.707107 +endloop +endfacet +facet normal 0.163173 -0.820326 0.548124 +outer loop +vertex 0.270598 -0.653282 0.707107 +vertex 0.000000 -0.923880 0.382683 +vertex 0.353553 -0.853553 0.382683 +endloop +endfacet +facet normal 0.109841 -0.552209 0.826438 +outer loop +vertex 0.000000 -0.707107 0.707107 +vertex 0.270598 -0.653282 0.707107 +vertex 0.000000 -0.382684 0.923879 +endloop +endfacet +facet normal 0.163173 -0.820326 0.548124 +outer loop +vertex 0.000000 -0.707107 0.707107 +vertex 0.000000 -0.923880 0.382683 +vertex 0.270598 -0.653282 0.707107 +endloop +endfacet +facet normal -0.163173 -0.820326 0.548124 +outer loop +vertex -0.270598 -0.653282 0.707107 +vertex 0.000000 -0.923880 0.382683 +vertex 0.000000 -0.707107 0.707107 +endloop +endfacet +facet normal -0.464677 -0.695439 0.548124 +outer loop +vertex -0.270598 -0.653282 0.707107 +vertex -0.653281 -0.653282 0.382683 +vertex -0.353553 -0.853553 0.382683 +endloop +endfacet +facet normal -0.312801 -0.468140 0.826438 +outer loop +vertex -0.500000 -0.500000 0.707107 +vertex -0.270598 -0.653282 0.707107 +vertex -0.270598 -0.270598 0.923879 +endloop +endfacet +facet normal -0.464677 -0.695439 0.548124 +outer loop +vertex -0.500000 -0.500000 0.707107 +vertex -0.653281 -0.653282 0.382683 +vertex -0.270598 -0.653282 0.707107 +endloop +endfacet +facet normal -0.695439 -0.464677 0.548124 +outer loop +vertex -0.653281 -0.270598 0.707107 +vertex -0.653281 -0.653282 0.382683 +vertex -0.500000 -0.500000 0.707107 +endloop +endfacet +facet normal -0.820326 -0.163173 0.548124 +outer loop +vertex -0.653281 -0.270598 0.707107 +vertex -0.923880 -0.000000 0.382683 +vertex -0.853553 -0.353553 0.382683 +endloop +endfacet +facet normal -0.552209 -0.109841 0.826438 +outer loop +vertex -0.707107 -0.000000 0.707107 +vertex -0.653281 -0.270598 0.707107 +vertex -0.382683 -0.000000 0.923880 +endloop +endfacet +facet normal -0.820326 -0.163173 0.548124 +outer loop +vertex -0.707107 -0.000000 0.707107 +vertex -0.923880 -0.000000 0.382683 +vertex -0.653281 -0.270598 0.707107 +endloop +endfacet +facet normal -0.820326 0.163172 0.548124 +outer loop +vertex -0.653281 0.270598 0.707107 +vertex -0.923880 -0.000000 0.382683 +vertex -0.707107 -0.000000 0.707107 +endloop +endfacet +facet normal -0.695439 0.464677 0.548124 +outer loop +vertex -0.653281 0.270598 0.707107 +vertex -0.653281 0.653281 0.382684 +vertex -0.853553 0.353553 0.382683 +endloop +endfacet +facet normal -0.468140 0.312801 0.826438 +outer loop +vertex -0.500000 0.500000 0.707107 +vertex -0.653281 0.270598 0.707107 +vertex -0.270598 0.270598 0.923880 +endloop +endfacet +facet normal -0.695439 0.464677 0.548124 +outer loop +vertex -0.500000 0.500000 0.707107 +vertex -0.653281 0.653281 0.382684 +vertex -0.653281 0.270598 0.707107 +endloop +endfacet +facet normal -0.464677 0.695439 0.548124 +outer loop +vertex -0.270598 0.653281 0.707107 +vertex -0.653281 0.653281 0.382684 +vertex -0.500000 0.500000 0.707107 +endloop +endfacet +facet normal -0.163173 0.820326 0.548124 +outer loop +vertex -0.270598 0.653281 0.707107 +vertex -0.000000 0.923879 0.382684 +vertex -0.353553 0.853553 0.382684 +endloop +endfacet +facet normal -0.109841 0.552208 0.826439 +outer loop +vertex -0.000000 0.707107 0.707107 +vertex -0.270598 0.653281 0.707107 +vertex -0.000000 0.382683 0.923880 +endloop +endfacet +facet normal -0.163173 0.820326 0.548124 +outer loop +vertex -0.000000 0.707107 0.707107 +vertex -0.000000 0.923879 0.382684 +vertex -0.270598 0.653281 0.707107 +endloop +endfacet +facet normal 0.163173 0.820326 0.548124 +outer loop +vertex 0.270598 0.653281 0.707107 +vertex -0.000000 0.923879 0.382684 +vertex -0.000000 0.707107 0.707107 +endloop +endfacet +facet normal 0.464677 0.695438 0.548124 +outer loop +vertex 0.270598 0.653281 0.707107 +vertex 0.653281 0.653281 0.382684 +vertex 0.353553 0.853553 0.382684 +endloop +endfacet +facet normal 0.312801 0.468140 0.826439 +outer loop +vertex 0.500000 0.500000 0.707107 +vertex 0.270598 0.653281 0.707107 +vertex 0.270598 0.270598 0.923880 +endloop +endfacet +facet normal 0.464677 0.695439 0.548124 +outer loop +vertex 0.500000 0.500000 0.707107 +vertex 0.653281 0.653281 0.382684 +vertex 0.270598 0.653281 0.707107 +endloop +endfacet +facet normal 0.820326 0.163173 0.548124 +outer loop +vertex 0.653281 0.270598 0.707107 +vertex 0.923880 -0.000000 0.382683 +vertex 0.853553 0.353553 0.382683 +endloop +endfacet +facet normal 0.695439 0.464677 0.548124 +outer loop +vertex 0.653281 0.270598 0.707107 +vertex 0.653281 0.653281 0.382684 +vertex 0.500000 0.500000 0.707107 +endloop +endfacet +facet normal 0.962637 -0.191481 0.191480 +outer loop +vertex 0.923880 -0.000000 0.382683 +vertex 0.923880 -0.382683 -0.000000 +vertex 1.000000 -0.000000 0.000000 +endloop +endfacet +facet normal 0.962637 0.191480 0.191480 +outer loop +vertex 0.923880 -0.000000 0.382683 +vertex 0.923880 0.382683 0.000000 +vertex 0.853553 0.353553 0.382683 +endloop +endfacet +facet normal 0.820326 -0.163173 0.548124 +outer loop +vertex 0.853553 -0.353553 0.382683 +vertex 0.923880 -0.000000 0.382683 +vertex 0.653281 -0.270598 0.707107 +endloop +endfacet +facet normal 0.962637 -0.191480 0.191480 +outer loop +vertex 0.853553 -0.353553 0.382683 +vertex 0.923880 -0.382683 -0.000000 +vertex 0.923880 -0.000000 0.382683 +endloop +endfacet +facet normal 0.816084 -0.545291 0.191480 +outer loop +vertex 0.653281 -0.653282 0.382683 +vertex 0.923880 -0.382683 -0.000000 +vertex 0.853553 -0.353553 0.382683 +endloop +endfacet +facet normal 0.545290 -0.816085 0.191480 +outer loop +vertex 0.653281 -0.653282 0.382683 +vertex 0.382683 -0.923880 -0.000000 +vertex 0.707107 -0.707107 -0.000000 +endloop +endfacet +facet normal 0.464677 -0.695439 0.548124 +outer loop +vertex 0.353553 -0.853553 0.382683 +vertex 0.653281 -0.653282 0.382683 +vertex 0.270598 -0.653282 0.707107 +endloop +endfacet +facet normal 0.545290 -0.816084 0.191481 +outer loop +vertex 0.353553 -0.853553 0.382683 +vertex 0.382683 -0.923880 -0.000000 +vertex 0.653281 -0.653282 0.382683 +endloop +endfacet +facet normal 0.191480 -0.962637 0.191480 +outer loop +vertex 0.000000 -0.923880 0.382683 +vertex 0.382683 -0.923880 -0.000000 +vertex 0.353553 -0.853553 0.382683 +endloop +endfacet +facet normal -0.191481 -0.962637 0.191480 +outer loop +vertex 0.000000 -0.923880 0.382683 +vertex -0.382683 -0.923880 -0.000000 +vertex 0.000000 -1.000000 -0.000000 +endloop +endfacet +facet normal -0.163173 -0.820326 0.548124 +outer loop +vertex -0.353553 -0.853553 0.382683 +vertex 0.000000 -0.923880 0.382683 +vertex -0.270598 -0.653282 0.707107 +endloop +endfacet +facet normal -0.191480 -0.962637 0.191480 +outer loop +vertex -0.353553 -0.853553 0.382683 +vertex -0.382683 -0.923880 -0.000000 +vertex 0.000000 -0.923880 0.382683 +endloop +endfacet +facet normal -0.545290 -0.816084 0.191480 +outer loop +vertex -0.653281 -0.653282 0.382683 +vertex -0.382683 -0.923880 -0.000000 +vertex -0.353553 -0.853553 0.382683 +endloop +endfacet +facet normal -0.816085 -0.545290 0.191481 +outer loop +vertex -0.653281 -0.653282 0.382683 +vertex -0.923880 -0.382683 -0.000000 +vertex -0.707107 -0.707107 -0.000000 +endloop +endfacet +facet normal -0.695438 -0.464677 0.548124 +outer loop +vertex -0.853553 -0.353553 0.382683 +vertex -0.653281 -0.653282 0.382683 +vertex -0.653281 -0.270598 0.707107 +endloop +endfacet +facet normal -0.816084 -0.545291 0.191480 +outer loop +vertex -0.853553 -0.353553 0.382683 +vertex -0.923880 -0.382683 -0.000000 +vertex -0.653281 -0.653282 0.382683 +endloop +endfacet +facet normal -0.962637 -0.191480 0.191480 +outer loop +vertex -0.923880 -0.000000 0.382683 +vertex -0.923880 -0.382683 -0.000000 +vertex -0.853553 -0.353553 0.382683 +endloop +endfacet +facet normal -0.962637 0.191480 0.191481 +outer loop +vertex -0.923880 -0.000000 0.382683 +vertex -0.923880 0.382683 0.000000 +vertex -1.000000 -0.000000 0.000000 +endloop +endfacet +facet normal -0.820326 0.163172 0.548124 +outer loop +vertex -0.853553 0.353553 0.382683 +vertex -0.923880 -0.000000 0.382683 +vertex -0.653281 0.270598 0.707107 +endloop +endfacet +facet normal -0.962637 0.191480 0.191480 +outer loop +vertex -0.853553 0.353553 0.382683 +vertex -0.923880 0.382683 0.000000 +vertex -0.923880 -0.000000 0.382683 +endloop +endfacet +facet normal -0.816084 0.545291 0.191480 +outer loop +vertex -0.653281 0.653281 0.382684 +vertex -0.923880 0.382683 0.000000 +vertex -0.853553 0.353553 0.382683 +endloop +endfacet +facet normal -0.545290 0.816085 0.191480 +outer loop +vertex -0.653281 0.653281 0.382684 +vertex -0.382683 0.923880 0.000000 +vertex -0.707107 0.707107 0.000000 +endloop +endfacet +facet normal -0.464677 0.695438 0.548125 +outer loop +vertex -0.353553 0.853553 0.382684 +vertex -0.653281 0.653281 0.382684 +vertex -0.270598 0.653281 0.707107 +endloop +endfacet +facet normal -0.545290 0.816084 0.191481 +outer loop +vertex -0.353553 0.853553 0.382684 +vertex -0.382683 0.923880 0.000000 +vertex -0.653281 0.653281 0.382684 +endloop +endfacet +facet normal -0.191480 0.962637 0.191481 +outer loop +vertex -0.000000 0.923879 0.382684 +vertex -0.382683 0.923880 0.000000 +vertex -0.353553 0.853553 0.382684 +endloop +endfacet +facet normal 0.191481 0.962637 0.191480 +outer loop +vertex -0.000000 0.923879 0.382684 +vertex 0.382683 0.923880 0.000000 +vertex -0.000000 1.000000 0.000000 +endloop +endfacet +facet normal 0.163173 0.820326 0.548124 +outer loop +vertex 0.353553 0.853553 0.382684 +vertex -0.000000 0.923879 0.382684 +vertex 0.270598 0.653281 0.707107 +endloop +endfacet +facet normal 0.191480 0.962637 0.191481 +outer loop +vertex 0.353553 0.853553 0.382684 +vertex 0.382683 0.923880 0.000000 +vertex -0.000000 0.923879 0.382684 +endloop +endfacet +facet normal 0.545290 0.816084 0.191480 +outer loop +vertex 0.653281 0.653281 0.382684 +vertex 0.382683 0.923880 0.000000 +vertex 0.353553 0.853553 0.382684 +endloop +endfacet +facet normal 0.816085 0.545290 0.191481 +outer loop +vertex 0.653281 0.653281 0.382684 +vertex 0.923880 0.382683 0.000000 +vertex 0.707107 0.707107 0.000000 +endloop +endfacet +facet normal 0.695439 0.464677 0.548124 +outer loop +vertex 0.853553 0.353553 0.382683 +vertex 0.653281 0.653281 0.382684 +vertex 0.653281 0.270598 0.707107 +endloop +endfacet +facet normal 0.816084 0.545291 0.191480 +outer loop +vertex 0.853553 0.353553 0.382683 +vertex 0.923880 0.382683 0.000000 +vertex 0.653281 0.653281 0.382684 +endloop +endfacet +facet normal 0.962637 0.191480 0.191481 +outer loop +vertex 1.000000 -0.000000 0.000000 +vertex 0.923880 0.382683 0.000000 +vertex 0.923880 -0.000000 0.382683 +endloop +endfacet +facet normal 0.962637 0.191481 -0.191480 +outer loop +vertex 1.000000 -0.000000 0.000000 +vertex 0.923880 0.000000 -0.382683 +vertex 0.923880 0.382683 0.000000 +endloop +endfacet +facet normal 0.962637 -0.191480 -0.191481 +outer loop +vertex 0.923880 -0.382683 -0.000000 +vertex 0.923880 0.000000 -0.382683 +vertex 1.000000 -0.000000 0.000000 +endloop +endfacet +facet normal 0.816084 -0.545290 -0.191480 +outer loop +vertex 0.923880 -0.382683 -0.000000 +vertex 0.653281 -0.653281 -0.382684 +vertex 0.853553 -0.353553 -0.382683 +endloop +endfacet +facet normal 0.816085 -0.545290 0.191481 +outer loop +vertex 0.707107 -0.707107 -0.000000 +vertex 0.923880 -0.382683 -0.000000 +vertex 0.653281 -0.653282 0.382683 +endloop +endfacet +facet normal 0.816084 -0.545290 -0.191481 +outer loop +vertex 0.707107 -0.707107 -0.000000 +vertex 0.653281 -0.653281 -0.382684 +vertex 0.923880 -0.382683 -0.000000 +endloop +endfacet +facet normal 0.545290 -0.816085 -0.191480 +outer loop +vertex 0.382683 -0.923880 -0.000000 +vertex 0.653281 -0.653281 -0.382684 +vertex 0.707107 -0.707107 -0.000000 +endloop +endfacet +facet normal 0.191480 -0.962637 -0.191481 +outer loop +vertex 0.382683 -0.923880 -0.000000 +vertex 0.000000 -0.923879 -0.382684 +vertex 0.353553 -0.853553 -0.382684 +endloop +endfacet +facet normal 0.191481 -0.962637 0.191480 +outer loop +vertex 0.000000 -1.000000 -0.000000 +vertex 0.382683 -0.923880 -0.000000 +vertex 0.000000 -0.923880 0.382683 +endloop +endfacet +facet normal 0.191481 -0.962637 -0.191480 +outer loop +vertex 0.000000 -1.000000 -0.000000 +vertex 0.000000 -0.923879 -0.382684 +vertex 0.382683 -0.923880 -0.000000 +endloop +endfacet +facet normal -0.191481 -0.962637 -0.191480 +outer loop +vertex -0.382683 -0.923880 -0.000000 +vertex 0.000000 -0.923879 -0.382684 +vertex 0.000000 -1.000000 -0.000000 +endloop +endfacet +facet normal -0.545290 -0.816084 -0.191481 +outer loop +vertex -0.382683 -0.923880 -0.000000 +vertex -0.653281 -0.653281 -0.382684 +vertex -0.353553 -0.853553 -0.382684 +endloop +endfacet +facet normal -0.545290 -0.816085 0.191480 +outer loop +vertex -0.707107 -0.707107 -0.000000 +vertex -0.382683 -0.923880 -0.000000 +vertex -0.653281 -0.653282 0.382683 +endloop +endfacet +facet normal -0.545290 -0.816085 -0.191480 +outer loop +vertex -0.707107 -0.707107 -0.000000 +vertex -0.653281 -0.653281 -0.382684 +vertex -0.382683 -0.923880 -0.000000 +endloop +endfacet +facet normal -0.816084 -0.545290 -0.191481 +outer loop +vertex -0.923880 -0.382683 -0.000000 +vertex -0.653281 -0.653281 -0.382684 +vertex -0.707107 -0.707107 -0.000000 +endloop +endfacet +facet normal -0.962637 -0.191480 -0.191480 +outer loop +vertex -0.923880 -0.382683 -0.000000 +vertex -0.923880 0.000000 -0.382683 +vertex -0.853553 -0.353553 -0.382683 +endloop +endfacet +facet normal -0.962637 -0.191481 0.191480 +outer loop +vertex -1.000000 -0.000000 0.000000 +vertex -0.923880 -0.382683 -0.000000 +vertex -0.923880 -0.000000 0.382683 +endloop +endfacet +facet normal -0.962637 -0.191480 -0.191481 +outer loop +vertex -1.000000 -0.000000 0.000000 +vertex -0.923880 0.000000 -0.382683 +vertex -0.923880 -0.382683 -0.000000 +endloop +endfacet +facet normal -0.962637 0.191481 -0.191480 +outer loop +vertex -0.923880 0.382683 0.000000 +vertex -0.923880 0.000000 -0.382683 +vertex -1.000000 -0.000000 0.000000 +endloop +endfacet +facet normal -0.816084 0.545291 -0.191480 +outer loop +vertex -0.923880 0.382683 0.000000 +vertex -0.653281 0.653282 -0.382683 +vertex -0.853553 0.353553 -0.382683 +endloop +endfacet +facet normal -0.816084 0.545290 0.191481 +outer loop +vertex -0.707107 0.707107 0.000000 +vertex -0.923880 0.382683 0.000000 +vertex -0.653281 0.653281 0.382684 +endloop +endfacet +facet normal -0.816085 0.545290 -0.191481 +outer loop +vertex -0.707107 0.707107 0.000000 +vertex -0.653281 0.653282 -0.382683 +vertex -0.923880 0.382683 0.000000 +endloop +endfacet +facet normal -0.545290 0.816085 -0.191480 +outer loop +vertex -0.382683 0.923880 0.000000 +vertex -0.653281 0.653282 -0.382683 +vertex -0.707107 0.707107 0.000000 +endloop +endfacet +facet normal -0.191480 0.962637 -0.191480 +outer loop +vertex -0.382683 0.923880 0.000000 +vertex -0.000000 0.923880 -0.382683 +vertex -0.353553 0.853553 -0.382683 +endloop +endfacet +facet normal -0.191481 0.962637 0.191480 +outer loop +vertex -0.000000 1.000000 0.000000 +vertex -0.382683 0.923880 0.000000 +vertex -0.000000 0.923879 0.382684 +endloop +endfacet +facet normal -0.191481 0.962637 -0.191480 +outer loop +vertex -0.000000 1.000000 0.000000 +vertex -0.000000 0.923880 -0.382683 +vertex -0.382683 0.923880 0.000000 +endloop +endfacet +facet normal 0.191481 0.962637 -0.191480 +outer loop +vertex 0.382683 0.923880 0.000000 +vertex -0.000000 0.923880 -0.382683 +vertex -0.000000 1.000000 0.000000 +endloop +endfacet +facet normal 0.545290 0.816084 -0.191481 +outer loop +vertex 0.382683 0.923880 0.000000 +vertex 0.653281 0.653282 -0.382683 +vertex 0.353553 0.853553 -0.382683 +endloop +endfacet +facet normal 0.545290 0.816085 0.191480 +outer loop +vertex 0.707107 0.707107 0.000000 +vertex 0.382683 0.923880 0.000000 +vertex 0.653281 0.653281 0.382684 +endloop +endfacet +facet normal 0.545290 0.816085 -0.191480 +outer loop +vertex 0.707107 0.707107 0.000000 +vertex 0.653281 0.653282 -0.382683 +vertex 0.382683 0.923880 0.000000 +endloop +endfacet +facet normal 0.962637 0.191480 -0.191480 +outer loop +vertex 0.923880 0.382683 0.000000 +vertex 0.923880 0.000000 -0.382683 +vertex 0.853553 0.353553 -0.382683 +endloop +endfacet +facet normal 0.816085 0.545290 -0.191481 +outer loop +vertex 0.923880 0.382683 0.000000 +vertex 0.653281 0.653282 -0.382683 +vertex 0.707107 0.707107 0.000000 +endloop +endfacet +facet normal 0.820326 -0.163173 -0.548124 +outer loop +vertex 0.923880 0.000000 -0.382683 +vertex 0.653281 -0.270598 -0.707107 +vertex 0.707107 0.000000 -0.707107 +endloop +endfacet +facet normal 0.820326 0.163173 -0.548124 +outer loop +vertex 0.923880 0.000000 -0.382683 +vertex 0.653281 0.270598 -0.707107 +vertex 0.853553 0.353553 -0.382683 +endloop +endfacet +facet normal 0.962637 -0.191480 -0.191480 +outer loop +vertex 0.853553 -0.353553 -0.382683 +vertex 0.923880 0.000000 -0.382683 +vertex 0.923880 -0.382683 -0.000000 +endloop +endfacet +facet normal 0.820326 -0.163172 -0.548124 +outer loop +vertex 0.853553 -0.353553 -0.382683 +vertex 0.653281 -0.270598 -0.707107 +vertex 0.923880 0.000000 -0.382683 +endloop +endfacet +facet normal 0.695439 -0.464677 -0.548124 +outer loop +vertex 0.653281 -0.653281 -0.382684 +vertex 0.653281 -0.270598 -0.707107 +vertex 0.853553 -0.353553 -0.382683 +endloop +endfacet +facet normal 0.464677 -0.695439 -0.548124 +outer loop +vertex 0.653281 -0.653281 -0.382684 +vertex 0.270598 -0.653281 -0.707107 +vertex 0.500000 -0.500000 -0.707107 +endloop +endfacet +facet normal 0.545290 -0.816084 -0.191481 +outer loop +vertex 0.353553 -0.853553 -0.382684 +vertex 0.653281 -0.653281 -0.382684 +vertex 0.382683 -0.923880 -0.000000 +endloop +endfacet +facet normal 0.464677 -0.695438 -0.548125 +outer loop +vertex 0.353553 -0.853553 -0.382684 +vertex 0.270598 -0.653281 -0.707107 +vertex 0.653281 -0.653281 -0.382684 +endloop +endfacet +facet normal 0.163173 -0.820326 -0.548124 +outer loop +vertex 0.000000 -0.923879 -0.382684 +vertex 0.270598 -0.653281 -0.707107 +vertex 0.353553 -0.853553 -0.382684 +endloop +endfacet +facet normal -0.163173 -0.820326 -0.548124 +outer loop +vertex 0.000000 -0.923879 -0.382684 +vertex -0.270598 -0.653281 -0.707107 +vertex 0.000000 -0.707107 -0.707107 +endloop +endfacet +facet normal -0.191480 -0.962637 -0.191481 +outer loop +vertex -0.353553 -0.853553 -0.382684 +vertex 0.000000 -0.923879 -0.382684 +vertex -0.382683 -0.923880 -0.000000 +endloop +endfacet +facet normal -0.163173 -0.820326 -0.548124 +outer loop +vertex -0.353553 -0.853553 -0.382684 +vertex -0.270598 -0.653281 -0.707107 +vertex 0.000000 -0.923879 -0.382684 +endloop +endfacet +facet normal -0.464677 -0.695438 -0.548125 +outer loop +vertex -0.653281 -0.653281 -0.382684 +vertex -0.270598 -0.653281 -0.707107 +vertex -0.353553 -0.853553 -0.382684 +endloop +endfacet +facet normal -0.695439 -0.464677 -0.548124 +outer loop +vertex -0.653281 -0.653281 -0.382684 +vertex -0.653281 -0.270598 -0.707107 +vertex -0.500000 -0.500000 -0.707107 +endloop +endfacet +facet normal -0.816084 -0.545291 -0.191480 +outer loop +vertex -0.853553 -0.353553 -0.382683 +vertex -0.653281 -0.653281 -0.382684 +vertex -0.923880 -0.382683 -0.000000 +endloop +endfacet +facet normal -0.695439 -0.464677 -0.548124 +outer loop +vertex -0.853553 -0.353553 -0.382683 +vertex -0.653281 -0.270598 -0.707107 +vertex -0.653281 -0.653281 -0.382684 +endloop +endfacet +facet normal -0.820326 -0.163172 -0.548124 +outer loop +vertex -0.923880 0.000000 -0.382683 +vertex -0.653281 -0.270598 -0.707107 +vertex -0.853553 -0.353553 -0.382683 +endloop +endfacet +facet normal -0.820326 0.163173 -0.548124 +outer loop +vertex -0.923880 0.000000 -0.382683 +vertex -0.653281 0.270598 -0.707107 +vertex -0.707107 0.000000 -0.707107 +endloop +endfacet +facet normal -0.962637 0.191480 -0.191480 +outer loop +vertex -0.853553 0.353553 -0.382683 +vertex -0.923880 0.000000 -0.382683 +vertex -0.923880 0.382683 0.000000 +endloop +endfacet +facet normal -0.820326 0.163173 -0.548124 +outer loop +vertex -0.853553 0.353553 -0.382683 +vertex -0.653281 0.270598 -0.707107 +vertex -0.923880 0.000000 -0.382683 +endloop +endfacet +facet normal -0.695438 0.464677 -0.548124 +outer loop +vertex -0.653281 0.653282 -0.382683 +vertex -0.653281 0.270598 -0.707107 +vertex -0.853553 0.353553 -0.382683 +endloop +endfacet +facet normal -0.464677 0.695439 -0.548124 +outer loop +vertex -0.653281 0.653282 -0.382683 +vertex -0.270598 0.653282 -0.707107 +vertex -0.500000 0.500000 -0.707107 +endloop +endfacet +facet normal -0.545290 0.816084 -0.191481 +outer loop +vertex -0.353553 0.853553 -0.382683 +vertex -0.653281 0.653282 -0.382683 +vertex -0.382683 0.923880 0.000000 +endloop +endfacet +facet normal -0.464677 0.695439 -0.548124 +outer loop +vertex -0.353553 0.853553 -0.382683 +vertex -0.270598 0.653282 -0.707107 +vertex -0.653281 0.653282 -0.382683 +endloop +endfacet +facet normal -0.163173 0.820326 -0.548124 +outer loop +vertex -0.000000 0.923880 -0.382683 +vertex -0.270598 0.653282 -0.707107 +vertex -0.353553 0.853553 -0.382683 +endloop +endfacet +facet normal 0.163173 0.820326 -0.548124 +outer loop +vertex -0.000000 0.923880 -0.382683 +vertex 0.270598 0.653282 -0.707107 +vertex -0.000000 0.707107 -0.707107 +endloop +endfacet +facet normal 0.191480 0.962637 -0.191480 +outer loop +vertex 0.353553 0.853553 -0.382683 +vertex -0.000000 0.923880 -0.382683 +vertex 0.382683 0.923880 0.000000 +endloop +endfacet +facet normal 0.163173 0.820326 -0.548124 +outer loop +vertex 0.353553 0.853553 -0.382683 +vertex 0.270598 0.653282 -0.707107 +vertex -0.000000 0.923880 -0.382683 +endloop +endfacet +facet normal 0.464677 0.695439 -0.548124 +outer loop +vertex 0.653281 0.653282 -0.382683 +vertex 0.270598 0.653282 -0.707107 +vertex 0.353553 0.853553 -0.382683 +endloop +endfacet +facet normal 0.695439 0.464677 -0.548124 +outer loop +vertex 0.653281 0.653282 -0.382683 +vertex 0.653281 0.270598 -0.707107 +vertex 0.500000 0.500000 -0.707107 +endloop +endfacet +facet normal 0.816084 0.545291 -0.191480 +outer loop +vertex 0.853553 0.353553 -0.382683 +vertex 0.653281 0.653282 -0.382683 +vertex 0.923880 0.382683 0.000000 +endloop +endfacet +facet normal 0.695438 0.464677 -0.548124 +outer loop +vertex 0.853553 0.353553 -0.382683 +vertex 0.653281 0.270598 -0.707107 +vertex 0.653281 0.653282 -0.382683 +endloop +endfacet +facet normal 0.820326 0.163173 -0.548124 +outer loop +vertex 0.707107 0.000000 -0.707107 +vertex 0.653281 0.270598 -0.707107 +vertex 0.923880 0.000000 -0.382683 +endloop +endfacet +facet normal 0.552209 0.109841 -0.826438 +outer loop +vertex 0.707107 0.000000 -0.707107 +vertex 0.382683 0.000000 -0.923880 +vertex 0.653281 0.270598 -0.707107 +endloop +endfacet +facet normal 0.552208 -0.109841 -0.826439 +outer loop +vertex 0.653281 -0.270598 -0.707107 +vertex 0.382683 0.000000 -0.923880 +vertex 0.707107 0.000000 -0.707107 +endloop +endfacet +facet normal 0.468140 -0.312801 -0.826439 +outer loop +vertex 0.653281 -0.270598 -0.707107 +vertex 0.270598 -0.270598 -0.923880 +vertex 0.353553 -0.146446 -0.923880 +endloop +endfacet +facet normal 0.695439 -0.464677 -0.548124 +outer loop +vertex 0.500000 -0.500000 -0.707107 +vertex 0.653281 -0.270598 -0.707107 +vertex 0.653281 -0.653281 -0.382684 +endloop +endfacet +facet normal 0.468140 -0.312801 -0.826438 +outer loop +vertex 0.500000 -0.500000 -0.707107 +vertex 0.270598 -0.270598 -0.923880 +vertex 0.653281 -0.270598 -0.707107 +endloop +endfacet +facet normal 0.312801 -0.468140 -0.826439 +outer loop +vertex 0.270598 -0.653281 -0.707107 +vertex 0.270598 -0.270598 -0.923880 +vertex 0.500000 -0.500000 -0.707107 +endloop +endfacet +facet normal 0.109841 -0.552209 -0.826439 +outer loop +vertex 0.270598 -0.653281 -0.707107 +vertex 0.000000 -0.382683 -0.923880 +vertex 0.146447 -0.353553 -0.923880 +endloop +endfacet +facet normal 0.163173 -0.820326 -0.548124 +outer loop +vertex 0.000000 -0.707107 -0.707107 +vertex 0.270598 -0.653281 -0.707107 +vertex 0.000000 -0.923879 -0.382684 +endloop +endfacet +facet normal 0.109841 -0.552208 -0.826439 +outer loop +vertex 0.000000 -0.707107 -0.707107 +vertex 0.000000 -0.382683 -0.923880 +vertex 0.270598 -0.653281 -0.707107 +endloop +endfacet +facet normal -0.109841 -0.552208 -0.826439 +outer loop +vertex -0.270598 -0.653281 -0.707107 +vertex 0.000000 -0.382683 -0.923880 +vertex 0.000000 -0.707107 -0.707107 +endloop +endfacet +facet normal -0.312801 -0.468140 -0.826439 +outer loop +vertex -0.270598 -0.653281 -0.707107 +vertex -0.270598 -0.270598 -0.923880 +vertex -0.146447 -0.353553 -0.923880 +endloop +endfacet +facet normal -0.464677 -0.695439 -0.548124 +outer loop +vertex -0.500000 -0.500000 -0.707107 +vertex -0.270598 -0.653281 -0.707107 +vertex -0.653281 -0.653281 -0.382684 +endloop +endfacet +facet normal -0.312801 -0.468140 -0.826439 +outer loop +vertex -0.500000 -0.500000 -0.707107 +vertex -0.270598 -0.270598 -0.923880 +vertex -0.270598 -0.653281 -0.707107 +endloop +endfacet +facet normal -0.468140 -0.312801 -0.826438 +outer loop +vertex -0.653281 -0.270598 -0.707107 +vertex -0.270598 -0.270598 -0.923880 +vertex -0.500000 -0.500000 -0.707107 +endloop +endfacet +facet normal -0.552208 -0.109841 -0.826439 +outer loop +vertex -0.653281 -0.270598 -0.707107 +vertex -0.382683 0.000000 -0.923880 +vertex -0.353553 -0.146446 -0.923880 +endloop +endfacet +facet normal -0.820326 -0.163172 -0.548124 +outer loop +vertex -0.707107 0.000000 -0.707107 +vertex -0.653281 -0.270598 -0.707107 +vertex -0.923880 0.000000 -0.382683 +endloop +endfacet +facet normal -0.552208 -0.109841 -0.826439 +outer loop +vertex -0.707107 0.000000 -0.707107 +vertex -0.382683 0.000000 -0.923880 +vertex -0.653281 -0.270598 -0.707107 +endloop +endfacet +facet normal -0.552209 0.109841 -0.826438 +outer loop +vertex -0.653281 0.270598 -0.707107 +vertex -0.382683 0.000000 -0.923880 +vertex -0.707107 0.000000 -0.707107 +endloop +endfacet +facet normal -0.468140 0.312801 -0.826438 +outer loop +vertex -0.653281 0.270598 -0.707107 +vertex -0.270598 0.270598 -0.923879 +vertex -0.353553 0.146447 -0.923880 +endloop +endfacet +facet normal -0.695439 0.464677 -0.548124 +outer loop +vertex -0.500000 0.500000 -0.707107 +vertex -0.653281 0.270598 -0.707107 +vertex -0.653281 0.653282 -0.382683 +endloop +endfacet +facet normal -0.468140 0.312801 -0.826439 +outer loop +vertex -0.500000 0.500000 -0.707107 +vertex -0.270598 0.270598 -0.923879 +vertex -0.653281 0.270598 -0.707107 +endloop +endfacet +facet normal -0.312801 0.468140 -0.826438 +outer loop +vertex -0.270598 0.653282 -0.707107 +vertex -0.270598 0.270598 -0.923879 +vertex -0.500000 0.500000 -0.707107 +endloop +endfacet +facet normal -0.109841 0.552208 -0.826439 +outer loop +vertex -0.270598 0.653282 -0.707107 +vertex -0.000000 0.382684 -0.923879 +vertex -0.146447 0.353554 -0.923879 +endloop +endfacet +facet normal -0.163173 0.820326 -0.548124 +outer loop +vertex -0.000000 0.707107 -0.707107 +vertex -0.270598 0.653282 -0.707107 +vertex -0.000000 0.923880 -0.382683 +endloop +endfacet +facet normal -0.109841 0.552209 -0.826438 +outer loop +vertex -0.000000 0.707107 -0.707107 +vertex -0.000000 0.382684 -0.923879 +vertex -0.270598 0.653282 -0.707107 +endloop +endfacet +facet normal 0.109841 0.552209 -0.826438 +outer loop +vertex 0.270598 0.653282 -0.707107 +vertex -0.000000 0.382684 -0.923879 +vertex -0.000000 0.707107 -0.707107 +endloop +endfacet +facet normal 0.312801 0.468140 -0.826438 +outer loop +vertex 0.270598 0.653282 -0.707107 +vertex 0.270598 0.270598 -0.923879 +vertex 0.146447 0.353554 -0.923879 +endloop +endfacet +facet normal 0.464677 0.695439 -0.548124 +outer loop +vertex 0.500000 0.500000 -0.707107 +vertex 0.270598 0.653282 -0.707107 +vertex 0.653281 0.653282 -0.382683 +endloop +endfacet +facet normal 0.312801 0.468140 -0.826438 +outer loop +vertex 0.500000 0.500000 -0.707107 +vertex 0.270598 0.270598 -0.923879 +vertex 0.270598 0.653282 -0.707107 +endloop +endfacet +facet normal 0.552209 0.109841 -0.826438 +outer loop +vertex 0.653281 0.270598 -0.707107 +vertex 0.382683 0.000000 -0.923880 +vertex 0.353553 0.146447 -0.923880 +endloop +endfacet +facet normal 0.468140 0.312801 -0.826439 +outer loop +vertex 0.653281 0.270598 -0.707107 +vertex 0.270598 0.270598 -0.923879 +vertex 0.500000 0.500000 -0.707107 +endloop +endfacet +facet normal 0.194944 0.038777 -0.980048 +outer loop +vertex 0.382683 0.000000 -0.923880 +vertex 0.000000 0.000000 -1.000000 +vertex 0.353553 0.146447 -0.923880 +endloop +endfacet +facet normal 0.552208 -0.109841 -0.826439 +outer loop +vertex 0.353553 -0.146446 -0.923880 +vertex 0.382683 0.000000 -0.923880 +vertex 0.653281 -0.270598 -0.707107 +endloop +endfacet +facet normal 0.194944 -0.038777 -0.980048 +outer loop +vertex 0.353553 -0.146446 -0.923880 +vertex 0.000000 0.000000 -1.000000 +vertex 0.382683 0.000000 -0.923880 +endloop +endfacet +facet normal 0.165265 -0.110426 -0.980048 +outer loop +vertex 0.270598 -0.270598 -0.923880 +vertex 0.000000 0.000000 -1.000000 +vertex 0.353553 -0.146446 -0.923880 +endloop +endfacet +facet normal 0.312801 -0.468140 -0.826438 +outer loop +vertex 0.146447 -0.353553 -0.923880 +vertex 0.270598 -0.270598 -0.923880 +vertex 0.270598 -0.653281 -0.707107 +endloop +endfacet +facet normal 0.110427 -0.165265 -0.980048 +outer loop +vertex 0.146447 -0.353553 -0.923880 +vertex 0.000000 0.000000 -1.000000 +vertex 0.270598 -0.270598 -0.923880 +endloop +endfacet +facet normal 0.038777 -0.194944 -0.980048 +outer loop +vertex 0.000000 -0.382683 -0.923880 +vertex 0.000000 0.000000 -1.000000 +vertex 0.146447 -0.353553 -0.923880 +endloop +endfacet +facet normal -0.109841 -0.552209 -0.826439 +outer loop +vertex -0.146447 -0.353553 -0.923880 +vertex 0.000000 -0.382683 -0.923880 +vertex -0.270598 -0.653281 -0.707107 +endloop +endfacet +facet normal -0.038777 -0.194944 -0.980048 +outer loop +vertex -0.146447 -0.353553 -0.923880 +vertex 0.000000 0.000000 -1.000000 +vertex 0.000000 -0.382683 -0.923880 +endloop +endfacet +facet normal -0.110427 -0.165265 -0.980048 +outer loop +vertex -0.270598 -0.270598 -0.923880 +vertex 0.000000 0.000000 -1.000000 +vertex -0.146447 -0.353553 -0.923880 +endloop +endfacet +facet normal -0.468140 -0.312800 -0.826439 +outer loop +vertex -0.353553 -0.146446 -0.923880 +vertex -0.270598 -0.270598 -0.923880 +vertex -0.653281 -0.270598 -0.707107 +endloop +endfacet +facet normal -0.165265 -0.110426 -0.980048 +outer loop +vertex -0.353553 -0.146446 -0.923880 +vertex 0.000000 0.000000 -1.000000 +vertex -0.270598 -0.270598 -0.923880 +endloop +endfacet +facet normal -0.194944 -0.038777 -0.980048 +outer loop +vertex -0.382683 0.000000 -0.923880 +vertex 0.000000 0.000000 -1.000000 +vertex -0.353553 -0.146446 -0.923880 +endloop +endfacet +facet normal -0.552209 0.109841 -0.826438 +outer loop +vertex -0.353553 0.146447 -0.923880 +vertex -0.382683 0.000000 -0.923880 +vertex -0.653281 0.270598 -0.707107 +endloop +endfacet +facet normal -0.194944 0.038777 -0.980048 +outer loop +vertex -0.353553 0.146447 -0.923880 +vertex 0.000000 0.000000 -1.000000 +vertex -0.382683 0.000000 -0.923880 +endloop +endfacet +facet normal -0.165265 0.110427 -0.980048 +outer loop +vertex -0.270598 0.270598 -0.923879 +vertex 0.000000 0.000000 -1.000000 +vertex -0.353553 0.146447 -0.923880 +endloop +endfacet +facet normal -0.312801 0.468140 -0.826438 +outer loop +vertex -0.146447 0.353554 -0.923879 +vertex -0.270598 0.270598 -0.923879 +vertex -0.270598 0.653282 -0.707107 +endloop +endfacet +facet normal -0.110427 0.165265 -0.980047 +outer loop +vertex -0.146447 0.353554 -0.923879 +vertex 0.000000 0.000000 -1.000000 +vertex -0.270598 0.270598 -0.923879 +endloop +endfacet +facet normal -0.038776 0.194944 -0.980048 +outer loop +vertex -0.000000 0.382684 -0.923879 +vertex 0.000000 0.000000 -1.000000 +vertex -0.146447 0.353554 -0.923879 +endloop +endfacet +facet normal 0.109841 0.552208 -0.826439 +outer loop +vertex 0.146447 0.353554 -0.923879 +vertex -0.000000 0.382684 -0.923879 +vertex 0.270598 0.653282 -0.707107 +endloop +endfacet +facet normal 0.038776 0.194944 -0.980048 +outer loop +vertex 0.146447 0.353554 -0.923879 +vertex 0.000000 0.000000 -1.000000 +vertex -0.000000 0.382684 -0.923879 +endloop +endfacet +facet normal 0.110427 0.165265 -0.980048 +outer loop +vertex 0.270598 0.270598 -0.923879 +vertex 0.000000 0.000000 -1.000000 +vertex 0.146447 0.353554 -0.923879 +endloop +endfacet +facet normal 0.468140 0.312801 -0.826438 +outer loop +vertex 0.353553 0.146447 -0.923880 +vertex 0.270598 0.270598 -0.923879 +vertex 0.653281 0.270598 -0.707107 +endloop +endfacet +facet normal 0.165265 0.110427 -0.980048 +outer loop +vertex 0.353553 0.146447 -0.923880 +vertex 0.000000 0.000000 -1.000000 +vertex 0.270598 0.270598 -0.923879 +endloop +endfacet +endsolid Exported from Blender-3.0.1