diff --git a/bindings/Mandos/python/Deformable3D.cpp b/bindings/Mandos/python/Deformable3D.cpp index 820086fbdf5675dfaae762896e9466a68288f469..24529bb1d2ac2b3fd72fafba4195a5c667f894bc 100644 --- a/bindings/Mandos/python/Deformable3D.cpp +++ b/bindings/Mandos/python/Deformable3D.cpp @@ -15,6 +15,7 @@ #include #include + NB_MAKE_OPAQUE(mandos::core::DiffParameterHandleV) void mandos::py::wrapDeformable3D(nb::module_ &m) @@ -84,9 +85,31 @@ void mandos::py::wrapDeformable3D(nb::module_ &m) nb::arg("x") = true, nb::arg("y") = true, nb::arg("z") = true) - .def("fixed_dof_vector", &Deformable3D::getFixedDofVector); + .def("fixed_dof_vector", &Deformable3D::getFixedDofVector) + // Differential parameters + //-------------------------- + // Mass Spring + .def("diff", [](const Deformable3D &self, mandos::core::MassSpring::Parameters parameter) { + switch (parameter) { + case mandos::core::MassSpring::Stiffness: { + mandos::core::DiffParameterHandle + paramHandle(self.handle()); + return mandos::core::DiffParameterHandleV(paramHandle); + } + case mandos::core::MassSpring::RestLength: { + mandos::core::DiffParameterHandle + paramHandle(self.handle()); + return mandos::core::DiffParameterHandleV(paramHandle); + } + } + }); } + mandos::core::SimulationObject &mandos::py::Deformable3D::simObject() { return m_handle.simulationObject(); diff --git a/bindings/Mandos/python/Differentiable.cpp b/bindings/Mandos/python/Differentiable.cpp index 184e88de44ec5340acda6565e409a77a54cf85c2..10106242a8c2ff93b508a3117f2ce46e55e869ff 100644 --- a/bindings/Mandos/python/Differentiable.cpp +++ b/bindings/Mandos/python/Differentiable.cpp @@ -4,7 +4,7 @@ #include #include - +#include namespace nb = nanobind; NB_MAKE_OPAQUE(mandos::core::DiffParameterHandleV) diff --git a/bindings/Mandos/python/Energies/CosseratBendingRod.cpp b/bindings/Mandos/python/Energies/CosseratBendingRod.cpp index 21fbd3e75e5d5da97b42a69d389c21e42b032071..5b946e17dac84af6f165595e47adefeeaebab2e9 100644 --- a/bindings/Mandos/python/Energies/CosseratBendingRod.cpp +++ b/bindings/Mandos/python/Energies/CosseratBendingRod.cpp @@ -6,6 +6,7 @@ #include #include +#include void mandos::py::energies::wrapCosseratBendingRod(nb::module_ &m) { @@ -40,14 +41,21 @@ void mandos::py::energies::wrapCosseratBendingRod(nb::module_ &m) [](const mandos::core::CosseratBendingRod &massSpring, int elementId) { return massSpring.getParameterSet(elementId); }) + .def("set_parameter_set", [](mandos::core::CosseratBendingRod &massSpring, int elementId, const mandos::core::CosseratBendingRod::ParameterSet ¶meterSet) { massSpring.setParameterSet(elementId, parameterSet); + }) + + .def("compute_bending_energy", + [](const mandos::core::CosseratBendingRod &bendingRod, const mandos::py::RigidBodyCloud3D &rbCloud) { + return bendingRod.computeEnergy(rbCloud.simObject().mstate); }); nb::enum_(cosseratBendingRod, "Parameters") .value("intrinsic_darboux", mandos::core::CosseratBendingRod::IntrinsicDarboux) + .value("stiffness_tensor", mandos::core::CosseratBendingRod::StiffnessTensor) .export_values(); } diff --git a/bindings/Mandos/python/Energies/CosseratRodAlignment.cpp b/bindings/Mandos/python/Energies/CosseratRodAlignment.cpp index f17544270383d819c1f2b425ce36022e2e30dc12..da5733c6520666c44bad7c69a457647e47bd6f3e 100644 --- a/bindings/Mandos/python/Energies/CosseratRodAlignment.cpp +++ b/bindings/Mandos/python/Energies/CosseratRodAlignment.cpp @@ -6,6 +6,7 @@ #include #include +#include void mandos::py::energies::wrapCosseratRodAlignment(nb::module_ &m) { @@ -42,5 +43,10 @@ void mandos::py::energies::wrapCosseratRodAlignment(nb::module_ &m) int elementId, const mandos::core::CosseratRodAlignment::ParameterSet ¶meterSet) { massSpring.setParameterSet(elementId, parameterSet); + }) + + .def("compute_cosserat_energy", + [](const mandos::core::CosseratRodAlignment &cosseratRod, const mandos::py::RigidBodyCloud3D &rbCloud) { + return cosseratRod.computeEnergy(rbCloud.simObject().mstate); }); } diff --git a/bindings/Mandos/python/Model.cpp b/bindings/Mandos/python/Model.cpp index 224d252cc7d0b762b4eb07e59106629cac413489..573815930976282be15580658797fe6ccd049c64 100644 --- a/bindings/Mandos/python/Model.cpp +++ b/bindings/Mandos/python/Model.cpp @@ -27,7 +27,7 @@ #include #include - +#include void mandos::py::wrapModel(nb::module_ &m) { const nb::class_ model_(m, "Model_"); @@ -273,6 +273,17 @@ void mandos::py::wrapModel(nb::module_ &m) model.computeEnergyAndGradient(h, g); }) + .def("compute_hessian", + [](Model &model, const mandos::core::Scalar h) { + auto nDof = model.nDof(); + mandos::core::Vec g(nDof); + g.setZero(); + mandos::core::SystemMatrix hessian(nDof, nDof); + // We need to compute advection to ensure inertial forces are correct + model.computeAdvection(h); + + model.computeEnergyGradientAndHessian(h, g, hessian); + }) .def("detect_collisions", [](Model &model) { // Ensure all the graph is updated diff --git a/bindings/Mandos/python/RigidBody.cpp b/bindings/Mandos/python/RigidBody.cpp index 25258bdacc65da3fd5a7d965466f28f78f623f0f..c94e2afdf25f35fbb864973d5e3b557c8c133b9b 100644 --- a/bindings/Mandos/python/RigidBody.cpp +++ b/bindings/Mandos/python/RigidBody.cpp @@ -75,7 +75,19 @@ void wrapRigidBody(nb::module_ &m) transform.block<3, 1>(0, 3) = self.x().segment<3>(0); // Position transform(3, 3) = 1.0; return transform; - }); + }) + + .def("diff", [](RigidBody3D &self, core::MassSpring::Parameters parameter) { + switch (parameter) { + case core::MassSpring::Stiffness: { + mandos::core::DiffParameterHandle + paramHandle(self.handle()); + return mandos::core::DiffParameterHandleV(paramHandle); + } + } + }); nb::class_>(m, "RigidBodyGlobal3D") .def_prop_rw("x", &RigidBody3D::x, &RigidBody3D::setX) @@ -109,6 +121,7 @@ void wrapRigidBody(nb::module_ &m) .def_prop_rw("v", &RigidBodyCloud3D::v, &RigidBodyCloud3D::setV) .def_prop_ro("grad", &RigidBodyCloud3D::grad) .def_prop_ro("hessian", &RigidBodyCloud3D::hessian) + .def_prop_ro("hessian_dense", &RigidBodyCloud3D::hessianDense, nb::rv_policy::copy) .def_prop_rw("mass", &RigidBodyCloud3D::mass, &RigidBodyCloud3D::setMass) .def_prop_rw("inertiaTensor", &RigidBodyCloud3D::inertiaTensor, &RigidBodyCloud3D::setInertiaTensor) .def("enable_gravity", @@ -135,7 +148,29 @@ void wrapRigidBody(nb::module_ &m) nb::arg("z") = true) .def("fix_rotation", &RigidBodyCloud3D::fixRigidBodyRotation, nb::arg("index")) .def("clear_fixing", &RigidBodyCloud3D::clearFixing) - .def("fixed_dof_vector", &RigidBodyCloud3D::getFixedDofVector); + .def("fixed_dof_vector", &RigidBodyCloud3D::getFixedDofVector) + .def("diff", [](RigidBodyCloud3D &self, core::MassSpring::Parameters parameter) { + switch (parameter) { + case core::MassSpring::Stiffness: { + mandos::core::DiffParameterHandle + paramHandle(self.handle()); + return mandos::core::DiffParameterHandleV(paramHandle); + } + } + }) + .def("diff", [](RigidBodyCloud3D &self, core::CosseratBendingRod::Parameters parameter) { + switch (parameter) { + case core::CosseratBendingRod::StiffnessTensor: { + mandos::core::DiffParameterHandle + paramHandle(self.handle()); + return mandos::core::DiffParameterHandleV(paramHandle); + } + } + }); } template @@ -292,6 +327,13 @@ const mandos::core::SparseMat &RigidBodyCloud3D::hessian() const return simObject().mstate.m_hessian; } +const Eigen::MatrixXd RigidBodyCloud3D::hessianDense() const +{ + mandos::core::SparseMat sparseHessian = simObject().mstate.m_hessian; + Eigen::MatrixXd denseHessian = sparseHessian.toDense(); + return denseHessian; +} + mandos::core::MassSpring &RigidBodyCloud3D::massSpring() { return simObject().template potential(); diff --git a/bindings/Mandos/python/RigidBody.hpp b/bindings/Mandos/python/RigidBody.hpp index 4c55d9b4021fde4970d14896936d3dc4f34be842..dc45b232b139fe9ec2c20862307bf2c428c30966 100644 --- a/bindings/Mandos/python/RigidBody.hpp +++ b/bindings/Mandos/python/RigidBody.hpp @@ -2,7 +2,7 @@ #define MANDOS_PY_RIGIDBODY_HPP #include - +#include #include #include #include @@ -85,6 +85,8 @@ struct RigidBodyCloud3D { const mandos::core::SparseMat &hessian() const; + const Eigen::MatrixXd hessianDense() const; + mandos::core::MassSpring &massSpring(); mandos::core::CosseratBendingRod &cosseratBendingRod(); mandos::core::CosseratRodAlignment &cosseratRodAlignment(); diff --git a/examples/python/ColonExperiments/axis.obj b/examples/python/ColonExperiments/axis.obj new file mode 100644 index 0000000000000000000000000000000000000000..e000459b8d1925a2caf4aa4b6aa368418b55348c --- /dev/null +++ b/examples/python/ColonExperiments/axis.obj @@ -0,0 +1,2295 @@ +# Blender 4.1.1 +# www.blender.org +o Sphere +v 0.000000 0.083147 -0.055557 +v 0.000000 0.055557 -0.083147 +v 0.000000 0.019509 -0.098079 +v 0.000000 -0.000000 -0.100000 +v 0.000000 -0.019509 -0.098079 +v 0.000000 -0.055557 -0.083147 +v 0.003806 0.098079 -0.019134 +v 0.007466 0.092388 -0.037533 +v 0.010839 0.083147 -0.054490 +v 0.013795 0.070711 -0.069352 +v 0.016221 0.055557 -0.081549 +v 0.018024 0.038268 -0.090613 +v 0.019134 0.019509 -0.096194 +v 0.019509 -0.000000 -0.098079 +v 0.019134 -0.019509 -0.096194 +v 0.018024 -0.038268 -0.090613 +v 0.016221 -0.055557 -0.081549 +v 0.013795 -0.070711 -0.069352 +v 0.010839 -0.083147 -0.054490 +v 0.007466 -0.092388 -0.037533 +v 0.003806 -0.098079 -0.019134 +v 0.007466 0.098079 -0.018024 +v 0.014645 0.092388 -0.035355 +v 0.021261 0.083147 -0.051328 +v 0.027060 0.070711 -0.065328 +v 0.031819 0.055557 -0.076818 +v 0.035355 0.038268 -0.085355 +v 0.037533 0.019509 -0.090613 +v 0.038268 -0.000000 -0.092388 +v 0.037533 -0.019509 -0.090613 +v 0.035355 -0.038268 -0.085355 +v 0.031819 -0.055557 -0.076818 +v 0.027060 -0.070711 -0.065328 +v 0.021261 -0.083147 -0.051328 +v 0.014645 -0.092388 -0.035355 +v 0.007466 -0.098079 -0.018024 +v 0.010839 0.098079 -0.016221 +v 0.021261 0.092388 -0.031819 +v 0.030866 0.083147 -0.046194 +v 0.039285 0.070711 -0.058794 +v 0.046194 0.055557 -0.069134 +v 0.051328 0.038268 -0.076818 +v 0.054490 0.019509 -0.081549 +v 0.055557 -0.000000 -0.083147 +v 0.054490 -0.019509 -0.081549 +v 0.051328 -0.038268 -0.076818 +v 0.046194 -0.055557 -0.069134 +v 0.039285 -0.070711 -0.058794 +v 0.030866 -0.083147 -0.046194 +v 0.021261 -0.092388 -0.031819 +v 0.010839 -0.098079 -0.016221 +v 0.013795 0.098079 -0.013795 +v 0.027060 0.092388 -0.027060 +v 0.039285 0.083147 -0.039285 +v 0.050000 0.070711 -0.050000 +v 0.058794 0.055557 -0.058794 +v 0.065328 0.038268 -0.065328 +v 0.069352 0.019509 -0.069352 +v 0.070711 -0.000000 -0.070711 +v 0.069352 -0.019509 -0.069352 +v 0.065328 -0.038268 -0.065328 +v 0.058794 -0.055557 -0.058794 +v 0.050000 -0.070711 -0.050000 +v 0.039285 -0.083147 -0.039285 +v 0.027060 -0.092388 -0.027060 +v 0.013795 -0.098079 -0.013795 +v 0.016221 0.098079 -0.010839 +v 0.031819 0.092388 -0.021261 +v 0.046194 0.083147 -0.030866 +v 0.058794 0.070711 -0.039285 +v 0.069134 0.055557 -0.046194 +v 0.076818 0.038268 -0.051328 +v 0.081549 0.019509 -0.054490 +v 0.083147 -0.000000 -0.055557 +v 0.081549 -0.019509 -0.054490 +v 0.076818 -0.038268 -0.051328 +v 0.069134 -0.055557 -0.046194 +v 0.058794 -0.070711 -0.039285 +v 0.046194 -0.083147 -0.030866 +v 0.031819 -0.092388 -0.021261 +v 0.016221 -0.098079 -0.010839 +v 0.000000 0.100000 -0.000000 +v 0.018024 0.098079 -0.007466 +v 0.035355 0.092388 -0.014645 +v 0.051328 0.083147 -0.021261 +v 0.065328 0.070711 -0.027060 +v 0.076818 0.055557 -0.031819 +v 0.085355 0.038268 -0.035355 +v 0.090613 0.019509 -0.037533 +v 0.092388 -0.000000 -0.038268 +v 0.090613 -0.019509 -0.037533 +v 0.085355 -0.038268 -0.035355 +v 0.076818 -0.055557 -0.031819 +v 0.065328 -0.070711 -0.027060 +v 0.051328 -0.083147 -0.021261 +v 0.035355 -0.092388 -0.014645 +v 0.018024 -0.098079 -0.007466 +v 0.019134 0.098079 -0.003806 +v 0.037533 0.092388 -0.007466 +v 0.054490 0.083147 -0.010839 +v 0.069352 0.070711 -0.013795 +v 0.081549 0.055557 -0.016221 +v 0.090613 0.038268 -0.018024 +v 0.096194 0.019509 -0.019134 +v 0.098079 -0.000000 -0.019509 +v 0.096194 -0.019509 -0.019134 +v 0.090613 -0.038268 -0.018024 +v 0.081549 -0.055557 -0.016221 +v 0.069352 -0.070711 -0.013795 +v 0.054490 -0.083147 -0.010839 +v 0.037533 -0.092388 -0.007466 +v 0.019134 -0.098079 -0.003806 +v 0.019509 0.098079 -0.000000 +v 0.038268 0.092388 -0.000000 +v 0.055557 0.083147 -0.000000 +v 0.070711 0.070711 -0.000000 +v 0.083147 0.055557 -0.000000 +v 0.092388 0.038268 -0.000000 +v 0.098079 0.019509 -0.000000 +v 0.100000 0.000000 0.000000 +v 0.098079 -0.019509 0.000000 +v 0.092388 -0.038268 0.000000 +v 0.083147 -0.055557 0.000000 +v 0.070711 -0.070711 0.000000 +v 0.055557 -0.083147 0.000000 +v 0.038268 -0.092388 0.000000 +v 0.019509 -0.098079 0.000000 +v 0.019134 0.098079 0.003806 +v 0.037533 0.092388 0.007466 +v 0.054490 0.083147 0.010839 +v 0.069352 0.070711 0.013795 +v 0.081549 0.055557 0.016221 +v 0.090613 0.038268 0.018024 +v 0.096194 0.019509 0.019134 +v 0.098078 0.000000 0.019509 +v 0.096194 -0.019509 0.019134 +v 0.090613 -0.038268 0.018024 +v 0.081549 -0.055557 0.016221 +v 0.069352 -0.070711 0.013795 +v 0.054490 -0.083147 0.010839 +v 0.037533 -0.092388 0.007466 +v 0.019134 -0.098079 0.003806 +v 0.018024 0.098079 0.007466 +v 0.035355 0.092388 0.014645 +v 0.051328 0.083147 0.021261 +v 0.065328 0.070711 0.027060 +v 0.076818 0.055557 0.031819 +v 0.085355 0.038268 0.035355 +v 0.090613 0.019509 0.037533 +v 0.092388 0.000000 0.038268 +v 0.090613 -0.019509 0.037533 +v 0.085355 -0.038268 0.035355 +v 0.076818 -0.055557 0.031819 +v 0.065328 -0.070711 0.027060 +v 0.051328 -0.083147 0.021261 +v 0.035355 -0.092388 0.014645 +v 0.018024 -0.098079 0.007466 +v 0.016221 0.098079 0.010839 +v 0.031819 0.092388 0.021261 +v 0.046194 0.083147 0.030866 +v 0.058794 0.070711 0.039285 +v 0.069134 0.055557 0.046194 +v 0.076818 0.038268 0.051328 +v 0.081549 0.019509 0.054490 +v 0.083147 0.000000 0.055557 +v 0.081549 -0.019509 0.054490 +v 0.076818 -0.038268 0.051328 +v 0.069134 -0.055557 0.046194 +v 0.058794 -0.070711 0.039285 +v 0.046194 -0.083147 0.030866 +v 0.031819 -0.092388 0.021261 +v 0.016221 -0.098079 0.010839 +v 0.013795 0.098079 0.013795 +v 0.027060 0.092388 0.027060 +v 0.039285 0.083147 0.039285 +v 0.050000 0.070711 0.050000 +v 0.058794 0.055557 0.058794 +v 0.065328 0.038268 0.065328 +v 0.069352 0.019509 0.069352 +v 0.070711 0.000000 0.070711 +v 0.069352 -0.019509 0.069352 +v 0.065328 -0.038268 0.065328 +v 0.058794 -0.055557 0.058794 +v 0.050000 -0.070711 0.050000 +v 0.039285 -0.083147 0.039285 +v 0.027060 -0.092388 0.027060 +v 0.013795 -0.098079 0.013795 +v 0.010839 0.098079 0.016221 +v 0.021261 0.092388 0.031819 +v 0.030866 0.083147 0.046194 +v 0.039285 0.070711 0.058794 +v 0.046194 0.055557 0.069134 +v 0.051328 0.038268 0.076818 +v 0.054489 0.019509 0.081549 +v 0.055557 0.000000 0.083147 +v 0.054489 -0.019509 0.081549 +v 0.051328 -0.038268 0.076818 +v 0.046194 -0.055557 0.069134 +v 0.039285 -0.070711 0.058794 +v 0.030866 -0.083147 0.046194 +v 0.021261 -0.092388 0.031819 +v 0.010839 -0.098079 0.016221 +v 0.007466 0.098079 0.018024 +v 0.014645 0.092388 0.035355 +v 0.021261 0.083147 0.051328 +v 0.027060 0.070711 0.065328 +v 0.031819 0.055557 0.076818 +v 0.035355 0.038268 0.085355 +v 0.037533 0.019509 0.090613 +v 0.038268 0.000000 0.092388 +v 0.037533 -0.019509 0.090613 +v 0.035355 -0.038268 0.085355 +v 0.031819 -0.055557 0.076818 +v 0.027060 -0.070711 0.065328 +v 0.021261 -0.083147 0.051328 +v 0.014645 -0.092388 0.035355 +v 0.007466 -0.098079 0.018024 +v 0.003806 0.098079 0.019134 +v 0.007466 0.092388 0.037533 +v 0.010839 0.083147 0.054489 +v 0.013795 0.070711 0.069352 +v 0.016221 0.055557 0.081549 +v 0.018024 0.038268 0.090613 +v 0.019134 0.019509 0.096194 +v 0.019509 0.000000 0.098078 +v 0.019134 -0.019509 0.096194 +v 0.018024 -0.038268 0.090613 +v 0.016221 -0.055557 0.081549 +v 0.013795 -0.070711 0.069352 +v 0.010839 -0.083147 0.054489 +v 0.007466 -0.092388 0.037533 +v 0.003806 -0.098079 0.019134 +v 0.000000 0.098079 0.019509 +v 0.000000 0.092388 0.038268 +v 0.000000 0.083147 0.055557 +v 0.000000 0.070711 0.070711 +v 0.000000 0.055557 0.083147 +v 0.000000 0.038268 0.092388 +v 0.000000 0.019509 0.098078 +v 0.000000 0.000000 0.100000 +v 0.000000 -0.019509 0.098078 +v 0.000000 -0.038268 0.092388 +v 0.000000 -0.055557 0.083147 +v 0.000000 -0.070711 0.070711 +v 0.000000 -0.083147 0.055557 +v 0.000000 -0.092388 0.038268 +v 0.000000 -0.098079 0.019509 +v -0.003806 0.098079 0.019134 +v -0.007466 0.092388 0.037533 +v -0.010839 0.083147 0.054489 +v -0.013795 0.070711 0.069352 +v -0.016221 0.055557 0.081549 +v -0.018024 0.038268 0.090613 +v -0.019134 0.019509 0.096194 +v -0.019509 0.000000 0.098078 +v -0.019134 -0.019509 0.096194 +v -0.018024 -0.038268 0.090613 +v -0.016221 -0.055557 0.081549 +v -0.013795 -0.070711 0.069352 +v -0.010839 -0.083147 0.054489 +v -0.007466 -0.092388 0.037533 +v -0.003806 -0.098079 0.019134 +v -0.007466 0.098079 0.018024 +v -0.014645 0.092388 0.035355 +v -0.021261 0.083147 0.051328 +v -0.027060 0.070711 0.065328 +v -0.031819 0.055557 0.076818 +v -0.035355 0.038268 0.085355 +v -0.037533 0.019509 0.090613 +v -0.038268 0.000000 0.092388 +v -0.037533 -0.019509 0.090613 +v -0.035355 -0.038268 0.085355 +v -0.031819 -0.055557 0.076818 +v -0.027060 -0.070711 0.065328 +v -0.021261 -0.083147 0.051328 +v -0.014645 -0.092388 0.035355 +v -0.007466 -0.098079 0.018024 +v -0.010839 0.098079 0.016221 +v -0.021261 0.092388 0.031819 +v -0.030866 0.083147 0.046194 +v -0.039285 0.070711 0.058794 +v -0.046194 0.055557 0.069134 +v -0.051328 0.038268 0.076818 +v -0.054490 0.019509 0.081549 +v -0.055557 0.000000 0.083147 +v -0.054490 -0.019509 0.081549 +v -0.051328 -0.038268 0.076818 +v -0.046194 -0.055557 0.069134 +v -0.039285 -0.070711 0.058794 +v -0.030866 -0.083147 0.046194 +v -0.021261 -0.092388 0.031819 +v -0.010839 -0.098079 0.016221 +v -0.013795 0.098079 0.013795 +v -0.027060 0.092388 0.027060 +v -0.039285 0.083147 0.039285 +v -0.050000 0.070711 0.050000 +v -0.058794 0.055557 0.058794 +v -0.065328 0.038268 0.065328 +v -0.069352 0.019509 0.069352 +v -0.070711 0.000000 0.070711 +v -0.069352 -0.019509 0.069352 +v -0.065328 -0.038268 0.065328 +v -0.058794 -0.055557 0.058794 +v -0.050000 -0.070711 0.050000 +v -0.039285 -0.083147 0.039285 +v -0.027060 -0.092388 0.027060 +v -0.013795 -0.098079 0.013795 +v 0.000000 -0.100000 0.000000 +v -0.016221 0.098079 0.010839 +v -0.031819 0.092388 0.021261 +v -0.046194 0.083147 0.030866 +v -0.058794 0.070711 0.039285 +v -0.069134 0.055557 0.046194 +v -0.076818 0.038268 0.051328 +v -0.081549 0.019509 0.054489 +v -0.083147 0.000000 0.055557 +v -0.081549 -0.019509 0.054489 +v -0.076818 -0.038268 0.051328 +v -0.069134 -0.055557 0.046194 +v -0.058794 -0.070711 0.039285 +v -0.046194 -0.083147 0.030866 +v -0.031819 -0.092388 0.021261 +v -0.016221 -0.098079 0.010839 +v -0.018024 0.098079 0.007466 +v -0.035355 0.092388 0.014645 +v -0.051328 0.083147 0.021261 +v -0.065328 0.070711 0.027060 +v -0.076818 0.055557 0.031819 +v -0.085355 0.038268 0.035355 +v -0.090613 0.019509 0.037533 +v -0.092388 0.000000 0.038268 +v -0.090613 -0.019509 0.037533 +v -0.085355 -0.038268 0.035355 +v -0.076818 -0.055557 0.031819 +v -0.065328 -0.070711 0.027060 +v -0.051328 -0.083147 0.021261 +v -0.035355 -0.092388 0.014645 +v -0.018024 -0.098079 0.007466 +v -0.019134 0.098079 0.003806 +v -0.037533 0.092388 0.007466 +v -0.054489 0.083147 0.010839 +v -0.069352 0.070711 0.013795 +v -0.081549 0.055557 0.016221 +v -0.090613 0.038268 0.018024 +v -0.096194 0.019509 0.019134 +v -0.098078 0.000000 0.019509 +v -0.096194 -0.019509 0.019134 +v -0.090613 -0.038268 0.018024 +v -0.081549 -0.055557 0.016221 +v -0.069352 -0.070711 0.013795 +v -0.054489 -0.083147 0.010839 +v -0.037533 -0.092388 0.007466 +v -0.019134 -0.098079 0.003806 +v -0.019509 0.098079 -0.000000 +v -0.038268 0.092388 -0.000000 +v -0.055557 0.083147 -0.000000 +v -0.070711 0.070711 -0.000000 +v -0.083147 0.055557 -0.000000 +v -0.092388 0.038268 -0.000000 +v -0.098078 0.019509 -0.000000 +v -0.100000 0.000000 0.000000 +v -0.098078 -0.019509 0.000000 +v -0.092388 -0.038268 0.000000 +v -0.083147 -0.055557 0.000000 +v -0.070711 -0.070711 0.000000 +v -0.055557 -0.083147 0.000000 +v -0.038268 -0.092388 0.000000 +v -0.019509 -0.098079 0.000000 +v -0.019134 0.098079 -0.003806 +v -0.037533 0.092388 -0.007466 +v -0.054489 0.083147 -0.010839 +v -0.069352 0.070711 -0.013795 +v -0.081549 0.055557 -0.016221 +v -0.090613 0.038268 -0.018024 +v -0.096194 0.019509 -0.019134 +v -0.098078 -0.000000 -0.019509 +v -0.096194 -0.019509 -0.019134 +v -0.090613 -0.038268 -0.018024 +v -0.081549 -0.055557 -0.016221 +v -0.069352 -0.070711 -0.013795 +v -0.054489 -0.083147 -0.010839 +v -0.037533 -0.092388 -0.007466 +v -0.019134 -0.098079 -0.003806 +v -0.018024 0.098079 -0.007466 +v -0.035355 0.092388 -0.014645 +v -0.051328 0.083147 -0.021261 +v -0.065328 0.070711 -0.027060 +v -0.076818 0.055557 -0.031819 +v -0.085355 0.038268 -0.035355 +v -0.090613 0.019509 -0.037533 +v -0.092388 -0.000000 -0.038268 +v -0.090613 -0.019509 -0.037533 +v -0.085355 -0.038268 -0.035355 +v -0.076818 -0.055557 -0.031819 +v -0.065328 -0.070711 -0.027060 +v -0.051328 -0.083147 -0.021261 +v -0.035355 -0.092388 -0.014645 +v -0.018024 -0.098079 -0.007466 +v -0.016221 0.098079 -0.010839 +v -0.031819 0.092388 -0.021261 +v -0.046194 0.083147 -0.030866 +v -0.058794 0.070711 -0.039285 +v -0.069134 0.055557 -0.046194 +v -0.076818 0.038268 -0.051328 +v -0.081549 0.019509 -0.054490 +v -0.083147 -0.000000 -0.055557 +v -0.081549 -0.019509 -0.054490 +v -0.076818 -0.038268 -0.051328 +v -0.069134 -0.055557 -0.046194 +v -0.058794 -0.070711 -0.039285 +v -0.046194 -0.083147 -0.030866 +v -0.031819 -0.092388 -0.021261 +v -0.016221 -0.098079 -0.010839 +v -0.013795 0.098079 -0.013795 +v -0.027060 0.092388 -0.027060 +v -0.039285 0.083147 -0.039285 +v -0.050000 0.070711 -0.050000 +v -0.058794 0.055557 -0.058794 +v -0.065328 0.038268 -0.065328 +v -0.069352 0.019509 -0.069352 +v -0.070711 -0.000000 -0.070711 +v -0.069352 -0.019509 -0.069352 +v -0.065328 -0.038268 -0.065328 +v -0.058794 -0.055557 -0.058794 +v -0.050000 -0.070711 -0.050000 +v -0.039285 -0.083147 -0.039285 +v -0.027060 -0.092388 -0.027060 +v -0.013795 -0.098079 -0.013795 +v -0.010839 0.098079 -0.016221 +v -0.021261 0.092388 -0.031819 +v -0.030866 0.083147 -0.046194 +v -0.039285 0.070711 -0.058794 +v -0.046194 0.055557 -0.069134 +v -0.051328 0.038268 -0.076818 +v -0.054489 0.019509 -0.081549 +v -0.055557 -0.000000 -0.083147 +v -0.054489 -0.019509 -0.081549 +v -0.051328 -0.038268 -0.076818 +v -0.046194 -0.055557 -0.069134 +v -0.039285 -0.070711 -0.058794 +v -0.030866 -0.083147 -0.046194 +v -0.021261 -0.092388 -0.031819 +v -0.010839 -0.098079 -0.016221 +v -0.007466 0.098079 -0.018024 +v -0.014645 0.092388 -0.035355 +v -0.021261 0.083147 -0.051328 +v -0.027060 0.070711 -0.065328 +v -0.031819 0.055557 -0.076818 +v -0.035355 0.038268 -0.085355 +v -0.037533 0.019509 -0.090613 +v -0.038268 -0.000000 -0.092388 +v -0.037533 -0.019509 -0.090613 +v -0.035355 -0.038268 -0.085355 +v -0.031819 -0.055557 -0.076818 +v -0.027060 -0.070711 -0.065328 +v -0.021261 -0.083147 -0.051328 +v -0.014645 -0.092388 -0.035355 +v -0.007466 -0.098079 -0.018024 +v -0.003806 0.098079 -0.019134 +v -0.007466 0.092388 -0.037533 +v -0.010839 0.083147 -0.054489 +v -0.013795 0.070711 -0.069352 +v -0.016221 0.055557 -0.081549 +v -0.018024 0.038268 -0.090613 +v -0.019134 0.019509 -0.096194 +v -0.019509 -0.000000 -0.098078 +v -0.019134 -0.019509 -0.096194 +v -0.018024 -0.038268 -0.090613 +v -0.016221 -0.055557 -0.081549 +v -0.013795 -0.070711 -0.069352 +v -0.010839 -0.083147 -0.054489 +v -0.007466 -0.092388 -0.037533 +v -0.003806 -0.098079 -0.019134 +v 0.000000 0.098079 -0.019509 +v 0.000000 0.092388 -0.038268 +v 0.000000 0.070711 -0.070711 +v 0.000000 0.038268 -0.092388 +v 0.000000 -0.038268 -0.092388 +v 0.000000 -0.070711 -0.070711 +v 0.000000 -0.083147 -0.055557 +v 0.000000 -0.092388 -0.038268 +v 0.000000 -0.098079 -0.019509 +v 0.000000 0.156934 1.844222 +v 0.028907 0.153918 1.844222 +v 0.056703 0.144988 1.844222 +v 0.082321 0.130486 1.844222 +v 0.104774 0.110969 1.844222 +v 0.123202 0.087188 1.844222 +v 0.136894 0.060056 1.844222 +v 0.145326 0.030616 1.844222 +v 0.148173 0.000000 1.844222 +v 0.145326 -0.030616 1.844222 +v 0.136894 -0.060056 1.844222 +v 0.123202 -0.087188 1.844222 +v 0.104774 -0.110969 1.844222 +v 0.082321 -0.130486 1.844222 +v 0.056703 -0.144988 1.844222 +v 0.028907 -0.153918 1.844222 +v 0.000000 -0.156934 1.844222 +v -0.028907 -0.153918 1.844222 +v -0.056703 -0.144988 1.844222 +v -0.082321 -0.130486 1.844222 +v -0.104774 -0.110969 1.844222 +v -0.123202 -0.087188 1.844222 +v -0.136894 -0.060056 1.844222 +v -0.145326 -0.030616 1.844222 +v -0.148173 0.000000 1.844222 +v -0.145326 0.030616 1.844222 +v -0.136894 0.060056 1.844222 +v -0.123202 0.087188 1.844222 +v -0.104774 0.110969 1.844222 +v -0.082321 0.130486 1.844222 +v -0.056703 0.144988 1.844222 +v -0.028907 0.153918 1.844222 +v 0.000000 0.000000 2.155777 +v 1.844222 0.156934 -0.000000 +v 1.844222 0.153918 -0.028907 +v 1.844222 0.144988 -0.056703 +v 1.844222 0.130486 -0.082321 +v 1.844222 0.110969 -0.104774 +v 1.844222 0.087188 -0.123202 +v 1.844222 0.060056 -0.136894 +v 1.844222 0.030616 -0.145326 +v 1.844222 -0.000000 -0.148173 +v 1.844222 -0.030616 -0.145326 +v 1.844222 -0.060056 -0.136894 +v 1.844222 -0.087188 -0.123202 +v 1.844222 -0.110969 -0.104774 +v 1.844222 -0.130486 -0.082321 +v 1.844222 -0.144988 -0.056703 +v 1.844222 -0.153918 -0.028907 +v 1.844222 -0.156934 0.000000 +v 1.844222 -0.153918 0.028907 +v 1.844222 -0.144988 0.056703 +v 1.844222 -0.130486 0.082321 +v 1.844222 -0.110969 0.104774 +v 1.844222 -0.087188 0.123202 +v 1.844222 -0.060056 0.136894 +v 1.844222 -0.030616 0.145326 +v 1.844222 0.000000 0.148173 +v 1.844222 0.030616 0.145326 +v 1.844222 0.060056 0.136894 +v 1.844222 0.087188 0.123202 +v 1.844222 0.110969 0.104774 +v 1.844222 0.130486 0.082321 +v 1.844222 0.144988 0.056703 +v 1.844222 0.153918 0.028907 +v 2.155777 0.000000 0.000000 +v 0.000000 1.844222 -0.156934 +v 0.028907 1.844222 -0.153918 +v 0.056703 1.844222 -0.144988 +v 0.082321 1.844222 -0.130486 +v 0.104774 1.844222 -0.110969 +v 0.123202 1.844222 -0.087188 +v 0.136894 1.844222 -0.060056 +v 0.145326 1.844222 -0.030616 +v 0.148173 1.844222 -0.000000 +v 0.145326 1.844222 0.030616 +v 0.136894 1.844222 0.060056 +v 0.123202 1.844222 0.087188 +v 0.104774 1.844222 0.110969 +v 0.082321 1.844222 0.130486 +v 0.056703 1.844222 0.144988 +v 0.028907 1.844222 0.153918 +v 0.000000 1.844222 0.156934 +v -0.028907 1.844222 0.153918 +v -0.056703 1.844222 0.144988 +v -0.082321 1.844222 0.130486 +v -0.104774 1.844222 0.110969 +v -0.123202 1.844222 0.087188 +v -0.136894 1.844222 0.060056 +v -0.145326 1.844222 0.030616 +v -0.148173 1.844222 -0.000000 +v -0.145326 1.844222 -0.030616 +v -0.136894 1.844222 -0.060056 +v -0.123202 1.844222 -0.087188 +v -0.104774 1.844222 -0.110969 +v -0.082321 1.844222 -0.130486 +v -0.056703 1.844222 -0.144988 +v -0.028907 1.844222 -0.153918 +v 0.000000 2.155777 -0.000000 +v 0.000000 0.067331 -0.000000 +v 0.000000 0.067331 2.000000 +v 0.013761 0.066038 -0.000000 +v 0.013761 0.066038 2.000000 +v 0.026992 0.062206 -0.000000 +v 0.026992 0.062206 2.000000 +v 0.039187 0.055984 -0.000000 +v 0.039187 0.055984 2.000000 +v 0.049875 0.047610 -0.000000 +v 0.049875 0.047610 2.000000 +v 0.058647 0.037407 -0.000000 +v 0.058647 0.037407 2.000000 +v 0.065165 0.025767 -0.000000 +v 0.065165 0.025767 2.000000 +v 0.069179 0.013136 -0.000000 +v 0.069179 0.013136 2.000000 +v 0.070534 0.000000 0.000000 +v 0.070534 0.000000 2.000000 +v 0.069179 -0.013136 0.000000 +v 0.069179 -0.013136 2.000000 +v 0.065165 -0.025767 0.000000 +v 0.065165 -0.025767 2.000000 +v 0.058647 -0.037407 0.000000 +v 0.058647 -0.037407 2.000000 +v 0.049875 -0.047610 0.000000 +v 0.049875 -0.047610 2.000000 +v 0.039187 -0.055984 0.000000 +v 0.039187 -0.055984 2.000000 +v 0.026992 -0.062206 0.000000 +v 0.026992 -0.062206 2.000000 +v 0.013761 -0.066038 0.000000 +v 0.013761 -0.066038 2.000000 +v 0.000000 -0.067331 0.000000 +v 0.000000 -0.067331 2.000000 +v -0.013761 -0.066038 0.000000 +v -0.013761 -0.066038 2.000000 +v -0.026992 -0.062206 0.000000 +v -0.026992 -0.062206 2.000000 +v -0.039187 -0.055984 0.000000 +v -0.039187 -0.055984 2.000000 +v -0.049875 -0.047610 0.000000 +v -0.049875 -0.047610 2.000000 +v -0.058647 -0.037407 0.000000 +v -0.058647 -0.037407 2.000000 +v -0.065165 -0.025767 0.000000 +v -0.065165 -0.025767 2.000000 +v -0.069179 -0.013136 0.000000 +v -0.069179 -0.013136 2.000000 +v -0.070534 0.000000 0.000000 +v -0.070534 0.000000 2.000000 +v -0.069179 0.013136 -0.000000 +v -0.069179 0.013136 2.000000 +v -0.065165 0.025767 -0.000000 +v -0.065165 0.025767 2.000000 +v -0.058647 0.037407 -0.000000 +v -0.058647 0.037407 2.000000 +v -0.049875 0.047610 -0.000000 +v -0.049875 0.047610 2.000000 +v -0.039187 0.055984 -0.000000 +v -0.039187 0.055984 2.000000 +v -0.026992 0.062206 -0.000000 +v -0.026992 0.062206 2.000000 +v -0.013761 0.066038 -0.000000 +v -0.013761 0.066038 2.000000 +v 0.000000 0.067331 -0.000000 +v 2.000000 0.067331 -0.000000 +v 0.000000 0.066038 -0.013761 +v 2.000000 0.066038 -0.013761 +v 0.000000 0.062206 -0.026992 +v 2.000000 0.062206 -0.026992 +v 0.000000 0.055984 -0.039187 +v 2.000000 0.055984 -0.039187 +v 0.000000 0.047610 -0.049875 +v 2.000000 0.047610 -0.049875 +v 0.000000 0.037407 -0.058647 +v 2.000000 0.037407 -0.058647 +v 0.000000 0.025767 -0.065165 +v 2.000000 0.025767 -0.065165 +v 0.000000 0.013136 -0.069179 +v 2.000000 0.013136 -0.069179 +v 0.000000 -0.000000 -0.070534 +v 2.000000 -0.000000 -0.070534 +v 0.000000 -0.013136 -0.069179 +v 2.000000 -0.013136 -0.069179 +v 0.000000 -0.025767 -0.065165 +v 2.000000 -0.025767 -0.065165 +v 0.000000 -0.037407 -0.058647 +v 2.000000 -0.037407 -0.058647 +v 0.000000 -0.047610 -0.049875 +v 2.000000 -0.047610 -0.049875 +v 0.000000 -0.055984 -0.039187 +v 2.000000 -0.055984 -0.039187 +v 0.000000 -0.062206 -0.026992 +v 2.000000 -0.062206 -0.026992 +v 0.000000 -0.066038 -0.013761 +v 2.000000 -0.066038 -0.013761 +v 0.000000 -0.067331 0.000000 +v 2.000000 -0.067331 0.000000 +v 0.000000 -0.066038 0.013761 +v 2.000000 -0.066038 0.013761 +v 0.000000 -0.062206 0.026992 +v 2.000000 -0.062206 0.026992 +v 0.000000 -0.055984 0.039187 +v 2.000000 -0.055984 0.039187 +v 0.000000 -0.047610 0.049875 +v 2.000000 -0.047610 0.049875 +v 0.000000 -0.037407 0.058647 +v 2.000000 -0.037407 0.058647 +v 0.000000 -0.025767 0.065165 +v 2.000000 -0.025767 0.065165 +v 0.000000 -0.013136 0.069179 +v 2.000000 -0.013136 0.069179 +v 0.000000 0.000000 0.070534 +v 2.000000 0.000000 0.070534 +v 0.000000 0.013136 0.069179 +v 2.000000 0.013136 0.069179 +v 0.000000 0.025767 0.065165 +v 2.000000 0.025767 0.065165 +v 0.000000 0.037407 0.058647 +v 2.000000 0.037407 0.058647 +v 0.000000 0.047610 0.049875 +v 2.000000 0.047610 0.049875 +v 0.000000 0.055984 0.039187 +v 2.000000 0.055984 0.039187 +v 0.000000 0.062206 0.026992 +v 2.000000 0.062206 0.026992 +v 0.000000 0.066038 0.013761 +v 2.000000 0.066038 0.013761 +v 0.000000 -0.000000 -0.067331 +v 0.000000 2.000000 -0.067331 +v 0.013761 -0.000000 -0.066038 +v 0.013761 2.000000 -0.066038 +v 0.026992 -0.000000 -0.062206 +v 0.026992 2.000000 -0.062206 +v 0.039187 -0.000000 -0.055984 +v 0.039187 2.000000 -0.055984 +v 0.049875 -0.000000 -0.047610 +v 0.049875 2.000000 -0.047611 +v 0.058647 -0.000000 -0.037407 +v 0.058647 2.000000 -0.037407 +v 0.065165 -0.000000 -0.025767 +v 0.065165 2.000000 -0.025767 +v 0.069179 -0.000000 -0.013136 +v 0.069179 2.000000 -0.013136 +v 0.070534 0.000000 0.000000 +v 0.070534 2.000000 -0.000000 +v 0.069179 0.000000 0.013136 +v 0.069179 2.000000 0.013136 +v 0.065165 0.000000 0.025767 +v 0.065165 2.000000 0.025767 +v 0.058647 0.000000 0.037407 +v 0.058647 2.000000 0.037407 +v 0.049875 0.000000 0.047611 +v 0.049875 2.000000 0.047610 +v 0.039187 0.000000 0.055984 +v 0.039187 2.000000 0.055984 +v 0.026992 0.000000 0.062206 +v 0.026992 2.000000 0.062206 +v 0.013761 0.000000 0.066038 +v 0.013761 2.000000 0.066038 +v 0.000000 0.000000 0.067331 +v 0.000000 2.000000 0.067331 +v -0.013761 0.000000 0.066038 +v -0.013761 2.000000 0.066038 +v -0.026992 0.000000 0.062206 +v -0.026992 2.000000 0.062206 +v -0.039187 0.000000 0.055984 +v -0.039187 2.000000 0.055984 +v -0.049875 0.000000 0.047611 +v -0.049875 2.000000 0.047610 +v -0.058647 0.000000 0.037407 +v -0.058647 2.000000 0.037407 +v -0.065165 0.000000 0.025767 +v -0.065165 2.000000 0.025767 +v -0.069179 0.000000 0.013136 +v -0.069179 2.000000 0.013136 +v -0.070534 0.000000 0.000000 +v -0.070534 2.000000 -0.000000 +v -0.069179 -0.000000 -0.013136 +v -0.069179 2.000000 -0.013136 +v -0.065165 -0.000000 -0.025767 +v -0.065165 2.000000 -0.025767 +v -0.058647 -0.000000 -0.037407 +v -0.058647 2.000000 -0.037407 +v -0.049875 -0.000000 -0.047610 +v -0.049875 2.000000 -0.047611 +v -0.039187 -0.000000 -0.055984 +v -0.039187 2.000000 -0.055984 +v -0.026992 -0.000000 -0.062206 +v -0.026992 2.000000 -0.062206 +v -0.013761 -0.000000 -0.066038 +v -0.013761 2.000000 -0.066038 +s 0 +f 477 11 12 +f 480 20 481 +f 477 13 3 +f 481 21 482 +f 4 13 14 +f 474 82 7 +f 308 482 21 +f 4 15 5 +f 475 7 8 +f 478 15 16 +f 1 8 9 +f 478 17 6 +f 1 10 476 +f 479 17 18 +f 476 11 2 +f 480 18 19 +f 17 33 18 +f 11 25 26 +f 19 33 34 +f 11 27 12 +f 20 34 35 +f 12 28 13 +f 20 36 21 +f 13 29 14 +f 7 82 22 +f 308 21 36 +f 15 29 30 +f 8 22 23 +f 16 30 31 +f 8 24 9 +f 17 31 32 +f 9 25 10 +f 308 36 51 +f 30 44 45 +f 23 37 38 +f 30 46 31 +f 24 38 39 +f 32 46 47 +f 25 39 40 +f 33 47 48 +f 25 41 26 +f 33 49 34 +f 26 42 27 +f 34 50 35 +f 28 42 43 +f 35 51 36 +f 28 44 29 +f 22 82 37 +f 49 63 64 +f 41 57 42 +f 49 65 50 +f 43 57 58 +f 51 65 66 +f 43 59 44 +f 37 82 52 +f 308 51 66 +f 45 59 60 +f 37 53 38 +f 45 61 46 +f 39 53 54 +f 47 61 62 +f 39 55 40 +f 47 63 48 +f 41 55 56 +f 53 67 68 +f 61 75 76 +f 53 69 54 +f 61 77 62 +f 55 69 70 +f 63 77 78 +f 55 71 56 +f 63 79 64 +f 57 71 72 +f 65 79 80 +f 57 73 58 +f 65 81 66 +f 59 73 74 +f 52 82 67 +f 308 66 81 +f 59 75 60 +f 72 87 88 +f 80 95 96 +f 72 89 73 +f 81 96 97 +f 74 89 90 +f 67 82 83 +f 308 81 97 +f 74 91 75 +f 67 84 68 +f 76 91 92 +f 68 85 69 +f 76 93 77 +f 69 86 70 +f 77 94 78 +f 71 86 87 +f 79 94 95 +f 91 107 92 +f 85 99 100 +f 92 108 93 +f 86 100 101 +f 94 108 109 +f 86 102 87 +f 94 110 95 +f 88 102 103 +f 95 111 96 +f 89 103 104 +f 97 111 112 +f 90 104 105 +f 83 82 98 +f 308 97 112 +f 90 106 91 +f 83 99 84 +f 111 125 126 +f 104 118 119 +f 112 126 127 +f 104 120 105 +f 98 82 113 +f 308 112 127 +f 106 120 121 +f 98 114 99 +f 106 122 107 +f 99 115 100 +f 108 122 123 +f 101 115 116 +f 108 124 109 +f 102 116 117 +f 109 125 110 +f 102 118 103 +f 115 129 130 +f 122 138 123 +f 115 131 116 +f 124 138 139 +f 116 132 117 +f 125 139 140 +f 118 132 133 +f 125 141 126 +f 118 134 119 +f 126 142 127 +f 120 134 135 +f 113 82 128 +f 308 127 142 +f 120 136 121 +f 114 128 129 +f 122 136 137 +f 133 149 134 +f 141 157 142 +f 135 149 150 +f 128 82 143 +f 308 142 157 +f 135 151 136 +f 129 143 144 +f 137 151 152 +f 129 145 130 +f 138 152 153 +f 130 146 131 +f 138 154 139 +f 132 146 147 +f 140 154 155 +f 132 148 133 +f 141 155 156 +f 153 167 168 +f 146 160 161 +f 154 168 169 +f 146 162 147 +f 154 170 155 +f 147 163 148 +f 155 171 156 +f 149 163 164 +f 156 172 157 +f 149 165 150 +f 143 82 158 +f 308 157 172 +f 151 165 166 +f 144 158 159 +f 151 167 152 +f 145 159 160 +f 172 186 187 +f 164 180 165 +f 158 82 173 +f 308 172 187 +f 166 180 181 +f 158 174 159 +f 166 182 167 +f 160 174 175 +f 168 182 183 +f 160 176 161 +f 168 184 169 +f 162 176 177 +f 170 184 185 +f 162 178 163 +f 170 186 171 +f 164 178 179 +f 184 198 199 +f 176 192 177 +f 184 200 185 +f 178 192 193 +f 186 200 201 +f 178 194 179 +f 186 202 187 +f 179 195 180 +f 173 82 188 +f 308 187 202 +f 181 195 196 +f 174 188 189 +f 182 196 197 +f 174 190 175 +f 182 198 183 +f 176 190 191 +f 188 82 203 +f 308 202 217 +f 196 210 211 +f 188 204 189 +f 196 212 197 +f 189 205 190 +f 197 213 198 +f 190 206 191 +f 198 214 199 +f 192 206 207 +f 200 214 215 +f 193 207 208 +f 201 215 216 +f 194 208 209 +f 202 216 217 +f 194 210 195 +f 206 222 207 +f 214 230 215 +f 208 222 223 +f 216 230 231 +f 209 223 224 +f 217 231 232 +f 209 225 210 +f 203 82 218 +f 308 217 232 +f 211 225 226 +f 203 219 204 +f 211 227 212 +f 204 220 205 +f 212 228 213 +f 206 220 221 +f 214 228 229 +f 226 240 241 +f 218 234 219 +f 227 241 242 +f 220 234 235 +f 228 242 243 +f 221 235 236 +f 228 244 229 +f 222 236 237 +f 229 245 230 +f 222 238 223 +f 230 246 231 +f 223 239 224 +f 232 246 247 +f 224 240 225 +f 218 82 233 +f 308 232 247 +f 245 259 260 +f 238 252 253 +f 246 260 261 +f 239 253 254 +f 246 262 247 +f 240 254 255 +f 233 82 248 +f 308 247 262 +f 240 256 241 +f 234 248 249 +f 241 257 242 +f 234 250 235 +f 242 258 243 +f 235 251 236 +f 244 258 259 +f 236 252 237 +f 249 263 264 +f 257 271 272 +f 250 264 265 +f 258 272 273 +f 250 266 251 +f 258 274 259 +f 252 266 267 +f 260 274 275 +f 252 268 253 +f 260 276 261 +f 253 269 254 +f 261 277 262 +f 255 269 270 +f 248 82 263 +f 308 262 277 +f 255 271 256 +f 267 283 268 +f 275 291 276 +f 269 283 284 +f 276 292 277 +f 269 285 270 +f 263 82 278 +f 308 277 292 +f 271 285 286 +f 264 278 279 +f 271 287 272 +f 265 279 280 +f 273 287 288 +f 266 280 281 +f 274 288 289 +f 266 282 267 +f 274 290 275 +f 286 302 287 +f 280 294 295 +f 288 302 303 +f 280 296 281 +f 288 304 289 +f 282 296 297 +f 290 304 305 +f 282 298 283 +f 290 306 291 +f 284 298 299 +f 292 306 307 +f 284 300 285 +f 278 82 293 +f 308 292 307 +f 286 300 301 +f 278 294 279 +f 306 321 322 +f 298 315 299 +f 306 323 307 +f 299 316 300 +f 293 82 309 +f 308 307 323 +f 301 316 317 +f 294 309 310 +f 302 317 318 +f 294 311 295 +f 302 319 303 +f 296 311 312 +f 304 319 320 +f 296 313 297 +f 304 321 305 +f 298 313 314 +f 318 334 319 +f 311 327 312 +f 319 335 320 +f 313 327 328 +f 321 335 336 +f 314 328 329 +f 322 336 337 +f 315 329 330 +f 323 337 338 +f 315 331 316 +f 309 82 324 +f 308 323 338 +f 317 331 332 +f 309 325 310 +f 317 333 318 +f 310 326 311 +f 338 352 353 +f 330 346 331 +f 324 82 339 +f 308 338 353 +f 332 346 347 +f 324 340 325 +f 332 348 333 +f 325 341 326 +f 333 349 334 +f 327 341 342 +f 335 349 350 +f 327 343 328 +f 335 351 336 +f 329 343 344 +f 337 351 352 +f 330 344 345 +f 342 356 357 +f 349 365 350 +f 343 357 358 +f 350 366 351 +f 343 359 344 +f 351 367 352 +f 344 360 345 +f 353 367 368 +f 345 361 346 +f 339 82 354 +f 308 353 368 +f 347 361 362 +f 339 355 340 +f 348 362 363 +f 341 355 356 +f 349 363 364 +f 361 375 376 +f 354 82 369 +f 308 368 383 +f 361 377 362 +f 355 369 370 +f 362 378 363 +f 355 371 356 +f 363 379 364 +f 356 372 357 +f 365 379 380 +f 357 373 358 +f 366 380 381 +f 359 373 374 +f 367 381 382 +f 360 374 375 +f 367 383 368 +f 379 395 380 +f 373 387 388 +f 381 395 396 +f 373 389 374 +f 381 397 382 +f 374 390 375 +f 382 398 383 +f 376 390 391 +f 369 82 384 +f 308 383 398 +f 376 392 377 +f 370 384 385 +f 378 392 393 +f 371 385 386 +f 379 393 394 +f 371 387 372 +f 384 82 399 +f 308 398 413 +f 392 406 407 +f 385 399 400 +f 392 408 393 +f 386 400 401 +f 394 408 409 +f 387 401 402 +f 395 409 410 +f 387 403 388 +f 395 411 396 +f 388 404 389 +f 396 412 397 +f 390 404 405 +f 397 413 398 +f 390 406 391 +f 403 417 418 +f 411 425 426 +f 403 419 404 +f 411 427 412 +f 405 419 420 +f 413 427 428 +f 405 421 406 +f 399 82 414 +f 308 413 428 +f 407 421 422 +f 399 415 400 +f 407 423 408 +f 401 415 416 +f 409 423 424 +f 401 417 402 +f 409 425 410 +f 422 436 437 +f 415 429 430 +f 423 437 438 +f 415 431 416 +f 423 439 424 +f 417 431 432 +f 425 439 440 +f 417 433 418 +f 425 441 426 +f 419 433 434 +f 427 441 442 +f 419 435 420 +f 427 443 428 +f 420 436 421 +f 414 82 429 +f 308 428 443 +f 441 455 456 +f 434 448 449 +f 442 456 457 +f 435 449 450 +f 443 457 458 +f 435 451 436 +f 429 82 444 +f 308 443 458 +f 437 451 452 +f 429 445 430 +f 437 453 438 +f 430 446 431 +f 438 454 439 +f 431 447 432 +f 439 455 440 +f 433 447 448 +f 452 468 453 +f 445 461 446 +f 453 469 454 +f 447 461 462 +f 455 469 470 +f 447 463 448 +f 455 471 456 +f 449 463 464 +f 457 471 472 +f 450 464 465 +f 458 472 473 +f 450 466 451 +f 444 82 459 +f 308 458 473 +f 452 466 467 +f 444 460 445 +f 471 481 472 +f 465 477 3 +f 473 481 482 +f 465 4 466 +f 459 82 474 +f 308 473 482 +f 467 4 5 +f 459 475 460 +f 467 478 468 +f 461 475 1 +f 469 478 6 +f 462 1 476 +f 469 479 470 +f 463 476 2 +f 470 480 471 +f 463 477 464 +f 477 2 11 +f 480 19 20 +f 477 12 13 +f 481 20 21 +f 4 3 13 +f 4 14 15 +f 475 474 7 +f 478 5 15 +f 1 475 8 +f 478 16 17 +f 1 9 10 +f 479 6 17 +f 476 10 11 +f 480 479 18 +f 17 32 33 +f 11 10 25 +f 19 18 33 +f 11 26 27 +f 20 19 34 +f 12 27 28 +f 20 35 36 +f 13 28 29 +f 15 14 29 +f 8 7 22 +f 16 15 30 +f 8 23 24 +f 17 16 31 +f 9 24 25 +f 30 29 44 +f 23 22 37 +f 30 45 46 +f 24 23 38 +f 32 31 46 +f 25 24 39 +f 33 32 47 +f 25 40 41 +f 33 48 49 +f 26 41 42 +f 34 49 50 +f 28 27 42 +f 35 50 51 +f 28 43 44 +f 49 48 63 +f 41 56 57 +f 49 64 65 +f 43 42 57 +f 51 50 65 +f 43 58 59 +f 45 44 59 +f 37 52 53 +f 45 60 61 +f 39 38 53 +f 47 46 61 +f 39 54 55 +f 47 62 63 +f 41 40 55 +f 53 52 67 +f 61 60 75 +f 53 68 69 +f 61 76 77 +f 55 54 69 +f 63 62 77 +f 55 70 71 +f 63 78 79 +f 57 56 71 +f 65 64 79 +f 57 72 73 +f 65 80 81 +f 59 58 73 +f 59 74 75 +f 72 71 87 +f 80 79 95 +f 72 88 89 +f 81 80 96 +f 74 73 89 +f 74 90 91 +f 67 83 84 +f 76 75 91 +f 68 84 85 +f 76 92 93 +f 69 85 86 +f 77 93 94 +f 71 70 86 +f 79 78 94 +f 91 106 107 +f 85 84 99 +f 92 107 108 +f 86 85 100 +f 94 93 108 +f 86 101 102 +f 94 109 110 +f 88 87 102 +f 95 110 111 +f 89 88 103 +f 97 96 111 +f 90 89 104 +f 90 105 106 +f 83 98 99 +f 111 110 125 +f 104 103 118 +f 112 111 126 +f 104 119 120 +f 106 105 120 +f 98 113 114 +f 106 121 122 +f 99 114 115 +f 108 107 122 +f 101 100 115 +f 108 123 124 +f 102 101 116 +f 109 124 125 +f 102 117 118 +f 115 114 129 +f 122 137 138 +f 115 130 131 +f 124 123 138 +f 116 131 132 +f 125 124 139 +f 118 117 132 +f 125 140 141 +f 118 133 134 +f 126 141 142 +f 120 119 134 +f 120 135 136 +f 114 113 128 +f 122 121 136 +f 133 148 149 +f 141 156 157 +f 135 134 149 +f 135 150 151 +f 129 128 143 +f 137 136 151 +f 129 144 145 +f 138 137 152 +f 130 145 146 +f 138 153 154 +f 132 131 146 +f 140 139 154 +f 132 147 148 +f 141 140 155 +f 153 152 167 +f 146 145 160 +f 154 153 168 +f 146 161 162 +f 154 169 170 +f 147 162 163 +f 155 170 171 +f 149 148 163 +f 156 171 172 +f 149 164 165 +f 151 150 165 +f 144 143 158 +f 151 166 167 +f 145 144 159 +f 172 171 186 +f 164 179 180 +f 166 165 180 +f 158 173 174 +f 166 181 182 +f 160 159 174 +f 168 167 182 +f 160 175 176 +f 168 183 184 +f 162 161 176 +f 170 169 184 +f 162 177 178 +f 170 185 186 +f 164 163 178 +f 184 183 198 +f 176 191 192 +f 184 199 200 +f 178 177 192 +f 186 185 200 +f 178 193 194 +f 186 201 202 +f 179 194 195 +f 181 180 195 +f 174 173 188 +f 182 181 196 +f 174 189 190 +f 182 197 198 +f 176 175 190 +f 196 195 210 +f 188 203 204 +f 196 211 212 +f 189 204 205 +f 197 212 213 +f 190 205 206 +f 198 213 214 +f 192 191 206 +f 200 199 214 +f 193 192 207 +f 201 200 215 +f 194 193 208 +f 202 201 216 +f 194 209 210 +f 206 221 222 +f 214 229 230 +f 208 207 222 +f 216 215 230 +f 209 208 223 +f 217 216 231 +f 209 224 225 +f 211 210 225 +f 203 218 219 +f 211 226 227 +f 204 219 220 +f 212 227 228 +f 206 205 220 +f 214 213 228 +f 226 225 240 +f 218 233 234 +f 227 226 241 +f 220 219 234 +f 228 227 242 +f 221 220 235 +f 228 243 244 +f 222 221 236 +f 229 244 245 +f 222 237 238 +f 230 245 246 +f 223 238 239 +f 232 231 246 +f 224 239 240 +f 245 244 259 +f 238 237 252 +f 246 245 260 +f 239 238 253 +f 246 261 262 +f 240 239 254 +f 240 255 256 +f 234 233 248 +f 241 256 257 +f 234 249 250 +f 242 257 258 +f 235 250 251 +f 244 243 258 +f 236 251 252 +f 249 248 263 +f 257 256 271 +f 250 249 264 +f 258 257 272 +f 250 265 266 +f 258 273 274 +f 252 251 266 +f 260 259 274 +f 252 267 268 +f 260 275 276 +f 253 268 269 +f 261 276 277 +f 255 254 269 +f 255 270 271 +f 267 282 283 +f 275 290 291 +f 269 268 283 +f 276 291 292 +f 269 284 285 +f 271 270 285 +f 264 263 278 +f 271 286 287 +f 265 264 279 +f 273 272 287 +f 266 265 280 +f 274 273 288 +f 266 281 282 +f 274 289 290 +f 286 301 302 +f 280 279 294 +f 288 287 302 +f 280 295 296 +f 288 303 304 +f 282 281 296 +f 290 289 304 +f 282 297 298 +f 290 305 306 +f 284 283 298 +f 292 291 306 +f 284 299 300 +f 286 285 300 +f 278 293 294 +f 306 305 321 +f 298 314 315 +f 306 322 323 +f 299 315 316 +f 301 300 316 +f 294 293 309 +f 302 301 317 +f 294 310 311 +f 302 318 319 +f 296 295 311 +f 304 303 319 +f 296 312 313 +f 304 320 321 +f 298 297 313 +f 318 333 334 +f 311 326 327 +f 319 334 335 +f 313 312 327 +f 321 320 335 +f 314 313 328 +f 322 321 336 +f 315 314 329 +f 323 322 337 +f 315 330 331 +f 317 316 331 +f 309 324 325 +f 317 332 333 +f 310 325 326 +f 338 337 352 +f 330 345 346 +f 332 331 346 +f 324 339 340 +f 332 347 348 +f 325 340 341 +f 333 348 349 +f 327 326 341 +f 335 334 349 +f 327 342 343 +f 335 350 351 +f 329 328 343 +f 337 336 351 +f 330 329 344 +f 342 341 356 +f 349 364 365 +f 343 342 357 +f 350 365 366 +f 343 358 359 +f 351 366 367 +f 344 359 360 +f 353 352 367 +f 345 360 361 +f 347 346 361 +f 339 354 355 +f 348 347 362 +f 341 340 355 +f 349 348 363 +f 361 360 375 +f 361 376 377 +f 355 354 369 +f 362 377 378 +f 355 370 371 +f 363 378 379 +f 356 371 372 +f 365 364 379 +f 357 372 373 +f 366 365 380 +f 359 358 373 +f 367 366 381 +f 360 359 374 +f 367 382 383 +f 379 394 395 +f 373 372 387 +f 381 380 395 +f 373 388 389 +f 381 396 397 +f 374 389 390 +f 382 397 398 +f 376 375 390 +f 376 391 392 +f 370 369 384 +f 378 377 392 +f 371 370 385 +f 379 378 393 +f 371 386 387 +f 392 391 406 +f 385 384 399 +f 392 407 408 +f 386 385 400 +f 394 393 408 +f 387 386 401 +f 395 394 409 +f 387 402 403 +f 395 410 411 +f 388 403 404 +f 396 411 412 +f 390 389 404 +f 397 412 413 +f 390 405 406 +f 403 402 417 +f 411 410 425 +f 403 418 419 +f 411 426 427 +f 405 404 419 +f 413 412 427 +f 405 420 421 +f 407 406 421 +f 399 414 415 +f 407 422 423 +f 401 400 415 +f 409 408 423 +f 401 416 417 +f 409 424 425 +f 422 421 436 +f 415 414 429 +f 423 422 437 +f 415 430 431 +f 423 438 439 +f 417 416 431 +f 425 424 439 +f 417 432 433 +f 425 440 441 +f 419 418 433 +f 427 426 441 +f 419 434 435 +f 427 442 443 +f 420 435 436 +f 441 440 455 +f 434 433 448 +f 442 441 456 +f 435 434 449 +f 443 442 457 +f 435 450 451 +f 437 436 451 +f 429 444 445 +f 437 452 453 +f 430 445 446 +f 438 453 454 +f 431 446 447 +f 439 454 455 +f 433 432 447 +f 452 467 468 +f 445 460 461 +f 453 468 469 +f 447 446 461 +f 455 454 469 +f 447 462 463 +f 455 470 471 +f 449 448 463 +f 457 456 471 +f 450 449 464 +f 458 457 472 +f 450 465 466 +f 452 451 466 +f 444 459 460 +f 471 480 481 +f 465 464 477 +f 473 472 481 +f 465 3 4 +f 467 466 4 +f 459 474 475 +f 467 5 478 +f 461 460 475 +f 469 468 478 +f 462 461 1 +f 469 6 479 +f 463 462 476 +f 470 479 480 +f 463 2 477 +f 483 515 484 +f 484 515 485 +f 485 515 486 +f 486 515 487 +f 487 515 488 +f 488 515 489 +f 489 515 490 +f 490 515 491 +f 491 515 492 +f 492 515 493 +f 493 515 494 +f 494 515 495 +f 495 515 496 +f 496 515 497 +f 497 515 498 +f 498 515 499 +f 499 515 500 +f 500 515 501 +f 501 515 502 +f 502 515 503 +f 503 515 504 +f 504 515 505 +f 505 515 506 +f 506 515 507 +f 507 515 508 +f 508 515 509 +f 509 515 510 +f 510 515 511 +f 511 515 512 +f 512 515 513 +f 512 513 486 +f 513 515 514 +f 514 515 483 +f 514 483 484 +f 484 485 514 +f 485 486 513 +f 514 485 513 +f 486 487 511 +f 487 488 510 +f 488 489 510 +f 489 490 509 +f 510 489 509 +f 490 491 507 +f 491 492 506 +f 492 493 506 +f 493 494 505 +f 506 493 505 +f 494 495 503 +f 495 496 502 +f 496 497 502 +f 497 498 501 +f 502 497 501 +f 498 499 500 +f 500 501 498 +f 502 503 495 +f 503 504 494 +f 504 505 494 +f 506 507 491 +f 507 508 490 +f 508 509 490 +f 510 511 487 +f 511 512 486 +f 516 548 517 +f 517 548 518 +f 518 548 519 +f 519 548 520 +f 520 548 521 +f 521 548 522 +f 522 548 523 +f 523 548 524 +f 524 548 525 +f 525 548 526 +f 526 548 527 +f 527 548 528 +f 528 548 529 +f 529 548 530 +f 530 548 531 +f 531 548 532 +f 532 548 533 +f 533 548 534 +f 534 548 535 +f 535 548 536 +f 536 548 537 +f 537 548 538 +f 538 548 539 +f 539 548 540 +f 540 548 541 +f 541 548 542 +f 542 548 543 +f 543 548 544 +f 544 548 545 +f 545 548 546 +f 545 546 519 +f 546 548 547 +f 547 548 516 +f 547 516 517 +f 517 518 547 +f 518 519 546 +f 547 518 546 +f 519 520 544 +f 520 521 543 +f 521 522 543 +f 522 523 542 +f 543 522 542 +f 523 524 540 +f 524 525 539 +f 525 526 539 +f 526 527 538 +f 539 526 538 +f 527 528 536 +f 528 529 535 +f 529 530 535 +f 530 531 534 +f 535 530 534 +f 531 532 533 +f 533 534 531 +f 535 536 528 +f 536 537 527 +f 537 538 527 +f 539 540 524 +f 540 541 523 +f 541 542 523 +f 543 544 520 +f 544 545 519 +f 549 581 550 +f 550 581 551 +f 551 581 552 +f 552 581 553 +f 553 581 554 +f 554 581 555 +f 555 581 556 +f 556 581 557 +f 557 581 558 +f 558 581 559 +f 559 581 560 +f 560 581 561 +f 561 581 562 +f 562 581 563 +f 563 581 564 +f 564 581 565 +f 565 581 566 +f 566 581 567 +f 567 581 568 +f 568 581 569 +f 569 581 570 +f 570 581 571 +f 571 581 572 +f 572 581 573 +f 573 581 574 +f 574 581 575 +f 575 581 576 +f 576 581 577 +f 577 581 578 +f 578 581 579 +f 578 579 552 +f 579 581 580 +f 580 581 549 +f 580 549 550 +f 550 551 580 +f 551 552 579 +f 580 551 579 +f 552 553 577 +f 553 554 576 +f 554 555 576 +f 555 556 575 +f 576 555 575 +f 556 557 573 +f 557 558 572 +f 558 559 572 +f 559 560 571 +f 572 559 571 +f 560 561 569 +f 561 562 568 +f 562 563 568 +f 563 564 567 +f 568 563 567 +f 564 565 566 +f 566 567 564 +f 568 569 561 +f 569 570 560 +f 570 571 560 +f 572 573 557 +f 573 574 556 +f 574 575 556 +f 576 577 553 +f 577 578 552 +f 583 584 582 +f 585 586 584 +f 587 588 586 +f 589 590 588 +f 591 592 590 +f 593 594 592 +f 595 596 594 +f 597 598 596 +f 599 600 598 +f 601 602 600 +f 603 604 602 +f 605 606 604 +f 607 608 606 +f 609 610 608 +f 611 612 610 +f 613 614 612 +f 615 616 614 +f 617 618 616 +f 619 620 618 +f 621 622 620 +f 623 624 622 +f 625 626 624 +f 627 628 626 +f 629 630 628 +f 631 632 630 +f 633 634 632 +f 635 636 634 +f 637 638 636 +f 639 640 638 +f 641 642 640 +f 591 589 607 +f 643 644 642 +f 645 582 644 +f 640 642 620 +f 583 585 584 +f 585 587 586 +f 587 589 588 +f 589 591 590 +f 591 593 592 +f 593 595 594 +f 595 597 596 +f 597 599 598 +f 599 601 600 +f 601 603 602 +f 603 605 604 +f 605 607 606 +f 607 609 608 +f 609 611 610 +f 611 613 612 +f 613 615 614 +f 615 617 616 +f 617 619 618 +f 619 621 620 +f 621 623 622 +f 623 625 624 +f 625 627 626 +f 627 629 628 +f 629 631 630 +f 631 633 632 +f 633 635 634 +f 635 637 636 +f 637 639 638 +f 639 641 640 +f 641 643 642 +f 587 585 613 +f 585 583 615 +f 583 645 617 +f 645 643 619 +f 643 641 619 +f 641 639 621 +f 619 641 621 +f 639 637 623 +f 637 635 625 +f 623 637 625 +f 635 633 629 +f 633 631 629 +f 629 627 635 +f 627 625 635 +f 623 621 639 +f 619 617 645 +f 617 615 583 +f 615 613 585 +f 613 611 587 +f 611 609 587 +f 609 607 589 +f 587 609 589 +f 607 605 591 +f 605 603 593 +f 591 605 593 +f 603 601 597 +f 601 599 597 +f 597 595 603 +f 595 593 603 +f 643 645 644 +f 645 583 582 +f 644 582 614 +f 582 584 612 +f 584 586 612 +f 586 588 610 +f 612 586 610 +f 588 590 606 +f 590 592 604 +f 592 594 604 +f 594 596 602 +f 604 594 602 +f 596 598 600 +f 600 602 596 +f 604 606 590 +f 606 608 588 +f 608 610 588 +f 612 614 582 +f 614 616 644 +f 616 618 644 +f 618 620 642 +f 644 618 642 +f 620 622 638 +f 622 624 636 +f 624 626 636 +f 626 628 634 +f 636 626 634 +f 628 630 632 +f 632 634 628 +f 636 638 622 +f 638 640 620 +f 647 648 646 +f 649 650 648 +f 651 652 650 +f 653 654 652 +f 655 656 654 +f 657 658 656 +f 659 660 658 +f 661 662 660 +f 663 664 662 +f 665 666 664 +f 667 668 666 +f 669 670 668 +f 671 672 670 +f 673 674 672 +f 675 676 674 +f 677 678 676 +f 679 680 678 +f 681 682 680 +f 683 684 682 +f 685 686 684 +f 687 688 686 +f 689 690 688 +f 691 692 690 +f 693 694 692 +f 695 696 694 +f 697 698 696 +f 699 700 698 +f 701 702 700 +f 703 704 702 +f 705 706 704 +f 655 653 671 +f 707 708 706 +f 709 646 708 +f 704 706 684 +f 647 649 648 +f 649 651 650 +f 651 653 652 +f 653 655 654 +f 655 657 656 +f 657 659 658 +f 659 661 660 +f 661 663 662 +f 663 665 664 +f 665 667 666 +f 667 669 668 +f 669 671 670 +f 671 673 672 +f 673 675 674 +f 675 677 676 +f 677 679 678 +f 679 681 680 +f 681 683 682 +f 683 685 684 +f 685 687 686 +f 687 689 688 +f 689 691 690 +f 691 693 692 +f 693 695 694 +f 695 697 696 +f 697 699 698 +f 699 701 700 +f 701 703 702 +f 703 705 704 +f 705 707 706 +f 651 649 677 +f 649 647 679 +f 647 709 681 +f 709 707 683 +f 707 705 683 +f 705 703 685 +f 683 705 685 +f 703 701 687 +f 701 699 689 +f 687 701 689 +f 699 697 693 +f 697 695 693 +f 693 691 699 +f 691 689 699 +f 687 685 703 +f 683 681 709 +f 681 679 647 +f 679 677 649 +f 677 675 651 +f 675 673 651 +f 673 671 653 +f 651 673 653 +f 671 669 655 +f 669 667 657 +f 655 669 657 +f 667 665 661 +f 665 663 661 +f 661 659 667 +f 659 657 667 +f 707 709 708 +f 709 647 646 +f 708 646 678 +f 646 648 676 +f 648 650 676 +f 650 652 674 +f 676 650 674 +f 652 654 670 +f 654 656 668 +f 656 658 668 +f 658 660 666 +f 668 658 666 +f 660 662 664 +f 664 666 660 +f 668 670 654 +f 670 672 652 +f 672 674 652 +f 676 678 646 +f 678 680 708 +f 680 682 708 +f 682 684 706 +f 708 682 706 +f 684 686 702 +f 686 688 700 +f 688 690 700 +f 690 692 698 +f 700 690 698 +f 692 694 696 +f 696 698 692 +f 700 702 686 +f 702 704 684 +f 711 712 710 +f 713 714 712 +f 715 716 714 +f 717 718 716 +f 719 720 718 +f 721 722 720 +f 723 724 722 +f 725 726 724 +f 727 728 726 +f 729 730 728 +f 731 732 730 +f 733 734 732 +f 735 736 734 +f 737 738 736 +f 739 740 738 +f 741 742 740 +f 743 744 742 +f 745 746 744 +f 747 748 746 +f 749 750 748 +f 751 752 750 +f 753 754 752 +f 755 756 754 +f 757 758 756 +f 759 760 758 +f 761 762 760 +f 763 764 762 +f 765 766 764 +f 767 768 766 +f 769 770 768 +f 719 717 735 +f 771 772 770 +f 773 710 772 +f 768 770 748 +f 711 713 712 +f 713 715 714 +f 715 717 716 +f 717 719 718 +f 719 721 720 +f 721 723 722 +f 723 725 724 +f 725 727 726 +f 727 729 728 +f 729 731 730 +f 731 733 732 +f 733 735 734 +f 735 737 736 +f 737 739 738 +f 739 741 740 +f 741 743 742 +f 743 745 744 +f 745 747 746 +f 747 749 748 +f 749 751 750 +f 751 753 752 +f 753 755 754 +f 755 757 756 +f 757 759 758 +f 759 761 760 +f 761 763 762 +f 763 765 764 +f 765 767 766 +f 767 769 768 +f 769 771 770 +f 715 713 741 +f 713 711 743 +f 711 773 745 +f 773 771 747 +f 771 769 747 +f 769 767 749 +f 747 769 749 +f 767 765 751 +f 765 763 753 +f 751 765 753 +f 763 761 757 +f 761 759 757 +f 757 755 763 +f 755 753 763 +f 751 749 767 +f 747 745 773 +f 745 743 711 +f 743 741 713 +f 741 739 715 +f 739 737 715 +f 737 735 717 +f 715 737 717 +f 735 733 719 +f 733 731 721 +f 719 733 721 +f 731 729 725 +f 729 727 725 +f 725 723 731 +f 723 721 731 +f 771 773 772 +f 773 711 710 +f 772 710 742 +f 710 712 740 +f 712 714 740 +f 714 716 738 +f 740 714 738 +f 716 718 734 +f 718 720 732 +f 720 722 732 +f 722 724 730 +f 732 722 730 +f 724 726 728 +f 728 730 724 +f 732 734 718 +f 734 736 716 +f 736 738 716 +f 740 742 710 +f 742 744 772 +f 744 746 772 +f 746 748 770 +f 772 746 770 +f 748 750 766 +f 750 752 764 +f 752 754 764 +f 754 756 762 +f 764 754 762 +f 756 758 760 +f 760 762 756 +f 764 766 750 +f 766 768 748 diff --git a/examples/python/ColonExperiments/colon.stl b/examples/python/ColonExperiments/colon.stl new file mode 100644 index 0000000000000000000000000000000000000000..14cc1b95aba175de59d44167cd2b4d3ec8913809 Binary files /dev/null and b/examples/python/ColonExperiments/colon.stl differ diff --git a/examples/python/ColonExperiments/demoJuanjoRigidColonAsDeformble.py b/examples/python/ColonExperiments/demoJuanjoRigidColonAsDeformble.py new file mode 100644 index 0000000000000000000000000000000000000000..2f19ce3af7f42b2a7b1e71d599779d959dac7855 --- /dev/null +++ b/examples/python/ColonExperiments/demoJuanjoRigidColonAsDeformble.py @@ -0,0 +1,307 @@ +import sys +import numpy as np +import meshio +import polyscope as ps + +import os +import pymandos + +from parallel_transport import compute_rotations_parallel_transport +import polyscope.imgui as psim + + +division_Coef = 1000 ### divie by 1000 to make the mm of the colon in meters +endoscopeR = 0.5 * 11.5 / division_Coef#mm radius of endoscope + +tubeL = 1500 / division_Coef +passiveBendingL = 45 / division_Coef #m +activeBendingL = 110 /division_Coef # m +tipL = 20 / division_Coef ##m + + +density_tube = 1700 +density_passiveBending = 800 +density_activeBending = 600 +density_tip = 1000 + + +tubePoints = 100 +passiveBendingPoints = 4 #5 +activeBendingPoints = 10 +tipPoints = 3 + +delta_xTube = tubeL / tubePoints +delta_xPassiveBending = passiveBendingL / passiveBendingPoints +delta_xActiveBending = activeBendingL / activeBendingPoints +delta_xTip = tipL / tipPoints + +total_length = tipL + activeBendingL + passiveBendingL + tubeL +n_points = tipPoints + activeBendingPoints + passiveBendingPoints + tubePoints + +massVector = ( + tubePoints * [density_tube * np.pi * endoscopeR**2 * tubeL / tubePoints] + + passiveBendingPoints * [density_passiveBending * np.pi * endoscopeR**2 * passiveBendingL / passiveBendingPoints] + + activeBendingPoints * [density_activeBending * np.pi * endoscopeR**2 * activeBendingL / activeBendingPoints] + + tipPoints * [density_tip * np.pi * endoscopeR**2 * tipL / tipPoints] +) + +delta_x = total_length / n_points +insertion_speed = 100 /division_Coef +vUnit = np.zeros(3) +m_point = [] +nNodes = 0 +playing = False + +def compute_edges(triangles): + # For each triangle, create its three edges + edges = np.vstack([ + triangles[:, [0, 1]], + triangles[:, [1, 2]], + triangles[:, [2, 0]] + ]) + # Sort each edge so that the order is consistent (smallest index first) + edges = np.sort(edges, axis=1) + # Remove duplicate edges + unique_edges = np.unique(edges, axis=0) + return unique_edges + +def create_model(): + + ## load the colon + mesh = meshio.read("colon.stl") + triangles = mesh.cells_dict["triangle"] + edges = compute_edges(triangles) + x = mesh.points /division_Coef + + # ## find the coordinates to place the endoscope + minZ = np.min(x[:,2]) + + initalIndices = np.where (x[:,2]< minZ + 5 /division_Coef) + average = np.average(x[initalIndices], axis=(0)) + print(average) + middlePoint = np.zeros((1,3)) + middlePoint[0,0] = average[0] + middlePoint[0,1] = average[1] + middlePoint[0,2] = average[2] + m_point.extend(middlePoint) + + print(average) + + # ## find a vector, perpendicular to the colons' whole + p = x[initalIndices[0][0]]; q = x[initalIndices[0][1]]; r = x[initalIndices[0][2]] + pq = q-p + pr = r-p + v = np.cross(pq,pr) + global vUnit + vUnit = v / (v**2).sum()**0.5 ##### carefull with the sign, if the endoscope goes to the wrong direction,change the sign! + + # ### Creat the pymandos model + model = pymandos.Model() + # ## create the rod model + endoscope = model.add_rigidbody_cloud(name="endoscope") + + # Set initial conditions + positions = np.zeros((n_points, 6)) + velocities = np.zeros((n_points, 6)) + + startingPos= np.array([middlePoint[0,0], middlePoint[0,1], middlePoint[0,2]]) + for i, position in enumerate(positions): + if i, + DiffParameterHandle, DiffParameterHandle, - DiffParameterHandle>; + DiffParameterHandle, + DiffParameterHandle>; using DiffParameterHandleV = DiffParametersList::as; diff --git a/src/Mandos/Core/Differentiable.hpp b/src/Mandos/Core/Differentiable.hpp index b680e0a71e2e6a213daa90d96ce2a1d3fca58b1e..b198504258cabdd03dcb9ff800bf5b01e2533063 100644 --- a/src/Mandos/Core/Differentiable.hpp +++ b/src/Mandos/Core/Differentiable.hpp @@ -52,13 +52,16 @@ struct MANDOS_CORE_EXPORT BackwardEngine { , m_oneOverH(1.0 / h) , m_step(m_trajectory.getNSteps()) { + if (h == 0.0) { + m_oneOverH = 0.0; + } } Model &m_model; const Trajectory &m_trajectory; const int m_NDof; const int m_NSteps; const Scalar m_h; - const Scalar m_oneOverH; + Scalar m_oneOverH; int m_step; void backwardStep(Eigen::Ref lossPositionGradient, diff --git a/src/Mandos/Core/Energies/ARAP.cpp b/src/Mandos/Core/Energies/ARAP.cpp index cd52fce1fa09dcbd138254053baff081d52f7b1f..55ec6ea7100e486525d97c88c47e11908a502a03 100644 --- a/src/Mandos/Core/Energies/ARAP.cpp +++ b/src/Mandos/Core/Energies/ARAP.cpp @@ -19,6 +19,7 @@ #include #include +#include namespace mandos::core { diff --git a/src/Mandos/Core/Energies/CosseratBendingRod.cpp b/src/Mandos/Core/Energies/CosseratBendingRod.cpp index d9ea454adef54e311deed669c9bc807cdcb45c19..cf22bce3ec72297fc350c0e36e91c9b46cbefdea 100644 --- a/src/Mandos/Core/Energies/CosseratBendingRod.cpp +++ b/src/Mandos/Core/Energies/CosseratBendingRod.cpp @@ -102,7 +102,7 @@ Scalar CosseratBendingRod::computeEnergy(const MechanicalState &ms const Mat3 Ak = 0.5 * (mandos::core::skew(m_intrinsicDarboux[i]) * J + J * mandos::core::skew(m_intrinsicDarboux[i])); const Mat3 JAk = J * mandos::core::Scalar{1.0} / m_restLength[i] + Ak; - energy += -(RB.transpose() * RA * JAk).trace(); // Bending energy + energy += -(RB.transpose() * RA * JAk).trace(); // Bending energy } return energy; } @@ -219,4 +219,32 @@ Vec3 CosseratBendingRod::computeEnergyGradientParameterDerivative(3).transpose() * dgradE_dp + mstate.m_grad[iB].segment<3>(3).transpose() * (-dgradE_dp); } + +template <> +Vec3 CosseratBendingRod::computeEnergyGradientParameterDerivative( + MechanicalState &mstate, + std::size_t index) const +{ + const auto iA = static_cast(m_indices[index][0]); + const auto iB = static_cast(m_indices[index][1]); + + const Mat3 RA = mandos::core::rotationExpMap(mstate.m_x[iA].segment<3>(3)); + const Mat3 RB = mandos::core::rotationExpMap(mstate.m_x[iB].segment<3>(3)); + const auto &stiffnessTensor = m_stiffnessTensor[index]; + + const Mat3 traceRaTRb = RA.transpose() * RB; + const Mat3 dudthita = (0.5 / m_restLength[index]) * (RA.transpose() - traceRaTRb.trace() * RB.transpose()); + const Mat3 B = Vec3(stiffnessTensor(0), stiffnessTensor(1), stiffnessTensor(2)).asDiagonal(); + Vec3 darbouxVector = computeDarbouxVector(m_restLength[index], RA, RB); + + Vec3 grad = m_restLength[index] * dudthita.transpose() * B * (darbouxVector - m_intrinsicDarboux[index]); + + const Mat3 dgradE_dp = + m_restLength[index] * dudthita.transpose() * (darbouxVector - m_intrinsicDarboux[index]).asDiagonal(); + + + return mstate.m_grad[iA].segment<3>(3).transpose() * dgradE_dp + + mstate.m_grad[iB].segment<3>(3).transpose() * (-dgradE_dp); +} + } // namespace mandos::core diff --git a/src/Mandos/Core/Energies/CosseratBendingRod.hpp b/src/Mandos/Core/Energies/CosseratBendingRod.hpp index 24708014e66dbb73e3c29792eaa7d3e80079d8c0..46cd35e77e3b17ac5d55906ecb9549884bc74b1b 100644 --- a/src/Mandos/Core/Energies/CosseratBendingRod.hpp +++ b/src/Mandos/Core/Energies/CosseratBendingRod.hpp @@ -25,7 +25,8 @@ public: }; enum Parameters { - IntrinsicDarboux, + IntrinsicDarboux, + StiffnessTensor, }; /** @@ -90,6 +91,11 @@ Vec3 CosseratBendingRod::computeEnergyGradientParameterDerivative &mstate, std::size_t index) const; +template <> +Vec3 CosseratBendingRod::computeEnergyGradientParameterDerivative( + MechanicalState &mstate, + std::size_t index) const; + } // namespace mandos::core #endif // MANDOS_ENERGIES_COSSEATRODBENDING_H diff --git a/src/Mandos/Core/Energies/CosseratRodAlignment.cpp b/src/Mandos/Core/Energies/CosseratRodAlignment.cpp index 7b4fcf616bdb8a980d8421654fef2286b6d9c1ff..4766909866c725b362eba7deed2096df783beaea 100644 --- a/src/Mandos/Core/Energies/CosseratRodAlignment.cpp +++ b/src/Mandos/Core/Energies/CosseratRodAlignment.cpp @@ -54,7 +54,7 @@ Scalar CosseratRodAlignment::computeEnergyAndGradient(MechanicalState(0) += grad; mstate.m_grad[iA].segment<3>(3) += diff --git a/src/Mandos/Core/Energies/MassSpring.cpp b/src/Mandos/Core/Energies/MassSpring.cpp index 0f1f3bd669eb94d4eb37dfdbad3312cb8a719924..b581019bd6e21ab4799c5efb85f73ba864cb811a 100644 --- a/src/Mandos/Core/Energies/MassSpring.cpp +++ b/src/Mandos/Core/Energies/MassSpring.cpp @@ -307,4 +307,32 @@ Scalar MassSpring::computeEnergyGradientParameterDerivative +Scalar MassSpring::computeEnergyGradientParameterDerivative( + MechanicalState &mstate, + std::size_t index) const +{ + const auto &indices{m_indices[index]}; + const auto iA = static_cast(indices[0]); + const auto iB = static_cast(indices[1]); + const Vec3 xA = mstate.m_x[iA].segment<3>(0); + const Vec3 xB = mstate.m_x[iB].segment<3>(0); + + const Scalar L = (xA - xB).norm() + std::numeric_limits::epsilon(); + const Vec3 u = (xA - xB) / L; + + const Vec3 dgrad_dK = [&]() -> Vec3 { + if (m_restLength[index] > std::numeric_limits::epsilon()) { // divide by L0 + return (L - m_restLength[index]) / m_restLength[index] * u; + } + return (L - m_restLength[index]) * u; + }(); + + Vec6 grad = Vec6::Zero(); + grad.segment<3>(0) = dgrad_dK; + return mstate.m_grad[iA].dot(grad) + mstate.m_grad[iB].dot(-grad); +} + + } // namespace mandos::core + diff --git a/src/Mandos/Core/Energies/MassSpring.hpp b/src/Mandos/Core/Energies/MassSpring.hpp index 8bb23c757bdb2b356ca361e06f9c525fe98378af..e628be8235bb32c957da184bc3f5bea1346f3a60 100644 --- a/src/Mandos/Core/Energies/MassSpring.hpp +++ b/src/Mandos/Core/Energies/MassSpring.hpp @@ -61,10 +61,12 @@ public: */ Scalar computeEnergyGradientAndHessian(MechanicalState &mstate) const; Scalar computeEnergyGradientAndHessian(MechanicalState &mstate) const; - + template Scalar computeEnergyGradientParameterDerivative(MechanicalState &mstate, std::size_t index) const; + template + Scalar computeEnergyGradientParameterDerivative(MechanicalState &mstate, std::size_t index) const; /** * @brief Add a new spring element. The rest length of the spring is taken from the current mechanical state * @@ -96,6 +98,11 @@ Scalar MassSpring::computeEnergyGradientParameterDerivative &mstate, std::size_t index) const; +template <> +Scalar MassSpring::computeEnergyGradientParameterDerivative( + MechanicalState &mstate, + std::size_t index) const; + } // namespace mandos::core -#endif // MANDOS_ENERGIES_SPRINGS_H +#endif // MANDOS_ENERGIES_SPRINGS_H \ No newline at end of file diff --git a/src/Mandos/Core/SystemMatrix.hpp b/src/Mandos/Core/SystemMatrix.hpp index c8ac89d2a81bfe62924fade0f8697e2d2663f88a..39f379b38ced9ee5201fbed5d96c82be2883bd9c 100644 --- a/src/Mandos/Core/SystemMatrix.hpp +++ b/src/Mandos/Core/SystemMatrix.hpp @@ -41,7 +41,7 @@ namespace mandos::core * */ -struct SystemMatrix : public Eigen::EigenBase { +struct MANDOS_CORE_EXPORT SystemMatrix : public Eigen::EigenBase { public: using Scalar = mandos::core::Scalar; using RealScalar = mandos::core::Scalar; @@ -147,6 +147,7 @@ struct generic_product_impl