[
  {
    "path": ".gitattributes",
    "content": "*.mp4 !text !filter !merge !diff\n"
  },
  {
    "path": ".gitignore",
    "content": "# Claude session folder\n.claude/\n\n# Python cache\n__pycache__/\n*.pyc\n\n# CCM tuner generated output files\nccm_frame_*.bmp\nccm_params_*.txt\n\n# GenX320 event streaming saved output files\nevents_*.png\nevents_*.csv\n\n# Thermal overlay calibration saved output files\nthermal_main_*.png\nthermal_lepton_*.png\nthermal_composite_*.png\nthermal_transform_*.txt\n\n# GenX320 overlay calibration saved output files\ngenx320_overlay_main_*.png\ngenx320_overlay_genx320_*.png\ngenx320_overlay_composite_*.png\ngenx320_overlay_transform_*.txt\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017 OpenMV\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "[![GitHub license](https://img.shields.io/github/license/openmv/openmv-projects?label=license%20%E2%9A%96)](https://github.com/openmv/openmv-projects/blob/master/LICENSE)\n[![GitHub forks](https://img.shields.io/github/forks/openmv/openmv-projects?color=green)](https://github.com/openmv/openmv-projects/network)\n[![GitHub stars](https://img.shields.io/github/stars/openmv/openmv-projects?color=yellow)](https://github.com/openmv/openmv-projects/stargazers)\n[![GitHub issues](https://img.shields.io/github/issues/openmv/openmv-projects?color=orange)](https://github.com/openmv/openmv-projects/issues)\n\n<img width=\"480\" src=\"https://raw.githubusercontent.com/openmv/openmv-media/master/logos/openmv-logo/logo.png\">\n\n# OpenMV Projects\n\nA collection of projects built with the [OpenMV Cam](https://openmv.io) — a small, low-power microcontroller board with a built-in camera, designed for machine vision applications at the edge.\n\n- [PC Tools](#pc-tools)\n- [Robotics](#robotics)\n- [Contributing to the project](#contributing-to-the-project)\n  + [Contribution guidelines](#contribution-guidelines)\n\n---\n\n## PC Tools\n\nDesktop GUI applications that pair with an OpenMV Cam over USB to provide real-time visualization, calibration, and analysis workflows. These tools run on your PC while the camera handles capture and streaming.\n\n| Project | Description |\n|---------|-------------|\n| [GenX320 Viz](tools/genx320-event-streaming/README.md) | Real-time event camera visualization with per-pixel frequency mapping for the Prophesee GenX320 sensor. |\n| [GenX320 Overlay Calibration](tools/genx320-overlay-calibration/README.md) | Streams color and GenX320 histogram frames simultaneously and composites them with manual or automatic blob-grid checkerboard homography alignment. |\n| [Thermal Overlay Calibration](tools/thermal-overlay-calibration/README.md) | Streams color and FLIR Lepton thermal frames simultaneously and composites them with manual or automatic heated-checkerboard homography alignment. |\n| [CCM Tuning](tools/ccm-tuning/README.md) | Interactive Color Correction Matrix tuner — streams raw Bayer frames and replicates the N6 ISP pipeline in software. |\n\n[Browse all tools](tools/README.md)\n\n---\n\n## Robotics\n\nComplete robotics projects that use the OpenMV Cam as the primary perception system — from autonomous rovers to self-driving cars.\n\n| Project | Description |\n|---------|-------------|\n| [Donkey Car](robotics/donkey-car/README.md) | OpenMV-powered Donkey Car build with line following and autonomous driving. |\n| [Autonomous Rover](robotics/autonomous-rover/README.md) | Tracked rover using monocular edge detection for obstacle avoidance, controlled by a Teensy 3.5. |\n\n[Browse all robotics projects](robotics/README.md)\n\n---\n\n## Contributing to the project\n\nContributions are most welcome. If you are interested in contributing to the project, start by creating a fork of the following repository:\n\n* https://github.com/openmv/openmv-projects.git\n\nClone the forked repository, and add a remote to the main repository:\n```bash\ngit clone https://github.com/<username>/openmv-projects.git\ngit -C openmv-projects remote add upstream https://github.com/openmv/openmv-projects.git\n```\n\nNow the repository is ready for pull requests. To send a pull request, create a new feature branch and push it to origin, and use GitHub to create the pull request from the forked repository to the upstream openmv/openmv-projects repository. For example:\n```bash\ngit checkout -b <some_branch_name>\n<commit changes>\ngit push origin -u <some_branch_name>\n```\n\n### Contribution guidelines\n\nPlease follow the [best practices](https://developers.google.com/blockly/guides/modify/contribute/write_a_good_pr) when sending pull requests upstream. In general, the pull request should:\n* Fix one problem. Don't try to tackle multiple issues at once.\n* Split the changes into logical groups using git commits.\n* Pull request title should be less than 78 characters, and match this pattern:\n  * `<scope>:<1 space><description><.>`\n* Commit subject line should be less than 78 characters, and match this pattern:\n  * `<scope>:<1 space><description><.>`\n"
  },
  {
    "path": "robotics/README.md",
    "content": "# OpenMV Robotics Projects\n\nComplete robotics builds that use the OpenMV Cam as the primary perception system. The camera runs MicroPython on-board — no desktop PC required during operation — and communicates with a microcontroller over UART or I2C to drive motors, servos, and other actuators.\n\n---\n\n## [Donkey Self-Driving Car](donkey-car/README.md)\n\nAn [OpenMV Cam](https://openmv.io)-powered build of the [Donkey Car](https://www.donkeycar.com/) platform — a 1/10-scale RC car converted to run autonomous laps around a track using a trained neural network.\n\n<img src=\"donkey-car/images/donkey-car-clean.jpg\" width=\"480\">\n\nThe OpenMV Cam replaces the standard Raspberry Pi camera, providing a compact self-contained vision system. A custom 3D-printed roll cage and camera mount fit the OpenMV Cam directly onto the standard Donkey Car chassis. A line-follower mode is also included that runs entirely on-camera without a host PC.\n\n**Includes:**\n- 3D-printable parts: roll cage, camera mount, and magnet plate (STL files in `download/`)\n- Step-by-step build photo guide (40+ steps)\n- `line_follower_main.py` — on-camera line following script\n- PCA9685 servo driver and servo controller Arduino sketch\n\n---\n\n## [Autonomous Rover](autonomous-rover/README.md)\n\nA tracked rover that uses monocular edge detection on the OpenMV Cam to navigate obstacle-free corridors without any external sensors for vision. A Teensy 3.5 handles all motor control, orientation, and odometry while the OpenMV Cam finds the widest gap ahead and reports its angular position over UART.\n\n<img src=\"autonomous-rover/images/Rover2.png\" width=\"480\">\n\nThe detection algorithm identifies the largest contiguous horizontal gap in a Canny edge map, finds its center of mass, and converts it to an angle within the camera's field of view. The Teensy then uses a VL53L0X TOF sensor and BNO055 IMU to execute the turn and track distance traveled before requesting the next frame analysis.\n\n**Hardware:**\n- OpenMV Cam (vision + UART)\n- Teensy 3.5 (motion control, odometry)\n- VL53L0X TOF sensor (close-range fallback distance)\n- BNO055 IMU (turn control)\n- Tracked aluminum chassis with Hall effect odometry sensors\n- Adafruit Motor Shield V2\n"
  },
  {
    "path": "robotics/autonomous-rover/README.md",
    "content": "# Teensy 3.5/OpenMV Rover\n\nThis project was based off a couple of other rover's that I built using multi-sonar sensors for obstacle detection and avoidance.  Needless to say they eye sores with everything hanging off the platform.  For many years wanted to do something with machine vision but most of the papers and projects used stereo vision vs monocular vision.  This also required you to send back to the PC the image to process and then send the commands back.  I wanted to keep the whole system closed on the rover platform with the need for any desktop software.  That's where the OpenMV camera came into play.  Forgot how I found out about it but when I saw it I knew I was going to start another project.\n\nAbout the same time I found another project that used a web camera and OpenCV to identify objects and associated avoidance code.  Peter Neal of [Big Face Robotics](https://bigfacerobotics.wordpress.com/2014/12/18/obstacle-detection-using-opencv/) describes the process as follows:\n>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The method I am using involves capturing an image, converting it to grayscale, blurring it slightly\nand then using canny edge detection to highlight the edges in the image. Using the edge detected image, starting from the left and moving\nalong the width of the image in intervals, I scan from the bottom of the image until I reach a pixel that is white, indicating the first\nedge encountered. I am left with an array that contains coordinates of the first edges found in front of the robot. Using this array, I\nthen look for changes in the direction of the slope of the edges that may indicate an object is present. At the moment I am ignoring\nanything in the top half of the image as anything found here will probably be far enough away from the robot to not be too concerned\nabout. This will change depending on the angle of the head. If the head is looking down towards the ground, obviously everything in the\nscene may be of interest. With the changes of slope found, I then scan in both directions to try and find the edge of the object,\nindicated by a sharp change in values in the array of nearest edges.\n\nWith the help of Nyamekye over at OpenMV I was able to implement a similar method.  Instead of changing the head angle, as Mr. Neal does, I determined the center position of large gaps (you can specify the gap size in pixels in the code) and found the center point.  Using this I was able to determing the angluar position in the FOV and then transmitted over the OpenMV UART to the Teensy 3.5 which does the rest.  I did add WiFi capabality to send the images but it slows the frame rate down too much.  The results of this process is illustrated in following figure:\n\n![EdgeDetection Test](images/EdgeDetectionTest.png)\n\nNow for the Rover design itself.  I used an off the shelf tracked chasis that I picked up off ebay quite a while ago.  Couldn't find the link to the exact one that i am using but a similar one is still available, http://www.ebay.com/itm/Tracked-Robot-Smart-Car-Platform-Aluminum-alloy-Chassis-with-Dual-DC-9V-Motor-/282615264298?hash=item41cd2eb42a:g:~FQAAOSw3ntZkVza .  One of the nice things about the chasis is that it had a Hall Effector Sensor that I could use for odometry.  A little different than the quad encoders but usuable.\n\n![Rover Chassis](images/EbayRover.jpg)\n\nAngular information is passed to the T3.5 which does the Obstacle avoidance stuff. It uses a single VL53L0X TOF sensor for distance measures, a BN055 for orientation which is used for turn control once the obstacle free direction is picked, a RC TX/Receiver and a RF module for telemetry and commands. As in my other project it has an odometry module for relative tracking based on the hall effect sensors on the motors (fixed the errors in my other code). It also has a manual mode for just sending motor commands. The odometry module receives manual commands individually in the format fx, bx, ly,ry where x is distance you want to travel in cm's and y is the relative angle you want to turn. I also use odometry once a direction is picked by the detection algorithm and then move half that distance before another round of image analysis is performed.\n\nThe whole thing is powered from a single 7.4 battery.  For power to the OpenMV camera the battery power goes to a 3.3v Pololu regulator.\n\nI designed custom break out board for the T3.5 so it would fit on a Arduino Mega type foot print with a custom IO board where I break out where i can mount Arduino break out boards.  In this case i use a Adafruit Motor Shield V2 to control the motors and a breadboard shield to hold a Adafruit TSL2561 light sensor.\n\nIf the camera can not see an edge, can happen if it gets too close to walls the obstacle avoidance algorith Tuses a modified vfh/bubble alogithm is the camera can not detect edge which relies on the VL53 sensor to get distances.\n\nTo see it in action check the video out, https://photos.app.goo.gl/JIc3378SOzJR2bSn1.  Discussion of the process and challenges can be seen in the OpenMV forum.\n\nSource Code and this readme is found on the TeensyOpenMV github page: https://github.com/mjs513/TeensyOpenMV\n\nHere are a couple of screen shots of the rover:\n1. http://forums.openmv.io/viewtopic.php?f=5&t=276\n2. http://forums.openmv.io/viewtopic.php?f=6&t=393\n\n![Front View](images/Rover2.png)\n![Side View](images/Rover1.png)\n"
  },
  {
    "path": "robotics/donkey-car/README.md",
    "content": "# Donkey Self-Driving Car\n\nThis instructable shows off how to create a [DIY Robocar](https://diyrobocars.com/) forked off of the [\"Donkey\"](http://www.donkeycar.com/) Self-Driving car platform using the OpenMV Cam instead of the RaspberryPi. You can see the car in action in this video [here](https://youtu.be/Pm88BEz3upM).\n\n![OpenMV Cam powered Donkey Car](images/donkey-car-web.jpg \"OpenMV Cam powered Donkey Car\")\n\n## Parts\n\nThe OpenMV Cam Donkey Car is designed to be easy to build out of parts that you can buy online and assemble together with basic tools. Below is the list of essential parts you'll need to build the self-driving car.\n\nPart Description | Part Link | Part Count | Part Cost\n---------------- | --------- | ---------- | ---------\n1/16 2.4Ghz Exceed RC Magnet Car<br />![1/16 2.4Ghz Exceed RC Magnet Car](images/parts/magnet-car.jpg \"1/16 2.4Ghz Exceed RC Magnet Car\") | https://www.amazon.com/2-4Ghz-Exceed-RC-Magnet-Electric/dp/9269803775 | 1 | $79.95\nMagnet Car Base Plate<br />![Magnet Car Base Plate](images/parts/base.jpg \"Magnet Car Base Plate\") | https://www.shapeways.com/product/6YD3XR9ND/magnet-car-base-plate<br /><br />You can download the STL file for this part [here](download/Magnet_Plate_v7.stl).<br /><br />*Magnet Base Plate by Adam Conway*. | 1 | $55.10\nMagnet Car Roll Cage</br >![Magnet Car Roll Cage](images/parts/cage.jpg \"Magnet Car Roll Cage\") | https://www.shapeways.com/product/74VXFV7AT/magnet-car-roll-cage<br /><br />You can download the STL file for this part [here](download/Magnet_Roll_Cage_v2.stl).<br /><br />*Magnet Car Roll Cage by Adam Conway*. | 1 | $66.92\nOpenMV Cam Donkey Mount<br />![OpenMV Cam Donkey Mount](images/parts/camera-mount.jpg \"OpenMV Cam Donkey Mount\") | https://www.shapeways.com/product/G7YQBUMRC/openmv-cam-donkey-mount<br /><br />You can download the STL file for these parts [here](download/OpenMV_Donkey_Mount.stl).<br /><br />*OpenMV Cam Donkey Mount by Chris Anderson*. | 1 | $21.18\nM2 Machine Screw Set<br />![M2 Machine Screw Set](images/parts/screws.jpg \"M2 Machine Screw Set\") | https://www.amazon.com/Glarks-280-Pieces-Phillips-Stainless-Assortment/dp/B01G0KRGXC | 1 | $11.89\nM3 35mm Machine Screws<br />![M3 35mm Machine Screws](images/parts/long.jpg \"M3 35mm Machine Screws\") | https://www.amazon.com/M3-3mm-0-50-Stainless-MonsterBolts/dp/B016YZTEB0 | 1 | $4.00\nM3 Machine Screw Nuts<br />![M3 Machine Screw Nuts](images/parts/nuts.jpg \"M3 Machine Screw Nuts\") | https://www.amazon.com/M3-0-5-3mm-Metric-Stainless-MonsterBolts/dp/B01528BPIU | 1 | $3.49\n30 CM Servo Lead Extension Assemblies<br />![30 CM Servo Lead Extension Assemblies](images/parts/extensions.jpg \"30 CM Servo Lead Extension Assemblies\") | http://hobbyking.com/en_us/30cm-servo-lead-extention-jr-with-hook-26awg-5pcs-bag-1.html | 1 | $1.39\nOpenMV Cam M7<br />![OpenMV Cam M7](images/parts/camera.jpg \"OpenMV Cam M7\") | https://openmv.io/products/openmv-cam-m7<br /><br />Note: You will need a soldering iron and solder to attach the pin headers for this part. | 1 | $65.00\nOpenMV Cam Servo Shield<br />![OpenMV Cam Servo Shield](images/parts/servos.jpg \"OpenMV Cam Servo Shield\") | https://openmv.io/products/servo-shield<br /><br />Note: You will need a soldering iron and solder to attach the pin headers for this part. | 1 | $15.00\nZip Ties<br />![Zip Ties](images/parts/ties.jpg \"Zip Ties\") | https://www.amazon.com/Cable-Zip-Ties-Fastening-Organization/dp/B01LPOB2JW | 1 | $9.99\nMicro USB Cable<br />![Micro USB Cable](images/parts/uusb.jpg \"Micro USB Cable\") | https://www.amazon.com/AmazonBasics-USB-Male-Micro-Cable/dp/B01EK87T9M | 1 | $5.99\n\n**Sub-Total $339.90** - However, if you can 3D print parts it's significantly cheaper to build the robocar. You may also have some of the above parts lying around (like the Micro USB cable).\n\nWhile the above parts list is all you need you may wish to instead control your robocar's servos using the below parts for an arduino based servo controller board which will allow you to control your robot remotely using the RC transmitter that comes with the magnet car. You don't need the servo shield above if you build your car using the below components. **I HEAVILY RECOMMEND THAT YOU BUY THE PARTS FOR THE ARDUINO SERVO SHIELD SO THAT YOU CAN CONTROL YOUR ROBOCAR THROTTLE REMOTELY. YOU WILL LIKELY IMMEDIATELY DAMAGE YOUR ROBOCAR WITHOUT IT BY ACCIDENTALLY DRIVING INTO A WALL!**\n\nPart Description | Part Link | Part Count | Part Cost\n---------------- | --------- | ---------- | ---------\n5V 16 MHz Arduino Pro Mini<br />![5V 16 MHz Arduino Pro Mini](images/parts/arduino.jpg \"5V 16 MHz Arduino Pro Mini\") | https://www.amazon.com/Arducam-Atmega328-Development-Compatible-Arduino/dp/B01981EBBA | 1 | $6.49\nArduino Pro Mini Programmer<br />![Arduino Pro Mini Programmer](images/parts/programmer.jpg \"Arduino Pro Mini Programmer\") | https://www.amazon.com/Micro-Basic-Breakout-Module-Arduino/dp/B00N4MCS1A | 1 | $9.95\nServo Controller Board<br />![Servo Controller Board](images/parts/controller.jpg \"Servo Controller Board\") | https://oshpark.com/shared_projects/2bKUWmbq<br /><br />You can download the Gerber files for this part [here](https://644db4de3505c40a0444-327723bce298e3ff5813fb42baeefbaa.ssl.cf1.rackcdn.com/ab7a7db45c3c6b37bcca1d8fc84e26e4.zip).<br /><br />*Servo Controller Board by Chris Anderson*. | 1 | $10.50\nMale Headers<br />![Male Headers](images/parts/male.jpg \"Male Headers\") | https://www.amazon.com/SamIdea-15-Pack-Straight-Connector-Prototype/dp/B01M9FCAXW<br /><br />Note: You will need a soldering iron and solder to attach these pin headers to the above PCB. | 1 | $5.69\n8-pin Stackable Headers<br />![8-pin Stackable Headers](images/parts/headers.jpg \"8-pin Stackable Headers\") | https://www.amazon.com/Venel-Electronic-Component-Stackable-Shields/dp/B071454KP1<br /><br />Note: You will need a soldering iron and solder to attach these pin headers to the above PCB. | 1 | $5.08\nRC Receiver Servo Adapters<br />![RC Receiver Servo Adapters](images/parts/shorts.jpg \"RC Receiver Servo Adapters\") | https://www.amazon.com/Hobbypower-Futaba-Servo-Extension-Cable/dp/B00RVDVWTC | 1 | $4.49\n\n**Sub-Total $42.20** - You may have some of the above parts lying around.\n\nIn addition to all of the above I **strongly** recommend that your purchase a wide angle lens for your OpenMV Cam. With the wide angle lens it's much easier for your self-driving car to make tight turns and not lose sight of the road ahead. Without it you *will* have to reduce your maximum speed in-order to make tight turns.\n\nPart Description | Part Link | Part Count | Part Cost\n---------------- | --------- | ---------- | ---------\nOpenMV Cam Wide Angle Lens<br />![OpenMV Cam Wide Angle Lens](images/parts/wide.jpg \"OpenMV Cam Wide Angle Lens\") | https://openmv.io/products/ultra-wide-angle-lens | 1 | $15.00\n\n**Sub-Total $15.00**\n\nMoving on, for better performance I recommend that you purchase LiPo batteries, adapters, and a LiPo charger. The NiMh battery that comes with the Magnet Car will quickly run out of power making it hard for you to test for hours before a race on the same day.\n\nPart Description | Part Link | Part Count | Part Cost\n---------------- | --------- | ---------- | ---------\nTurnigy 1300mAh 2S 20C LiPo Pack<br />![Turnigy 1300mAh 2S 20C LiPo Pack](images/parts/lipo.jpg \"Turnigy 1300mAh 2S 20C LiPo Pack\") | http://hobbyking.com/en_us/turnigy-1300mah-2s-20c-lipo-pack-suit-1-18th-truck.html | 3 | $10.03\nTamiya Mini Female to XT60 Male Adapters<br />![Tamiya Mini Female to XT60 Male Adapters](images/parts/adapters.jpg \"Tamiya Mini Female to XT60 Male Adapters\") | http://hobbyking.com/en_us/female-mini-tamiya-gt-male-xt60-3pcs-bag.html | 1 | $3.36\nTurnigy E3 Compact 2S/3S Lipo Charger<br />![Turnigy E3 Compact 2S/3S Lipo Charger](images/parts/lipo-charger.jpg \"Turnigy E3 Compact 2S/3S Lipo Charger\") | http://hobbyking.com/en_us/turnigy-e3-compact-2s-3s-lipo-charger-100-240v-us-plug.html | 1 | $12.35\n\n**Sub-Total $45.77**\n\nFinally, for wireless programming I recommend that you purchase a WiFi shield for the OpenMV Cam. With the WiFi shield you'll be able to comfortably test your self-driving car from one position versus having to follow your car around tethered by a USB cable.\n\nPart Description | Part Link | Part Count | Part Cost\n---------------- | --------- | ---------- | ---------\nOpenMV Cam WiFi Shield<br />![OpenMV Cam WiFi Shield](images/parts/wifi.jpg \"OpenMV Cam WiFi Shield\") | https://openmv.io/products/wifi-shield | 1 | $35.00\n\n*Note, as of 8/15/2017 wireless programming has not yet been implemented for the OpenMV Cam but it is coming soon.*\n\n**Sub-Total $35.00**\n\n## Assembly\n\nOnce you've purchased and received all the parts you want for your DIY Robocar above you can now build it.\n\n![Parts](images/build/step(1)small.jpg \"Parts\")\n\nNote that you're going to need an exacto knife, a philips screw driver, pliers, a soldering iron, and some solder.\n\n![Tools](images/build/step(2)small.jpg \"Tools\")\n\n### Step 1 - Clean up parts:\n\nYour 3D printed parts are most-likely going to need some cleanup. Using the extaco knife remove any burs on the 3D printed parts and cleanout any excess material in any of the holes in the 3D printed parts. In particular, you're going to want to make sure to clear out material left over in the slots on the sides of the roll bar.\n\n![De-bur](images/build/step(3)small.jpg \"De-bur\")\n\nNext, try to insert the 3D printed OpenMV Cam mount neck part into its holder. The parts are designed to fit snuggly so this takes a bit of work. If you're having trouble try widening the neck holder with a file. Since we want the most height for the camera you just need to get the neck mount in enough to line up the first set of holes.\n\n![Insert](images/build/step(4)small.jpg \"Insert\")\n\n### Step 2 - Assemble the body:\n\nThe rollbar mounts to the base plate using three M2 screws and nuts - a pair for each leg on the rollbar. Feel free to use any M2 screw length that fits. Moving on, before mounting the rollbar to the base plate make sure the screw stands on the base plate are facing up. The screw stands are for a Raspberry Pi and a servo controller which we won't be using, but, the screw holes shouldn't be upside down if you want to mount something else on there later on.\n\n![Body](images/build/step(5)small.jpg \"Body\")\n\nTo attach the rollbar to the base plate you need to insert a nut into the slots on either side of the front two rollbar legs (note that the screws are inserted from the bottom of the base plate). You then have to keep the nuts in place while screwing in the M2 screws. Doing this isn't particularly easy. You may wish to use a tool to keep the nuts from spinning in their slots.\n\n![Body](images/build/step(6)small.jpg \"Body\")\n\nAfter you've attached both of the front legs to the base plate you can then attach the third back leg. This should be rather easy as you can just press down on the nut from the top to keep it from spinning as you tighten the M2 screw from the bottom.\n\n![Last](images/build/step(7)small.jpg \"Last\")\n\nNext, attach the OpenMV Cam neck holder mount to the top of the rollbar using four more medium-length M2 screws. Note that this will take some work since the screw holes are unlikely to lineup exactly. I recommend screwing in all four screws only a little bit to get them started first before screwing each one in all the way.\n\n![Align](images/build/step(8)small.jpg \"Align\")\n\nMoving on, insert one of the long M3 screws in between the neck holder and the neck part's bottom hole. Use an M3 locknut afterwards to tighten the connection to make sure the neck part is stable.\n\n![Lock](images/build/step(9)small.jpg \"Lock\")\n\nNow, attach the OpenMV Cam holder to the top of the neck part and use another long M3 screw and locknut secure the holder in place. Make sure to get the orientation right like in the picture below.\n\n![Holder](images/build/step(10)small.jpg \"Holder\")\n\nNext, remove the plastic hood from your RC car. The hood is held on by four metal pin clips. After removing the hood you should see the guts of your RC car like in the image below. We'll mount the base onto the four posts on your RC car. To secure the base we'll use the same metal clips the hood was held on with. However, we'll have to put some effort into doing this since cutouts on the base to secure the base to the RC car are tight.\n\n![Hood](images/build/step(11)small.jpg \"Hood\")\n\nSo first, bend the four metal clips slightly so we can more easily get them through the holes in the mounting stands after we've attached the base.\n\n![Clip](images/build/step(12)small.jpg \"Clip\")\n\nAfterwards, cut away material using your exacto knife from the groves in the base to make space for the metal pins to go through the stand holes.\n\n![Exacto](images/build/step(13)small.jpg \"Exacto\")\n\nFinally, push each pin through each stand hole to firmly attach the base to the RC Car.\n\n![Attach](images/build/step(14)small.jpg \"Attach\")\n\nOnce you've finished this your car should look like this below.\n\n![Done](images/build/step(15)small.jpg \"Done\")\n\n### Step 3 - Assemble the head:\n\nNow we're going to assemble the OpenMV Cam head of your Robocar. First, remove the lens mount from your OpenMV Cam using a screw driver and clean off the camera IC under the lens mount using some isopropyl alcohol and a Q-Tip. Make sure to get off any dirt and don't leave any fibers on the camera IC.\n\n![Clean-up](images/build/step(16)small.jpg \"Clean-up\")\n\nThen reattach the lens mount. Next, we need to solder the pin headers onto the OpenMV Cam that it comes with. Using a soldering iron attach the two 8-pin headers on each side of the camera so that the 8-pin header legs are sticking out the back of the OpenMV Cam.\n\n![Legs](images/build/step(17)small.jpg \"Legs\")\n\nFinally, if you bought the wide angle lens above replace the lens that your OpenMV Cam comes with the wide angle lens.\n\n![Lens](images/build/step(18)small.jpg \"Lens\")\n\nNext, let's build up the servo shield for your OpenMV Cam so that it can control the RC car.\n\n![Shield](images/build/step(19)small.jpg \"Shield\")\n\nYou need to solder on the two 8-pin headers on either side of the servo controller board with the pin legs facing down. Then, solder on the two servo connection headers. The plastic parts on each header should be vertical and not flat against the servo controller board.\n\n![Soldered](images/build/step(20)small.jpg \"Soldered\")\n\nIf you bought a WiFi shield let's build that up too. Solder the two 8-pin headers it came with on either side of it with the legs facing down.\n\n![WiFi](images/build/step(21)small.jpg \"WiFi\")\n\nFinally, let's stack everything up. You can mount shields on the OpenMV Cam from either the top or bottom of the board. But, let's put the WiFi shield on the bottom of the OpenMV Cam and the servo shield on the top.\n\n![Stack](images/build/step(22)small.jpg \"Stack\")\n\n### Step 4 - Putting it together:\n\nAttach the OpenMV Cam using it's two screw mounting holes to the OpenMV Cam mount on the top of the robocar body. To give ourselves more freedom we're mounting the OpenMV Cam upside down. You'll be able to un-rotate the OpenMV Cam's field of view in software.\n\n![Mounting](images/build/step(23)small.jpg \"Mounting\")\n\nNext, using the servo extension headers attach channels 0 and 1 from the servo shield to the throttle and steering servo wires respectively. Make sure to thread the servo extension wires through the hole in the base plate. Also, use the zip ties to tie down all your wires so they aren't swaying everywhere. You don't want your robocar accidentally destroying itself by running over one of its wires. Your car should like the picture below once done.\n\n![Controller](images/build/step(24)small.jpg \"Controller\")\n\nFinally, put the black tube that comes with your RC Car over the antenna to protect the antenna.\n\n![Antenna](images/build/step(25)small.jpg \"Antenna\")\n\nIf you bought the LiPo battery upgrade parts let's install those next. First, attach the XT60 adapters to each LiPo battery.\n\n![Adapters](images/build/step(26)small.jpg \"Adapters\")\n\nThen, replace the NiMh battery on your RC car with one of the LiPo batteries. Make sure to place the battery with the wires going towards the front of the car like in the picture below.\n\n![Lipo](images/build/step(27)small.jpg \"Lipo\")\n\nAfter your done it should look like the picture below.\n\n![Done](images/build/step(28)small.jpg \"Done\")\n\n**LAST, MAKE SURE TO MOVE THE JUMPER ON YOUR ESC TO THE LIPO POSITION TOO!**\n\n![Danger](images/build/step(29)small.jpg \"Danger\")\n\n### Step 5 - Installing the software:\n\nBecause you're using the OpenMV Cam this is going to be the easiest part. Download OpenMV IDE from [here](https://openmv.io/pages/download) and install it on your laptop. Once that's done attach the micro USB cable to your OpenMV Cam and to your laptop.\n\n![OpenMV_Cam](images/build/step(40)small.jpg \"OpenMV_Cam\")\n\nNext, launch OpenMV IDE and hit the connect button the bottom left hand corner of the IDE. After doing so OpenMV IDE should display on the bottom right hand corner that your OpenMV Cam's firmware is out-of-date.\n\n![Update](images/build/step(41).png \"Update\")\n\nClick on the text and walk through the dialog to update your OpenMV Cam's firmware. When OpenMV IDE asks you if you want to erase the OpenMV Cam's flash drive select yes. Afterwards, OpenMV IDE will update your OpenMV Cam's firmware. Note that your OpenMV Cam is unbrickable, so, if anything goes wrong you can recover.\n\n![Firmware](images/build/step(42).png \"Firmware\")\n\nNow that your OpenMV Cam is updated. You need to focus the lens. Please run the hello world script (click the green run arrow) and turn the lens until the picture comes into focus on the frame buffer viewer in OpenMV IDE.\n\n![View](images/build/step(43).png \"View\")\n\nAfter doing all of this download the code for the robocar [here](https://github.com/openmv/openmv-projects/blob/master/donkey-car/line_follower_main.py) and open the script in OpenMV IDE. How the script works is documented in the comments. Note that you need to set the ``ARDUINO_SERVO_CONTROLLER_ATTACHED`` variable to ``True`` for the OpenMV Cam to output serial data to control the Arduino Servo Controller Shield and ``False`` for the OpenMV Cam to output serial data to control the Servo Controller Shield (the non-Arduino one).\n\n![Script](images/build/step(44).png \"Script\")\n\nFinally, once you're done tweaking settings go to ``Tools->Save open script to OpenMV Cam`` and save the script while keeping comments. Then click ``Tools->Reset OpenMV Cam``. You can now disconnect your OpenMV Cam from your laptop and it will run the script by itself. Follow the above two steps each time you want your OpenMV Cam to run the script without the laptop attached to it. For quick testing and debug while your laptop is connected just use the run button and stop button to start and stop the script between edits.\n\n*If you're using the Servo Controller Shield (the non-Arduino one), you also need to copy two scripts from OpenMV IDE to the OpenMV Cam board for things to work. Please go to ``Files->Examples->15-Servo-Shield->pca9865.py`` and save it on your OpenMV Cam's internal flash drive. Additionally, you also need to save ``Files->Examples->15-Servo-Shield->servo.py`` on your OpenMV Cam's internal flash drive. These two steps only need to be done once (You can also get these two scripts from the directory where this README is located).*\n\n### Optional Step 1 - Building the Arduino based Servo Controller:\n\nIf you opted to get the Arduino based Servo Controller so you can use your RC controller to act as a kill switch for your robocar (which is a **VERY** good idea) here's how to build it.\n\n![Parts](images/build/step(30)small.jpg \"Parts\")\n\nFirst, solder up the Arduino Pro Mini like the image below.\n\n![Arduino](images/build/step(31)small.jpg \"Arduino\")\n\nNext, solder the Arduino onto the ``123D Circuits`` circuits main board like below. We're trying to mount this onto the back of the OpenMV Cam board so the layout looks a little bit reversed. Just copy what's in the image below.\n\n![Controller](images/build/step(32)small.jpg \"Controller\")\n\nIt should look like this on the bottom.\n\n![Bottom](images/build/step(33)small.jpg \"Bottom\")\n\nNow, mount the board onto the back of the OpenMV Cam shield stack-up. Note that we don't need the extra length of the board connectors coming out of the back. Feel free to trim them if you like. Or, leave them on to stack more boards. If you decide to leave them on make sure they don't short with each other.\n\n![Stack-up](images/build/step(34)small.jpg \"Stack-up\")\n\nFinally, let's connect the steering servo to channel (1) on the Arduino, the throttle servo to channel (2), the RC radio receiver steering output to channel (3), and the RC radio receiver throttle output to channel (4). Note that the RC radio receiver's steering output is channel (1) and its throttle output is channel (2). Also, you're going to need to use the short-length female-to-female RC servo wire extension cables and long extension cables to wire up the RC radio receiver to the Arduino Servo Controller board.\n\n![Wire](images/build/step(35)small.jpg \"Wire\")\n\nOnce you're finished with all of this your robot should look like this below. Note that you should use the cable ties to clean-up the wiring job.\n\n![Done](images/build/step(36)small.jpg \"Done\")\n\n### Optional Step 2 - Programming the Arduino based Servo Controller:\n\nConnect the USB to serial adapter to the 6-pin header sticking out of the top on your Arduino Pro Mini. Make sure to connect ``GND`` to ``GND`` and ``DTR`` to ``DTR``. Next, connect the micro USB cable to the USB to serial converter and your laptop.\n\n![Programmer](images/build/step(37)small.jpg \"Programmer\")\n\nInstall the Arduino IDE from [here](https://www.arduino.cc/en/Main/Software). Download the servo controller code from [here](https://github.com/openmv/openmv-projects/blob/master/donkey-car/servo_controller/servo_controller.ino) and open it using the Arduino IDE. Go to ``Tools->Board`` and select ``Arduino Pro or Arduino Pro Mini`` and ``Tools->Processor`` and select ``Atmega328 (5V, 16Mhz)`` .\n\n![Arduino_IDE](images/build/step(38).png \"Arduino_IDE\")\n\nFinally, go to ``Tools->Port`` and select the COM port your USB to serial convert is connected to (it's usually the highest numbered COM port) and then click the upload button (round right arrow). The Arduino IDE should then compile the code and start programming the Arduino Pro Mini. Once it's finished remove the USB to serial converter from your Arduino Pro Mini and your servo controller board will be ready to use.\n\n![Arduino_IDE_Done](images/build/step(39).png \"Arduino_IDE_Done\")\n\nThe Arduino Servo Controller board allows you to directly control the robot's throttle and steering when the OpenMV Cam isn't running using the RC transmitter. Once the OpenMV Cam starts running and sending commands to the Arduino the Arduino will only drive the steering servo if the RC transmitter is on and will only drive the throttle if the RC transmitter throttle trigger is engaged (either for going forward or backwards). At any time you can use the steering control on the RC transmitter to override the OpenMV Cam steering. Finally, for fully autonomous control just adjust the throttle trim knob on the RC transmitter after turning it on with the throttle trim knob set to zero. Make sure to set the throttle trim knob back to zero after turning off the RC transmitter.\n\n## How does the robocar follow the line?\n\nThe OpenMV Cam uses linear regression to detect where the line is and then follow it. With the OpenMV Cam the machine vision part is simple. Most of the work the script the OpenMV Cam is running has to do with turning the line detection into servo outputs to control the robocar. You can read more about what's going on at the blog post [here](https://openmv.io/blogs/news/linear-regression-line-following).\n"
  },
  {
    "path": "robotics/donkey-car/download/OpenMV_Donkey_Mount.stl",
    "content": "solid stl_item0\n  facet normal 1 0 0\n    outer loop\n      vertex 61 -57 20\n      vertex 61 -60 20\n      vertex 61 -59.097 16.003\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 61 -60 16.003\n      vertex 61 -59.097 16.003\n      vertex 61 -60 20\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 61 -60 0\n      vertex 61 -59.097 10.097\n      vertex 61 -60 10.097\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 32.03106 11.64583 -14.81199\n      vertex 30.2 12.534 -18.127\n      vertex 32.059 11.6008 -14.64391\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 61 -59.097 16.003\n      vertex 61 -59.097 10.097\n      vertex 61 -57 20\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 61 -57 0\n      vertex 61 -57 20\n      vertex 61 -59.097 10.097\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 61 -60 0\n      vertex 61 -57 0\n      vertex 61 -59.097 10.097\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 20.1 -60 10.097\n      vertex 20.1 -59.097 10.097\n      vertex 20.1 -60 0\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 20.1 -60 20\n      vertex 20.1 -59.097 16.003\n      vertex 20.1 -60 16.003\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 20.1 -60 0\n      vertex 20.1 -59.097 10.097\n      vertex 20.1 -57 0\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 20.1 -57 20\n      vertex 20.1 -57 0\n      vertex 20.1 -59.097 10.097\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 20.1 -57 20\n      vertex 20.1 -59.097 10.097\n      vertex 20.1 -59.097 16.003\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 20.1 -57 20\n      vertex 20.1 -59.097 16.003\n      vertex 20.1 -60 20\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 58.2 8 20\n      vertex 56.103 2.403 20\n      vertex 58.2 -3.2 20\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 56.103 -0.802 20\n      vertex 58.2 -3.2 20\n      vertex 56.103 2.403 20\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 58.2 -3.2 20\n      vertex 56.103 -0.802 20\n      vertex 27.1 -3.2 20\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 46.1 -57 15\n      vertex 46.1 -55.482 14.12\n      vertex 46.1 -56.524 13.078\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 46.1 -57 15\n      vertex 46.1 -56.524 13.078\n      vertex 46.1 -57 12.14379\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 46.1 -56.524 7.542\n      vertex 46.1 -55.482 6.5\n      vertex 46.1 -57 5.6\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 46.1 -57 8.47621\n      vertex 46.1 -56.524 7.542\n      vertex 46.1 -57 5.6\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 27.1 8 20\n      vertex 29.097 2.403 20\n      vertex 45.937 8 20\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 46.1 -55.482 6.5\n      vertex 46.1 -54.168 5.831\n      vertex 46.1 -57 5.6\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 29.097 -0.802 20\n      vertex 27.1 -3.2 20\n      vertex 56.103 -0.802 20\n    endloop\n  endfacet\n  facet normal 0 0.45359 0.89121\n    outer loop\n      vertex 45.18865 -41.208 13.396\n      vertex 45.13548 -41.59019 13.59052\n      vertex 45.182 -41.591 13.59093\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 27.1 8 20\n      vertex 27.1 -3.2 20\n      vertex 29.097 2.403 20\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 29.097 -0.802 20\n      vertex 29.097 2.403 20\n      vertex 27.1 -3.2 20\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 26.6 -36.2 20\n      vertex 52.2 -36.2 20\n      vertex 26.6 -33.2 20\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 56.103 2.403 20\n      vertex 45.937 8 20\n      vertex 29.097 2.403 20\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 26.6 -33.2 20\n      vertex 52.2 -36.2 20\n      vertex 52.2 -33.2 20\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 32.514 11.9629 -15.99543\n      vertex 30.2 12.534 -18.127\n      vertex 32.3618 11.92344 -15.84815\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 32.237 11.8912 -15.72781\n      vertex 32.3618 11.92344 -15.84815\n      vertex 30.2 12.534 -18.127\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 32.514 11.9629 -15.99543\n      vertex 32.67122 11.98363 -16.0728\n      vertex 30.2 12.534 -18.127\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 32.237 11.5105 -14.30687\n      vertex 31.997 11.14241 -12.933\n      vertex 32.38921 11.47118 -14.1601\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 32.514 11.43885 -14.03945\n      vertex 32.38921 11.47118 -14.1601\n      vertex 31.997 11.14241 -12.933\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 32.1568 11.55121 -14.4588\n      vertex 31.997 11.14241 -12.933\n      vertex 32.237 11.5105 -14.30687\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 58.2 8 20\n      vertex 51.9 8 19.90931\n      vertex 45.937 8 20\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 45.937 8 20\n      vertex 56.103 2.403 20\n      vertex 58.2 8 20\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 34.539 -57 20\n      vertex 61 -60 20\n      vertex 54.937 -57 20\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 54.648 -60 16.327\n      vertex 54.265 -60 16.522\n      vertex 53.698 -60 16.003\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 55.073 -60 16.259\n      vertex 54.648 -60 16.327\n      vertex 53.698 -60 16.003\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 54.937 -57 20\n      vertex 61 -60 20\n      vertex 61 -57 20\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 20.1 -57 20\n      vertex 26.419 -60 20\n      vertex 34.539 -57 20\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 61 -60 20\n      vertex 34.539 -57 20\n      vertex 26.419 -60 20\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 26.419 -60 20\n      vertex 20.1 -57 20\n      vertex 20.1 -60 20\n    endloop\n  endfacet\n  facet normal 0.99982 0.01896 0.00193\n    outer loop\n      vertex 58.18832 -0.78834 0\n      vertex 58.008 9.368 -6.378\n      vertex 58.02918 7.60273 0\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 53.96 -60 18.444\n      vertex 26.419 -60 20\n      vertex 53.765 -60 18.06\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 55.2 7.74214 -12.60822\n      vertex 55.2 6.95722 -4.89569\n      vertex 55.2 4.36328 0\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 55.2 6.45898 0\n      vertex 55.2 4.36328 0\n      vertex 55.2 6.95722 -4.89569\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 37.8 22.7 4.662\n      vertex 37.8 22.60546 1.94475\n      vertex 37.8 26.19 1.681\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 52.2 -36.2 -10.48639\n      vertex 52.2 -36.2 -58\n      vertex 52.2 -33.2 -58\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 52.2 -36.2 -10.48639\n      vertex 52.2 -33.2 -58\n      vertex 52.2 -33.2 20\n    endloop\n  endfacet\n  facet normal 0 0.9994 -0.03477\n    outer loop\n      vertex 46.9 22.7 4.662\n      vertex 46.1 22.603 1.874\n      vertex 37.8 22.7 4.662\n    endloop\n  endfacet\n  facet normal 0 0.9994 -0.03477\n    outer loop\n      vertex 37.8 22.60546 1.94475\n      vertex 37.8 22.7 4.662\n      vertex 46.1 22.603 1.874\n    endloop\n  endfacet\n  facet normal 0.98801 0.1543 -0.00564\n    outer loop\n      vertex 40.882 19.30637 2.33263\n      vertex 40.882 19.40817 5.11997\n      vertex 40.89557 19.21993 2.34466\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 45.937 8 20\n      vertex 51.9 8 19.90931\n      vertex 46.9 8 19.90931\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 51.54319 5.13795 -2.89068\n      vertex 51.502 5.0705 -2.639\n      vertex 33.98219 5.10296 -2.76013\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 52.752 5.39395 -3.84597\n      vertex 55.2 7.74214 -12.60822\n      vertex 53.138 5.37813 -3.78692\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 53.96 -60 16.827\n      vertex 53.698 -60 16.003\n      vertex 54.265 -60 16.522\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.487 5.33204 -3.61494\n      vertex 53.138 5.37813 -3.78692\n      vertex 55.2 7.74214 -12.60822\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.487 5.33204 -3.61494\n      vertex 55.2 7.74214 -12.60822\n      vertex 53.67405 5.28375 -3.43474\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.764 5.26059 -3.3483\n      vertex 53.67405 5.28375 -3.43474\n      vertex 55.2 7.74214 -12.60822\n    endloop\n  endfacet\n  facet normal 0.46126 0.88667 -0.03246\n    outer loop\n      vertex 41.504 18.07045 2.50458\n      vertex 41.504 18.1725 5.29188\n      vertex 41.59237 18.02471 2.51094\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.764 5.26059 -3.3483\n      vertex 55.2 7.74214 -12.60822\n      vertex 53.8835 5.19975 -3.12129\n    endloop\n  endfacet\n  facet normal 0.45961 0.88753 -0.03242\n    outer loop\n      vertex 41.59237 18.02471 2.51094\n      vertex 41.69207 18.07515 5.30542\n      vertex 41.925 17.85333 2.53478\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 32.366 7.85499 -0.66298\n      vertex 30.2 7.67736 0\n      vertex 32.752 7.83917 -0.60393\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.539 -47.788 10.31\n      vertex 34.539 -50.584 9.881\n      vertex 34.539 -48.019 8.855\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.539 -51.311 8.88\n      vertex 34.539 -51.788 8.63766\n      vertex 34.539 -49.73 6.5\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.539 -50.868 9.323\n      vertex 34.539 -48.019 8.855\n      vertex 34.539 -50.584 9.881\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 31.563 8.06241 -1.43714\n      vertex 30.2 7.67736 0\n      vertex 31.741 7.97239 -1.10114\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 32.017 7.90082 -0.83403\n      vertex 30.2 7.67736 0\n      vertex 32.366 7.85499 -0.66298\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.539 -47.788 10.31\n      vertex 34.539 -48.019 11.765\n      vertex 34.539 -50.486 10.5\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 31.502 8.1623 -1.80997\n      vertex 30.2 7.67736 0\n      vertex 31.54787 8.08719 -1.52965\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 31.54787 8.08719 -1.52965\n      vertex 30.2 7.67736 0\n      vertex 31.563 8.06241 -1.43714\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 32.017 7.90082 -0.83403\n      vertex 31.741 7.97239 -1.10114\n      vertex 30.2 7.67736 0\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 31.741 8.35244 -2.51968\n      vertex 31.997 11.14241 -12.933\n      vertex 31.60713 8.28455 -2.26628\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 31.80942 8.37017 -2.58583\n      vertex 31.997 11.14241 -12.933\n      vertex 31.741 8.35244 -2.51968\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.539 -51.044 14.789\n      vertex 34.539 -51.311 12.12\n      vertex 34.539 -49.73 14.12\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 32.017 8.42381 -2.78603\n      vertex 31.997 11.14241 -12.933\n      vertex 31.80942 8.37017 -2.58583\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 32.366 8.46988 -2.95801\n      vertex 31.997 11.14241 -12.933\n      vertex 32.017 8.42381 -2.78603\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.539 -50.868 11.677\n      vertex 34.539 -49.73 14.12\n      vertex 34.539 -51.311 12.12\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.539 -51.788 12.36234\n      vertex 34.539 -51.311 12.12\n      vertex 34.539 -51.044 14.789\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.539 -51.788 12.36234\n      vertex 34.539 -51.044 14.789\n      vertex 34.539 -51.788 14.90704\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.539 -50.486 10.5\n      vertex 34.539 -50.584 9.881\n      vertex 34.539 -47.788 10.31\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.539 -50.584 11.119\n      vertex 34.539 -50.486 10.5\n      vertex 34.539 -48.019 11.765\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.539 -48.019 11.765\n      vertex 34.539 -48.688 13.078\n      vertex 34.539 -50.584 11.119\n    endloop\n  endfacet\n  facet normal -0.46127 0.88667 -0.03239\n    outer loop\n      vertex 42.859 17.95514 5.32211\n      vertex 43.04729 18.0526 5.30856\n      vertex 42.859 17.85333 2.53478\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.539 -49.73 14.12\n      vertex 34.539 -50.868 11.677\n      vertex 34.539 -48.688 13.078\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.539 -50.868 11.677\n      vertex 34.539 -50.584 11.119\n      vertex 34.539 -48.688 13.078\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 32.752 8.4857 -3.01706\n      vertex 31.997 11.14241 -12.933\n      vertex 32.366 8.46988 -2.95801\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 31.997 11.14241 -12.933\n      vertex 32.059 11.6008 -14.64391\n      vertex 30.2 12.534 -18.127\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 32.059 11.80093 -15.39088\n      vertex 30.2 12.534 -18.127\n      vertex 32.02493 11.74602 -15.18592\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 31.997 11.70088 -15.01744\n      vertex 32.02493 11.74602 -15.18592\n      vertex 30.2 12.534 -18.127\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 32.059 11.80093 -15.39088\n      vertex 32.237 11.8912 -15.72781\n      vertex 30.2 12.534 -18.127\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.539 -48.019 8.855\n      vertex 34.539 -50.868 9.323\n      vertex 34.539 -48.688 7.542\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.539 -48.688 7.542\n      vertex 34.539 -51.311 8.88\n      vertex 34.539 -49.73 6.5\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.539 -51.311 8.88\n      vertex 34.539 -48.688 7.542\n      vertex 34.539 -50.868 9.323\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.539 -51.044 5.831\n      vertex 34.539 -49.73 6.5\n      vertex 34.539 -51.788 8.63766\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.539 -51.788 5.71296\n      vertex 34.539 -51.044 5.831\n      vertex 34.539 -51.788 8.63766\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 31.502 8.1623 -1.80997\n      vertex 31.51712 8.18705 -1.90237\n      vertex 30.2 7.67736 0\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 31.563 8.26222 -2.18292\n      vertex 30.2 7.67736 0\n      vertex 31.51712 8.18705 -1.90237\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 31.60713 8.28455 -2.26628\n      vertex 31.997 11.14241 -12.933\n      vertex 31.563 8.26222 -2.18292\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 31.563 8.26222 -2.18292\n      vertex 31.997 11.14241 -12.933\n      vertex 30.2 7.67736 0\n    endloop\n  endfacet\n  facet normal -0.15985 -0.98648 0.03603\n    outer loop\n      vertex 42.859 20.75938 2.13049\n      vertex 42.859 20.86119 4.91782\n      vertex 42.78952 20.77058 2.12893\n    endloop\n  endfacet\n  facet normal 0.70742 0.18299 -0.6827\n    outer loop\n      vertex 32.2711 8.41066 -15.10281\n      vertex 32.38921 11.47118 -14.1601\n      vertex 32.514 8.34773 -14.86798\n    endloop\n  endfacet\n  facet normal -0.15779 -0.98681 0.03613\n    outer loop\n      vertex 42.78952 20.77058 2.12893\n      vertex 42.67964 20.8901 4.9138\n      vertex 42.392 20.83382 2.12013\n    endloop\n  endfacet\n  facet normal -0.71259 -0.70111 0.02561\n    outer loop\n      vertex 43.614 20.30653 4.99498\n      vertex 43.28 20.64428 4.948\n      vertex 43.614 20.20472 2.20765\n    endloop\n  endfacet\n  facet normal 0.89433 0.4471 -0.01633\n    outer loop\n      vertex 40.956 18.9367 5.18556\n      vertex 41.17 18.40899 2.45748\n      vertex 40.956 18.83489 2.39823\n    endloop\n  endfacet\n  facet normal 0.98801 0.15428 -0.00564\n    outer loop\n      vertex 40.956 18.9367 5.18556\n      vertex 40.956 18.83489 2.39823\n      vertex 40.91319 19.20945 5.14761\n    endloop\n  endfacet\n  facet normal 0.98801 0.15428 -0.00564\n    outer loop\n      vertex 40.89557 19.21993 2.34466\n      vertex 40.91319 19.20945 5.14761\n      vertex 40.956 18.83489 2.39823\n    endloop\n  endfacet\n  facet normal 0.98801 0.1543 -0.00564\n    outer loop\n      vertex 40.89557 19.21993 2.34466\n      vertex 40.882 19.40817 5.11997\n      vertex 40.91319 19.20945 5.14761\n    endloop\n  endfacet\n  facet normal 0.98806 -0.15398 0.00562\n    outer loop\n      vertex 40.94322 19.69723 2.27826\n      vertex 40.9256 19.68651 5.08124\n      vertex 40.882 19.30637 2.33263\n    endloop\n  endfacet\n  facet normal 0.98806 -0.15398 0.00562\n    outer loop\n      vertex 40.882 19.40817 5.11997\n      vertex 40.882 19.30637 2.33263\n      vertex 40.9256 19.68651 5.08124\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 32.8 8.01 19.9\n      vertex 32.8 26.19 1.681\n      vertex 32.8 8 19.80394\n    endloop\n  endfacet\n  facet normal 0.98806 -0.15397 0.00562\n    outer loop\n      vertex 40.956 19.77882 2.26691\n      vertex 40.956 19.88063 5.05424\n      vertex 40.94322 19.69723 2.27826\n    endloop\n  endfacet\n  facet normal 0.98806 -0.15397 0.00562\n    outer loop\n      vertex 40.9256 19.68651 5.08124\n      vertex 40.94322 19.69723 2.27826\n      vertex 40.956 19.88063 5.05424\n    endloop\n  endfacet\n  facet normal 0.89433 -0.4471 0.01633\n    outer loop\n      vertex 41.17 20.20472 2.20765\n      vertex 41.17 20.30653 4.99498\n      vertex 40.956 19.77882 2.26691\n    endloop\n  endfacet\n  facet normal 0.89073 -0.11774 0.43903\n    outer loop\n      vertex 32.059 8.71 -16.21979\n      vertex 32.237 8.80029 -16.55671\n      vertex 32.237 11.8912 -15.72781\n    endloop\n  endfacet\n  facet normal 0.15779 0.98682 -0.03604\n    outer loop\n      vertex 41.925 17.85333 2.53478\n      vertex 41.925 17.95514 5.32211\n      vertex 42.02497 17.83743 2.537\n    endloop\n  endfacet\n  facet normal 0.15779 0.98682 -0.03604\n    outer loop\n      vertex 42.13522 17.9217 5.32677\n      vertex 42.02497 17.83743 2.537\n      vertex 41.925 17.95514 5.32211\n    endloop\n  endfacet\n  facet normal 0.70652 -0.18331 0.68354\n    outer loop\n      vertex 32.47992 8.86306 -16.79096\n      vertex 32.3618 11.92344 -15.84815\n      vertex 32.237 8.80029 -16.55671\n    endloop\n  endfacet\n  facet normal 0.15771 0.98683 -0.03604\n    outer loop\n      vertex 42.392 17.88087 5.33245\n      vertex 42.392 17.77907 2.54512\n      vertex 42.13522 17.9217 5.32677\n    endloop\n  endfacet\n  facet normal 0.15771 0.98683 -0.03604\n    outer loop\n      vertex 42.02497 17.83743 2.537\n      vertex 42.13522 17.9217 5.32677\n      vertex 42.392 17.77907 2.54512\n    endloop\n  endfacet\n  facet normal 0.46126 0.88667 -0.03246\n    outer loop\n      vertex 41.69207 18.07515 5.30542\n      vertex 41.59237 18.02471 2.51094\n      vertex 41.504 18.1725 5.29188\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 61 -60 16.003\n      vertex 56.186 -60 16.827\n      vertex 55.882 -60 16.522\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 61 -60 16.003\n      vertex 55.882 -60 16.522\n      vertex 55.498 -60 16.327\n    endloop\n  endfacet\n  facet normal 0.45961 0.88753 -0.03242\n    outer loop\n      vertex 41.925 17.85333 2.53478\n      vertex 41.69207 18.07515 5.30542\n      vertex 41.925 17.95514 5.32211\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 56.186 -60 16.827\n      vertex 61 -60 16.003\n      vertex 56.381 -60 17.21\n    endloop\n  endfacet\n  facet normal 0.71361 0.70007 -0.02563\n    outer loop\n      vertex 41.23776 18.34046 2.46701\n      vertex 41.31708 18.36207 5.2655\n      vertex 41.504 18.07045 2.50458\n    endloop\n  endfacet\n  facet normal 0.71361 0.70007 -0.02563\n    outer loop\n      vertex 41.504 18.1725 5.29188\n      vertex 41.504 18.07045 2.50458\n      vertex 41.31708 18.36207 5.2655\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 61 -60 16.003\n      vertex 61 -60 20\n      vertex 56.449 -60 17.635\n    endloop\n  endfacet\n  facet normal 0.71259 0.70111 -0.02561\n    outer loop\n      vertex 41.17 18.40899 2.45748\n      vertex 41.17 18.5108 5.24481\n      vertex 41.23776 18.34046 2.46701\n    endloop\n  endfacet\n  facet normal 0.71259 0.70111 -0.02561\n    outer loop\n      vertex 41.31708 18.36207 5.2655\n      vertex 41.23776 18.34046 2.46701\n      vertex 41.17 18.5108 5.24481\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 55.882 -60 18.748\n      vertex 61 -60 20\n      vertex 55.498 -60 18.943\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 54.265 -60 18.748\n      vertex 54.648 -60 18.943\n      vertex 26.419 -60 20\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 54.648 -60 18.943\n      vertex 55.073 -60 19.011\n      vertex 26.419 -60 20\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 61 -60 20\n      vertex 26.419 -60 20\n      vertex 55.073 -60 19.011\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 55.498 -60 18.943\n      vertex 61 -60 20\n      vertex 55.073 -60 19.011\n    endloop\n  endfacet\n  facet normal 0.89086 0.11765 -0.43877\n    outer loop\n      vertex 32.237 11.5105 -14.30687\n      vertex 32.237 8.41947 -15.13569\n      vertex 32.1568 11.55121 -14.4588\n    endloop\n  endfacet\n  facet normal 0.89086 0.11765 -0.43877\n    outer loop\n      vertex 32.237 8.41947 -15.13569\n      vertex 32.0809 8.49871 -15.43139\n      vertex 32.1568 11.55121 -14.4588\n    endloop\n  endfacet\n  facet normal 0.89073 0.11774 -0.43903\n    outer loop\n      vertex 32.1568 11.55121 -14.4588\n      vertex 32.0809 8.49871 -15.43139\n      vertex 32.059 11.6008 -14.64391\n    endloop\n  endfacet\n  facet normal 0.89073 0.11774 -0.43903\n    outer loop\n      vertex 32.059 8.50982 -15.47284\n      vertex 32.059 11.6008 -14.64391\n      vertex 32.0809 8.49871 -15.43139\n    endloop\n  endfacet\n  facet normal 0.98742 0.04094 -0.15274\n    outer loop\n      vertex 31.997 8.60981 -15.84596\n      vertex 31.997 11.70088 -15.01744\n      vertex 32.00463 8.59749 -15.79996\n    endloop\n  endfacet\n  facet normal 0.98742 0.04094 -0.15274\n    outer loop\n      vertex 32.03106 11.64583 -14.81199\n      vertex 32.00463 8.59749 -15.79996\n      vertex 31.997 11.70088 -15.01744\n    endloop\n  endfacet\n  facet normal 0.89433 0.4471 -0.01633\n    outer loop\n      vertex 41.17 18.5108 5.24481\n      vertex 41.17 18.40899 2.45748\n      vertex 40.956 18.9367 5.18556\n    endloop\n  endfacet\n  facet normal 0.98736 0.04106 -0.15311\n    outer loop\n      vertex 32.059 11.6008 -14.64391\n      vertex 32.059 8.50982 -15.47284\n      vertex 32.03106 11.64583 -14.81199\n    endloop\n  endfacet\n  facet normal 0.98736 0.04106 -0.15311\n    outer loop\n      vertex 32.00463 8.59749 -15.79996\n      vertex 32.03106 11.64583 -14.81199\n      vertex 32.059 8.50982 -15.47284\n    endloop\n  endfacet\n  facet normal 0.98736 -0.04106 0.15311\n    outer loop\n      vertex 32.059 8.71 -16.21979\n      vertex 32.059 11.80093 -15.39088\n      vertex 32.05137 8.69769 -16.17389\n    endloop\n  endfacet\n  facet normal 0.98736 -0.04106 0.15311\n    outer loop\n      vertex 32.02493 11.74602 -15.18592\n      vertex 32.05137 8.69769 -16.17389\n      vertex 32.059 11.80093 -15.39088\n    endloop\n  endfacet\n  facet normal 0.89433 -0.4471 0.01633\n    outer loop\n      vertex 40.956 19.88063 5.05424\n      vertex 40.956 19.77882 2.26691\n      vertex 41.17 20.30653 4.99498\n    endloop\n  endfacet\n  facet normal 0.98742 -0.04094 0.15274\n    outer loop\n      vertex 32.05137 8.69769 -16.17389\n      vertex 32.02493 11.74602 -15.18592\n      vertex 31.997 8.60981 -15.84596\n    endloop\n  endfacet\n  facet normal 0.98742 -0.04094 0.15274\n    outer loop\n      vertex 31.997 11.70088 -15.01744\n      vertex 31.997 8.60981 -15.84596\n      vertex 32.02493 11.74602 -15.18592\n    endloop\n  endfacet\n  facet normal 0.89073 -0.11774 0.43903\n    outer loop\n      vertex 32.059 11.80093 -15.39088\n      vertex 32.059 8.71 -16.21979\n      vertex 32.237 11.8912 -15.72781\n    endloop\n  endfacet\n  facet normal 0.70652 -0.18331 0.68354\n    outer loop\n      vertex 32.237 11.8912 -15.72781\n      vertex 32.237 8.80029 -16.55671\n      vertex 32.3618 11.92344 -15.84815\n    endloop\n  endfacet\n  facet normal 0.70775 -0.1829 0.68238\n    outer loop\n      vertex 32.514 8.8719 -16.82394\n      vertex 32.514 11.9629 -15.99543\n      vertex 32.47992 8.86306 -16.79096\n    endloop\n  endfacet\n  facet normal 0.70775 -0.1829 0.68238\n    outer loop\n      vertex 32.3618 11.92344 -15.84815\n      vertex 32.47992 8.86306 -16.79096\n      vertex 32.514 11.9629 -15.99543\n    endloop\n  endfacet\n  facet normal 0.45391 -0.23069 0.86067\n    outer loop\n      vertex 32.82001 8.91225 -16.97451\n      vertex 32.67122 11.98363 -16.0728\n      vertex 32.514 8.8719 -16.82394\n    endloop\n  endfacet\n  facet normal 0.45391 -0.23069 0.86067\n    outer loop\n      vertex 32.514 11.9629 -15.99543\n      vertex 32.514 8.8719 -16.82394\n      vertex 32.67122 11.98363 -16.0728\n    endloop\n  endfacet\n  facet normal 0.45248 -0.23096 0.86135\n    outer loop\n      vertex 32.82001 8.91225 -16.97451\n      vertex 32.863 12.00881 -16.16679\n      vertex 32.67122 11.98363 -16.0728\n    endloop\n  endfacet\n  facet normal -0.89433 -0.4471 0.01633\n    outer loop\n      vertex 43.828 19.77882 2.26691\n      vertex 43.828 19.88063 5.05424\n      vertex 43.614 20.30653 4.99498\n    endloop\n  endfacet\n  facet normal -0.89433 -0.4471 0.01633\n    outer loop\n      vertex 43.828 19.77882 2.26691\n      vertex 43.614 20.30653 4.99498\n      vertex 43.614 20.20472 2.20765\n    endloop\n  endfacet\n  facet normal 0.45444 0.23062 -0.86041\n    outer loop\n      vertex 32.514 11.43885 -14.03945\n      vertex 32.863 8.30164 -14.69601\n      vertex 32.514 8.34773 -14.86798\n    endloop\n  endfacet\n  facet normal 0.70742 0.18299 -0.6827\n    outer loop\n      vertex 32.514 11.43885 -14.03945\n      vertex 32.514 8.34773 -14.86798\n      vertex 32.38921 11.47118 -14.1601\n    endloop\n  endfacet\n  facet normal 0.70652 0.18329 -0.68355\n    outer loop\n      vertex 32.237 8.41947 -15.13569\n      vertex 32.237 11.5105 -14.30687\n      vertex 32.2711 8.41066 -15.10281\n    endloop\n  endfacet\n  facet normal 0.70652 0.18329 -0.68355\n    outer loop\n      vertex 32.38921 11.47118 -14.1601\n      vertex 32.2711 8.41066 -15.10281\n      vertex 32.237 11.5105 -14.30687\n    endloop\n  endfacet\n  facet normal -0.98806 -0.15397 0.00562\n    outer loop\n      vertex 43.902 19.40817 5.11997\n      vertex 43.87146 19.60318 5.09284\n      vertex 43.902 19.30637 2.33263\n    endloop\n  endfacet\n  facet normal -0.98806 -0.15397 0.00562\n    outer loop\n      vertex 43.88871 19.39119 2.32083\n      vertex 43.902 19.30637 2.33263\n      vertex 43.87146 19.60318 5.09284\n    endloop\n  endfacet\n  facet normal -0.98806 -0.15398 0.00562\n    outer loop\n      vertex 43.87146 19.60318 5.09284\n      vertex 43.828 19.88063 5.05424\n      vertex 43.88871 19.39119 2.32083\n    endloop\n  endfacet\n  facet normal -0.98806 -0.15398 0.00562\n    outer loop\n      vertex 43.828 19.77882 2.26691\n      vertex 43.88871 19.39119 2.32083\n      vertex 43.828 19.88063 5.05424\n    endloop\n  endfacet\n  facet normal -0.98801 0.1543 -0.00564\n    outer loop\n      vertex 43.828 18.9367 5.18556\n      vertex 43.85931 19.13616 5.15781\n      vertex 43.828 18.83489 2.39823\n    endloop\n  endfacet\n  facet normal -0.98801 0.1543 -0.00564\n    outer loop\n      vertex 43.84205 18.9244 2.38577\n      vertex 43.828 18.83489 2.39823\n      vertex 43.85931 19.13616 5.15781\n    endloop\n  endfacet\n  facet normal 0.15642 0.25577 -0.954\n    outer loop\n      vertex 32.752 7.83917 -0.60393\n      vertex 32.752 4.74728 -1.43288\n      vertex 32.366 7.85499 -0.66298\n    endloop\n  endfacet\n  facet normal 0.45248 0.23093 -0.86136\n    outer loop\n      vertex 32.366 7.85499 -0.66298\n      vertex 32.366 4.7631 -1.49193\n      vertex 32.017 7.90082 -0.83403\n    endloop\n  endfacet\n  facet normal 0.45248 0.23093 -0.86136\n    outer loop\n      vertex 32.017 4.80894 -1.66297\n      vertex 32.017 7.90082 -0.83403\n      vertex 32.366 4.7631 -1.49193\n    endloop\n  endfacet\n  facet normal -0.98801 0.15428 -0.00564\n    outer loop\n      vertex 43.84205 18.9244 2.38577\n      vertex 43.85931 19.13616 5.15781\n      vertex 43.902 19.40817 5.11997\n    endloop\n  endfacet\n  facet normal -0.98801 0.15428 -0.00564\n    outer loop\n      vertex 43.84205 18.9244 2.38577\n      vertex 43.902 19.40817 5.11997\n      vertex 43.902 19.30637 2.33263\n    endloop\n  endfacet\n  facet normal 0.70779 0.18293 -0.68232\n    outer loop\n      vertex 31.741 4.88052 -1.93008\n      vertex 31.741 7.97239 -1.10114\n      vertex 32.017 4.80894 -1.66297\n    endloop\n  endfacet\n  facet normal -0.89433 0.4471 -0.01633\n    outer loop\n      vertex 43.828 18.83489 2.39823\n      vertex 43.614 18.40899 2.45748\n      vertex 43.828 18.9367 5.18556\n    endloop\n  endfacet\n  facet normal -0.89433 0.4471 -0.01633\n    outer loop\n      vertex 43.614 18.5108 5.24481\n      vertex 43.828 18.9367 5.18556\n      vertex 43.614 18.40899 2.45748\n    endloop\n  endfacet\n  facet normal 0.15642 -0.25577 0.954\n    outer loop\n      vertex 32.366 8.46988 -2.95801\n      vertex 32.366 5.37813 -3.78692\n      vertex 32.752 8.4857 -3.01706\n    endloop\n  endfacet\n  facet normal -0.71258 0.70112 -0.02567\n    outer loop\n      vertex 43.28 18.1725 5.29188\n      vertex 43.42738 18.32152 5.27114\n      vertex 43.28 18.07045 2.50458\n    endloop\n  endfacet\n  facet normal -0.71258 0.70112 -0.02567\n    outer loop\n      vertex 43.34925 18.14048 2.49484\n      vertex 43.28 18.07045 2.50458\n      vertex 43.42738 18.32152 5.27114\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 61 -60 20\n      vertex 55.882 -60 18.748\n      vertex 56.186 -60 18.444\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 56.381 -60 18.06\n      vertex 56.449 -60 17.635\n      vertex 61 -60 20\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 56.449 -60 17.635\n      vertex 56.381 -60 17.21\n      vertex 61 -60 16.003\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 56.186 -60 18.444\n      vertex 56.381 -60 18.06\n      vertex 61 -60 20\n    endloop\n  endfacet\n  facet normal -0.71362 0.70007 -0.02557\n    outer loop\n      vertex 43.34925 18.14048 2.49484\n      vertex 43.42738 18.32152 5.27114\n      vertex 43.614 18.5108 5.24481\n    endloop\n  endfacet\n  facet normal -0.71362 0.70007 -0.02557\n    outer loop\n      vertex 43.34925 18.14048 2.49484\n      vertex 43.614 18.5108 5.24481\n      vertex 43.614 18.40899 2.45748\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 20.1 -60 0\n      vertex 61 -60 0\n      vertex 61 -60 10.097\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 55.498 -60 16.327\n      vertex 55.073 -60 16.259\n      vertex 61 -60 16.003\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 53.698 -60 16.003\n      vertex 61 -60 16.003\n      vertex 55.073 -60 16.259\n    endloop\n  endfacet\n  facet normal -0.4596 0.88753 -0.03249\n    outer loop\n      vertex 43.28 18.07045 2.50458\n      vertex 42.94855 17.89968 2.52834\n      vertex 43.28 18.1725 5.29188\n    endloop\n  endfacet\n  facet normal -0.4596 0.88753 -0.03249\n    outer loop\n      vertex 43.04729 18.0526 5.30856\n      vertex 43.28 18.1725 5.29188\n      vertex 42.94855 17.89968 2.52834\n    endloop\n  endfacet\n  facet normal -0.46127 0.88667 -0.03239\n    outer loop\n      vertex 42.94855 17.89968 2.52834\n      vertex 42.859 17.85333 2.53478\n      vertex 43.04729 18.0526 5.30856\n    endloop\n  endfacet\n  facet normal -0.15771 0.98683 -0.03605\n    outer loop\n      vertex 42.859 17.95514 5.32211\n      vertex 42.859 17.85333 2.53478\n      vertex 42.60231 17.91433 5.32779\n    endloop\n  endfacet\n  facet normal -0.15771 0.98683 -0.03605\n    outer loop\n      vertex 42.49244 17.79505 2.54289\n      vertex 42.60231 17.91433 5.32779\n      vertex 42.859 17.85333 2.53478\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 24.557 -60 16.784\n      vertex 24.073 -60 16.003\n      vertex 24.884 -60 16.617\n    endloop\n  endfacet\n  facet normal -0.15779 0.98682 -0.03604\n    outer loop\n      vertex 42.60231 17.91433 5.32779\n      vertex 42.49244 17.79505 2.54289\n      vertex 42.392 17.88087 5.33245\n    endloop\n  endfacet\n  facet normal -0.15779 0.98682 -0.03604\n    outer loop\n      vertex 42.392 17.77907 2.54512\n      vertex 42.392 17.88087 5.33245\n      vertex 42.49244 17.79505 2.54289\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 53.698 -60 16.003\n      vertex 25.936 -60 16.784\n      vertex 25.609 -60 16.617\n    endloop\n  endfacet\n  facet normal 0.71259 -0.70111 0.02561\n    outer loop\n      vertex 41.17 20.30653 4.99498\n      vertex 41.17 20.20472 2.20765\n      vertex 41.504 20.64428 4.948\n    endloop\n  endfacet\n  facet normal 0.71259 -0.70111 0.02561\n    outer loop\n      vertex 41.504 20.64428 4.948\n      vertex 41.17 20.20472 2.20765\n      vertex 41.504 20.54247 2.16067\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 25.936 -60 16.784\n      vertex 53.698 -60 16.003\n      vertex 26.195 -60 17.043\n    endloop\n  endfacet\n  facet normal 0.45961 -0.88753 0.03242\n    outer loop\n      vertex 41.504 20.64428 4.948\n      vertex 41.504 20.54247 2.16067\n      vertex 41.925 20.86119 4.91782\n    endloop\n  endfacet\n  facet normal 0.45961 -0.88753 0.03242\n    outer loop\n      vertex 41.925 20.75938 2.13049\n      vertex 41.925 20.86119 4.91782\n      vertex 41.504 20.54247 2.16067\n    endloop\n  endfacet\n  facet normal 0.45444 -0.23067 0.86039\n    outer loop\n      vertex 32.366 5.37813 -3.78692\n      vertex 32.366 8.46988 -2.95801\n      vertex 32.017 5.33204 -3.61494\n    endloop\n  endfacet\n  facet normal 0.45444 -0.23067 0.86039\n    outer loop\n      vertex 32.017 8.42381 -2.78603\n      vertex 32.017 5.33204 -3.61494\n      vertex 32.366 8.46988 -2.95801\n    endloop\n  endfacet\n  facet normal 0.15779 -0.98682 0.03604\n    outer loop\n      vertex 42.32306 20.8227 2.12168\n      vertex 42.21282 20.90698 4.91145\n      vertex 41.925 20.75938 2.13049\n    endloop\n  endfacet\n  facet normal 0.15779 -0.98682 0.03604\n    outer loop\n      vertex 41.925 20.86119 4.91782\n      vertex 41.925 20.75938 2.13049\n      vertex 42.21282 20.90698 4.91145\n    endloop\n  endfacet\n  facet normal 0.15642 -0.25577 0.954\n    outer loop\n      vertex 32.752 5.39395 -3.84597\n      vertex 32.752 8.4857 -3.01706\n      vertex 32.366 5.37813 -3.78692\n    endloop\n  endfacet\n  facet normal 0.15984 -0.98648 0.03612\n    outer loop\n      vertex 42.392 20.83382 2.12013\n      vertex 42.392 20.93586 4.90743\n      vertex 42.32306 20.8227 2.12168\n    endloop\n  endfacet\n  facet normal 0.15984 -0.98648 0.03612\n    outer loop\n      vertex 42.21282 20.90698 4.91145\n      vertex 42.32306 20.8227 2.12168\n      vertex 42.392 20.93586 4.90743\n    endloop\n  endfacet\n  facet normal -0.15985 -0.98648 0.03603\n    outer loop\n      vertex 42.67964 20.8901 4.9138\n      vertex 42.78952 20.77058 2.12893\n      vertex 42.859 20.86119 4.91782\n    endloop\n  endfacet\n  facet normal 0.15642 0.25577 -0.954\n    outer loop\n      vertex 32.366 4.7631 -1.49193\n      vertex 32.366 7.85499 -0.66298\n      vertex 32.752 4.74728 -1.43288\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 26.419 -60 20\n      vertex 20.1 -60 20\n      vertex 24.884 -60 18.849\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 24.297 -60 18.422\n      vertex 20.1 -60 20\n      vertex 24.13 -60 18.095\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 24.557 -60 18.682\n      vertex 20.1 -60 20\n      vertex 24.297 -60 18.422\n    endloop\n  endfacet\n  facet normal -0.15779 -0.98681 0.03613\n    outer loop\n      vertex 42.67964 20.8901 4.9138\n      vertex 42.392 20.93586 4.90743\n      vertex 42.392 20.83382 2.12013\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 25.936 -60 18.682\n      vertex 26.419 -60 20\n      vertex 25.609 -60 18.849\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 24.557 -60 18.682\n      vertex 24.884 -60 18.849\n      vertex 20.1 -60 20\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 26.419 -60 20\n      vertex 24.884 -60 18.849\n      vertex 25.246 -60 18.906\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 25.609 -60 18.849\n      vertex 26.419 -60 20\n      vertex 25.246 -60 18.906\n    endloop\n  endfacet\n  facet normal -0.45961 -0.88753 0.03242\n    outer loop\n      vertex 43.28 20.54247 2.16067\n      vertex 43.28 20.64428 4.948\n      vertex 42.859 20.86119 4.91782\n    endloop\n  endfacet\n  facet normal -0.45961 -0.88753 0.03242\n    outer loop\n      vertex 43.28 20.54247 2.16067\n      vertex 42.859 20.86119 4.91782\n      vertex 42.859 20.75938 2.13049\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 26.419 -60 20\n      vertex 25.936 -60 18.682\n      vertex 26.195 -60 18.422\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 53.765 -60 17.21\n      vertex 53.698 -60 17.635\n      vertex 26.419 -60 17.733\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 53.96 -60 16.827\n      vertex 53.765 -60 17.21\n      vertex 26.419 -60 17.733\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 26.362 -60 17.37\n      vertex 53.698 -60 16.003\n      vertex 26.419 -60 17.733\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 26.362 -60 18.095\n      vertex 26.419 -60 17.733\n      vertex 53.698 -60 17.635\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 26.195 -60 18.422\n      vertex 26.362 -60 18.095\n      vertex 53.698 -60 17.635\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 26.419 -60 20\n      vertex 26.195 -60 18.422\n      vertex 53.698 -60 17.635\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 53.698 -60 17.635\n      vertex 53.765 -60 18.06\n      vertex 26.419 -60 20\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 53.96 -60 18.444\n      vertex 54.265 -60 18.748\n      vertex 26.419 -60 20\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 61 -60 10.097\n      vertex 20.1 -60 10.097\n      vertex 20.1 -60 0\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 26.195 -60 17.043\n      vertex 53.698 -60 16.003\n      vertex 26.362 -60 17.37\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 25.246 -60 16.559\n      vertex 24.073 -60 16.003\n      vertex 25.609 -60 16.617\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 53.698 -60 16.003\n      vertex 25.609 -60 16.617\n      vertex 24.073 -60 16.003\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 25.246 -60 16.559\n      vertex 24.884 -60 16.617\n      vertex 24.073 -60 16.003\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 53.96 -60 16.827\n      vertex 26.419 -60 17.733\n      vertex 53.698 -60 16.003\n    endloop\n  endfacet\n  facet normal -0.71259 -0.70111 0.02561\n    outer loop\n      vertex 43.28 20.54247 2.16067\n      vertex 43.614 20.20472 2.20765\n      vertex 43.28 20.64428 4.948\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 24.073 -60 16.003\n      vertex 24.297 -60 17.043\n      vertex 20.1 -60 16.003\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 24.557 -60 16.784\n      vertex 24.297 -60 17.043\n      vertex 24.073 -60 16.003\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 24.13 -60 17.37\n      vertex 20.1 -60 16.003\n      vertex 24.297 -60 17.043\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 24.13 -60 17.37\n      vertex 24.073 -60 17.733\n      vertex 20.1 -60 16.003\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 20.1 -60 20\n      vertex 20.1 -60 16.003\n      vertex 24.073 -60 17.733\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 24.073 -60 17.733\n      vertex 24.13 -60 18.095\n      vertex 20.1 -60 20\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 45.265 -3.2 12.665\n      vertex 58.2 -3.2 20\n      vertex 44.867 -3.2 13.445\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.616 -54.491 10.5\n      vertex 34.616 -57 5.6\n      vertex 34.616 -54.393 9.881\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 43.467 -3.2 14.463\n      vertex 44.248 -3.2 14.065\n      vertex 58.2 -3.2 20\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.616 -54.393 9.881\n      vertex 34.616 -57 5.6\n      vertex 34.616 -54.109 9.323\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 44.248 -3.2 14.065\n      vertex 44.867 -3.2 13.445\n      vertex 58.2 -3.2 20\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 43.467 -3.2 14.463\n      vertex 58.2 -3.2 20\n      vertex 42.601 -3.2 14.6\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 45.265 -3.2 10.933\n      vertex 58.2 -3.2 0\n      vertex 45.402 -3.2 11.799\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 45.402 -3.2 11.799\n      vertex 58.2 -3.2 20\n      vertex 45.265 -3.2 12.665\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.955 -3.2 9.533\n      vertex 40.335 -3.2 10.152\n      vertex 27.1 -3.2 0\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 41.735 8 9.135\n      vertex 37.8 8 5.23414\n      vertex 40.955 8 9.533\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.335 8 10.152\n      vertex 37.8 8 5.23414\n      vertex 39.937 8 10.933\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 45.265 8 10.933\n      vertex 45.402 8 11.799\n      vertex 46.9 8 5.23414\n    endloop\n  endfacet\n  facet normal 0.89035 -0.1179 0.43974\n    outer loop\n      vertex 31.60713 8.28455 -2.26628\n      vertex 31.563 5.17042 -3.01184\n      vertex 31.6832 5.23127 -3.23889\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 44.867 8 10.152\n      vertex 45.265 8 10.933\n      vertex 46.9 8 5.23414\n    endloop\n  endfacet\n  facet normal 0.89073 -0.11767 0.43905\n    outer loop\n      vertex 31.60713 8.28455 -2.26628\n      vertex 31.6832 5.23127 -3.23889\n      vertex 31.741 8.35244 -2.51968\n    endloop\n  endfacet\n  facet normal 0.89073 -0.11767 0.43905\n    outer loop\n      vertex 31.741 5.26059 -3.3483\n      vertex 31.741 8.35244 -2.51968\n      vertex 31.6832 5.23127 -3.23889\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 44.248 8 9.533\n      vertex 44.867 8 10.152\n      vertex 46.9 8 5.23414\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 34.17384 -36.2 15.21\n      vertex 26.6 -36.2 20\n      vertex 34.17386 -36.2 13.85081\n    endloop\n  endfacet\n  facet normal 0.70746 -0.18295 0.68266\n    outer loop\n      vertex 31.741 8.35244 -2.51968\n      vertex 31.741 5.26059 -3.3483\n      vertex 31.80942 8.37017 -2.58583\n    endloop\n  endfacet\n  facet normal 0.70746 -0.18295 0.68266\n    outer loop\n      vertex 31.92735 5.30887 -3.52849\n      vertex 31.80942 8.37017 -2.58583\n      vertex 31.741 5.26059 -3.3483\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.8 8 19.80394\n      vertex 40.335 8 13.445\n      vertex 39.937 8 12.665\n    endloop\n  endfacet\n  facet normal -0.99984 0.01785 0.00038\n    outer loop\n      vertex 34.12628 -38.94719 14.16569\n      vertex 34.168 -36.574 12.442\n      vertex 34.12587 -38.969 14.123\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.955 8 14.065\n      vertex 40.335 8 13.445\n      vertex 37.8 8 19.80394\n    endloop\n  endfacet\n  facet normal 0.70779 0.18293 -0.68232\n    outer loop\n      vertex 32.017 7.90082 -0.83403\n      vertex 32.017 4.80894 -1.66297\n      vertex 31.741 7.97239 -1.10114\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.955 8 14.065\n      vertex 37.8 8 19.80394\n      vertex 41.735 8 14.463\n    endloop\n  endfacet\n  facet normal 0.89021 0.11797 -0.44\n    outer loop\n      vertex 31.563 4.97056 -2.26607\n      vertex 31.563 8.06241 -1.43714\n      vertex 31.741 4.88052 -1.93008\n    endloop\n  endfacet\n  facet normal 0.89021 0.11797 -0.44\n    outer loop\n      vertex 31.741 7.97239 -1.10114\n      vertex 31.741 4.88052 -1.93008\n      vertex 31.563 8.06241 -1.43714\n    endloop\n  endfacet\n  facet normal -0.99984 0.01785 0.00038\n    outer loop\n      vertex 34.168 -36.574 12.442\n      vertex 34.149 -37.616 11.4\n      vertex 34.12587 -38.969 14.123\n    endloop\n  endfacet\n  facet normal 0.98775 0.0404 -0.1507\n    outer loop\n      vertex 31.52181 5.03807 -2.51797\n      vertex 31.54787 8.08719 -1.52965\n      vertex 31.563 4.97056 -2.26607\n    endloop\n  endfacet\n  facet normal 0.98775 0.0404 -0.1507\n    outer loop\n      vertex 31.563 8.06241 -1.43714\n      vertex 31.563 4.97056 -2.26607\n      vertex 31.54787 8.08719 -1.52965\n    endloop\n  endfacet\n  facet normal 0.98774 0.04044 -0.1508\n    outer loop\n      vertex 31.502 5.0705 -2.639\n      vertex 31.502 8.1623 -1.80997\n      vertex 31.52181 5.03807 -2.51797\n    endloop\n  endfacet\n  facet normal 0.98774 0.04044 -0.1508\n    outer loop\n      vertex 31.54787 8.08719 -1.52965\n      vertex 31.52181 5.03807 -2.51797\n      vertex 31.502 8.1623 -1.80997\n    endloop\n  endfacet\n  facet normal 0.98774 -0.04044 0.1508\n    outer loop\n      vertex 31.502 8.1623 -1.80997\n      vertex 31.502 5.0705 -2.639\n      vertex 31.51712 8.18705 -1.90237\n    endloop\n  endfacet\n  facet normal 0.98774 -0.04044 0.1508\n    outer loop\n      vertex 31.54319 5.13795 -2.89068\n      vertex 31.51712 8.18705 -1.90237\n      vertex 31.502 5.0705 -2.639\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 44.248 8 14.065\n      vertex 43.467 8 14.463\n      vertex 45.937 8 20\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 45.937 8 20\n      vertex 46.9 8 19.90931\n      vertex 44.248 8 14.065\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 43.467 8 14.463\n      vertex 42.601 8 14.6\n      vertex 45.937 8 20\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 41.735 8 14.463\n      vertex 37.8 8 19.80394\n      vertex 42.601 8 14.6\n    endloop\n  endfacet\n  facet normal 0.98775 -0.0404 0.1507\n    outer loop\n      vertex 31.563 5.17042 -3.01184\n      vertex 31.563 8.26222 -2.18292\n      vertex 31.54319 5.13795 -2.89068\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 46.9 8 19.90931\n      vertex 46.9 8 5.23414\n      vertex 45.402 8 11.799\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 45.402 8 11.799\n      vertex 45.265 8 12.665\n      vertex 46.9 8 19.90931\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 45.265 8 12.665\n      vertex 44.867 8 13.445\n      vertex 46.9 8 19.90931\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 44.867 8 13.445\n      vertex 44.248 8 14.065\n      vertex 46.9 8 19.90931\n    endloop\n  endfacet\n  facet normal 0.89035 -0.1179 0.43974\n    outer loop\n      vertex 31.60713 8.28455 -2.26628\n      vertex 31.563 8.26222 -2.18292\n      vertex 31.563 5.17042 -3.01184\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.601 8 8.998\n      vertex 37.8 8 5.23414\n      vertex 41.735 8 9.135\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 43.467 8 9.135\n      vertex 46.9 8 5.23414\n      vertex 42.601 8 8.998\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 43.467 8 9.135\n      vertex 44.248 8 9.533\n      vertex 46.9 8 5.23414\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.335 8 10.152\n      vertex 40.955 8 9.533\n      vertex 37.8 8 5.23414\n    endloop\n  endfacet\n  facet normal 0.70656 -0.18325 0.68352\n    outer loop\n      vertex 31.80942 8.37017 -2.58583\n      vertex 31.92735 5.30887 -3.52849\n      vertex 32.017 8.42381 -2.78603\n    endloop\n  endfacet\n  facet normal 0.70656 -0.18325 0.68352\n    outer loop\n      vertex 32.017 5.33204 -3.61494\n      vertex 32.017 8.42381 -2.78603\n      vertex 31.92735 5.30887 -3.52849\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 39.8 8 11.799\n      vertex 37.8 8 19.80394\n      vertex 39.937 8 12.665\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.8 8 5.23414\n      vertex 37.8 8 19.80394\n      vertex 39.8 8 11.799\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 39.8 8 11.799\n      vertex 39.937 8 10.933\n      vertex 37.8 8 5.23414\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 45.937 8 20\n      vertex 42.601 8 14.6\n      vertex 37.8 8 19.80394\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 32.8 8 19.80394\n      vertex 27.1 8 20\n      vertex 37.8 8 19.80394\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.616 -54.109 9.323\n      vertex 34.616 -57 5.6\n      vertex 34.616 -53.666 8.88\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 34.616 -0.802 0\n      vertex 40.955 -0.802 9.533\n      vertex 41.735 -0.802 9.135\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.335 -0.802 10.152\n      vertex 34.616 -0.802 0\n      vertex 39.937 -0.802 10.933\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.616 -53.666 8.88\n      vertex 34.616 -57 5.6\n      vertex 34.616 -53.107 8.596\n    endloop\n  endfacet\n  facet normal -0.99985 0.0174 -0.00001\n    outer loop\n      vertex 34.17386 -36.2 13.85081\n      vertex 34.13044 -38.69427 14.66089\n      vertex 34.13062 -38.684 14.681\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.616 -52.488 8.497\n      vertex 34.616 -51.788 5.6\n      vertex 34.616 -51.87 8.596\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.616 -51.788 8.63766\n      vertex 34.616 -51.87 8.596\n      vertex 34.616 -51.788 5.6\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 44.248 -0.802 9.533\n      vertex 55.3377 -0.802 0\n      vertex 43.467 -0.802 9.135\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.616 -51.788 12.36234\n      vertex 34.616 -51.788 15\n      vertex 34.616 -51.87 12.404\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.616 -52.488 12.503\n      vertex 34.616 -51.87 12.404\n      vertex 34.616 -51.788 15\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.955 -0.802 14.065\n      vertex 29.097 -0.802 20\n      vertex 41.735 -0.802 14.463\n    endloop\n  endfacet\n  facet normal 0.98775 -0.0404 0.1507\n    outer loop\n      vertex 31.51712 8.18705 -1.90237\n      vertex 31.54319 5.13795 -2.89068\n      vertex 31.563 8.26222 -2.18292\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 44.248 -0.802 14.065\n      vertex 43.467 -0.802 14.463\n      vertex 56.103 -0.802 20\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 43.467 -0.802 14.463\n      vertex 42.601 -0.802 14.6\n      vertex 56.103 -0.802 20\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 41.735 -0.802 14.463\n      vertex 29.097 -0.802 20\n      vertex 42.601 -0.802 14.6\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 56.103 -0.802 20\n      vertex 42.601 -0.802 14.6\n      vertex 29.097 -0.802 20\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 45.402 -0.802 11.799\n      vertex 55.3377 -0.802 0\n      vertex 45.265 -0.802 10.933\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 45.265 -0.802 12.665\n      vertex 56.103 -0.802 20\n      vertex 45.402 -0.802 11.799\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 44.867 -0.802 13.445\n      vertex 56.103 -0.802 20\n      vertex 45.265 -0.802 12.665\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.335 -0.802 10.152\n      vertex 40.955 -0.802 9.533\n      vertex 34.616 -0.802 0\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 43.467 -0.802 9.135\n      vertex 55.3377 -0.802 0\n      vertex 42.601 -0.802 8.998\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.601 -0.802 8.998\n      vertex 34.616 -0.802 0\n      vertex 41.735 -0.802 9.135\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.335 -0.802 13.445\n      vertex 29.097 -0.802 20\n      vertex 40.955 -0.802 14.065\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 39.937 -0.802 12.665\n      vertex 29.097 -0.802 20\n      vertex 40.335 -0.802 13.445\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 34.616 -0.802 0\n      vertex 29.097 -0.802 20\n      vertex 39.937 -0.802 10.933\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 39.8 -0.802 11.799\n      vertex 39.937 -0.802 10.933\n      vertex 29.097 -0.802 20\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 39.8 -0.802 11.799\n      vertex 29.097 -0.802 20\n      vertex 39.937 -0.802 12.665\n    endloop\n  endfacet\n  facet normal 0.15626 0 0.98772\n    outer loop\n      vertex 42.601 -3.2 8.998\n      vertex 42.601 -0.802 8.998\n      vertex 41.735 -0.802 9.135\n    endloop\n  endfacet\n  facet normal 0.15626 0 0.98772\n    outer loop\n      vertex 42.601 -3.2 8.998\n      vertex 41.735 -0.802 9.135\n      vertex 41.735 -3.2 9.135\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.496 -33.2 -1.077\n      vertex 41.277 -33.2 -0.679\n      vertex 40.867 -33.2 -7.837\n    endloop\n  endfacet\n  facet normal 0.45451 0 0.89074\n    outer loop\n      vertex 41.735 -3.2 9.135\n      vertex 41.735 -0.802 9.135\n      vertex 40.955 -0.802 9.533\n    endloop\n  endfacet\n  facet normal 0.45451 0 0.89074\n    outer loop\n      vertex 41.735 -3.2 9.135\n      vertex 40.955 -0.802 9.533\n      vertex 40.955 -3.2 9.533\n    endloop\n  endfacet\n  facet normal -0.99986 0.01691 -0.00031\n    outer loop\n      vertex 34.11926 -39.33152 13.76047\n      vertex 34.149 -37.616 11.4\n      vertex 34.11792 -39.412 13.68\n    endloop\n  endfacet\n  facet normal 0.70654 0 0.70768\n    outer loop\n      vertex 40.955 -3.2 9.533\n      vertex 40.955 -0.802 9.533\n      vertex 40.335 -0.802 10.152\n    endloop\n  endfacet\n  facet normal 0.70654 0 0.70768\n    outer loop\n      vertex 40.955 -3.2 9.533\n      vertex 40.335 -0.802 10.152\n      vertex 40.335 -3.2 10.152\n    endloop\n  endfacet\n  facet normal 0.89098 0 0.45405\n    outer loop\n      vertex 39.937 -0.802 10.933\n      vertex 39.937 -3.2 10.933\n      vertex 40.335 -3.2 10.152\n    endloop\n  endfacet\n  facet normal 0.89098 0 0.45405\n    outer loop\n      vertex 39.937 -0.802 10.933\n      vertex 40.335 -3.2 10.152\n      vertex 40.335 -0.802 10.152\n    endloop\n  endfacet\n  facet normal 0.98772 0 0.15626\n    outer loop\n      vertex 39.937 -3.2 10.933\n      vertex 39.937 -0.802 10.933\n      vertex 39.8 -0.802 11.799\n    endloop\n  endfacet\n  facet normal 0.98772 0 0.15626\n    outer loop\n      vertex 39.937 -3.2 10.933\n      vertex 39.8 -0.802 11.799\n      vertex 39.8 -3.2 11.799\n    endloop\n  endfacet\n  facet normal 0.98772 0 -0.15626\n    outer loop\n      vertex 39.8 -0.802 11.799\n      vertex 39.937 -3.2 12.665\n      vertex 39.8 -3.2 11.799\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.295 -33.2 0.721\n      vertex 42.267 -33.2 -8.855\n      vertex 41.897 -33.2 -0.06\n    endloop\n  endfacet\n  facet normal 0 -0.70711 0.70711\n    outer loop\n      vertex 34.11792 -39.412 13.68\n      vertex 45.21983 -39.412 13.68\n      vertex 34.11926 -39.33152 13.76047\n    endloop\n  endfacet\n  facet normal -0.98772 0 0.15626\n    outer loop\n      vertex 45.402 -3.2 11.799\n      vertex 45.402 -0.802 11.799\n      vertex 45.265 -0.802 10.933\n    endloop\n  endfacet\n  facet normal -0.98772 0 0.15626\n    outer loop\n      vertex 45.402 -3.2 11.799\n      vertex 45.265 -0.802 10.933\n      vertex 45.265 -3.2 10.933\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 38.765 -33.2 -1.077\n      vertex 39.63 -33.2 -1.214\n      vertex 39.135 -33.2 -7.837\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.001 -33.2 -7.7\n      vertex 39.135 -33.2 -7.837\n      vertex 39.63 -33.2 -1.214\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 39.63 -33.2 -1.214\n      vertex 40.496 -33.2 -1.077\n      vertex 40.001 -33.2 -7.7\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 41.277 -33.2 -0.679\n      vertex 41.897 -33.2 -0.06\n      vertex 41.648 -33.2 -8.235\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 41.648 -33.2 -8.235\n      vertex 40.867 -33.2 -7.837\n      vertex 41.277 -33.2 -0.679\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.001 -33.2 -7.7\n      vertex 40.496 -33.2 -1.077\n      vertex 40.867 -33.2 -7.837\n    endloop\n  endfacet\n  facet normal -0.89098 0 0.45405\n    outer loop\n      vertex 44.867 -0.802 10.152\n      vertex 45.265 -3.2 10.933\n      vertex 45.265 -0.802 10.933\n    endloop\n  endfacet\n  facet normal -0.89098 0 0.45405\n    outer loop\n      vertex 44.867 -3.2 10.152\n      vertex 45.265 -3.2 10.933\n      vertex 44.867 -0.802 10.152\n    endloop\n  endfacet\n  facet normal -0.70711 0 0.70711\n    outer loop\n      vertex 44.867 -3.2 10.152\n      vertex 44.867 -0.802 10.152\n      vertex 44.248 -0.802 9.533\n    endloop\n  endfacet\n  facet normal -0.70711 0 0.70711\n    outer loop\n      vertex 44.867 -3.2 10.152\n      vertex 44.248 -0.802 9.533\n      vertex 44.248 -3.2 9.533\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 41.648 -33.2 -8.235\n      vertex 41.897 -33.2 -0.06\n      vertex 42.267 -33.2 -8.855\n    endloop\n  endfacet\n  facet normal -0.99985 0.01727 -0.00042\n    outer loop\n      vertex 34.17415 -36.2 13.17602\n      vertex 34.12628 -38.94719 14.16569\n      vertex 34.17386 -36.2 13.85081\n    endloop\n  endfacet\n  facet normal -0.45405 0 0.89098\n    outer loop\n      vertex 44.248 -3.2 9.533\n      vertex 44.248 -0.802 9.533\n      vertex 43.467 -0.802 9.135\n    endloop\n  endfacet\n  facet normal -0.45405 0 0.89098\n    outer loop\n      vertex 44.248 -3.2 9.533\n      vertex 43.467 -0.802 9.135\n      vertex 43.467 -3.2 9.135\n    endloop\n  endfacet\n  facet normal -0.15626 0 0.98772\n    outer loop\n      vertex 43.467 -3.2 9.135\n      vertex 43.467 -0.802 9.135\n      vertex 42.601 -0.802 8.998\n    endloop\n  endfacet\n  facet normal -0.15626 0 0.98772\n    outer loop\n      vertex 43.467 -3.2 9.135\n      vertex 42.601 -0.802 8.998\n      vertex 42.601 -3.2 8.998\n    endloop\n  endfacet\n  facet normal -0.99985 0.01727 -0.00042\n    outer loop\n      vertex 34.168 -36.574 12.442\n      vertex 34.12628 -38.94719 14.16569\n      vertex 34.17415 -36.2 13.17602\n    endloop\n  endfacet\n  facet normal -0.99985 0.01727 -0.00042\n    outer loop\n      vertex 34.13044 -38.69427 14.66089\n      vertex 34.17386 -36.2 13.85081\n      vertex 34.12628 -38.94719 14.16569\n    endloop\n  endfacet\n  facet normal 0.98772 0 -0.15626\n    outer loop\n      vertex 39.937 -0.802 12.665\n      vertex 39.937 -3.2 12.665\n      vertex 39.8 -0.802 11.799\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.267 -33.2 -8.855\n      vertex 42.295 -33.2 0.721\n      vertex 42.665 -33.2 -9.635\n    endloop\n  endfacet\n  facet normal 0.89074 0 -0.45451\n    outer loop\n      vertex 40.335 -0.802 13.445\n      vertex 40.335 -3.2 13.445\n      vertex 39.937 -3.2 12.665\n    endloop\n  endfacet\n  facet normal 0.89074 0 -0.45451\n    outer loop\n      vertex 40.335 -0.802 13.445\n      vertex 39.937 -3.2 12.665\n      vertex 39.937 -0.802 12.665\n    endloop\n  endfacet\n  facet normal 0.70711 0 -0.70711\n    outer loop\n      vertex 40.955 -0.802 14.065\n      vertex 40.955 -3.2 14.065\n      vertex 40.335 -3.2 13.445\n    endloop\n  endfacet\n  facet normal 0.70711 0 -0.70711\n    outer loop\n      vertex 40.955 -0.802 14.065\n      vertex 40.335 -3.2 13.445\n      vertex 40.335 -0.802 13.445\n    endloop\n  endfacet\n  facet normal 0.45451 0 -0.89074\n    outer loop\n      vertex 41.735 -0.802 14.463\n      vertex 41.735 -3.2 14.463\n      vertex 40.955 -3.2 14.065\n    endloop\n  endfacet\n  facet normal 0.45451 0 -0.89074\n    outer loop\n      vertex 41.735 -0.802 14.463\n      vertex 40.955 -3.2 14.065\n      vertex 40.955 -0.802 14.065\n    endloop\n  endfacet\n  facet normal 0.01556 0.89085 -0.45404\n    outer loop\n      vertex 34.17415 -36.2 13.17602\n      vertex 34.27425 -36.2 13.17945\n      vertex 34.26765 -36.57574 12.442\n    endloop\n  endfacet\n  facet normal 0.15626 0 -0.98772\n    outer loop\n      vertex 42.601 -0.802 14.6\n      vertex 42.601 -3.2 14.6\n      vertex 41.735 -3.2 14.463\n    endloop\n  endfacet\n  facet normal 0.15626 0 -0.98772\n    outer loop\n      vertex 42.601 -0.802 14.6\n      vertex 41.735 -3.2 14.463\n      vertex 41.735 -0.802 14.463\n    endloop\n  endfacet\n  facet normal -0.15626 0 -0.98772\n    outer loop\n      vertex 43.467 -0.802 14.463\n      vertex 43.467 -3.2 14.463\n      vertex 42.601 -3.2 14.6\n    endloop\n  endfacet\n  facet normal -0.15626 0 -0.98772\n    outer loop\n      vertex 43.467 -0.802 14.463\n      vertex 42.601 -3.2 14.6\n      vertex 42.601 -0.802 14.6\n    endloop\n  endfacet\n  facet normal -0.45405 0 -0.89098\n    outer loop\n      vertex 44.248 -0.802 14.065\n      vertex 44.248 -3.2 14.065\n      vertex 43.467 -3.2 14.463\n    endloop\n  endfacet\n  facet normal -0.45405 0 -0.89098\n    outer loop\n      vertex 44.248 -0.802 14.065\n      vertex 43.467 -3.2 14.463\n      vertex 43.467 -0.802 14.463\n    endloop\n  endfacet\n  facet normal 0 -0.45359 0.89121\n    outer loop\n      vertex 34.11109 -39.82012 13.47229\n      vertex 45.21014 -39.97 13.396\n      vertex 34.11792 -39.412 13.68\n    endloop\n  endfacet\n  facet normal -0.70768 0 -0.70654\n    outer loop\n      vertex 44.248 -3.2 14.065\n      vertex 44.248 -0.802 14.065\n      vertex 44.867 -0.802 13.445\n    endloop\n  endfacet\n  facet normal -0.70768 0 -0.70654\n    outer loop\n      vertex 44.248 -3.2 14.065\n      vertex 44.867 -0.802 13.445\n      vertex 44.867 -3.2 13.445\n    endloop\n  endfacet\n  facet normal -0.89074 0 -0.45451\n    outer loop\n      vertex 44.867 -3.2 13.445\n      vertex 44.867 -0.802 13.445\n      vertex 45.265 -0.802 12.665\n    endloop\n  endfacet\n  facet normal -0.89074 0 -0.45451\n    outer loop\n      vertex 44.867 -3.2 13.445\n      vertex 45.265 -0.802 12.665\n      vertex 45.265 -3.2 12.665\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.001 -36.2 -7.7\n      vertex 39.63 -36.2 -1.214\n      vertex 39.135 -36.2 -7.837\n    endloop\n  endfacet\n  facet normal 0 -0.89056 0.45486\n    outer loop\n      vertex 34.12628 -38.94719 14.16569\n      vertex 45.22752 -38.969 14.123\n      vertex 34.13044 -38.69427 14.66089\n    endloop\n  endfacet\n  facet normal 0 -0.89056 0.45486\n    outer loop\n      vertex 34.12587 -38.969 14.123\n      vertex 45.22752 -38.969 14.123\n      vertex 34.12628 -38.94719 14.16569\n    endloop\n  endfacet\n  facet normal 0 -0.89056 0.45486\n    outer loop\n      vertex 45.22752 -38.969 14.123\n      vertex 45.23247 -38.684 14.681\n      vertex 34.13044 -38.69427 14.66089\n    endloop\n  endfacet\n  facet normal -0.98772 0 -0.15626\n    outer loop\n      vertex 45.402 -0.802 11.799\n      vertex 45.402 -3.2 11.799\n      vertex 45.265 -0.802 12.665\n    endloop\n  endfacet\n  facet normal -0.98772 0 -0.15626\n    outer loop\n      vertex 45.265 -3.2 12.665\n      vertex 45.265 -0.802 12.665\n      vertex 45.402 -3.2 11.799\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 39.937 2.403 10.933\n      vertex 30.30975 2.403 0\n      vertex 40.335 2.403 10.152\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.001 -36.2 -7.7\n      vertex 40.867 -36.2 -7.837\n      vertex 40.496 -36.2 -1.077\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.867 -36.2 -7.837\n      vertex 41.648 -36.2 -8.235\n      vertex 41.277 -36.2 -0.679\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 44.867 2.403 10.152\n      vertex 55.27692 2.403 0\n      vertex 45.265 2.403 10.933\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 44.248 2.403 9.533\n      vertex 55.27692 2.403 0\n      vertex 44.867 2.403 10.152\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 41.277 -36.2 -0.679\n      vertex 40.496 -36.2 -1.077\n      vertex 40.867 -36.2 -7.837\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 39.63 -36.2 -1.214\n      vertex 40.001 -36.2 -7.7\n      vertex 40.496 -36.2 -1.077\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.984 -36.2 -0.679\n      vertex 38.355 -36.2 -8.235\n      vertex 38.765 -36.2 -1.077\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 52.2 -36.2 -10.48639\n      vertex 41.897 -36.2 -0.06\n      vertex 42.267 -36.2 -8.855\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 58.2 -3.2 0\n      vertex 58.2 8 0\n      vertex 58.2 -3.2 20\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 58.2 8 20\n      vertex 58.2 -3.2 20\n      vertex 58.2 8 0\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 56.103 2.403 20\n      vertex 29.097 2.403 20\n      vertex 42.601 2.403 14.6\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.295 -36.2 0.721\n      vertex 41.897 -36.2 -0.06\n      vertex 52.2 -36.2 -10.48639\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 41.648 -36.2 -8.235\n      vertex 42.267 -36.2 -8.855\n      vertex 41.897 -36.2 -0.06\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.665 -36.2 -9.635\n      vertex 52.2 -36.2 -10.48639\n      vertex 42.267 -36.2 -8.855\n    endloop\n  endfacet\n  facet normal 0.70711 0 -0.70711\n    outer loop\n      vertex 38.355 -33.2 -8.235\n      vertex 38.355 -36.2 -8.235\n      vertex 37.735 -33.2 -8.855\n    endloop\n  endfacet\n  facet normal 0.45451 0 -0.89074\n    outer loop\n      vertex 38.355 -33.2 -8.235\n      vertex 39.135 -36.2 -7.837\n      vertex 38.355 -36.2 -8.235\n    endloop\n  endfacet\n  facet normal -0.45405 0 -0.89098\n    outer loop\n      vertex 41.648 -33.2 -8.235\n      vertex 41.648 -36.2 -8.235\n      vertex 40.867 -36.2 -7.837\n    endloop\n  endfacet\n  facet normal -0.45405 0 -0.89098\n    outer loop\n      vertex 41.648 -33.2 -8.235\n      vertex 40.867 -36.2 -7.837\n      vertex 40.867 -33.2 -7.837\n    endloop\n  endfacet\n  facet normal -0.70768 0 -0.70654\n    outer loop\n      vertex 41.648 -36.2 -8.235\n      vertex 41.648 -33.2 -8.235\n      vertex 42.267 -33.2 -8.855\n    endloop\n  endfacet\n  facet normal -0.70768 0 -0.70654\n    outer loop\n      vertex 41.648 -36.2 -8.235\n      vertex 42.267 -33.2 -8.855\n      vertex 42.267 -36.2 -8.855\n    endloop\n  endfacet\n  facet normal -0.89074 0 -0.45451\n    outer loop\n      vertex 42.665 -33.2 -9.635\n      vertex 42.267 -36.2 -8.855\n      vertex 42.267 -33.2 -8.855\n    endloop\n  endfacet\n  facet normal 0.45451 0 -0.89074\n    outer loop\n      vertex 39.135 -33.2 -7.837\n      vertex 39.135 -36.2 -7.837\n      vertex 38.355 -33.2 -8.235\n    endloop\n  endfacet\n  facet normal 0.15626 0 -0.98772\n    outer loop\n      vertex 40.001 -33.2 -7.7\n      vertex 40.001 -36.2 -7.7\n      vertex 39.135 -36.2 -7.837\n    endloop\n  endfacet\n  facet normal 0.15626 0 -0.98772\n    outer loop\n      vertex 40.001 -33.2 -7.7\n      vertex 39.135 -36.2 -7.837\n      vertex 39.135 -33.2 -7.837\n    endloop\n  endfacet\n  facet normal -0.15626 0 -0.98772\n    outer loop\n      vertex 40.867 -33.2 -7.837\n      vertex 40.867 -36.2 -7.837\n      vertex 40.001 -36.2 -7.7\n    endloop\n  endfacet\n  facet normal -0.15626 0 -0.98772\n    outer loop\n      vertex 40.867 -33.2 -7.837\n      vertex 40.001 -36.2 -7.7\n      vertex 40.001 -33.2 -7.7\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -48.231 11.765\n      vertex 54.937 -50.486 10.5\n      vertex 54.937 -48 10.31\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -50.486 10.5\n      vertex 54.937 -50.584 9.881\n      vertex 54.937 -48 10.31\n    endloop\n  endfacet\n  facet normal 0.15643 0 0.98769\n    outer loop\n      vertex 38.765 -33.2 -1.077\n      vertex 38.765 -36.2 -1.077\n      vertex 39.63 -36.2 -1.214\n    endloop\n  endfacet\n  facet normal 0.15643 0 0.98769\n    outer loop\n      vertex 38.765 -33.2 -1.077\n      vertex 39.63 -36.2 -1.214\n      vertex 39.63 -33.2 -1.214\n    endloop\n  endfacet\n  facet normal 0.45405 0 0.89098\n    outer loop\n      vertex 37.984 -33.2 -0.679\n      vertex 37.984 -36.2 -0.679\n      vertex 38.765 -36.2 -1.077\n    endloop\n  endfacet\n  facet normal 0.45405 0 0.89098\n    outer loop\n      vertex 37.984 -33.2 -0.679\n      vertex 38.765 -36.2 -1.077\n      vertex 38.765 -33.2 -1.077\n    endloop\n  endfacet\n  facet normal -0.15626 0 0.98772\n    outer loop\n      vertex 40.496 -36.2 -1.077\n      vertex 40.496 -33.2 -1.077\n      vertex 39.63 -33.2 -1.214\n    endloop\n  endfacet\n  facet normal -0.15626 0 0.98772\n    outer loop\n      vertex 40.496 -36.2 -1.077\n      vertex 39.63 -33.2 -1.214\n      vertex 39.63 -36.2 -1.214\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -54.109 9.323\n      vertex 54.937 -55.482 6.5\n      vertex 54.937 -53.666 8.88\n    endloop\n  endfacet\n  facet normal -0.89098 0 0.45405\n    outer loop\n      vertex 41.897 -33.2 -0.06\n      vertex 41.897 -36.2 -0.06\n      vertex 42.295 -33.2 0.721\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 45.265 2.403 12.665\n      vertex 56.103 2.403 20\n      vertex 44.867 2.403 13.445\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 44.867 2.403 13.445\n      vertex 56.103 2.403 20\n      vertex 44.248 2.403 14.065\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -55.482 14.12\n      vertex 54.937 -56.524 13.078\n      vertex 54.937 -54.109 11.677\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -53.666 8.88\n      vertex 54.937 -54.168 5.831\n      vertex 54.937 -53.107 8.596\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 56.103 2.403 20\n      vertex 42.601 2.403 14.6\n      vertex 43.467 2.403 14.463\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 44.248 2.403 14.065\n      vertex 56.103 2.403 20\n      vertex 43.467 2.403 14.463\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 45.402 2.403 11.799\n      vertex 56.103 2.403 20\n      vertex 45.265 2.403 12.665\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 45.265 2.403 10.933\n      vertex 55.27692 2.403 0\n      vertex 45.402 2.403 11.799\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 41.735 2.403 9.135\n      vertex 30.30975 2.403 0\n      vertex 42.601 2.403 8.998\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.955 2.403 9.533\n      vertex 30.30975 2.403 0\n      vertex 41.735 2.403 9.135\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.955 2.403 9.533\n      vertex 40.335 2.403 10.152\n      vertex 30.30975 2.403 0\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 39.8 2.403 11.799\n      vertex 39.937 2.403 12.665\n      vertex 29.097 2.403 20\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 39.937 2.403 12.665\n      vertex 40.335 2.403 13.445\n      vertex 29.097 2.403 20\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.335 2.403 13.445\n      vertex 40.955 2.403 14.065\n      vertex 29.097 2.403 20\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.955 2.403 14.065\n      vertex 41.735 2.403 14.463\n      vertex 29.097 2.403 20\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 41.735 2.403 14.463\n      vertex 42.601 2.403 14.6\n      vertex 29.097 2.403 20\n    endloop\n  endfacet\n  facet normal 0.15626 0 0.98772\n    outer loop\n      vertex 42.601 8 8.998\n      vertex 41.735 2.403 9.135\n      vertex 42.601 2.403 8.998\n    endloop\n  endfacet\n  facet normal -0.99985 0.0174 0\n    outer loop\n      vertex 34.06549 -42.42509 14.54757\n      vertex 34.023 -44.866 13.755\n      vertex 34.06431 -42.493 14.681\n    endloop\n  endfacet\n  facet normal -0.99985 0.0174 0\n    outer loop\n      vertex 34.06285 -42.57675 15.21\n      vertex 34.06431 -42.493 14.681\n      vertex 34.019 -45.096 15.21\n    endloop\n  endfacet\n  facet normal 0.98772 0 0.15626\n    outer loop\n      vertex 39.937 2.403 10.933\n      vertex 39.8 8 11.799\n      vertex 39.8 2.403 11.799\n    endloop\n  endfacet\n  facet normal 0.98772 0 -0.15626\n    outer loop\n      vertex 39.8 8 11.799\n      vertex 39.937 2.403 12.665\n      vertex 39.8 2.403 11.799\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 51.6568 11.55105 -14.45823\n      vertex 46.1 7.67736 0\n      vertex 51.737 11.51035 -14.30631\n    endloop\n  endfacet\n  facet normal -0.99985 0.01748 -0.00023\n    outer loop\n      vertex 34.0718 -42.07143 13.98543\n      vertex 34.035 -44.197 12.442\n      vertex 34.06937 -42.209 14.123\n    endloop\n  endfacet\n  facet normal -0.98772 0 0.15626\n    outer loop\n      vertex 45.265 8 10.933\n      vertex 45.265 2.403 10.933\n      vertex 45.402 2.403 11.799\n    endloop\n  endfacet\n  facet normal -0.89098 0 0.45405\n    outer loop\n      vertex 45.265 2.403 10.933\n      vertex 45.265 8 10.933\n      vertex 44.867 2.403 10.152\n    endloop\n  endfacet\n  facet normal -0.99985 0.01748 -0.00023\n    outer loop\n      vertex 34.035 -44.197 12.442\n      vertex 34.023 -44.866 13.755\n      vertex 34.06937 -42.209 14.123\n    endloop\n  endfacet\n  facet normal -0.15626 0 0.98772\n    outer loop\n      vertex 43.467 2.403 9.135\n      vertex 42.601 8 8.998\n      vertex 42.601 2.403 8.998\n    endloop\n  endfacet\n  facet normal 0.98772 0 -0.15626\n    outer loop\n      vertex 39.937 8 12.665\n      vertex 39.937 2.403 12.665\n      vertex 39.8 8 11.799\n    endloop\n  endfacet\n  facet normal 0.89074 0 -0.45451\n    outer loop\n      vertex 40.335 8 13.445\n      vertex 40.335 2.403 13.445\n      vertex 39.937 2.403 12.665\n    endloop\n  endfacet\n  facet normal 0.89074 0 -0.45451\n    outer loop\n      vertex 40.335 8 13.445\n      vertex 39.937 2.403 12.665\n      vertex 39.937 8 12.665\n    endloop\n  endfacet\n  facet normal 0.70711 0 -0.70711\n    outer loop\n      vertex 40.955 2.403 14.065\n      vertex 40.335 2.403 13.445\n      vertex 40.335 8 13.445\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 51.737 11.89105 -15.72725\n      vertex 46.9 12.534 -18.127\n      vertex 51.559 11.80078 -15.39032\n    endloop\n  endfacet\n  facet normal 0.45451 0 -0.89074\n    outer loop\n      vertex 41.735 8 14.463\n      vertex 41.735 2.403 14.463\n      vertex 40.955 2.403 14.065\n    endloop\n  endfacet\n  facet normal 0.15626 0 -0.98772\n    outer loop\n      vertex 41.735 2.403 14.463\n      vertex 41.735 8 14.463\n      vertex 42.601 2.403 14.6\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 51.498 11.70084 -15.0173\n      vertex 46.9 12.534 -18.127\n      vertex 51.559 11.60065 -14.64335\n    endloop\n  endfacet\n  facet normal -0.45405 0 -0.89098\n    outer loop\n      vertex 44.248 8 14.065\n      vertex 44.248 2.403 14.065\n      vertex 43.467 2.403 14.463\n    endloop\n  endfacet\n  facet normal -0.70768 0 -0.70654\n    outer loop\n      vertex 44.248 2.403 14.065\n      vertex 44.248 8 14.065\n      vertex 44.867 2.403 13.445\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 51.502 8.1623 -1.80997\n      vertex 51.51712 8.18705 -1.90237\n      vertex 46.1 7.67736 0\n    endloop\n  endfacet\n  facet normal -0.70654 0 0.70768\n    outer loop\n      vertex 41.277 -33.2 -0.679\n      vertex 41.277 -36.2 -0.679\n      vertex 41.897 -36.2 -0.06\n    endloop\n  endfacet\n  facet normal -0.70654 0 0.70768\n    outer loop\n      vertex 41.277 -33.2 -0.679\n      vertex 41.897 -36.2 -0.06\n      vertex 41.897 -33.2 -0.06\n    endloop\n  endfacet\n  facet normal -0.45405 0 0.89098\n    outer loop\n      vertex 41.277 -36.2 -0.679\n      vertex 41.277 -33.2 -0.679\n      vertex 40.496 -36.2 -1.077\n    endloop\n  endfacet\n  facet normal -0.45405 0 0.89098\n    outer loop\n      vertex 40.496 -33.2 -1.077\n      vertex 40.496 -36.2 -1.077\n      vertex 41.277 -33.2 -0.679\n    endloop\n  endfacet\n  facet normal 0 0.70711 0.70711\n    outer loop\n      vertex 45.12437 -42.209 14.123\n      vertex 37.8 -41.766 13.68\n      vertex 34.06937 -42.209 14.123\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 51.559 11.80078 -15.39032\n      vertex 46.9 12.534 -18.127\n      vertex 51.498 11.70084 -15.0173\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 46.9 12.534 -18.127\n      vertex 46.1 7.67736 0\n      vertex 51.559 11.60065 -14.64335\n    endloop\n  endfacet\n  facet normal 0.15626 0 0.98772\n    outer loop\n      vertex 41.735 8 9.135\n      vertex 41.735 2.403 9.135\n      vertex 42.601 8 8.998\n    endloop\n  endfacet\n  facet normal 0.45451 0 0.89074\n    outer loop\n      vertex 41.735 2.403 9.135\n      vertex 41.735 8 9.135\n      vertex 40.955 2.403 9.533\n    endloop\n  endfacet\n  facet normal 0.45451 0 0.89074\n    outer loop\n      vertex 40.955 8 9.533\n      vertex 40.955 2.403 9.533\n      vertex 41.735 8 9.135\n    endloop\n  endfacet\n  facet normal 0.70654 0 0.70768\n    outer loop\n      vertex 40.335 8 10.152\n      vertex 40.335 2.403 10.152\n      vertex 40.955 2.403 9.533\n    endloop\n  endfacet\n  facet normal 0.70654 0 0.70768\n    outer loop\n      vertex 40.335 8 10.152\n      vertex 40.955 2.403 9.533\n      vertex 40.955 8 9.533\n    endloop\n  endfacet\n  facet normal 0 0.89121 0.45359\n    outer loop\n      vertex 45.11967 -42.493 14.681\n      vertex 45.12037 -42.45247 14.60135\n      vertex 34.06549 -42.42509 14.54757\n    endloop\n  endfacet\n  facet normal 0.89098 0 0.45405\n    outer loop\n      vertex 40.335 2.403 10.152\n      vertex 40.335 8 10.152\n      vertex 39.937 2.403 10.933\n    endloop\n  endfacet\n  facet normal 0.89098 0 0.45405\n    outer loop\n      vertex 39.937 8 10.933\n      vertex 39.937 2.403 10.933\n      vertex 40.335 8 10.152\n    endloop\n  endfacet\n  facet normal 0.98772 0 0.15626\n    outer loop\n      vertex 39.8 8 11.799\n      vertex 39.937 2.403 10.933\n      vertex 39.937 8 10.933\n    endloop\n  endfacet\n  facet normal -0.98772 0 0.15626\n    outer loop\n      vertex 45.265 8 10.933\n      vertex 45.402 2.403 11.799\n      vertex 45.402 8 11.799\n    endloop\n  endfacet\n  facet normal -0.89098 0 0.45405\n    outer loop\n      vertex 44.867 8 10.152\n      vertex 44.867 2.403 10.152\n      vertex 45.265 8 10.933\n    endloop\n  endfacet\n  facet normal -0.70711 0 0.70711\n    outer loop\n      vertex 44.867 2.403 10.152\n      vertex 44.867 8 10.152\n      vertex 44.248 2.403 9.533\n    endloop\n  endfacet\n  facet normal -0.70711 0 0.70711\n    outer loop\n      vertex 44.248 8 9.533\n      vertex 44.248 2.403 9.533\n      vertex 44.867 8 10.152\n    endloop\n  endfacet\n  facet normal -0.45405 0 0.89098\n    outer loop\n      vertex 43.467 8 9.135\n      vertex 43.467 2.403 9.135\n      vertex 44.248 2.403 9.533\n    endloop\n  endfacet\n  facet normal -0.45405 0 0.89098\n    outer loop\n      vertex 43.467 8 9.135\n      vertex 44.248 2.403 9.533\n      vertex 44.248 8 9.533\n    endloop\n  endfacet\n  facet normal -0.15626 0 0.98772\n    outer loop\n      vertex 43.467 2.403 9.135\n      vertex 43.467 8 9.135\n      vertex 42.601 8 8.998\n    endloop\n  endfacet\n  facet normal 0 0.89121 0.45359\n    outer loop\n      vertex 34.06431 -42.493 14.681\n      vertex 45.11967 -42.493 14.681\n      vertex 34.06549 -42.42509 14.54757\n    endloop\n  endfacet\n  facet normal 0.70711 0 -0.70711\n    outer loop\n      vertex 40.955 8 14.065\n      vertex 40.955 2.403 14.065\n      vertex 40.335 8 13.445\n    endloop\n  endfacet\n  facet normal 0.45451 0 -0.89074\n    outer loop\n      vertex 40.955 2.403 14.065\n      vertex 40.955 8 14.065\n      vertex 41.735 8 14.463\n    endloop\n  endfacet\n  facet normal 0.98775 -0.0404 0.1507\n    outer loop\n      vertex 51.563 8.26222 -2.18292\n      vertex 51.54319 5.13795 -2.89068\n      vertex 51.563 5.17042 -3.01184\n    endloop\n  endfacet\n  facet normal 0.15626 0 -0.98772\n    outer loop\n      vertex 42.601 2.403 14.6\n      vertex 41.735 8 14.463\n      vertex 42.601 8 14.6\n    endloop\n  endfacet\n  facet normal -0.15626 0 -0.98772\n    outer loop\n      vertex 42.601 2.403 14.6\n      vertex 42.601 8 14.6\n      vertex 43.467 2.403 14.463\n    endloop\n  endfacet\n  facet normal -0.15626 0 -0.98772\n    outer loop\n      vertex 43.467 8 14.463\n      vertex 43.467 2.403 14.463\n      vertex 42.601 8 14.6\n    endloop\n  endfacet\n  facet normal 0.89035 -0.1179 0.43974\n    outer loop\n      vertex 51.563 8.26222 -2.18292\n      vertex 51.563 5.17042 -3.01184\n      vertex 51.60713 8.28455 -2.26628\n    endloop\n  endfacet\n  facet normal 0.89035 -0.1179 0.43974\n    outer loop\n      vertex 51.6832 5.23127 -3.23889\n      vertex 51.60713 8.28455 -2.26628\n      vertex 51.563 5.17042 -3.01184\n    endloop\n  endfacet\n  facet normal 0 -0.70711 0.70711\n    outer loop\n      vertex 45.22752 -38.969 14.123\n      vertex 34.12587 -38.969 14.123\n      vertex 45.21983 -39.412 13.68\n    endloop\n  endfacet\n  facet normal -0.45405 0 -0.89098\n    outer loop\n      vertex 44.248 8 14.065\n      vertex 43.467 2.403 14.463\n      vertex 43.467 8 14.463\n    endloop\n  endfacet\n  facet normal 0.89073 -0.11767 0.43905\n    outer loop\n      vertex 51.741 5.26059 -3.3483\n      vertex 51.741 8.35244 -2.51968\n      vertex 51.6832 5.23127 -3.23889\n    endloop\n  endfacet\n  facet normal -0.70768 0 -0.70654\n    outer loop\n      vertex 44.867 8 13.445\n      vertex 44.867 2.403 13.445\n      vertex 44.248 8 14.065\n    endloop\n  endfacet\n  facet normal -0.89074 0 -0.45451\n    outer loop\n      vertex 44.867 2.403 13.445\n      vertex 44.867 8 13.445\n      vertex 45.265 2.403 12.665\n    endloop\n  endfacet\n  facet normal -0.89074 0 -0.45451\n    outer loop\n      vertex 45.265 8 12.665\n      vertex 45.265 2.403 12.665\n      vertex 44.867 8 13.445\n    endloop\n  endfacet\n  facet normal -0.98772 0 -0.15626\n    outer loop\n      vertex 45.265 8 12.665\n      vertex 45.402 2.403 11.799\n      vertex 45.265 2.403 12.665\n    endloop\n  endfacet\n  facet normal -0.98772 0 -0.15626\n    outer loop\n      vertex 45.402 8 11.799\n      vertex 45.402 2.403 11.799\n      vertex 45.265 8 12.665\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 37.8 8 19.80394\n      vertex 37.8 22.7 4.662\n      vertex 37.8 8.01 19.9\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 37.8 8 5.23414\n      vertex 37.8 8.051 6.7\n      vertex 37.8 8 19.80394\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 37.8 8.051 6.7\n      vertex 37.8 22.7 4.662\n      vertex 37.8 8 19.80394\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 37.8 26.19 1.681\n      vertex 37.8 8.01 19.9\n      vertex 37.8 22.7 4.662\n    endloop\n  endfacet\n  facet normal 0.89021 0.11797 -0.44\n    outer loop\n      vertex 51.741 7.97239 -1.10114\n      vertex 51.741 4.88052 -1.93008\n      vertex 51.563 8.06241 -1.43714\n    endloop\n  endfacet\n  facet normal 0.89021 0.11797 -0.44\n    outer loop\n      vertex 51.563 4.97056 -2.26607\n      vertex 51.563 8.06241 -1.43714\n      vertex 51.741 4.88052 -1.93008\n    endloop\n  endfacet\n  facet normal 0.98775 0.0404 -0.1507\n    outer loop\n      vertex 51.52181 5.03807 -2.51797\n      vertex 51.54787 8.08719 -1.52965\n      vertex 51.563 4.97056 -2.26607\n    endloop\n  endfacet\n  facet normal 0.98775 0.0404 -0.1507\n    outer loop\n      vertex 51.563 8.06241 -1.43714\n      vertex 51.563 4.97056 -2.26607\n      vertex 51.54787 8.08719 -1.52965\n    endloop\n  endfacet\n  facet normal 0.98774 0.04044 -0.1508\n    outer loop\n      vertex 51.502 5.0705 -2.639\n      vertex 51.502 8.1623 -1.80997\n      vertex 51.52181 5.03807 -2.51797\n    endloop\n  endfacet\n  facet normal 0.98774 0.04044 -0.1508\n    outer loop\n      vertex 51.54787 8.08719 -1.52965\n      vertex 51.52181 5.03807 -2.51797\n      vertex 51.502 8.1623 -1.80997\n    endloop\n  endfacet\n  facet normal 0.98774 -0.04044 0.1508\n    outer loop\n      vertex 51.502 8.1623 -1.80997\n      vertex 51.502 5.0705 -2.639\n      vertex 51.51712 8.18705 -1.90237\n    endloop\n  endfacet\n  facet normal 0.98774 -0.04044 0.1508\n    outer loop\n      vertex 51.54319 5.13795 -2.89068\n      vertex 51.51712 8.18705 -1.90237\n      vertex 51.502 5.0705 -2.639\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.616 -54.109 11.677\n      vertex 34.616 -57 15\n      vertex 34.616 -54.393 11.119\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.616 -53.107 12.404\n      vertex 34.616 -57 15\n      vertex 34.616 -53.666 12.12\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.616 -57 15\n      vertex 34.616 -53.107 12.404\n      vertex 34.616 -51.788 15\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.616 -52.488 12.503\n      vertex 34.616 -51.788 15\n      vertex 34.616 -53.107 12.404\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.616 -54.109 11.677\n      vertex 34.616 -53.666 12.12\n      vertex 34.616 -57 15\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.616 -52.488 8.497\n      vertex 34.616 -53.107 8.596\n      vertex 34.616 -51.788 5.6\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.616 -51.788 5.6\n      vertex 34.616 -53.107 8.596\n      vertex 34.616 -57 5.6\n    endloop\n  endfacet\n  facet normal 0.00274 0.15665 -0.98765\n    outer loop\n      vertex 34.101 -40.385 10.5\n      vertex 34.127 -38.929 10.731\n      vertex 34.201 -40.3736 10.50209\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.616 -54.393 11.119\n      vertex 34.616 -57 15\n      vertex 34.616 -54.491 10.5\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.616 -57 5.6\n      vertex 34.616 -54.491 10.5\n      vertex 34.616 -57 15\n    endloop\n  endfacet\n  facet normal 0.98775 -0.0404 0.1507\n    outer loop\n      vertex 51.563 8.26222 -2.18292\n      vertex 51.51712 8.18705 -1.90237\n      vertex 51.54319 5.13795 -2.89068\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -52.712 5.6\n      vertex 54.937 -51.256 5.831\n      vertex 54.937 -52.489 8.497\n    endloop\n  endfacet\n  facet normal 0.89073 -0.11767 0.43905\n    outer loop\n      vertex 51.60713 8.28455 -2.26628\n      vertex 51.6832 5.23127 -3.23889\n      vertex 51.741 8.35244 -2.51968\n    endloop\n  endfacet\n  facet normal 0.70746 -0.18295 0.68266\n    outer loop\n      vertex 51.741 5.26059 -3.3483\n      vertex 51.80941 8.37017 -2.58583\n      vertex 51.741 8.35244 -2.51968\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -51.256 5.831\n      vertex 54.937 -49.942 6.5\n      vertex 54.937 -51.87 8.596\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -51.311 8.88\n      vertex 54.937 -51.87 8.596\n      vertex 54.937 -49.942 6.5\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -49.942 6.5\n      vertex 54.937 -48.9 7.542\n      vertex 54.937 -51.311 8.88\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -50.486 10.5\n      vertex 54.937 -48.231 11.765\n      vertex 54.937 -50.584 11.119\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.4 -53.666 8.88\n      vertex 25.4 -57 5.6\n      vertex 25.4 -54.109 9.323\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -50.868 11.677\n      vertex 54.937 -48.9 13.078\n      vertex 54.937 -51.311 12.12\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.4 -54.393 9.881\n      vertex 25.4 -54.109 9.323\n      vertex 25.4 -57 5.6\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.4 -54.393 11.119\n      vertex 25.4 -57 15\n      vertex 25.4 -54.109 11.677\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.4 -57 5.6\n      vertex 25.4 -57 15\n      vertex 25.4 -54.491 10.5\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -52.712 15.02\n      vertex 54.937 -54.168 14.789\n      vertex 54.937 -53.107 12.404\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -53.666 12.12\n      vertex 54.937 -53.107 12.404\n      vertex 54.937 -54.168 14.789\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.4 -57 5.6\n      vertex 25.4 -53.666 8.88\n      vertex 25.4 -53.107 8.596\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.4 -52.488 8.497\n      vertex 25.4 -51.788 5.6\n      vertex 25.4 -53.107 8.596\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -52.489 12.503\n      vertex 54.937 -51.87 12.404\n      vertex 54.937 -51.256 14.789\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -53.107 12.404\n      vertex 54.937 -52.489 12.503\n      vertex 54.937 -52.712 15.02\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -52.712 15.02\n      vertex 54.937 -52.489 12.503\n      vertex 54.937 -51.256 14.789\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.4 -51.788 8.63766\n      vertex 25.4 -51.788 5.6\n      vertex 25.4 -51.87 8.596\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.4 -52.488 8.497\n      vertex 25.4 -51.87 8.596\n      vertex 25.4 -51.788 5.6\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.4 -52.488 12.503\n      vertex 25.4 -51.788 15\n      vertex 25.4 -51.87 12.404\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.4 -51.788 12.36234\n      vertex 25.4 -51.87 12.404\n      vertex 25.4 -51.788 15\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -51.311 12.12\n      vertex 54.937 -49.942 14.12\n      vertex 54.937 -51.87 12.404\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -48.9 13.078\n      vertex 54.937 -50.868 11.677\n      vertex 54.937 -50.584 11.119\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -50.584 9.881\n      vertex 54.937 -50.868 9.323\n      vertex 54.937 -48.231 8.855\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -49.942 14.12\n      vertex 54.937 -51.311 12.12\n      vertex 54.937 -48.9 13.078\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -51.256 14.789\n      vertex 54.937 -51.87 12.404\n      vertex 54.937 -49.942 14.12\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.4 -53.666 12.12\n      vertex 25.4 -57 15\n      vertex 25.4 -53.107 12.404\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.4 -54.109 11.677\n      vertex 25.4 -57 15\n      vertex 25.4 -53.666 12.12\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.4 -57 15\n      vertex 25.4 -51.788 15\n      vertex 25.4 -53.107 12.404\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.4 -52.488 12.503\n      vertex 25.4 -53.107 12.404\n      vertex 25.4 -51.788 15\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -48.231 8.855\n      vertex 54.937 -48 10.31\n      vertex 54.937 -50.584 9.881\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -48.9 7.542\n      vertex 54.937 -48.231 8.855\n      vertex 54.937 -50.868 9.323\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -48.9 13.078\n      vertex 54.937 -50.584 11.119\n      vertex 54.937 -48.231 11.765\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -50.868 9.323\n      vertex 54.937 -51.311 8.88\n      vertex 54.937 -48.9 7.542\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -51.87 8.596\n      vertex 54.937 -52.489 8.497\n      vertex 54.937 -51.256 5.831\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -52.489 8.497\n      vertex 54.937 -53.107 8.596\n      vertex 54.937 -52.712 5.6\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -52.712 5.6\n      vertex 54.937 -53.107 8.596\n      vertex 54.937 -54.168 5.831\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -54.393 9.881\n      vertex 54.937 -57 8.47621\n      vertex 54.937 -54.109 9.323\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -56.524 13.078\n      vertex 54.937 -57 12.14379\n      vertex 54.937 -54.393 11.119\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -54.393 11.119\n      vertex 54.937 -54.109 11.677\n      vertex 54.937 -56.524 13.078\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -54.168 14.789\n      vertex 54.937 -55.482 14.12\n      vertex 54.937 -53.666 12.12\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -54.109 11.677\n      vertex 54.937 -53.666 12.12\n      vertex 54.937 -55.482 14.12\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -54.491 10.5\n      vertex 54.937 -54.393 11.119\n      vertex 54.937 -57 12.14379\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -57 12.14379\n      vertex 54.937 -57 8.47621\n      vertex 54.937 -54.491 10.5\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -54.491 10.5\n      vertex 54.937 -57 8.47621\n      vertex 54.937 -54.393 9.881\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -56.524 7.542\n      vertex 54.937 -54.109 9.323\n      vertex 54.937 -57 8.47621\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -55.482 6.5\n      vertex 54.937 -54.109 9.323\n      vertex 54.937 -56.524 7.542\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.937 -54.168 5.831\n      vertex 54.937 -53.666 8.88\n      vertex 54.937 -55.482 6.5\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 58.2 8 20\n      vertex 58.2 8 0\n      vertex 51.9 8 3.01932\n    endloop\n  endfacet\n  facet normal 0.00274 0.15665 -0.98765\n    outer loop\n      vertex 34.201 -40.3736 10.50209\n      vertex 34.20077 -40.38674 10.5\n      vertex 34.101 -40.385 10.5\n    endloop\n  endfacet\n  facet normal -0.00274 -0.15665 -0.98765\n    outer loop\n      vertex 34.20077 -40.38674 10.5\n      vertex 34.183 -41.399 10.6606\n      vertex 34.101 -40.385 10.5\n    endloop\n  endfacet\n  facet normal 0 0.45359 0.89121\n    outer loop\n      vertex 45.18865 -41.208 13.396\n      vertex 34.0868 -41.208 13.396\n      vertex 37.8 -41.766 13.68\n    endloop\n  endfacet\n  facet normal 0.89086 0.11761 -0.43879\n    outer loop\n      vertex 51.58089 8.49849 -15.43054\n      vertex 51.6568 11.55105 -14.45823\n      vertex 51.737 8.41924 -15.13485\n    endloop\n  endfacet\n  facet normal -0.00274 -0.15665 -0.98765\n    outer loop\n      vertex 34.076 -41.841 10.731\n      vertex 34.101 -40.385 10.5\n      vertex 34.183 -41.399 10.6606\n    endloop\n  endfacet\n  facet normal 0.89073 0.1177 -0.43904\n    outer loop\n      vertex 51.559 8.50959 -15.47199\n      vertex 51.559 11.60065 -14.64335\n      vertex 51.58089 8.49849 -15.43054\n    endloop\n  endfacet\n  facet normal 0.89073 0.1177 -0.43904\n    outer loop\n      vertex 51.6568 11.55105 -14.45823\n      vertex 51.58089 8.49849 -15.43054\n      vertex 51.559 11.60065 -14.64335\n    endloop\n  endfacet\n  facet normal 0 0.9877 -0.15637\n    outer loop\n      vertex 34.06424 -42.49669 15.89568\n      vertex 45.11944 -42.50613 15.83607\n      vertex 34.0626 -42.591 15.3\n    endloop\n  endfacet\n  facet normal 0.98781 0.0403 -0.15034\n    outer loop\n      vertex 51.559 11.60065 -14.64335\n      vertex 51.559 8.50959 -15.47199\n      vertex 51.498 11.70084 -15.0173\n    endloop\n  endfacet\n  facet normal 0.98781 0.0403 -0.15034\n    outer loop\n      vertex 51.498 8.60981 -15.84593\n      vertex 51.498 11.70084 -15.0173\n      vertex 51.559 8.50959 -15.47199\n    endloop\n  endfacet\n  facet normal 0.98775 -0.0404 0.1507\n    outer loop\n      vertex 51.559 11.80078 -15.39032\n      vertex 51.498 8.60981 -15.84593\n      vertex 51.559 8.70977 -16.21894\n    endloop\n  endfacet\n  facet normal -0.99985 0.01755 0\n    outer loop\n      vertex 34.183 -41.399 10.5\n      vertex 34.183 -41.399 10.6606\n      vertex 34.20077 -40.38674 10.5\n    endloop\n  endfacet\n  facet normal 0.89073 -0.1177 0.43904\n    outer loop\n      vertex 51.559 11.80078 -15.39032\n      vertex 51.559 8.70977 -16.21894\n      vertex 51.737 11.89105 -15.72725\n    endloop\n  endfacet\n  facet normal 0.89073 -0.1177 0.43904\n    outer loop\n      vertex 51.737 8.80006 -16.55586\n      vertex 51.737 11.89105 -15.72725\n      vertex 51.559 8.70977 -16.21894\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.4 -57 5.6\n      vertex 25.4 -53.107 8.596\n      vertex 25.4 -51.788 5.6\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.4 -54.393 11.119\n      vertex 25.4 -54.491 10.5\n      vertex 25.4 -57 15\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.4 -54.393 9.881\n      vertex 25.4 -57 5.6\n      vertex 25.4 -54.491 10.5\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.539 -52.62606 15\n      vertex 25.539 -52.5 15.02\n      vertex 25.539 -52.37394 15\n    endloop\n  endfacet\n  facet normal 0 0.45371 0.89115\n    outer loop\n      vertex 45.937 -51.256 14.789\n      vertex 54.937 -51.256 14.789\n      vertex 54.937 -49.942 14.12\n    endloop\n  endfacet\n  facet normal 0 0.15669 0.98765\n    outer loop\n      vertex 54.821 -52.58594 15\n      vertex 54.937 -52.712 15.02\n      vertex 54.821 -51.7 14.85944\n    endloop\n  endfacet\n  facet normal 0 0.15669 0.98765\n    outer loop\n      vertex 54.937 -52.712 15.02\n      vertex 54.937 -51.256 14.789\n      vertex 54.821 -51.7 14.85944\n    endloop\n  endfacet\n  facet normal 0 -0.15669 0.98765\n    outer loop\n      vertex 54.821 -54.168 14.789\n      vertex 54.937 -54.168 14.789\n      vertex 54.821 -52.83806 15\n    endloop\n  endfacet\n  facet normal 0 -0.15669 0.98765\n    outer loop\n      vertex 54.937 -52.712 15.02\n      vertex 54.821 -52.83806 15\n      vertex 54.937 -54.168 14.789\n    endloop\n  endfacet\n  facet normal 0 -0.45371 0.89115\n    outer loop\n      vertex 54.937 -54.168 14.789\n      vertex 54.821 -54.168 14.789\n      vertex 54.821 -55.482 14.12\n    endloop\n  endfacet\n  facet normal 0 -0.45371 0.89115\n    outer loop\n      vertex 54.937 -54.168 14.789\n      vertex 54.821 -55.482 14.12\n      vertex 54.937 -55.482 14.12\n    endloop\n  endfacet\n  facet normal 0 -0.70711 0.70711\n    outer loop\n      vertex 54.821 -55.482 14.12\n      vertex 54.821 -56.524 13.078\n      vertex 54.937 -56.524 13.078\n    endloop\n  endfacet\n  facet normal 0 -0.70711 0.70711\n    outer loop\n      vertex 54.821 -55.482 14.12\n      vertex 54.937 -56.524 13.078\n      vertex 54.937 -55.482 14.12\n    endloop\n  endfacet\n  facet normal 0 -0.89101 0.45399\n    outer loop\n      vertex 54.821 -56.524 13.078\n      vertex 54.821 -57 12.14379\n      vertex 54.937 -57 12.14379\n    endloop\n  endfacet\n  facet normal 0 -0.89101 0.45399\n    outer loop\n      vertex 54.821 -56.524 13.078\n      vertex 54.937 -57 12.14379\n      vertex 54.937 -56.524 13.078\n    endloop\n  endfacet\n  facet normal 0 -0.89101 -0.45399\n    outer loop\n      vertex 54.937 -57 8.47621\n      vertex 54.821 -57 8.47621\n      vertex 54.821 -56.524 7.542\n    endloop\n  endfacet\n  facet normal 0 -0.89101 -0.45399\n    outer loop\n      vertex 54.937 -57 8.47621\n      vertex 54.821 -56.524 7.542\n      vertex 54.937 -56.524 7.542\n    endloop\n  endfacet\n  facet normal 0 -0.70711 -0.70711\n    outer loop\n      vertex 54.821 -56.524 7.542\n      vertex 54.821 -55.482 6.5\n      vertex 54.937 -55.482 6.5\n    endloop\n  endfacet\n  facet normal 0 -0.70711 -0.70711\n    outer loop\n      vertex 54.821 -56.524 7.542\n      vertex 54.937 -55.482 6.5\n      vertex 54.937 -56.524 7.542\n    endloop\n  endfacet\n  facet normal 0 -0.45371 -0.89115\n    outer loop\n      vertex 54.937 -54.168 5.831\n      vertex 54.937 -55.482 6.5\n      vertex 54.821 -54.168 5.831\n    endloop\n  endfacet\n  facet normal 0 -0.45371 -0.89115\n    outer loop\n      vertex 54.821 -55.482 6.5\n      vertex 54.821 -54.168 5.831\n      vertex 54.937 -55.482 6.5\n    endloop\n  endfacet\n  facet normal 0 -0.15669 -0.98765\n    outer loop\n      vertex 54.821 -54.168 5.831\n      vertex 54.821 -52.712 5.6\n      vertex 54.937 -52.712 5.6\n    endloop\n  endfacet\n  facet normal 0 -0.15669 -0.98765\n    outer loop\n      vertex 54.821 -54.168 5.831\n      vertex 54.937 -52.712 5.6\n      vertex 54.937 -54.168 5.831\n    endloop\n  endfacet\n  facet normal 0 0.15669 -0.98765\n    outer loop\n      vertex 54.937 -52.712 5.6\n      vertex 54.821 -51.7 5.76056\n      vertex 54.937 -51.256 5.831\n    endloop\n  endfacet\n  facet normal 0 0.15669 -0.98765\n    outer loop\n      vertex 54.821 -52.712 5.6\n      vertex 54.821 -51.7 5.76056\n      vertex 54.937 -52.712 5.6\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 34.17415 -36.2 13.17602\n      vertex 34.17386 -36.2 13.85081\n      vertex 26.6 -36.2 20\n    endloop\n  endfacet\n  facet normal 0 0.70711 -0.70711\n    outer loop\n      vertex 45.937 -48.9 7.542\n      vertex 54.937 -48.9 7.542\n      vertex 54.937 -49.942 6.5\n    endloop\n  endfacet\n  facet normal -0.99986 0.01691 -0.00031\n    outer loop\n      vertex 34.127 -38.929 10.731\n      vertex 34.11792 -39.412 13.68\n      vertex 34.149 -37.616 11.4\n    endloop\n  endfacet\n  facet normal -0.99984 0.01785 0.00038\n    outer loop\n      vertex 34.11926 -39.33152 13.76047\n      vertex 34.12587 -38.969 14.123\n      vertex 34.149 -37.616 11.4\n    endloop\n  endfacet\n  facet normal -0.99984 0.01785 0\n    outer loop\n      vertex 34.127 -38.929 10.731\n      vertex 34.101 -40.385 10.5\n      vertex 34.10841 -39.97 13.396\n    endloop\n  endfacet\n  facet normal -0.99984 0.01785 0\n    outer loop\n      vertex 34.11109 -39.82012 13.47229\n      vertex 34.127 -38.929 10.731\n      vertex 34.10841 -39.97 13.396\n    endloop\n  endfacet\n  facet normal 0 -0.99463 0.10354\n    outer loop\n      vertex 32.8 8.01 19.9\n      vertex 32.8 8 19.80394\n      vertex 37.8 8.01 19.9\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 34.539 -52.37394 15\n      vertex 34.539 -52.5 15.02\n      vertex 34.539 -52.62606 15\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 26.6 -36.2 -58\n      vertex 26.6 -36.2 20\n      vertex 26.6 -33.2 -58\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.821 -51.7 14.85944\n      vertex 54.821 -51.7 15\n      vertex 54.821 -52.58594 15\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.821 -57 15\n      vertex 54.821 -54.168 14.789\n      vertex 54.821 -52.83806 15\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 27.1 8 20\n      vertex 27.1 8 0\n      vertex 27.1 -3.2 20\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.821 -52.712 5.6\n      vertex 54.821 -51.7 5.6\n      vertex 54.821 -51.7 5.76056\n    endloop\n  endfacet\n  facet normal -0.99986 0.01691 -0.00031\n    outer loop\n      vertex 34.127 -38.929 10.731\n      vertex 34.11109 -39.82012 13.47229\n      vertex 34.11792 -39.412 13.68\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.821 -54.168 14.789\n      vertex 54.821 -57 15\n      vertex 54.821 -55.482 14.12\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.821 -55.482 14.12\n      vertex 54.821 -57 15\n      vertex 54.821 -56.524 13.078\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 32.8 8 19.80394\n      vertex 32.8 8 3.01941\n      vertex 27.1 8 20\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.821 -57 12.14379\n      vertex 54.821 -56.524 13.078\n      vertex 54.821 -57 15\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.821 -57 8.47621\n      vertex 54.821 -57 5.6\n      vertex 54.821 -56.524 7.542\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.821 -54.168 5.831\n      vertex 54.821 -55.482 6.5\n      vertex 54.821 -57 5.6\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.821 -56.524 7.542\n      vertex 54.821 -57 5.6\n      vertex 54.821 -55.482 6.5\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 54.821 -52.712 5.6\n      vertex 54.821 -54.168 5.831\n      vertex 54.821 -57 5.6\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 45.937 8 20\n      vertex 37.8 8 19.80394\n      vertex 27.1 8 20\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 34.27425 -36.2 13.17945\n      vertex 34.17415 -36.2 13.17602\n      vertex 34.27425 -36.2 10.5\n    endloop\n  endfacet\n  facet normal 0.01556 0.89085 -0.45404\n    outer loop\n      vertex 34.17415 -36.2 13.17602\n      vertex 34.26765 -36.57574 12.442\n      vertex 34.168 -36.574 12.442\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01736 0\n    outer loop\n      vertex 45.23247 -38.684 14.681\n      vertex 45.22752 -38.969 14.123\n      vertex 45.274 -36.292 10.5\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01736 0\n    outer loop\n      vertex 45.22752 -38.969 14.123\n      vertex 45.21983 -39.412 13.68\n      vertex 45.274 -36.292 10.5\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01736 0\n    outer loop\n      vertex 45.274 -36.292 19.9\n      vertex 45.23417 -38.586 15.3\n      vertex 45.274 -36.292 10.5\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 34.17386 -36.2 16.56919\n      vertex 34.17415 -36.2 17.24398\n      vertex 26.6 -36.2 20\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01736 0\n    outer loop\n      vertex 45.23417 -38.586 15.3\n      vertex 45.274 -36.292 19.9\n      vertex 45.23247 -38.684 15.919\n    endloop\n  endfacet\n  facet normal -0.99985 0.01717 0\n    outer loop\n      vertex 34.101 -40.385 17.27037\n      vertex 34.0975 -40.589 17.303\n      vertex 34.101 -40.385 19.92\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01736 0\n    outer loop\n      vertex 45.22752 -38.969 16.477\n      vertex 45.274 -36.292 19.9\n      vertex 45.21983 -39.412 16.92\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01736 0\n    outer loop\n      vertex 45.182 -41.591 17.00907\n      vertex 45.18865 -41.208 17.204\n      vertex 45.182 -41.591 19.9\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01736 0\n    outer loop\n      vertex 45.1994 -40.589 17.303\n      vertex 45.21014 -39.97 17.204\n      vertex 45.182 -41.591 19.9\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01736 0\n    outer loop\n      vertex 45.274 -36.292 19.9\n      vertex 45.182 -41.591 19.9\n      vertex 45.21014 -39.97 17.204\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01736 0\n    outer loop\n      vertex 45.18865 -41.208 17.204\n      vertex 45.1994 -40.589 17.303\n      vertex 45.182 -41.591 19.9\n    endloop\n  endfacet\n  facet normal -0.89074 0 -0.45451\n    outer loop\n      vertex 42.665 -36.2 -9.635\n      vertex 42.267 -36.2 -8.855\n      vertex 42.665 -33.2 -9.635\n    endloop\n  endfacet\n  facet normal -0.99984 0.01785 0\n    outer loop\n      vertex 34.101 -40.385 13.3303\n      vertex 34.10841 -39.97 13.396\n      vertex 34.101 -40.385 10.5\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01736 0\n    outer loop\n      vertex 45.21014 -39.97 17.204\n      vertex 45.21983 -39.412 16.92\n      vertex 45.274 -36.292 19.9\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01736 0\n    outer loop\n      vertex 45.23247 -38.684 15.919\n      vertex 45.274 -36.292 19.9\n      vertex 45.22752 -38.969 16.477\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01736 0\n    outer loop\n      vertex 45.23247 -38.684 14.681\n      vertex 45.274 -36.292 10.5\n      vertex 45.23417 -38.586 15.3\n    endloop\n  endfacet\n  facet normal -0.99985 0.01717 0\n    outer loop\n      vertex 34.0975 -40.589 13.298\n      vertex 34.101 -40.385 13.3303\n      vertex 34.101 -40.385 10.5\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 52.2 -33.2 -58\n      vertex 26.6 -33.2 -58\n      vertex 39.701 -33.2 -52.403\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 26.6 -36.2 20\n      vertex 34.27425 -36.2 10.5\n      vertex 34.17415 -36.2 13.17602\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01717 0\n    outer loop\n      vertex 45.15516 -40.45194 19.9\n      vertex 45.153 -40.578 19.92\n      vertex 45.15084 -40.70406 19.9\n    endloop\n  endfacet\n  facet normal 0.01235 0.70694 -0.70717\n    outer loop\n      vertex 34.149 -37.616 11.4\n      vertex 34.168 -36.574 12.442\n      vertex 34.24936 -37.61775 11.4\n    endloop\n  endfacet\n  facet normal 0.01235 0.70694 -0.70717\n    outer loop\n      vertex 34.26765 -36.57574 12.442\n      vertex 34.24936 -37.61775 11.4\n      vertex 34.168 -36.574 12.442\n    endloop\n  endfacet\n  facet normal 0.00793 0.45386 -0.89104\n    outer loop\n      vertex 34.22632 -38.93073 10.731\n      vertex 34.127 -38.929 10.731\n      vertex 34.22653 -38.91893 10.73701\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.365 -33.2 -50.467\n      vertex 52.2 -33.2 -58\n      vertex 41.967 -33.2 -51.248\n    endloop\n  endfacet\n  facet normal 0.00274 0.15665 0.98765\n    outer loop\n      vertex 45.15516 -40.45194 19.9\n      vertex 44.19837 -40.43523 19.9\n      vertex 45.153 -40.578 19.92\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 41.348 -33.2 -51.867\n      vertex 52.2 -33.2 -58\n      vertex 40.567 -33.2 -52.265\n    endloop\n  endfacet\n  facet normal -0.00274 -0.15665 0.98765\n    outer loop\n      vertex 34.19855 -40.5128 19.9\n      vertex 45.15084 -40.70406 19.9\n      vertex 45.153 -40.578 19.92\n    endloop\n  endfacet\n  facet normal 0.00793 0.45387 -0.89103\n    outer loop\n      vertex 34.24936 -37.61775 11.4\n      vertex 34.22653 -38.91893 10.73701\n      vertex 34.149 -37.616 11.4\n    endloop\n  endfacet\n  facet normal 0.00793 0.45387 -0.89103\n    outer loop\n      vertex 34.127 -38.929 10.731\n      vertex 34.149 -37.616 11.4\n      vertex 34.22653 -38.91893 10.73701\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 52.2 -36.2 20\n      vertex 26.6 -36.2 20\n      vertex 40.00412 -36.2 19.9\n    endloop\n  endfacet\n  facet normal 0.00274 0.15665 0.98765\n    outer loop\n      vertex 34.20298 -40.26068 19.9\n      vertex 34.101 -40.385 19.92\n      vertex 44.19837 -40.43523 19.9\n    endloop\n  endfacet\n  facet normal 0.00274 0.15665 -0.98765\n    outer loop\n      vertex 34.127 -38.929 10.731\n      vertex 34.22632 -38.93073 10.731\n      vertex 34.201 -40.3736 10.50209\n    endloop\n  endfacet\n  facet normal -0.99985 0.01748 -0.00023\n    outer loop\n      vertex 34.06549 -42.42509 14.54757\n      vertex 34.06937 -42.209 14.123\n      vertex 34.023 -44.866 13.755\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 45.15084 -40.70406 19.9\n      vertex 45.182 -41.591 19.9\n      vertex 45.15516 -40.45194 19.9\n    endloop\n  endfacet\n  facet normal -0.99985 0.0174 0\n    outer loop\n      vertex 34.019 -45.096 15.21\n      vertex 34.06431 -42.493 14.681\n      vertex 34.023 -44.866 13.755\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 44.19837 -40.43523 19.9\n      vertex 45.15516 -40.45194 19.9\n      vertex 45.274 -36.292 19.9\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 38.835 -33.2 -46.937\n      vertex 38.055 -33.2 -47.335\n      vertex 38.452 -33.2 -38.767\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 45.274 -36.292 19.9\n      vertex 45.15516 -40.45194 19.9\n      vertex 45.182 -41.591 19.9\n    endloop\n  endfacet\n  facet normal -0.99985 0.01747 -0.0001\n    outer loop\n      vertex 34.09068 -40.9861 13.36087\n      vertex 34.076 -41.841 10.731\n      vertex 34.0868 -41.208 13.396\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 41.745 -33.2 -38.767\n      vertex 42.365 -33.2 -38.148\n      vertex 41.967 -33.2 -47.955\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 41.967 -33.2 -47.955\n      vertex 41.348 -33.2 -47.335\n      vertex 41.745 -33.2 -38.767\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 34.27425 -36.2 19.9\n      vertex 34.20298 -40.26068 19.9\n      vertex 40.00412 -36.2 19.9\n    endloop\n  endfacet\n  facet normal -0.99985 0.01747 -0.0001\n    outer loop\n      vertex 34.08046 -41.56961 13.58004\n      vertex 34.0868 -41.208 13.396\n      vertex 34.053 -43.154 11.4\n    endloop\n  endfacet\n  facet normal -0.99985 0.01747 -0.0001\n    outer loop\n      vertex 34.076 -41.841 10.731\n      vertex 34.053 -43.154 11.4\n      vertex 34.0868 -41.208 13.396\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 40.00412 -36.2 19.9\n      vertex 44.19837 -40.43523 19.9\n      vertex 45.274 -36.292 19.9\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.965 -33.2 -39.165\n      vertex 41.745 -33.2 -38.767\n      vertex 41.348 -33.2 -47.335\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 41.348 -33.2 -47.335\n      vertex 40.567 -33.2 -46.937\n      vertex 40.965 -33.2 -39.165\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.567 -33.2 -46.937\n      vertex 39.701 -33.2 -46.8\n      vertex 40.099 -33.2 -39.302\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.099 -33.2 -39.302\n      vertex 40.965 -33.2 -39.165\n      vertex 40.567 -33.2 -46.937\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 39.233 -33.2 -39.165\n      vertex 40.099 -33.2 -39.302\n      vertex 39.701 -33.2 -46.8\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 39.701 -33.2 -46.8\n      vertex 38.835 -33.2 -46.937\n      vertex 39.233 -33.2 -39.165\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 38.452 -33.2 -38.767\n      vertex 39.233 -33.2 -39.165\n      vertex 38.835 -33.2 -46.937\n    endloop\n  endfacet\n  facet normal -0.99985 0.01729 0.00003\n    outer loop\n      vertex 34.08046 -41.56961 13.58004\n      vertex 34.053 -43.154 11.4\n      vertex 34.07707 -41.766 13.68\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 45.22923 -36.2 16.63187\n      vertex 52.2 -36.2 20\n      vertex 45.22932 -36.2 16.86519\n    endloop\n  endfacet\n  facet normal -0.99985 0.01729 0.00003\n    outer loop\n      vertex 34.07707 -41.766 13.68\n      vertex 34.053 -43.154 11.4\n      vertex 34.035 -44.197 12.442\n    endloop\n  endfacet\n  facet normal -0.99985 0.01729 0.00003\n    outer loop\n      vertex 34.0718 -42.07143 13.98543\n      vertex 34.07707 -41.766 13.68\n      vertex 34.035 -44.197 12.442\n    endloop\n  endfacet\n  facet normal 0 0.15669 0.98765\n    outer loop\n      vertex 45.937 -52.712 15.02\n      vertex 54.937 -52.712 15.02\n      vertex 46.1 -52.58594 15\n    endloop\n  endfacet\n  facet normal 0 0.15669 0.98765\n    outer loop\n      vertex 54.821 -52.58594 15\n      vertex 46.1 -52.58594 15\n      vertex 54.937 -52.712 15.02\n    endloop\n  endfacet\n  facet normal 0 -0.15669 0.98765\n    outer loop\n      vertex 54.821 -52.83806 15\n      vertex 54.937 -52.712 15.02\n      vertex 46.1 -52.83806 15\n    endloop\n  endfacet\n  facet normal 0 -0.15669 0.98765\n    outer loop\n      vertex 45.937 -52.712 15.02\n      vertex 46.1 -52.83806 15\n      vertex 54.937 -52.712 15.02\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 54.821 -51.7 15\n      vertex 46.1 -51.7 15\n      vertex 46.1 -52.58594 15\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 54.821 -51.7 15\n      vertex 46.1 -52.58594 15\n      vertex 54.821 -52.58594 15\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 55.2 4.36328 0\n      vertex 54.002 5.0705 -2.639\n      vertex 55.2 7.74214 -12.60822\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.941 5.17042 -3.01184\n      vertex 53.8835 5.19975 -3.12129\n      vertex 55.2 7.74214 -12.60822\n    endloop\n  endfacet\n  facet normal -0.99986 0.01691 0.00031\n    outer loop\n      vertex 34.12057 -39.25577 16.76377\n      vertex 34.11798 -39.412 16.92\n      vertex 34.149 -37.616 19.02\n    endloop\n  endfacet\n  facet normal -0.99986 0.01691 0.00031\n    outer loop\n      vertex 34.11198 -39.76991 17.10216\n      vertex 34.127 -38.929 19.689\n      vertex 34.11798 -39.412 16.92\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01727 -0.00042\n    outer loop\n      vertex 45.22923 -36.2 16.63187\n      vertex 45.22932 -36.2 16.86519\n      vertex 45.22764 -36.29119 16.60226\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01727 -0.00042\n    outer loop\n      vertex 45.22783 -36.29119 17.04417\n      vertex 45.22764 -36.29119 16.60226\n      vertex 45.22932 -36.2 16.86519\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 54.821 -52.83806 15\n      vertex 46.1 -52.83806 15\n      vertex 54.821 -57 15\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 46.1 -52.83806 15\n      vertex 46.1 -57 15\n      vertex 54.821 -57 15\n    endloop\n  endfacet\n  facet normal 0.89086 0.11761 -0.43879\n    outer loop\n      vertex 51.737 11.51035 -14.30631\n      vertex 51.737 8.41924 -15.13485\n      vertex 51.6568 11.55105 -14.45823\n    endloop\n  endfacet\n  facet normal 0.98775 -0.0404 0.1507\n    outer loop\n      vertex 51.559 11.80078 -15.39032\n      vertex 51.498 11.70084 -15.0173\n      vertex 51.498 8.60981 -15.84593\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.763 -33.2 -35.635\n      vertex 42.365 -33.2 -34.855\n      vertex 51.8 -33.2 -30.37797\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 51.8 -33.2 -30.37797\n      vertex 42.365 -33.2 -34.855\n      vertex 41.745 -33.2 -34.235\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.965 -33.2 -33.837\n      vertex 41.394 -33.2 -25.767\n      vertex 41.745 -33.2 -34.235\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 51.8 -33.2 -30.37797\n      vertex 42.365 -33.2 -48.735\n      vertex 42.763 -33.2 -37.367\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.365 -33.2 -38.148\n      vertex 42.763 -33.2 -37.367\n      vertex 42.365 -33.2 -48.735\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 51.8 -33.2 -30.37797\n      vertex 42.763 -33.2 -37.367\n      vertex 42.9 -33.2 -36.501\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.763 -33.2 -35.635\n      vertex 51.8 -33.2 -30.37797\n      vertex 42.9 -33.2 -36.501\n    endloop\n  endfacet\n  facet normal -0.99984 0.01785 -0.00038\n    outer loop\n      vertex 34.149 -37.616 19.02\n      vertex 34.1258 -38.969 16.477\n      vertex 34.12057 -39.25577 16.76377\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.365 -33.2 -50.467\n      vertex 42.503 -33.2 -49.601\n      vertex 52.2 -33.2 -58\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.503 -33.2 -49.601\n      vertex 42.365 -33.2 -48.735\n      vertex 52.2 -33.2 -58\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 51.8 -33.2 -30.37797\n      vertex 52.2 -33.2 -58\n      vertex 42.365 -33.2 -48.735\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.365 -33.2 -48.735\n      vertex 41.967 -33.2 -47.955\n      vertex 42.365 -33.2 -38.148\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 38.835 -33.2 -52.265\n      vertex 39.701 -33.2 -52.403\n      vertex 26.6 -33.2 -58\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 39.701 -33.2 -52.403\n      vertex 40.567 -33.2 -52.265\n      vertex 52.2 -33.2 -58\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 41.348 -33.2 -51.867\n      vertex 41.967 -33.2 -51.248\n      vertex 52.2 -33.2 -58\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.735 -33.2 -8.855\n      vertex 27.1 -33.2 0\n      vertex 38.355 -33.2 -8.235\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.984 -33.2 -0.679\n      vertex 38.765 -33.2 -1.077\n      vertex 38.355 -33.2 -8.235\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 38.355 -33.2 -8.235\n      vertex 38.765 -33.2 -1.077\n      vertex 39.135 -33.2 -7.837\n    endloop\n  endfacet\n  facet normal 0.01235 0.70694 0.70717\n    outer loop\n      vertex 34.26765 -36.57574 17.978\n      vertex 34.168 -36.574 17.978\n      vertex 34.24936 -37.61775 19.02\n    endloop\n  endfacet\n  facet normal 0.01556 0.89085 0.45404\n    outer loop\n      vertex 45.22932 -36.2 16.86519\n      vertex 40.00412 -36.2 17.04422\n      vertex 45.22783 -36.29119 17.04417\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.00412 -36.2 17.04422\n      vertex 45.22932 -36.2 16.86519\n      vertex 40.00412 -36.2 19.9\n    endloop\n  endfacet\n  facet normal -0.99984 0.01785 0\n    outer loop\n      vertex 34.101 -40.385 17.27037\n      vertex 34.101 -40.385 19.92\n      vertex 34.10841 -39.97 17.204\n    endloop\n  endfacet\n  facet normal -0.00274 -0.15665 0.98765\n    outer loop\n      vertex 34.076 -41.841 19.689\n      vertex 34.183 -41.399 19.7594\n      vertex 34.101 -40.385 19.92\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.138 4.7631 -1.49193\n      vertex 55.2 4.36328 0\n      vertex 52.752 4.74728 -1.43288\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01727 0.00042\n    outer loop\n      vertex 45.22923 -36.2 13.78813\n      vertex 45.22764 -36.29119 13.81774\n      vertex 45.22932 -36.2 13.55481\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.764 4.88052 -1.93008\n      vertex 55.2 4.36328 0\n      vertex 53.487 4.80894 -1.66297\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.138 4.7631 -1.49193\n      vertex 53.487 4.80894 -1.66297\n      vertex 55.2 4.36328 0\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 55.2 4.36328 0\n      vertex 53.764 4.88052 -1.93008\n      vertex 53.941 4.97056 -2.26607\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 55.2 4.36328 0\n      vertex 53.941 4.97056 -2.26607\n      vertex 53.96081 5.003 -2.38713\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 55.2 4.36328 0\n      vertex 53.96081 5.003 -2.38713\n      vertex 54.002 5.0705 -2.639\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.98219 5.10296 -2.76013\n      vertex 55.2 7.74214 -12.60822\n      vertex 54.002 5.0705 -2.639\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.941 5.17042 -3.01184\n      vertex 55.2 7.74214 -12.60822\n      vertex 53.98219 5.10296 -2.76013\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01727 0.00042\n    outer loop\n      vertex 45.22783 -36.29119 13.37583\n      vertex 45.22932 -36.2 13.55481\n      vertex 45.22764 -36.29119 13.81774\n    endloop\n  endfacet\n  facet normal 0.99985 -0.0174 0.00001\n    outer loop\n      vertex 45.22764 -36.29119 13.81774\n      vertex 45.22923 -36.2 13.78813\n      vertex 45.2292 -36.2 15.21\n    endloop\n  endfacet\n  facet normal 0.99985 -0.0174 0.00001\n    outer loop\n      vertex 45.22764 -36.29119 13.81774\n      vertex 45.2292 -36.2 15.21\n      vertex 45.22762 -36.29119 15.21\n    endloop\n  endfacet\n  facet normal -0.99986 0.01691 0.00031\n    outer loop\n      vertex 34.149 -37.616 19.02\n      vertex 34.11798 -39.412 16.92\n      vertex 34.127 -38.929 19.689\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 26.6 -36.2 20\n      vertex 34.17415 -36.2 17.24398\n      vertex 34.27425 -36.2 19.9\n    endloop\n  endfacet\n  facet normal -0.99985 0.01727 0.00042\n    outer loop\n      vertex 34.168 -36.574 17.978\n      vertex 34.17415 -36.2 17.24398\n      vertex 34.12746 -38.88013 16.30301\n    endloop\n  endfacet\n  facet normal -0.99985 0.01727 0.00042\n    outer loop\n      vertex 34.17386 -36.2 16.56919\n      vertex 34.12746 -38.88013 16.30301\n      vertex 34.17415 -36.2 17.24398\n    endloop\n  endfacet\n  facet normal 0 -0.07378 -0.99727\n    outer loop\n      vertex 51.8 22.60526 1.93881\n      vertex 51.9 26.09 1.681\n      vertex 51.8 21.60559 2.01276\n    endloop\n  endfacet\n  facet normal 0 -0.07378 -0.99727\n    outer loop\n      vertex 46.9 26.09 1.681\n      vertex 51.9 26.09 1.681\n      vertex 51.8 22.60526 1.93881\n    endloop\n  endfacet\n  facet normal 0 -0.07378 -0.99727\n    outer loop\n      vertex 51.9 8 3.01932\n      vertex 51.8 21.60559 2.01276\n      vertex 51.9 26.09 1.681\n    endloop\n  endfacet\n  facet normal 0.99985 -0.0174 -0.00001\n    outer loop\n      vertex 45.22923 -36.2 16.63187\n      vertex 45.22764 -36.29119 16.60226\n      vertex 45.2292 -36.2 15.21\n    endloop\n  endfacet\n  facet normal 0.99985 -0.0174 -0.00001\n    outer loop\n      vertex 45.22762 -36.29119 15.21\n      vertex 45.2292 -36.2 15.21\n      vertex 45.22764 -36.29119 16.60226\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 52.2 -36.2 20\n      vertex 40.00412 -36.2 19.9\n      vertex 45.22932 -36.2 16.86519\n    endloop\n  endfacet\n  facet normal 0.01556 0.89085 -0.45404\n    outer loop\n      vertex 40.00412 -36.2 13.37578\n      vertex 45.22932 -36.2 13.55481\n      vertex 45.22783 -36.29119 13.37583\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 52.70234 8.93177 -17.04733\n      vertex 55.2 9.443 -18.955\n      vertex 52.75 8.93371 -17.0546\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.137 8.91767 -16.99473\n      vertex 55.2 9.443 -18.955\n      vertex 53.44302 8.87748 -16.84475\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.08934 8.91962 -17.002\n      vertex 55.2 9.443 -18.955\n      vertex 53.137 8.91767 -16.99473\n    endloop\n  endfacet\n  facet normal 0.01556 0.89085 0.45404\n    outer loop\n      vertex 34.26765 -36.57574 17.978\n      vertex 34.17415 -36.2 17.24398\n      vertex 34.168 -36.574 17.978\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 55.2 9.443 -18.955\n      vertex 53.486 8.8718 -16.82357\n      vertex 53.44302 8.87748 -16.84475\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 51.8 22.603 1.874\n      vertex 51.8 22.60526 1.93881\n      vertex 51.8 21.60559 2.01276\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 46.9 8 19.90931\n      vertex 46.9 26.09 1.681\n      vertex 46.9 22.7 4.662\n    endloop\n  endfacet\n  facet normal 0.01746 0.99985 0\n    outer loop\n      vertex 45.22783 -36.29119 17.04417\n      vertex 45.274 -36.292 19.9\n      vertex 45.22764 -36.29119 16.60226\n    endloop\n  endfacet\n  facet normal 0.01746 0.99985 0\n    outer loop\n      vertex 40.00412 -36.2 19.9\n      vertex 45.274 -36.292 19.9\n      vertex 45.22783 -36.29119 17.04417\n    endloop\n  endfacet\n  facet normal -0.99984 0.01785 -0.00038\n    outer loop\n      vertex 34.149 -37.616 19.02\n      vertex 34.168 -36.574 17.978\n      vertex 34.1258 -38.969 16.477\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 46.9 21.60559 2.01276\n      vertex 46.9 8 3.01932\n      vertex 46.9 8 3.9056\n    endloop\n  endfacet\n  facet normal -0.99984 0.01785 -0.00038\n    outer loop\n      vertex 34.12746 -38.88013 16.30301\n      vertex 34.1258 -38.969 16.477\n      vertex 34.168 -36.574 17.978\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 51.9 8 3.01932\n      vertex 58.2 8 0\n      vertex 46.9 8 3.01932\n    endloop\n  endfacet\n  facet normal -0.99985 0.01717 0\n    outer loop\n      vertex 34.101 -40.385 10.5\n      vertex 34.076 -41.841 10.731\n      vertex 34.0975 -40.589 13.298\n    endloop\n  endfacet\n  facet normal -0.99985 0.01717 0\n    outer loop\n      vertex 34.09068 -40.9861 13.36087\n      vertex 34.0975 -40.589 13.298\n      vertex 34.076 -41.841 10.731\n    endloop\n  endfacet\n  facet normal 0.01746 0.99985 0\n    outer loop\n      vertex 45.22764 -36.29119 16.60226\n      vertex 45.274 -36.292 19.9\n      vertex 45.22762 -36.29119 15.21\n    endloop\n  endfacet\n  facet normal 0.01746 0.99985 0\n    outer loop\n      vertex 45.22762 -36.29119 15.21\n      vertex 45.274 -36.292 10.5\n      vertex 45.22764 -36.29119 13.81774\n    endloop\n  endfacet\n  facet normal 0 -0.07378 -0.99727\n    outer loop\n      vertex 46.9 21.60559 2.01276\n      vertex 51.8 21.60559 2.01276\n      vertex 46.9 8 3.01932\n    endloop\n  endfacet\n  facet normal 0 -0.07378 -0.99727\n    outer loop\n      vertex 51.9 8 3.01932\n      vertex 46.9 8 3.01932\n      vertex 51.8 21.60559 2.01276\n    endloop\n  endfacet\n  facet normal 0.01746 0.99985 0\n    outer loop\n      vertex 45.274 -36.292 10.5\n      vertex 45.22762 -36.29119 15.21\n      vertex 45.274 -36.292 19.9\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 56.103 2.403 20\n      vertex 45.402 2.403 11.799\n      vertex 55.27692 2.403 0\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 46.1 22.603 1.874\n      vertex 51.8 22.603 1.874\n      vertex 46.9 21.60559 2.01276\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 51.8 21.60559 2.01276\n      vertex 46.9 21.60559 2.01276\n      vertex 51.8 22.603 1.874\n    endloop\n  endfacet\n  facet normal 0.01746 0.99985 0\n    outer loop\n      vertex 40.00412 -36.2 19.9\n      vertex 45.22783 -36.29119 17.04417\n      vertex 40.00412 -36.2 17.04422\n    endloop\n  endfacet\n  facet normal 0.01746 0.99985 0\n    outer loop\n      vertex 45.22783 -36.29119 13.37583\n      vertex 45.22764 -36.29119 13.81774\n      vertex 45.274 -36.292 10.5\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 46.9 26.09 1.681\n      vertex 46.9 22.60526 1.93881\n      vertex 46.9 22.7 4.662\n    endloop\n  endfacet\n  facet normal 0 -0.07378 -0.99727\n    outer loop\n      vertex 51.8 22.60526 1.93881\n      vertex 46.9 22.60526 1.93881\n      vertex 46.9 26.09 1.681\n    endloop\n  endfacet\n  facet normal 0 0.15637 0.9877\n    outer loop\n      vertex 45.18865 -41.208 13.396\n      vertex 34.09068 -40.9861 13.36087\n      vertex 34.0868 -41.208 13.396\n    endloop\n  endfacet\n  facet normal 0 0.15637 0.9877\n    outer loop\n      vertex 45.18865 -41.208 13.396\n      vertex 34.0975 -40.589 13.298\n      vertex 34.09068 -40.9861 13.36087\n    endloop\n  endfacet\n  facet normal 0 0.9994 -0.03477\n    outer loop\n      vertex 51.8 22.603 1.874\n      vertex 46.1 22.603 1.874\n      vertex 46.9 22.60526 1.93881\n    endloop\n  endfacet\n  facet normal 0 0.9994 -0.03477\n    outer loop\n      vertex 46.1 22.603 1.874\n      vertex 46.9 22.7 4.662\n      vertex 46.9 22.60526 1.93881\n    endloop\n  endfacet\n  facet normal -0.99985 0.01755 0\n    outer loop\n      vertex 34.27425 -36.2 13.17945\n      vertex 34.27425 -36.2 10.5\n      vertex 34.26765 -36.57574 12.442\n    endloop\n  endfacet\n  facet normal 0 0.9994 -0.03477\n    outer loop\n      vertex 46.9 22.60526 1.93881\n      vertex 51.8 22.60526 1.93881\n      vertex 51.8 22.603 1.874\n    endloop\n  endfacet\n  facet normal -0.99985 0.01755 0\n    outer loop\n      vertex 34.22653 -38.91893 10.73701\n      vertex 34.24936 -37.61775 11.4\n      vertex 34.27425 -36.2 10.5\n    endloop\n  endfacet\n  facet normal -0.99985 0.01755 0\n    outer loop\n      vertex 34.27425 -36.2 10.5\n      vertex 34.24936 -37.61775 11.4\n      vertex 34.26765 -36.57574 12.442\n    endloop\n  endfacet\n  facet normal -0.99985 0.01755 0\n    outer loop\n      vertex 34.20077 -40.38674 10.5\n      vertex 34.201 -40.3736 10.50209\n      vertex 34.27425 -36.2 10.5\n    endloop\n  endfacet\n  facet normal -0.99985 0.01755 0\n    outer loop\n      vertex 34.27425 -36.2 10.5\n      vertex 34.22632 -38.93073 10.731\n      vertex 34.22653 -38.91893 10.73701\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 46.1 -51.7 5.6\n      vertex 54.821 -52.712 5.6\n      vertex 46.1 -52.712 5.6\n    endloop\n  endfacet\n  facet normal -0.99985 0.01755 0\n    outer loop\n      vertex 34.22632 -38.93073 10.731\n      vertex 34.27425 -36.2 10.5\n      vertex 34.201 -40.3736 10.50209\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 46.1 -57 5.6\n      vertex 46.1 -52.712 5.6\n      vertex 54.821 -57 5.6\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 54.821 -51.7 5.6\n      vertex 54.821 -52.712 5.6\n      vertex 46.1 -51.7 5.6\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 54.821 -52.712 5.6\n      vertex 54.821 -57 5.6\n      vertex 46.1 -52.712 5.6\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 52.2 -36.2 -10.48639\n      vertex 52.2 -33.2 20\n      vertex 52.2 -36.2 20\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01747 -0.0001\n    outer loop\n      vertex 45.105 -43.347 19.02\n      vertex 45.13241 -41.766 16.92\n      vertex 45.13549 -41.59019 17.00948\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01747 -0.0001\n    outer loop\n      vertex 45.13186 -41.79772 16.88828\n      vertex 45.13241 -41.766 16.92\n      vertex 45.105 -43.347 19.02\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01747 -0.0001\n    outer loop\n      vertex 45.13549 -41.59019 17.00948\n      vertex 45.13562 -41.59019 18.32374\n      vertex 45.105 -43.347 19.02\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 51.9 8 19.90931\n      vertex 58.2 8 20\n      vertex 51.9 8 3.01932\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01747 -0.0001\n    outer loop\n      vertex 45.128 -42.034 19.689\n      vertex 45.105 -43.347 19.02\n      vertex 45.13562 -41.59019 18.32374\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01717 0\n    outer loop\n      vertex 45.13562 -41.59019 18.32374\n      vertex 45.13562 -41.59019 19.75941\n      vertex 45.128 -42.034 19.689\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 51.9 8 3.01932\n      vertex 51.9 26.09 1.681\n      vertex 51.9 8 19.90931\n    endloop\n  endfacet\n  facet normal 0 0.70979 0.70441\n    outer loop\n      vertex 46.9 26.09 1.681\n      vertex 46.9 8 19.90931\n      vertex 51.9 26.09 1.681\n    endloop\n  endfacet\n  facet normal 0 0.70979 0.70441\n    outer loop\n      vertex 51.9 8 19.90931\n      vertex 51.9 26.09 1.681\n      vertex 46.9 8 19.90931\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 55.3377 -0.802 0\n      vertex 45.402 -0.802 11.799\n      vertex 56.103 -0.802 20\n    endloop\n  endfacet\n  facet normal 0.99985 -0.0174 0\n    outer loop\n      vertex 45.11821 -42.57675 15.21\n      vertex 45.11796 -42.591 15.3\n      vertex 45.071 -45.289 15.21\n    endloop\n  endfacet\n  facet normal 0.99985 -0.0174 0\n    outer loop\n      vertex 45.11944 -42.50613 15.83607\n      vertex 45.075 -45.059 16.665\n      vertex 45.11796 -42.591 15.3\n    endloop\n  endfacet\n  facet normal 0.99985 -0.0174 0\n    outer loop\n      vertex 45.071 -45.289 15.21\n      vertex 45.11796 -42.591 15.3\n      vertex 45.075 -45.059 16.665\n    endloop\n  endfacet\n  facet normal 0.99984 -0.01784 -0.00037\n    outer loop\n      vertex 45.105 -43.347 19.02\n      vertex 45.12436 -42.209 16.477\n      vertex 45.13186 -41.79772 16.88828\n    endloop\n  endfacet\n  facet normal 0 -0.15637 0.9877\n    outer loop\n      vertex 34.10841 -39.97 13.396\n      vertex 34.101 -40.385 13.3303\n      vertex 45.1994 -40.589 13.298\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 45.22923 -36.2 13.78813\n      vertex 45.22932 -36.2 13.55481\n      vertex 52.2 -36.2 20\n    endloop\n  endfacet\n  facet normal 0.99984 -0.01784 -0.00037\n    outer loop\n      vertex 45.12436 -42.209 16.477\n      vertex 45.105 -43.347 19.02\n      vertex 45.086 -44.39 17.978\n    endloop\n  endfacet\n  facet normal 0.99984 -0.01784 -0.00037\n    outer loop\n      vertex 45.12379 -42.23973 16.41663\n      vertex 45.12436 -42.209 16.477\n      vertex 45.086 -44.39 17.978\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 46.9 22.7 4.662\n      vertex 46.9 8.051 6.7\n      vertex 46.9 8 19.90931\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 46.9 8 5.23414\n      vertex 46.9 8 19.90931\n      vertex 46.9 8.051 6.7\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 45.2292 -36.2 15.21\n      vertex 45.22923 -36.2 13.78813\n      vertex 52.2 -36.2 20\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.337 -33.2 -9.635\n      vertex 27.1 -33.2 0\n      vertex 37.735 -33.2 -8.855\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.984 -33.2 -0.679\n      vertex 38.355 -33.2 -8.235\n      vertex 27.1 -33.2 0\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01727 0.00042\n    outer loop\n      vertex 45.12379 -42.23973 16.41663\n      vertex 45.086 -44.39 17.978\n      vertex 45.11963 -42.493 15.919\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.364 -33.2 -0.06\n      vertex 37.984 -33.2 -0.679\n      vertex 27.1 -33.2 0\n    endloop\n  endfacet\n  facet normal 0 -0.15793 -0.98745\n    outer loop\n      vertex 34.0975 -40.589 17.303\n      vertex 34.101 -40.385 17.27037\n      vertex 45.1994 -40.589 17.303\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01727 0.00042\n    outer loop\n      vertex 45.075 -45.059 16.665\n      vertex 45.11963 -42.493 15.919\n      vertex 45.086 -44.39 17.978\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01727 0.00042\n    outer loop\n      vertex 45.11944 -42.50613 15.83607\n      vertex 45.11963 -42.493 15.919\n      vertex 45.075 -45.059 16.665\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01727 -0.00042\n    outer loop\n      vertex 45.12037 -42.45247 14.60135\n      vertex 45.075 -45.059 13.755\n      vertex 45.12437 -42.209 14.123\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01727 -0.00042\n    outer loop\n      vertex 45.12532 -42.15262 14.06662\n      vertex 45.12437 -42.209 14.123\n      vertex 45.086 -44.39 12.442\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 39.63 -36.2 -1.214\n      vertex 38.765 -36.2 -1.077\n      vertex 39.135 -36.2 -7.837\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.364 -36.2 -0.06\n      vertex 31.06376 -36.2 -10.48639\n      vertex 37.984 -36.2 -0.679\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 39.937 -3.2 12.665\n      vertex 40.335 -3.2 13.445\n      vertex 27.1 -3.2 20\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 39.937 -3.2 12.665\n      vertex 27.1 -3.2 20\n      vertex 39.8 -3.2 11.799\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01727 -0.00042\n    outer loop\n      vertex 45.086 -44.39 12.442\n      vertex 45.12437 -42.209 14.123\n      vertex 45.075 -45.059 13.755\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 38.355 -36.2 -8.235\n      vertex 39.135 -36.2 -7.837\n      vertex 38.765 -36.2 -1.077\n    endloop\n  endfacet\n  facet normal 0.99985 -0.0174 0\n    outer loop\n      vertex 45.11821 -42.57675 15.21\n      vertex 45.071 -45.289 15.21\n      vertex 45.11967 -42.493 14.681\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 39.937 2.403 10.933\n      vertex 39.8 2.403 11.799\n      vertex 30.30975 2.403 0\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 29.097 2.403 20\n      vertex 30.30975 2.403 0\n      vertex 39.8 2.403 11.799\n    endloop\n  endfacet\n  facet normal 0 -0.99463 0.10354\n    outer loop\n      vertex 37.8 8.01 19.9\n      vertex 32.8 8 19.80394\n      vertex 37.8 8 19.80394\n    endloop\n  endfacet\n  facet normal 0.99985 -0.0174 0\n    outer loop\n      vertex 45.12037 -42.45247 14.60135\n      vertex 45.11967 -42.493 14.681\n      vertex 45.075 -45.059 13.755\n    endloop\n  endfacet\n  facet normal 0.99985 -0.0174 0\n    outer loop\n      vertex 45.075 -45.059 13.755\n      vertex 45.11967 -42.493 14.681\n      vertex 45.071 -45.289 15.21\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 40.91319 19.20945 5.14761\n      vertex 37.8 22.7 4.662\n      vertex 40.956 18.9367 5.18556\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 38.355 -36.2 -8.235\n      vertex 37.984 -36.2 -0.679\n      vertex 37.735 -36.2 -8.855\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 40.956 19.88063 5.05424\n      vertex 41.17 20.30653 4.99498\n      vertex 37.8 22.7 4.662\n    endloop\n  endfacet\n  facet normal 0.89074 0 -0.45451\n    outer loop\n      vertex 37.735 -33.2 -8.855\n      vertex 37.735 -36.2 -8.855\n      vertex 37.337 -36.2 -9.635\n    endloop\n  endfacet\n  facet normal 0.89074 0 -0.45451\n    outer loop\n      vertex 37.735 -33.2 -8.855\n      vertex 37.337 -36.2 -9.635\n      vertex 37.337 -33.2 -9.635\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 41.504 18.1725 5.29188\n      vertex 37.8 8.051 6.7\n      vertex 41.69207 18.07515 5.30542\n    endloop\n  endfacet\n  facet normal 0.70711 0 -0.70711\n    outer loop\n      vertex 37.735 -33.2 -8.855\n      vertex 38.355 -36.2 -8.235\n      vertex 37.735 -36.2 -8.855\n    endloop\n  endfacet\n  facet normal -0.00274 -0.15665 0.98765\n    outer loop\n      vertex 34.076 -41.841 19.689\n      vertex 45.128 -42.034 19.689\n      vertex 34.183 -41.399 19.7594\n    endloop\n  endfacet\n  facet normal 0.70654 0 0.70768\n    outer loop\n      vertex 37.364 -33.2 -0.06\n      vertex 37.364 -36.2 -0.06\n      vertex 37.984 -36.2 -0.679\n    endloop\n  endfacet\n  facet normal 0.70654 0 0.70768\n    outer loop\n      vertex 37.364 -33.2 -0.06\n      vertex 37.984 -36.2 -0.679\n      vertex 37.984 -33.2 -0.679\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 41.17 18.5108 5.24481\n      vertex 37.8 8.051 6.7\n      vertex 41.31708 18.36207 5.2655\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 41.504 18.1725 5.29188\n      vertex 41.31708 18.36207 5.2655\n      vertex 37.8 8.051 6.7\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 41.925 17.95514 5.32211\n      vertex 41.69207 18.07515 5.30542\n      vertex 37.8 8.051 6.7\n    endloop\n  endfacet\n  facet normal 0.98772 0 -0.15626\n    outer loop\n      vertex 37.337 -36.2 -9.635\n      vertex 37.2 -36.2 -10.501\n      vertex 37.337 -33.2 -9.635\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 40.956 18.9367 5.18556\n      vertex 37.8 8.051 6.7\n      vertex 41.17 18.5108 5.24481\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 26.6 -36.2 -58\n      vertex 26.6 -33.2 -58\n      vertex 52.2 -33.2 -58\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 43.87146 19.60318 5.09284\n      vertex 46.9 22.7 4.662\n      vertex 43.828 19.88063 5.05424\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.435 -33.2 -51.248\n      vertex 26.6 -33.2 -58\n      vertex 37.037 -33.2 -50.467\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 43.614 18.5108 5.24481\n      vertex 46.9 8.051 6.7\n      vertex 43.828 18.9367 5.18556\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 43.42738 18.32152 5.27114\n      vertex 46.9 8.051 6.7\n      vertex 43.614 18.5108 5.24481\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 43.28 18.1725 5.29188\n      vertex 46.9 8.051 6.7\n      vertex 43.42738 18.32152 5.27114\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 42.859 17.95514 5.32211\n      vertex 46.9 8.051 6.7\n      vertex 43.04729 18.0526 5.30856\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 43.28 18.1725 5.29188\n      vertex 43.04729 18.0526 5.30856\n      vertex 46.9 8.051 6.7\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 37.8 8.051 6.7\n      vertex 42.13522 17.9217 5.32677\n      vertex 41.925 17.95514 5.32211\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 37.8 8.051 6.7\n      vertex 46.9 8.051 6.7\n      vertex 42.392 17.88087 5.33245\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 41.504 20.64428 4.948\n      vertex 37.8 22.7 4.662\n      vertex 41.17 20.30653 4.99498\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 41.925 20.86119 4.91782\n      vertex 37.8 22.7 4.662\n      vertex 41.504 20.64428 4.948\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 46.9 22.7 4.662\n      vertex 37.8 22.7 4.662\n      vertex 42.392 20.93586 4.90743\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 42.67964 20.8901 4.9138\n      vertex 46.9 22.7 4.662\n      vertex 42.392 20.93586 4.90743\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 42.859 20.86119 4.91782\n      vertex 46.9 22.7 4.662\n      vertex 42.67964 20.8901 4.9138\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 42.21282 20.90698 4.91145\n      vertex 42.392 20.93586 4.90743\n      vertex 37.8 22.7 4.662\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.833 -33.2 -38.148\n      vertex 38.452 -33.2 -38.767\n      vertex 38.055 -33.2 -47.335\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 38.055 -33.2 -47.335\n      vertex 37.435 -33.2 -47.955\n      vertex 37.833 -33.2 -38.148\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 43.28 20.64428 4.948\n      vertex 46.9 22.7 4.662\n      vertex 42.859 20.86119 4.91782\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 46.9 22.7 4.662\n      vertex 43.28 20.64428 4.948\n      vertex 43.614 20.30653 4.99498\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.763 8.80006 -16.55586\n      vertex 53.72891 8.80887 -16.58874\n      vertex 55.2 9.443 -18.955\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.486 8.8718 -16.82357\n      vertex 55.2 9.443 -18.955\n      vertex 53.72891 8.80887 -16.58874\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 43.614 20.30653 4.99498\n      vertex 43.828 19.88063 5.05424\n      vertex 46.9 22.7 4.662\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 46.9 22.7 4.662\n      vertex 43.87146 19.60318 5.09284\n      vertex 43.902 19.40817 5.11997\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 43.85931 19.13616 5.15781\n      vertex 43.828 18.9367 5.18556\n      vertex 46.9 22.7 4.662\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 46.9 8.051 6.7\n      vertex 46.9 22.7 4.662\n      vertex 43.828 18.9367 5.18556\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 43.902 19.40817 5.11997\n      vertex 43.85931 19.13616 5.15781\n      vertex 46.9 22.7 4.662\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 42.13522 17.9217 5.32677\n      vertex 37.8 8.051 6.7\n      vertex 42.392 17.88087 5.33245\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 42.859 17.95514 5.32211\n      vertex 42.60231 17.91433 5.32779\n      vertex 46.9 8.051 6.7\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 40.882 19.40817 5.11997\n      vertex 37.8 22.7 4.662\n      vertex 40.91319 19.20945 5.14761\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 40.9256 19.68651 5.08124\n      vertex 37.8 22.7 4.662\n      vertex 40.882 19.40817 5.11997\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 40.956 19.88063 5.05424\n      vertex 37.8 22.7 4.662\n      vertex 40.9256 19.68651 5.08124\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 41.925 20.86119 4.91782\n      vertex 42.21282 20.90698 4.91145\n      vertex 37.8 22.7 4.662\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 37.8 8.051 6.7\n      vertex 40.956 18.9367 5.18556\n      vertex 37.8 22.7 4.662\n    endloop\n  endfacet\n  facet normal -0.01556 -0.89084 -0.45404\n    outer loop\n      vertex 45.086 -44.39 12.442\n      vertex 34.023 -44.866 13.755\n      vertex 34.035 -44.197 12.442\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 55.2 7.74214 -12.60822\n      vertex 52.366 5.37813 -3.78692\n      vertex 53.137 8.30163 -14.69598\n    endloop\n  endfacet\n  facet normal -0.01725 -0.98758 -0.15616\n    outer loop\n      vertex 34.023 -44.866 13.755\n      vertex 45.075 -45.059 13.755\n      vertex 34.019 -45.096 15.21\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.137 8.30163 -14.69598\n      vertex 52.366 5.37813 -3.78692\n      vertex 52.79762 8.28775 -14.64419\n    endloop\n  endfacet\n  facet normal 0 0.45359 0.89121\n    outer loop\n      vertex 34.07707 -41.766 13.68\n      vertex 37.8 -41.766 13.68\n      vertex 34.08046 -41.56961 13.58004\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 41.897 -33.2 3.234\n      vertex 41.277 -33.2 3.853\n      vertex 52.2 -33.2 20\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.295 -33.2 2.453\n      vertex 41.897 -33.2 3.234\n      vertex 52.2 -33.2 20\n    endloop\n  endfacet\n  facet normal 0 0.45359 0.89121\n    outer loop\n      vertex 34.08046 -41.56961 13.58004\n      vertex 37.8 -41.766 13.68\n      vertex 34.0868 -41.208 13.396\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 52.2 -33.2 20\n      vertex 42.665 -33.2 -9.635\n      vertex 42.295 -33.2 0.721\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.78491 8.43036 -15.17632\n      vertex 55.2 7.74214 -12.60822\n      vertex 53.763 8.41924 -15.13485\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.496 -33.2 4.251\n      vertex 39.63 -33.2 4.388\n      vertex 52.2 -33.2 20\n    endloop\n  endfacet\n  facet normal 0 -0.15637 0.9877\n    outer loop\n      vertex 34.0975 -40.589 13.298\n      vertex 45.1994 -40.589 13.298\n      vertex 34.101 -40.385 13.3303\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.486 8.34772 -14.86795\n      vertex 55.2 7.74214 -12.60822\n      vertex 53.137 8.30163 -14.69598\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.52008 8.35653 -14.90081\n      vertex 55.2 7.74214 -12.60822\n      vertex 53.486 8.34772 -14.86795\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.295 -33.2 2.453\n      vertex 52.2 -33.2 20\n      vertex 42.432 -33.2 1.587\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.432 -33.2 1.587\n      vertex 52.2 -33.2 20\n      vertex 42.295 -33.2 0.721\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 39.937 -3.2 10.933\n      vertex 39.8 -3.2 11.799\n      vertex 27.1 -3.2 0\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.52008 8.35653 -14.90081\n      vertex 53.763 8.41924 -15.13485\n      vertex 55.2 7.74214 -12.60822\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.941 8.50959 -15.47199\n      vertex 54.002 8.60981 -15.84593\n      vertex 55.2 7.74214 -12.60822\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 55.2 9.443 -18.955\n      vertex 55.2 7.74214 -12.60822\n      vertex 54.002 8.60981 -15.84593\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 54.002 8.60981 -15.84593\n      vertex 53.941 8.70977 -16.21894\n      vertex 55.2 9.443 -18.955\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.941 8.70977 -16.21894\n      vertex 53.763 8.80006 -16.55586\n      vertex 55.2 9.443 -18.955\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.78491 8.43036 -15.17632\n      vertex 53.941 8.50959 -15.47199\n      vertex 55.2 7.74214 -12.60822\n    endloop\n  endfacet\n  facet normal 0 0.98763 0.1568\n    outer loop\n      vertex 25.539 -47.788 10.31\n      vertex 25.539 -48.019 11.765\n      vertex 34.539 -47.788 10.31\n    endloop\n  endfacet\n  facet normal 0 0.98763 0.1568\n    outer loop\n      vertex 34.539 -48.019 11.765\n      vertex 34.539 -47.788 10.31\n      vertex 25.539 -48.019 11.765\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 53.08934 8.91962 -17.002\n      vertex 52.75 8.93371 -17.0546\n      vertex 55.2 9.443 -18.955\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 35.0753 9.443 -18.955\n      vertex 55.2 9.443 -18.955\n      vertex 52.363 8.91767 -16.99473\n    endloop\n  endfacet\n  facet normal 0 0.89101 0.45399\n    outer loop\n      vertex 25.539 -48.688 13.078\n      vertex 34.539 -48.688 13.078\n      vertex 34.539 -48.019 11.765\n    endloop\n  endfacet\n  facet normal 0 0.89101 0.45399\n    outer loop\n      vertex 25.539 -48.688 13.078\n      vertex 34.539 -48.019 11.765\n      vertex 25.539 -48.019 11.765\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 52.32002 8.91199 -16.97355\n      vertex 35.0753 9.443 -18.955\n      vertex 52.363 8.91767 -16.99473\n    endloop\n  endfacet\n  facet normal 0 0.70711 0.70711\n    outer loop\n      vertex 34.539 -48.688 13.078\n      vertex 25.539 -48.688 13.078\n      vertex 25.539 -49.73 14.12\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 44.867 -0.802 13.445\n      vertex 44.248 -0.802 14.065\n      vertex 56.103 -0.802 20\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.432 -36.2 1.587\n      vertex 52.2 -36.2 -10.48639\n      vertex 42.295 -36.2 2.453\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.496 -36.2 4.251\n      vertex 40.00412 -36.2 10.5\n      vertex 39.63 -36.2 4.388\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 27.1 -33.2 0\n      vertex 37.083 -33.2 -24.367\n      vertex 37.435 -33.2 -35.635\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.432 -36.2 1.587\n      vertex 42.295 -36.2 0.721\n      vertex 52.2 -36.2 -10.48639\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 41.897 -36.2 -0.06\n      vertex 41.277 -36.2 -0.679\n      vertex 41.648 -36.2 -8.235\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.083 -33.2 -24.367\n      vertex 37.481 -33.2 -25.148\n      vertex 37.435 -33.2 -35.635\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.833 -33.2 -34.855\n      vertex 37.435 -33.2 -35.635\n      vertex 37.481 -33.2 -25.148\n    endloop\n  endfacet\n  facet normal 0 0.89101 -0.45399\n    outer loop\n      vertex 25.539 -48.019 8.855\n      vertex 34.539 -48.019 8.855\n      vertex 34.539 -48.688 7.542\n    endloop\n  endfacet\n  facet normal 0 0.89101 -0.45399\n    outer loop\n      vertex 25.539 -48.019 8.855\n      vertex 34.539 -48.688 7.542\n      vertex 25.539 -48.688 7.542\n    endloop\n  endfacet\n  facet normal 0 0.98763 -0.1568\n    outer loop\n      vertex 25.539 -48.019 8.855\n      vertex 25.539 -47.788 10.31\n      vertex 34.539 -48.019 8.855\n    endloop\n  endfacet\n  facet normal 0 0.98763 -0.1568\n    outer loop\n      vertex 25.539 -47.788 10.31\n      vertex 34.539 -47.788 10.31\n      vertex 34.539 -48.019 8.855\n    endloop\n  endfacet\n  facet normal 0.45405 0 -0.89098\n    outer loop\n      vertex 38.765 -33.2 4.251\n      vertex 38.765 -36.2 4.251\n      vertex 37.984 -36.2 3.853\n    endloop\n  endfacet\n  facet normal 0.45405 0 -0.89098\n    outer loop\n      vertex 38.765 -33.2 4.251\n      vertex 37.984 -36.2 3.853\n      vertex 37.984 -33.2 3.853\n    endloop\n  endfacet\n  facet normal 0 0.70711 0.70711\n    outer loop\n      vertex 34.539 -48.688 13.078\n      vertex 25.539 -49.73 14.12\n      vertex 34.539 -49.73 14.12\n    endloop\n  endfacet\n  facet normal 0.15643 0 -0.98769\n    outer loop\n      vertex 39.63 -33.2 4.388\n      vertex 39.63 -36.2 4.388\n      vertex 38.765 -36.2 4.251\n    endloop\n  endfacet\n  facet normal 0.15643 0 -0.98769\n    outer loop\n      vertex 39.63 -33.2 4.388\n      vertex 38.765 -36.2 4.251\n      vertex 38.765 -33.2 4.251\n    endloop\n  endfacet\n  facet normal 0 0.45371 0.89115\n    outer loop\n      vertex 34.539 -49.73 14.12\n      vertex 25.539 -51.044 14.789\n      vertex 34.539 -51.044 14.789\n    endloop\n  endfacet\n  facet normal -0.15626 0 -0.98772\n    outer loop\n      vertex 40.496 -33.2 4.251\n      vertex 40.496 -36.2 4.251\n      vertex 39.63 -36.2 4.388\n    endloop\n  endfacet\n  facet normal -0.15626 0 -0.98772\n    outer loop\n      vertex 40.496 -33.2 4.251\n      vertex 39.63 -36.2 4.388\n      vertex 39.63 -33.2 4.388\n    endloop\n  endfacet\n  facet normal 0 0.45371 0.89115\n    outer loop\n      vertex 25.539 -49.73 14.12\n      vertex 25.539 -51.044 14.789\n      vertex 34.539 -49.73 14.12\n    endloop\n  endfacet\n  facet normal 0 0.15669 0.98765\n    outer loop\n      vertex 25.539 -51.044 14.789\n      vertex 25.539 -51.788 14.90704\n      vertex 34.539 -51.788 14.90704\n    endloop\n  endfacet\n  facet normal 0 0.15669 0.98765\n    outer loop\n      vertex 25.539 -51.044 14.789\n      vertex 34.539 -51.788 14.90704\n      vertex 34.539 -51.044 14.789\n    endloop\n  endfacet\n  facet normal -0.45405 0 -0.89098\n    outer loop\n      vertex 41.277 -33.2 3.853\n      vertex 41.277 -36.2 3.853\n      vertex 40.496 -36.2 4.251\n    endloop\n  endfacet\n  facet normal -0.45405 0 -0.89098\n    outer loop\n      vertex 41.277 -33.2 3.853\n      vertex 40.496 -36.2 4.251\n      vertex 40.496 -33.2 4.251\n    endloop\n  endfacet\n  facet normal 0 0.15669 -0.98765\n    outer loop\n      vertex 25.539 -51.044 5.831\n      vertex 34.539 -51.044 5.831\n      vertex 34.539 -51.788 5.71296\n    endloop\n  endfacet\n  facet normal 0 0.15669 -0.98765\n    outer loop\n      vertex 25.539 -51.044 5.831\n      vertex 34.539 -51.788 5.71296\n      vertex 25.539 -51.788 5.71296\n    endloop\n  endfacet\n  facet normal -0.70654 0 -0.70768\n    outer loop\n      vertex 41.897 -33.2 3.234\n      vertex 41.897 -36.2 3.234\n      vertex 41.277 -36.2 3.853\n    endloop\n  endfacet\n  facet normal -0.70654 0 -0.70768\n    outer loop\n      vertex 41.897 -33.2 3.234\n      vertex 41.277 -36.2 3.853\n      vertex 41.277 -33.2 3.853\n    endloop\n  endfacet\n  facet normal 0 0.45371 -0.89115\n    outer loop\n      vertex 25.539 -49.73 6.5\n      vertex 34.539 -49.73 6.5\n      vertex 34.539 -51.044 5.831\n    endloop\n  endfacet\n  facet normal 0 0.45371 -0.89115\n    outer loop\n      vertex 25.539 -49.73 6.5\n      vertex 34.539 -51.044 5.831\n      vertex 25.539 -51.044 5.831\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.503 -36.2 -49.601\n      vertex 52.2 -36.2 -58\n      vertex 42.365 -36.2 -48.735\n    endloop\n  endfacet\n  facet normal -0.89098 0 -0.45405\n    outer loop\n      vertex 42.295 -33.2 2.453\n      vertex 42.295 -36.2 2.453\n      vertex 41.897 -36.2 3.234\n    endloop\n  endfacet\n  facet normal -0.89098 0 -0.45405\n    outer loop\n      vertex 42.295 -33.2 2.453\n      vertex 41.897 -36.2 3.234\n      vertex 41.897 -33.2 3.234\n    endloop\n  endfacet\n  facet normal 0 0.70711 -0.70711\n    outer loop\n      vertex 25.539 -49.73 6.5\n      vertex 25.539 -48.688 7.542\n      vertex 34.539 -49.73 6.5\n    endloop\n  endfacet\n  facet normal 0 0.70711 -0.70711\n    outer loop\n      vertex 34.539 -48.688 7.542\n      vertex 34.539 -49.73 6.5\n      vertex 25.539 -48.688 7.542\n    endloop\n  endfacet\n  facet normal -0.98772 0 -0.15626\n    outer loop\n      vertex 42.432 -33.2 1.587\n      vertex 42.432 -36.2 1.587\n      vertex 42.295 -36.2 2.453\n    endloop\n  endfacet\n  facet normal -0.98772 0 -0.15626\n    outer loop\n      vertex 42.432 -33.2 1.587\n      vertex 42.295 -36.2 2.453\n      vertex 42.295 -33.2 2.453\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.833 -36.2 -38.148\n      vertex 38.055 -36.2 -47.335\n      vertex 38.452 -36.2 -38.767\n    endloop\n  endfacet\n  facet normal 0 -0.45295 0.89154\n    outer loop\n      vertex 25.539 -51.788 8.63766\n      vertex 30.72 -51.87 8.596\n      vertex 25.539 -51.311 8.88\n    endloop\n  endfacet\n  facet normal -0.98772 0 0.15626\n    outer loop\n      vertex 42.295 -33.2 0.721\n      vertex 42.295 -36.2 0.721\n      vertex 42.432 -36.2 1.587\n    endloop\n  endfacet\n  facet normal -0.98772 0 0.15626\n    outer loop\n      vertex 42.295 -33.2 0.721\n      vertex 42.432 -36.2 1.587\n      vertex 42.432 -33.2 1.587\n    endloop\n  endfacet\n  facet normal -0.89098 0 0.45405\n    outer loop\n      vertex 42.295 -33.2 0.721\n      vertex 41.897 -36.2 -0.06\n      vertex 42.295 -36.2 0.721\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01717 0\n    outer loop\n      vertex 45.13562 -41.59019 12.09626\n      vertex 45.128 -42.034 10.731\n      vertex 45.13562 -41.59019 10.66059\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.298 -33.2 -36.501\n      vertex 27.1 -33.2 0\n      vertex 37.435 -33.2 -35.635\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.037 -33.2 -48.735\n      vertex 26.6 -33.2 -58\n      vertex 37.435 -33.2 -37.367\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.435 -33.2 -37.367\n      vertex 37.833 -33.2 -38.148\n      vertex 37.435 -33.2 -47.955\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.435 -33.2 -51.248\n      vertex 38.055 -33.2 -51.867\n      vertex 26.6 -33.2 -58\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 38.055 -33.2 -51.867\n      vertex 38.835 -33.2 -52.265\n      vertex 26.6 -33.2 -58\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.298 -33.2 -36.501\n      vertex 37.435 -33.2 -37.367\n      vertex 26.6 -33.2 -58\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.435 -33.2 -47.955\n      vertex 37.037 -33.2 -48.735\n      vertex 37.435 -33.2 -37.367\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 36.9 -33.2 -49.601\n      vertex 26.6 -33.2 -58\n      vertex 37.037 -33.2 -48.735\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 36.9 -33.2 -49.601\n      vertex 37.037 -33.2 -50.467\n      vertex 26.6 -33.2 -58\n    endloop\n  endfacet\n  facet normal -0.00793 -0.45386 -0.89104\n    outer loop\n      vertex 45.128 -42.034 10.731\n      vertex 45.105 -43.347 11.4\n      vertex 34.076 -41.841 10.731\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 38.835 -36.2 -46.937\n      vertex 38.452 -36.2 -38.767\n      vertex 38.055 -36.2 -47.335\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 27.1 -3.2 0\n      vertex 58.2 -3.2 0\n      vertex 42.601 -3.2 8.998\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.8 8 3.9056\n      vertex 46.9 8 3.9056\n      vertex 37.8 8 3.01941\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 37.8 8 3.9056\n      vertex 37.8 8 3.01941\n      vertex 37.8 21.5208 2.02456\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 39.701 -36.2 -46.8\n      vertex 40.567 -36.2 -46.937\n      vertex 40.099 -36.2 -39.302\n    endloop\n  endfacet\n  facet normal 0 -0.70711 0.70711\n    outer loop\n      vertex 34.539 -50.868 9.323\n      vertex 25.539 -50.868 9.323\n      vertex 25.539 -51.311 8.88\n    endloop\n  endfacet\n  facet normal 0 -0.89121 0.45359\n    outer loop\n      vertex 25.539 -50.584 9.881\n      vertex 25.539 -50.868 9.323\n      vertex 34.539 -50.868 9.323\n    endloop\n  endfacet\n  facet normal 0 -0.9877 0.15637\n    outer loop\n      vertex 25.539 -50.486 10.5\n      vertex 25.539 -50.584 9.881\n      vertex 34.539 -50.486 10.5\n    endloop\n  endfacet\n  facet normal 0 -0.9877 -0.15637\n    outer loop\n      vertex 25.539 -50.584 11.119\n      vertex 25.539 -50.486 10.5\n      vertex 34.539 -50.584 11.119\n    endloop\n  endfacet\n  facet normal 0 -0.9877 -0.15637\n    outer loop\n      vertex 34.539 -50.486 10.5\n      vertex 34.539 -50.584 11.119\n      vertex 25.539 -50.486 10.5\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.965 -36.2 -33.837\n      vertex 40.613 -36.2 -26.165\n      vertex 40.099 -36.2 -33.7\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.099 -36.2 -33.7\n      vertex 39.747 -36.2 -26.303\n      vertex 39.233 -36.2 -33.837\n    endloop\n  endfacet\n  facet normal 0 -0.89121 -0.45359\n    outer loop\n      vertex 25.539 -50.868 11.677\n      vertex 25.539 -50.584 11.119\n      vertex 34.539 -50.868 11.677\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.365 -36.2 -48.735\n      vertex 52.2 -36.2 -58\n      vertex 42.365 -36.2 -38.148\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.567 -36.2 -46.937\n      vertex 41.348 -36.2 -47.335\n      vertex 40.965 -36.2 -39.165\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.965 -36.2 -39.165\n      vertex 40.099 -36.2 -39.302\n      vertex 40.567 -36.2 -46.937\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 39.701 -36.2 -46.8\n      vertex 40.099 -36.2 -39.302\n      vertex 39.233 -36.2 -39.165\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 38.452 -36.2 -38.767\n      vertex 38.835 -36.2 -46.937\n      vertex 39.233 -36.2 -39.165\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.365 -36.2 -38.148\n      vertex 41.745 -36.2 -38.767\n      vertex 41.967 -36.2 -47.955\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 41.348 -36.2 -47.335\n      vertex 41.967 -36.2 -47.955\n      vertex 41.745 -36.2 -38.767\n    endloop\n  endfacet\n  facet normal 0 -0.70711 0.70711\n    outer loop\n      vertex 25.539 -51.311 8.88\n      vertex 34.539 -51.311 8.88\n      vertex 34.539 -50.868 9.323\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.9 -36.2 -36.501\n      vertex 46.9 -36.2 -31.18159\n      vertex 42.763 -36.2 -35.635\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.365 -36.2 -34.855\n      vertex 46.9 -36.2 -31.18159\n      vertex 41.745 -36.2 -34.235\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.013 -36.2 -25.148\n      vertex 41.394 -36.2 -25.767\n      vertex 46.9 -36.2 -31.18159\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.365 -36.2 -34.855\n      vertex 42.763 -36.2 -35.635\n      vertex 46.9 -36.2 -31.18159\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.763 -36.2 -37.367\n      vertex 52.2 -36.2 -58\n      vertex 42.9 -36.2 -36.501\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 41.967 -36.2 -47.955\n      vertex 42.365 -36.2 -48.735\n      vertex 42.365 -36.2 -38.148\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 41.745 -36.2 -38.767\n      vertex 40.965 -36.2 -39.165\n      vertex 41.348 -36.2 -47.335\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.763 -36.2 -37.367\n      vertex 42.365 -36.2 -38.148\n      vertex 52.2 -36.2 -58\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.365 -36.2 -50.467\n      vertex 52.2 -36.2 -58\n      vertex 42.503 -36.2 -49.601\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 41.967 -36.2 -51.248\n      vertex 52.2 -36.2 -58\n      vertex 42.365 -36.2 -50.467\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 41.348 -36.2 -51.867\n      vertex 52.2 -36.2 -58\n      vertex 41.967 -36.2 -51.248\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.567 -36.2 -52.265\n      vertex 52.2 -36.2 -58\n      vertex 41.348 -36.2 -51.867\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 46.9 -36.2 -31.18159\n      vertex 42.9 -36.2 -36.501\n      vertex 52.2 -36.2 -58\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 41.735 -3.2 9.135\n      vertex 27.1 -3.2 0\n      vertex 42.601 -3.2 8.998\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 26.6 -36.2 -58\n      vertex 52.2 -36.2 -58\n      vertex 39.701 -36.2 -52.403\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 38.835 -36.2 -52.265\n      vertex 26.6 -36.2 -58\n      vertex 39.701 -36.2 -52.403\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 38.055 -36.2 -51.867\n      vertex 26.6 -36.2 -58\n      vertex 38.835 -36.2 -52.265\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.567 -36.2 -52.265\n      vertex 39.701 -36.2 -52.403\n      vertex 52.2 -36.2 -58\n    endloop\n  endfacet\n  facet normal 0.15737 0 0.98754\n    outer loop\n      vertex 38.835 -33.2 -52.265\n      vertex 38.835 -36.2 -52.265\n      vertex 39.701 -36.2 -52.403\n    endloop\n  endfacet\n  facet normal 0.15737 0 0.98754\n    outer loop\n      vertex 38.835 -33.2 -52.265\n      vertex 39.701 -36.2 -52.403\n      vertex 39.701 -33.2 -52.403\n    endloop\n  endfacet\n  facet normal 0.45451 0 0.89074\n    outer loop\n      vertex 38.055 -33.2 -51.867\n      vertex 38.055 -36.2 -51.867\n      vertex 38.835 -36.2 -52.265\n    endloop\n  endfacet\n  facet normal 0.45451 0 0.89074\n    outer loop\n      vertex 38.055 -33.2 -51.867\n      vertex 38.835 -36.2 -52.265\n      vertex 38.835 -33.2 -52.265\n    endloop\n  endfacet\n  facet normal 0.70654 0 0.70768\n    outer loop\n      vertex 37.435 -33.2 -51.248\n      vertex 38.055 -36.2 -51.867\n      vertex 38.055 -33.2 -51.867\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 36.966 -33.2 0.721\n      vertex 27.1 -33.2 0\n      vertex 36.829 -33.2 1.587\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 38.452 -36.2 -34.235\n      vertex 34.019 -36.2 -31.18159\n      vertex 37.833 -36.2 -34.855\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.984 -33.2 3.853\n      vertex 37.364 -33.2 3.234\n      vertex 26.6 -33.2 20\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 39.233 -36.2 -33.837\n      vertex 38.881 -36.2 -26.165\n      vertex 38.452 -36.2 -34.235\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.435 -36.2 -35.635\n      vertex 37.833 -36.2 -34.855\n      vertex 34.019 -36.2 -31.18159\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.435 -36.2 -37.367\n      vertex 37.435 -36.2 -47.955\n      vertex 37.833 -36.2 -38.148\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 39.701 -36.2 -46.8\n      vertex 39.233 -36.2 -39.165\n      vertex 38.835 -36.2 -46.937\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.298 -36.2 -36.501\n      vertex 34.019 -36.2 -31.18159\n      vertex 37.435 -36.2 -37.367\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.298 -36.2 -36.501\n      vertex 37.435 -36.2 -35.635\n      vertex 34.019 -36.2 -31.18159\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 36.829 -33.2 1.587\n      vertex 27.1 -33.2 0\n      vertex 36.966 -33.2 2.453\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 26.6 -36.2 -58\n      vertex 38.055 -36.2 -51.867\n      vertex 37.435 -36.2 -51.248\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.037 -36.2 -50.467\n      vertex 26.6 -36.2 -58\n      vertex 37.435 -36.2 -51.248\n    endloop\n  endfacet\n  facet normal 0 0.89101 0.45399\n    outer loop\n      vertex 45.937 -48.9 13.078\n      vertex 54.937 -48.9 13.078\n      vertex 54.937 -48.231 11.765\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 36.9 -36.2 -49.601\n      vertex 26.6 -36.2 -58\n      vertex 37.037 -36.2 -50.467\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 34.019 -36.2 -31.18159\n      vertex 26.6 -36.2 -58\n      vertex 37.037 -36.2 -48.735\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 34.019 -36.2 -31.18159\n      vertex 37.037 -36.2 -48.735\n      vertex 37.435 -36.2 -47.955\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 38.055 -36.2 -47.335\n      vertex 37.833 -36.2 -38.148\n      vertex 37.435 -36.2 -47.955\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 34.019 -36.2 -31.18159\n      vertex 37.435 -36.2 -47.955\n      vertex 37.435 -36.2 -37.367\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.037 -36.2 -48.735\n      vertex 26.6 -36.2 -58\n      vertex 36.9 -36.2 -49.601\n    endloop\n  endfacet\n  facet normal 0.70654 0 0.70768\n    outer loop\n      vertex 37.435 -33.2 -51.248\n      vertex 37.435 -36.2 -51.248\n      vertex 38.055 -36.2 -51.867\n    endloop\n  endfacet\n  facet normal 0 0.70711 0.70711\n    outer loop\n      vertex 54.937 -49.942 14.12\n      vertex 54.937 -48.9 13.078\n      vertex 45.937 -48.9 13.078\n    endloop\n  endfacet\n  facet normal 0.89098 0 0.45405\n    outer loop\n      vertex 37.037 -33.2 -50.467\n      vertex 37.037 -36.2 -50.467\n      vertex 37.435 -36.2 -51.248\n    endloop\n  endfacet\n  facet normal 0.89098 0 0.45405\n    outer loop\n      vertex 37.037 -33.2 -50.467\n      vertex 37.435 -36.2 -51.248\n      vertex 37.435 -33.2 -51.248\n    endloop\n  endfacet\n  facet normal 0.98772 0 0.15626\n    outer loop\n      vertex 37.037 -36.2 -50.467\n      vertex 37.037 -33.2 -50.467\n      vertex 36.9 -33.2 -49.601\n    endloop\n  endfacet\n  facet normal 0.98772 0 0.15626\n    outer loop\n      vertex 37.037 -36.2 -50.467\n      vertex 36.9 -33.2 -49.601\n      vertex 36.9 -36.2 -49.601\n    endloop\n  endfacet\n  facet normal 0 0.89101 -0.45399\n    outer loop\n      vertex 45.937 -48.9 7.542\n      vertex 45.937 -48.231 8.855\n      vertex 54.937 -48.9 7.542\n    endloop\n  endfacet\n  facet normal 0 0.89101 -0.45399\n    outer loop\n      vertex 54.937 -48.231 8.855\n      vertex 54.937 -48.9 7.542\n      vertex 45.937 -48.231 8.855\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.984 -36.2 3.853\n      vertex 38.765 -36.2 4.251\n      vertex 34.27425 -36.2 10.5\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 38.765 -36.2 4.251\n      vertex 39.63 -36.2 4.388\n      vertex 40.00412 -36.2 10.5\n    endloop\n  endfacet\n  facet normal 0.98772 0 -0.15626\n    outer loop\n      vertex 37.037 -33.2 -48.735\n      vertex 37.037 -36.2 -48.735\n      vertex 36.9 -36.2 -49.601\n    endloop\n  endfacet\n  facet normal 0.98772 0 -0.15626\n    outer loop\n      vertex 37.037 -33.2 -48.735\n      vertex 36.9 -36.2 -49.601\n      vertex 36.9 -33.2 -49.601\n    endloop\n  endfacet\n  facet normal 0 0.98763 -0.1568\n    outer loop\n      vertex 54.937 -48.231 8.855\n      vertex 45.937 -48.231 8.855\n      vertex 54.937 -48 10.31\n    endloop\n  endfacet\n  facet normal 0.89074 0 -0.45451\n    outer loop\n      vertex 37.435 -33.2 -47.955\n      vertex 37.435 -36.2 -47.955\n      vertex 37.037 -36.2 -48.735\n    endloop\n  endfacet\n  facet normal 0.89074 0 -0.45451\n    outer loop\n      vertex 37.435 -33.2 -47.955\n      vertex 37.037 -36.2 -48.735\n      vertex 37.037 -33.2 -48.735\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 36.966 -36.2 0.721\n      vertex 31.06376 -36.2 -10.48639\n      vertex 37.364 -36.2 -0.06\n    endloop\n  endfacet\n  facet normal 0.70711 0 -0.70711\n    outer loop\n      vertex 38.055 -33.2 -47.335\n      vertex 38.055 -36.2 -47.335\n      vertex 37.435 -36.2 -47.955\n    endloop\n  endfacet\n  facet normal 0.70711 0 -0.70711\n    outer loop\n      vertex 38.055 -33.2 -47.335\n      vertex 37.435 -36.2 -47.955\n      vertex 37.435 -33.2 -47.955\n    endloop\n  endfacet\n  facet normal 0.89098 0 0.45405\n    outer loop\n      vertex 37.435 -33.2 -37.367\n      vertex 37.435 -36.2 -37.367\n      vertex 37.833 -33.2 -38.148\n    endloop\n  endfacet\n  facet normal 0.98772 0 0.15626\n    outer loop\n      vertex 37.435 -36.2 -37.367\n      vertex 37.435 -33.2 -37.367\n      vertex 37.298 -36.2 -36.501\n    endloop\n  endfacet\n  facet normal 0.98772 0 0.15626\n    outer loop\n      vertex 37.298 -33.2 -36.501\n      vertex 37.298 -36.2 -36.501\n      vertex 37.435 -33.2 -37.367\n    endloop\n  endfacet\n  facet normal 0 0.15669 0.98765\n    outer loop\n      vertex 54.821 -51.7 14.85944\n      vertex 54.937 -51.256 14.789\n      vertex 46.1 -51.7 14.85944\n    endloop\n  endfacet\n  facet normal 0 0.15669 0.98765\n    outer loop\n      vertex 45.937 -51.256 14.789\n      vertex 46.1 -51.7 14.85944\n      vertex 54.937 -51.256 14.789\n    endloop\n  endfacet\n  facet normal 0.98772 0 -0.15626\n    outer loop\n      vertex 37.435 -33.2 -35.635\n      vertex 37.435 -36.2 -35.635\n      vertex 37.298 -36.2 -36.501\n    endloop\n  endfacet\n  facet normal 0.98772 0 -0.15626\n    outer loop\n      vertex 37.435 -33.2 -35.635\n      vertex 37.298 -36.2 -36.501\n      vertex 37.298 -33.2 -36.501\n    endloop\n  endfacet\n  facet normal 0 0.15669 -0.98765\n    outer loop\n      vertex 54.821 -51.7 5.76056\n      vertex 46.1 -51.7 5.76056\n      vertex 54.937 -51.256 5.831\n    endloop\n  endfacet\n  facet normal 0 0.15669 -0.98765\n    outer loop\n      vertex 45.937 -51.256 5.831\n      vertex 54.937 -51.256 5.831\n      vertex 46.1 -51.7 5.76056\n    endloop\n  endfacet\n  facet normal 0 0.45371 -0.89115\n    outer loop\n      vertex 54.937 -49.942 6.5\n      vertex 54.937 -51.256 5.831\n      vertex 45.937 -51.256 5.831\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.364 -33.2 -0.06\n      vertex 27.1 -33.2 0\n      vertex 36.966 -33.2 0.721\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.2 -36.2 -10.501\n      vertex 37.337 -36.2 -9.635\n      vertex 31.06376 -36.2 -10.48639\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 34.27425 -36.2 10.5\n      vertex 31.06376 -36.2 -10.48639\n      vertex 36.829 -36.2 1.587\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 38.452 -33.2 -34.235\n      vertex 37.833 -33.2 -34.855\n      vertex 38.1 -33.2 -25.767\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 36.966 -36.2 2.453\n      vertex 34.27425 -36.2 10.5\n      vertex 36.829 -36.2 1.587\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.364 -36.2 3.234\n      vertex 34.27425 -36.2 10.5\n      vertex 36.966 -36.2 2.453\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 34.27425 -36.2 10.5\n      vertex 37.364 -36.2 3.234\n      vertex 37.984 -36.2 3.853\n    endloop\n  endfacet\n  facet normal 0.89098 0 0.45405\n    outer loop\n      vertex 36.966 -36.2 0.721\n      vertex 37.364 -36.2 -0.06\n      vertex 36.966 -33.2 0.721\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.083 -33.2 -22.635\n      vertex 27.1 -33.2 0\n      vertex 37.481 -33.2 -21.855\n    endloop\n  endfacet\n  facet normal 0.70654 0 -0.70768\n    outer loop\n      vertex 37.364 -36.2 3.234\n      vertex 37.364 -33.2 3.234\n      vertex 37.984 -36.2 3.853\n    endloop\n  endfacet\n  facet normal 0.70654 0 -0.70768\n    outer loop\n      vertex 37.984 -33.2 3.853\n      vertex 37.984 -36.2 3.853\n      vertex 37.364 -33.2 3.234\n    endloop\n  endfacet\n  facet normal 0.89098 0 0.45405\n    outer loop\n      vertex 37.364 -33.2 -0.06\n      vertex 36.966 -33.2 0.721\n      vertex 37.364 -36.2 -0.06\n    endloop\n  endfacet\n  facet normal 0 -0.89121 -0.45359\n    outer loop\n      vertex 34.539 -50.584 11.119\n      vertex 34.539 -50.868 11.677\n      vertex 25.539 -50.584 11.119\n    endloop\n  endfacet\n  facet normal 0.89098 0 -0.45405\n    outer loop\n      vertex 37.364 -36.2 3.234\n      vertex 36.966 -36.2 2.453\n      vertex 36.966 -33.2 2.453\n    endloop\n  endfacet\n  facet normal 0.89098 0 -0.45405\n    outer loop\n      vertex 37.364 -36.2 3.234\n      vertex 36.966 -33.2 2.453\n      vertex 37.364 -33.2 3.234\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.2 -33.2 -10.501\n      vertex 27.1 -33.2 0\n      vertex 37.337 -33.2 -9.635\n    endloop\n  endfacet\n  facet normal 0 -0.70711 -0.70711\n    outer loop\n      vertex 25.539 -50.868 11.677\n      vertex 34.539 -50.868 11.677\n      vertex 25.539 -51.311 12.12\n    endloop\n  endfacet\n  facet normal 0.98772 0 0.15626\n    outer loop\n      vertex 36.829 -33.2 1.587\n      vertex 36.829 -36.2 1.587\n      vertex 36.966 -33.2 0.721\n    endloop\n  endfacet\n  facet normal 0 -0.45295 -0.89154\n    outer loop\n      vertex 25.539 -51.311 12.12\n      vertex 34.539 -51.311 12.12\n      vertex 30.72 -51.87 12.404\n    endloop\n  endfacet\n  facet normal 0.98772 0 -0.15626\n    outer loop\n      vertex 36.966 -33.2 2.453\n      vertex 36.966 -36.2 2.453\n      vertex 36.829 -36.2 1.587\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 38.1 -33.2 -21.235\n      vertex 37.481 -33.2 -21.855\n      vertex 37.735 -33.2 -12.148\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.2 -33.2 -10.501\n      vertex 37.337 -33.2 -11.367\n      vertex 27.1 -33.2 0\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.481 -33.2 -25.148\n      vertex 38.1 -33.2 -25.767\n      vertex 37.833 -33.2 -34.855\n    endloop\n  endfacet\n  facet normal 0.98772 0 0.15626\n    outer loop\n      vertex 36.966 -36.2 0.721\n      vertex 36.966 -33.2 0.721\n      vertex 36.829 -36.2 1.587\n    endloop\n  endfacet\n  facet normal 0 -0.45295 0.89154\n    outer loop\n      vertex 25.539 -51.311 8.88\n      vertex 30.72 -51.87 8.596\n      vertex 34.539 -51.311 8.88\n    endloop\n  endfacet\n  facet normal 0 -0.45295 0.89154\n    outer loop\n      vertex 34.539 -51.311 8.88\n      vertex 30.72 -51.87 8.596\n      vertex 34.539 -51.788 8.63766\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 36.946 -33.2 -23.501\n      vertex 27.1 -33.2 0\n      vertex 37.083 -33.2 -22.635\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.337 -33.2 -11.367\n      vertex 37.735 -33.2 -12.148\n      vertex 37.481 -33.2 -21.855\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 27.1 -33.2 0\n      vertex 36.946 -33.2 -23.501\n      vertex 37.083 -33.2 -24.367\n    endloop\n  endfacet\n  facet normal 0 -0.89121 0.45359\n    outer loop\n      vertex 25.539 -50.584 9.881\n      vertex 34.539 -50.868 9.323\n      vertex 34.539 -50.584 9.881\n    endloop\n  endfacet\n  facet normal 0.98772 0 -0.15626\n    outer loop\n      vertex 36.966 -33.2 2.453\n      vertex 36.829 -36.2 1.587\n      vertex 36.829 -33.2 1.587\n    endloop\n  endfacet\n  facet normal 0 -0.9877 0.15637\n    outer loop\n      vertex 25.539 -50.584 9.881\n      vertex 34.539 -50.584 9.881\n      vertex 34.539 -50.486 10.5\n    endloop\n  endfacet\n  facet normal 0 -0.70711 -0.70711\n    outer loop\n      vertex 34.539 -51.311 12.12\n      vertex 25.539 -51.311 12.12\n      vertex 34.539 -50.868 11.677\n    endloop\n  endfacet\n  facet normal 0 -0.07338 -0.9973\n    outer loop\n      vertex 32.8 21.5208 2.02456\n      vertex 37.8 21.5208 2.02456\n      vertex 37.8 8 3.01941\n    endloop\n  endfacet\n  facet normal 0 -0.45295 -0.89154\n    outer loop\n      vertex 34.539 -51.788 12.36234\n      vertex 30.72 -51.87 12.404\n      vertex 34.539 -51.311 12.12\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.337 -36.2 -11.367\n      vertex 31.06376 -36.2 -10.48639\n      vertex 37.735 -36.2 -12.148\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.364 -33.2 3.234\n      vertex 36.966 -33.2 2.453\n      vertex 26.6 -33.2 20\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 38.765 -33.2 4.251\n      vertex 26.6 -33.2 20\n      vertex 39.63 -33.2 4.388\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 34.019 -36.2 -31.18159\n      vertex 38.452 -36.2 -34.235\n      vertex 38.881 -36.2 -26.165\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 25.4 -51.788 5.6\n      vertex 25.4 -51.788 8.63766\n      vertex 25.539 -51.788 5.71296\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 25.539 -51.788 8.63766\n      vertex 25.539 -51.788 5.71296\n      vertex 25.4 -51.788 8.63766\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.00412 -36.2 10.5\n      vertex 34.27425 -36.2 10.5\n      vertex 38.765 -36.2 4.251\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 25.4 -51.788 12.36234\n      vertex 25.539 -51.788 14.90704\n      vertex 25.539 -51.788 12.36234\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 25.4 -51.788 15\n      vertex 25.539 -51.788 14.90704\n      vertex 25.4 -51.788 12.36234\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 34.616 -51.788 5.6\n      vertex 34.539 -51.788 5.71296\n      vertex 34.616 -51.788 8.63766\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.98688 8.13752 -1.71749\n      vertex 53.941 8.06241 -1.43714\n      vertex 55.2 7.67736 0\n    endloop\n  endfacet\n  facet normal -0.01745 -0.99985 0\n    outer loop\n      vertex 34.183 -41.399 10.6606\n      vertex 34.183 -41.399 10.5\n      vertex 45.13562 -41.59019 10.66059\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.764 7.97239 -1.10114\n      vertex 55.2 7.67736 0\n      vertex 53.941 8.06241 -1.43714\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 34.539 -51.788 12.36234\n      vertex 34.539 -51.788 14.90704\n      vertex 34.616 -51.788 12.36234\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.487 7.90082 -0.83403\n      vertex 55.2 7.67736 0\n      vertex 53.764 7.97239 -1.10114\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.138 7.85499 -0.66298\n      vertex 55.2 7.67736 0\n      vertex 53.487 7.90082 -0.83403\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 46.1 7.67736 0\n      vertex 55.2 7.67736 0\n      vertex 52.752 7.83917 -0.60393\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 46.1 7.67736 0\n      vertex 52.752 7.83917 -0.60393\n      vertex 52.366 7.85499 -0.66298\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 37.8 8 3.9056\n      vertex 37.8 21.5208 2.02456\n      vertex 40.956 18.83489 2.39823\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 40.956 18.83489 2.39823\n      vertex 37.8 21.5208 2.02456\n      vertex 40.89557 19.21993 2.34466\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 40.882 19.30637 2.33263\n      vertex 37.8 21.5208 2.02456\n      vertex 40.94322 19.69723 2.27826\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 40.94322 19.69723 2.27826\n      vertex 37.8 21.5208 2.02456\n      vertex 40.956 19.77882 2.26691\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.487 8.42381 -2.78603\n      vertex 53.486 11.43882 -14.03931\n      vertex 53.138 8.46988 -2.95801\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.764 8.35244 -2.51968\n      vertex 53.6382 11.47814 -14.18608\n      vertex 53.55569 8.40608 -2.71986\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.55569 8.40608 -2.71986\n      vertex 53.486 11.43882 -14.03931\n      vertex 53.487 8.42381 -2.78603\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.80787 8.33011 -2.43633\n      vertex 53.763 11.51035 -14.30631\n      vertex 53.764 8.35244 -2.51968\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 37.8 8 3.9056\n      vertex 41.59237 18.02471 2.51094\n      vertex 41.925 17.85333 2.53478\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 37.8 8 3.9056\n      vertex 41.925 17.85333 2.53478\n      vertex 42.02497 17.83743 2.537\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.941 8.26222 -2.18292\n      vertex 53.763 11.51035 -14.30631\n      vertex 53.80787 8.33011 -2.43633\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 41.23776 18.34046 2.46701\n      vertex 41.504 18.07045 2.50458\n      vertex 37.8 8 3.9056\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 41.504 18.07045 2.50458\n      vertex 41.59237 18.02471 2.51094\n      vertex 37.8 8 3.9056\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 37.8 8 3.9056\n      vertex 40.956 18.83489 2.39823\n      vertex 41.17 18.40899 2.45748\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 41.17 18.40899 2.45748\n      vertex 41.23776 18.34046 2.46701\n      vertex 37.8 8 3.9056\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.138 7.85499 -0.66298\n      vertex 52.752 7.83917 -0.60393\n      vertex 55.2 7.67736 0\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.95612 8.23746 -2.0905\n      vertex 54.002 8.1623 -1.80997\n      vertex 55.2 7.67736 0\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 54.002 8.1623 -1.80997\n      vertex 53.98688 8.13752 -1.71749\n      vertex 55.2 7.67736 0\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.941 8.26222 -2.18292\n      vertex 53.95612 8.23746 -2.0905\n      vertex 55.2 7.67736 0\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 43.614 20.20472 2.20765\n      vertex 46.9 21.60559 2.01276\n      vertex 43.828 19.77882 2.26691\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 43.88871 19.39119 2.32083\n      vertex 43.828 19.77882 2.26691\n      vertex 46.9 21.60559 2.01276\n    endloop\n  endfacet\n  facet normal 0 0.9877 0.15637\n    outer loop\n      vertex 45.11967 -42.493 14.681\n      vertex 34.06431 -42.493 14.681\n      vertex 45.11821 -42.57675 15.21\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 43.902 19.30637 2.33263\n      vertex 46.9 21.60559 2.01276\n      vertex 43.84205 18.9244 2.38577\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 43.84205 18.9244 2.38577\n      vertex 46.9 21.60559 2.01276\n      vertex 43.828 18.83489 2.39823\n    endloop\n  endfacet\n  facet normal 0 0.70711 0.70711\n    outer loop\n      vertex 45.12437 -42.209 14.123\n      vertex 45.12532 -42.15262 14.06662\n      vertex 37.8 -41.766 13.68\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 34.019 -36.2 -31.18159\n      vertex 37.481 -36.2 -25.148\n      vertex 37.083 -36.2 -24.367\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 43.614 18.40899 2.45748\n      vertex 46.9 8 3.9056\n      vertex 43.34925 18.14048 2.49484\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 43.614 18.40899 2.45748\n      vertex 43.828 18.83489 2.39823\n      vertex 46.9 8 3.9056\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 43.28 18.07045 2.50458\n      vertex 46.9 8 3.9056\n      vertex 42.94855 17.89968 2.52834\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 43.34925 18.14048 2.49484\n      vertex 46.9 8 3.9056\n      vertex 43.28 18.07045 2.50458\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 42.859 17.85333 2.53478\n      vertex 42.94855 17.89968 2.52834\n      vertex 46.9 8 3.9056\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.083 -36.2 -22.635\n      vertex 31.06376 -36.2 -10.48639\n      vertex 36.946 -36.2 -23.501\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 42.392 17.77907 2.54512\n      vertex 37.8 8 3.9056\n      vertex 42.02497 17.83743 2.537\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.481 -36.2 -21.855\n      vertex 38.1 -36.2 -21.235\n      vertex 31.06376 -36.2 -10.48639\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 42.859 17.85333 2.53478\n      vertex 46.9 8 3.9056\n      vertex 42.49244 17.79505 2.54289\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 37.8 8 3.9056\n      vertex 42.392 17.77907 2.54512\n      vertex 46.9 8 3.9056\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 42.49244 17.79505 2.54289\n      vertex 46.9 8 3.9056\n      vertex 42.392 17.77907 2.54512\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 41.504 20.54247 2.16067\n      vertex 41.17 20.20472 2.20765\n      vertex 37.8 22.603 1.874\n    endloop\n  endfacet\n  facet normal 0 0.89121 -0.45359\n    outer loop\n      vertex 45.12379 -42.23973 16.41663\n      vertex 45.11963 -42.493 15.919\n      vertex 34.16879 -42.209 16.477\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 41.925 20.75938 2.13049\n      vertex 41.504 20.54247 2.16067\n      vertex 37.8 22.603 1.874\n    endloop\n  endfacet\n  facet normal 0.00793 0.45387 0.89103\n    outer loop\n      vertex 34.22632 -38.93073 19.689\n      vertex 34.24915 -37.62968 19.02608\n      vertex 34.127 -38.929 19.689\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.083 -36.2 -24.367\n      vertex 36.946 -36.2 -23.501\n      vertex 34.019 -36.2 -31.18159\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 34.019 -36.2 -31.18159\n      vertex 36.946 -36.2 -23.501\n      vertex 31.06376 -36.2 -10.48639\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.083 -36.2 -22.635\n      vertex 37.481 -36.2 -21.855\n      vertex 31.06376 -36.2 -10.48639\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.2 -36.2 -10.501\n      vertex 31.06376 -36.2 -10.48639\n      vertex 37.337 -36.2 -11.367\n    endloop\n  endfacet\n  facet normal 0 0.70711 0.70711\n    outer loop\n      vertex 45.13237 -41.766 13.68\n      vertex 37.8 -41.766 13.68\n      vertex 45.12532 -42.15262 14.06662\n    endloop\n  endfacet\n  facet normal 0.89098 0 0.45405\n    outer loop\n      vertex 37.083 -36.2 -24.367\n      vertex 37.481 -36.2 -25.148\n      vertex 37.481 -33.2 -25.148\n    endloop\n  endfacet\n  facet normal 0.89074 0 -0.45451\n    outer loop\n      vertex 37.481 -33.2 -21.855\n      vertex 37.481 -36.2 -21.855\n      vertex 37.083 -36.2 -22.635\n    endloop\n  endfacet\n  facet normal 0.01235 0.70694 0.70717\n    outer loop\n      vertex 34.149 -37.616 19.02\n      vertex 34.24936 -37.61775 19.02\n      vertex 34.168 -36.574 17.978\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 34.27425 -36.2 17.24055\n      vertex 34.27425 -36.2 19.9\n      vertex 34.17415 -36.2 17.24398\n    endloop\n  endfacet\n  facet normal 0.89098 0 0.45405\n    outer loop\n      vertex 37.337 -33.2 -11.367\n      vertex 37.337 -36.2 -11.367\n      vertex 37.735 -36.2 -12.148\n    endloop\n  endfacet\n  facet normal 0.89098 0 0.45405\n    outer loop\n      vertex 37.337 -33.2 -11.367\n      vertex 37.735 -36.2 -12.148\n      vertex 37.735 -33.2 -12.148\n    endloop\n  endfacet\n  facet normal 0.01556 0.89085 0.45404\n    outer loop\n      vertex 34.27425 -36.2 17.24055\n      vertex 34.17415 -36.2 17.24398\n      vertex 34.26765 -36.57574 17.978\n    endloop\n  endfacet\n  facet normal 0.98772 0 0.15626\n    outer loop\n      vertex 37.337 -36.2 -11.367\n      vertex 37.337 -33.2 -11.367\n      vertex 37.2 -36.2 -10.501\n    endloop\n  endfacet\n  facet normal 0 0.45359 -0.89121\n    outer loop\n      vertex 43.008 -41.208 17.204\n      vertex 45.13549 -41.59019 17.00948\n      vertex 45.13241 -41.766 16.92\n    endloop\n  endfacet\n  facet normal 0.89098 0 0.45405\n    outer loop\n      vertex 37.083 -33.2 -24.367\n      vertex 37.083 -36.2 -24.367\n      vertex 37.481 -33.2 -25.148\n    endloop\n  endfacet\n  facet normal 0 0.70711 -0.70711\n    outer loop\n      vertex 45.12436 -42.209 16.477\n      vertex 34.16879 -42.209 16.477\n      vertex 45.13186 -41.79772 16.88828\n    endloop\n  endfacet\n  facet normal 0 0.70711 -0.70711\n    outer loop\n      vertex 45.13186 -41.79772 16.88828\n      vertex 34.16879 -42.209 16.477\n      vertex 45.13241 -41.766 16.92\n    endloop\n  endfacet\n  facet normal 0 0.89121 -0.45359\n    outer loop\n      vertex 45.12436 -42.209 16.477\n      vertex 45.12379 -42.23973 16.41663\n      vertex 34.16879 -42.209 16.477\n    endloop\n  endfacet\n  facet normal 0.98772 0 0.15626\n    outer loop\n      vertex 37.083 -36.2 -24.367\n      vertex 37.083 -33.2 -24.367\n      vertex 36.946 -33.2 -23.501\n    endloop\n  endfacet\n  facet normal 0.98772 0 0.15626\n    outer loop\n      vertex 37.083 -36.2 -24.367\n      vertex 36.946 -33.2 -23.501\n      vertex 36.946 -36.2 -23.501\n    endloop\n  endfacet\n  facet normal 0.98772 0 -0.15626\n    outer loop\n      vertex 37.083 -33.2 -22.635\n      vertex 37.083 -36.2 -22.635\n      vertex 36.946 -36.2 -23.501\n    endloop\n  endfacet\n  facet normal 0.98772 0 -0.15626\n    outer loop\n      vertex 37.083 -33.2 -22.635\n      vertex 36.946 -36.2 -23.501\n      vertex 36.946 -33.2 -23.501\n    endloop\n  endfacet\n  facet normal 0.89074 0 -0.45451\n    outer loop\n      vertex 37.083 -36.2 -22.635\n      vertex 37.083 -33.2 -22.635\n      vertex 37.481 -33.2 -21.855\n    endloop\n  endfacet\n  facet normal 0.98772 0 0.15626\n    outer loop\n      vertex 37.337 -33.2 -11.367\n      vertex 37.2 -33.2 -10.501\n      vertex 37.2 -36.2 -10.501\n    endloop\n  endfacet\n  facet normal -0.99984 0.01785 0\n    outer loop\n      vertex 34.101 -40.385 19.92\n      vertex 34.127 -38.929 19.689\n      vertex 34.10841 -39.97 17.204\n    endloop\n  endfacet\n  facet normal 0.98772 0 -0.15626\n    outer loop\n      vertex 37.2 -33.2 -10.501\n      vertex 37.337 -33.2 -9.635\n      vertex 37.2 -36.2 -10.501\n    endloop\n  endfacet\n  facet normal -0.99984 0.01785 0\n    outer loop\n      vertex 34.11198 -39.76991 17.10216\n      vertex 34.10841 -39.97 17.204\n      vertex 34.127 -38.929 19.689\n    endloop\n  endfacet\n  facet normal -0.00793 -0.45386 0.89104\n    outer loop\n      vertex 34.076 -41.841 19.689\n      vertex 45.105 -43.347 19.02\n      vertex 45.128 -42.034 19.689\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 35.0753 9.443 -18.955\n      vertex 33.25 8.93375 -17.05474\n      vertex 30.2 9.443 -18.955\n    endloop\n  endfacet\n  facet normal -0.00274 -0.15665 0.98765\n    outer loop\n      vertex 34.183 -41.399 19.7594\n      vertex 34.19855 -40.5128 19.9\n      vertex 34.101 -40.385 19.92\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 32.863 8.9179 -16.99558\n      vertex 30.2 9.443 -18.955\n      vertex 33.20235 8.93177 -17.04736\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 32.82001 8.91225 -16.97451\n      vertex 30.2 9.443 -18.955\n      vertex 32.863 8.9179 -16.99558\n    endloop\n  endfacet\n  facet normal -0.00274 -0.15665 0.98765\n    outer loop\n      vertex 45.13562 -41.59019 19.75941\n      vertex 34.183 -41.399 19.7594\n      vertex 45.128 -42.034 19.689\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.58934 8.91988 -17.00297\n      vertex 33.25 8.93375 -17.05474\n      vertex 35.0753 9.443 -18.955\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.20235 8.93177 -17.04736\n      vertex 30.2 9.443 -18.955\n      vertex 33.25 8.93375 -17.05474\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 52.363 12.00867 -16.16623\n      vertex 52.53732 12.0159 -16.19325\n      vertex 46.9 12.534 -18.127\n    endloop\n  endfacet\n  facet normal -0.98754 0 0.15737\n    outer loop\n      vertex 42.365 -33.2 -50.467\n      vertex 42.365 -36.2 -50.467\n      vertex 42.503 -36.2 -49.601\n    endloop\n  endfacet\n  facet normal -0.98754 0 0.15737\n    outer loop\n      vertex 42.365 -33.2 -50.467\n      vertex 42.503 -36.2 -49.601\n      vertex 42.503 -33.2 -49.601\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 34.616 -51.788 15\n      vertex 34.616 -51.788 12.36234\n      vertex 34.539 -51.788 14.90704\n    endloop\n  endfacet\n  facet normal 0.00274 0.15665 0.98765\n    outer loop\n      vertex 34.22632 -38.93073 19.689\n      vertex 34.127 -38.929 19.689\n      vertex 34.22609 -38.94382 19.69108\n    endloop\n  endfacet\n  facet normal -0.89098 0 0.45405\n    outer loop\n      vertex 41.967 -33.2 -51.248\n      vertex 41.967 -36.2 -51.248\n      vertex 42.365 -36.2 -50.467\n    endloop\n  endfacet\n  facet normal -0.89098 0 0.45405\n    outer loop\n      vertex 41.967 -33.2 -51.248\n      vertex 42.365 -36.2 -50.467\n      vertex 42.365 -33.2 -50.467\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 25.4 -51.788 15\n      vertex 34.616 -51.788 15\n      vertex 25.539 -51.788 14.90704\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 34.539 -51.788 14.90704\n      vertex 25.539 -51.788 14.90704\n      vertex 34.616 -51.788 15\n    endloop\n  endfacet\n  facet normal -0.70711 0 0.70711\n    outer loop\n      vertex 41.348 -33.2 -51.867\n      vertex 41.348 -36.2 -51.867\n      vertex 41.967 -36.2 -51.248\n    endloop\n  endfacet\n  facet normal -0.70711 0 0.70711\n    outer loop\n      vertex 41.348 -33.2 -51.867\n      vertex 41.967 -36.2 -51.248\n      vertex 41.967 -33.2 -51.248\n    endloop\n  endfacet\n  facet normal -0.45405 0 0.89098\n    outer loop\n      vertex 40.567 -33.2 -52.265\n      vertex 40.567 -36.2 -52.265\n      vertex 41.348 -36.2 -51.867\n    endloop\n  endfacet\n  facet normal -0.45405 0 0.89098\n    outer loop\n      vertex 40.567 -33.2 -52.265\n      vertex 41.348 -36.2 -51.867\n      vertex 41.348 -33.2 -51.867\n    endloop\n  endfacet\n  facet normal 0.00274 0.15665 0.98765\n    outer loop\n      vertex 34.101 -40.385 19.92\n      vertex 34.20298 -40.26068 19.9\n      vertex 34.127 -38.929 19.689\n    endloop\n  endfacet\n  facet normal 0.00274 0.15665 0.98765\n    outer loop\n      vertex 34.127 -38.929 19.689\n      vertex 34.20298 -40.26068 19.9\n      vertex 34.22609 -38.94382 19.69108\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 34.539 -51.788 8.63766\n      vertex 34.616 -51.788 8.63766\n      vertex 34.539 -51.788 5.71296\n    endloop\n  endfacet\n  facet normal -0.15737 0 0.98754\n    outer loop\n      vertex 39.701 -33.2 -52.403\n      vertex 39.701 -36.2 -52.403\n      vertex 40.567 -36.2 -52.265\n    endloop\n  endfacet\n  facet normal -0.15737 0 0.98754\n    outer loop\n      vertex 39.701 -33.2 -52.403\n      vertex 40.567 -36.2 -52.265\n      vertex 40.567 -33.2 -52.265\n    endloop\n  endfacet\n  facet normal 0.45451 0 -0.89074\n    outer loop\n      vertex 38.835 -33.2 -46.937\n      vertex 38.835 -36.2 -46.937\n      vertex 38.055 -36.2 -47.335\n    endloop\n  endfacet\n  facet normal 0.45451 0 -0.89074\n    outer loop\n      vertex 38.835 -33.2 -46.937\n      vertex 38.055 -36.2 -47.335\n      vertex 38.055 -33.2 -47.335\n    endloop\n  endfacet\n  facet normal 0.00793 0.45387 0.89103\n    outer loop\n      vertex 34.24915 -37.62968 19.02608\n      vertex 34.149 -37.616 19.02\n      vertex 34.127 -38.929 19.689\n    endloop\n  endfacet\n  facet normal 0.15626 0 -0.98772\n    outer loop\n      vertex 38.835 -36.2 -46.937\n      vertex 38.835 -33.2 -46.937\n      vertex 39.701 -33.2 -46.8\n    endloop\n  endfacet\n  facet normal 0.15626 0 -0.98772\n    outer loop\n      vertex 38.835 -36.2 -46.937\n      vertex 39.701 -33.2 -46.8\n      vertex 39.701 -36.2 -46.8\n    endloop\n  endfacet\n  facet normal 0.00793 0.45386 0.89104\n    outer loop\n      vertex 34.149 -37.616 19.02\n      vertex 34.24915 -37.62968 19.02608\n      vertex 34.24936 -37.61775 19.02\n    endloop\n  endfacet\n  facet normal -0.15626 0 -0.98772\n    outer loop\n      vertex 40.567 -33.2 -46.937\n      vertex 40.567 -36.2 -46.937\n      vertex 39.701 -36.2 -46.8\n    endloop\n  endfacet\n  facet normal -0.15626 0 -0.98772\n    outer loop\n      vertex 40.567 -33.2 -46.937\n      vertex 39.701 -36.2 -46.8\n      vertex 39.701 -33.2 -46.8\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.137 12.00867 -16.16623\n      vertex 55.2 12.534 -18.127\n      vertex 52.92433 12.01736 -16.19868\n    endloop\n  endfacet\n  facet normal -0.45405 0 -0.89098\n    outer loop\n      vertex 41.348 -33.2 -47.335\n      vertex 41.348 -36.2 -47.335\n      vertex 40.567 -36.2 -46.937\n    endloop\n  endfacet\n  facet normal -0.45405 0 -0.89098\n    outer loop\n      vertex 41.348 -33.2 -47.335\n      vertex 40.567 -36.2 -46.937\n      vertex 40.567 -33.2 -46.937\n    endloop\n  endfacet\n  facet normal -0.70768 0 -0.70654\n    outer loop\n      vertex 41.967 -33.2 -47.955\n      vertex 41.967 -36.2 -47.955\n      vertex 41.348 -36.2 -47.335\n    endloop\n  endfacet\n  facet normal -0.70768 0 -0.70654\n    outer loop\n      vertex 41.967 -33.2 -47.955\n      vertex 41.348 -36.2 -47.335\n      vertex 41.348 -33.2 -47.335\n    endloop\n  endfacet\n  facet normal -0.89074 0 -0.45451\n    outer loop\n      vertex 42.365 -33.2 -48.735\n      vertex 42.365 -36.2 -48.735\n      vertex 41.967 -36.2 -47.955\n    endloop\n  endfacet\n  facet normal -0.89074 0 -0.45451\n    outer loop\n      vertex 42.365 -33.2 -48.735\n      vertex 41.967 -36.2 -47.955\n      vertex 41.967 -33.2 -47.955\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.486 11.9627 -15.99467\n      vertex 55.2 12.534 -18.127\n      vertex 53.2942 11.98802 -16.08918\n    endloop\n  endfacet\n  facet normal -0.98754 0 -0.15737\n    outer loop\n      vertex 42.365 -36.2 -48.735\n      vertex 42.365 -33.2 -48.735\n      vertex 42.503 -36.2 -49.601\n    endloop\n  endfacet\n  facet normal -0.98754 0 -0.15737\n    outer loop\n      vertex 42.503 -33.2 -49.601\n      vertex 42.503 -36.2 -49.601\n      vertex 42.365 -33.2 -48.735\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.2942 11.98802 -16.08918\n      vertex 55.2 12.534 -18.127\n      vertex 53.137 12.00867 -16.16623\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.61079 11.93038 -15.87403\n      vertex 55.2 12.534 -18.127\n      vertex 53.486 11.9627 -15.99467\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.763 11.89105 -15.72725\n      vertex 55.2 12.534 -18.127\n      vertex 53.61079 11.93038 -15.87403\n    endloop\n  endfacet\n  facet normal 0.15626 0 0.98772\n    outer loop\n      vertex 39.233 -33.2 -39.165\n      vertex 39.233 -36.2 -39.165\n      vertex 40.099 -36.2 -39.302\n    endloop\n  endfacet\n  facet normal 0.15626 0 0.98772\n    outer loop\n      vertex 39.233 -33.2 -39.165\n      vertex 40.099 -36.2 -39.302\n      vertex 40.099 -33.2 -39.302\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.941 11.80078 -15.39032\n      vertex 55.2 12.534 -18.127\n      vertex 53.763 11.89105 -15.72725\n    endloop\n  endfacet\n  facet normal 0.45405 0 0.89098\n    outer loop\n      vertex 38.452 -33.2 -38.767\n      vertex 38.452 -36.2 -38.767\n      vertex 39.233 -36.2 -39.165\n    endloop\n  endfacet\n  facet normal 0.45405 0 0.89098\n    outer loop\n      vertex 38.452 -33.2 -38.767\n      vertex 39.233 -36.2 -39.165\n      vertex 39.233 -33.2 -39.165\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 54.002 11.70084 -15.0173\n      vertex 55.2 12.534 -18.127\n      vertex 53.941 11.80078 -15.39032\n    endloop\n  endfacet\n  facet normal 0.70711 0 0.70711\n    outer loop\n      vertex 37.833 -33.2 -38.148\n      vertex 37.833 -36.2 -38.148\n      vertex 38.452 -36.2 -38.767\n    endloop\n  endfacet\n  facet normal 0.70711 0 0.70711\n    outer loop\n      vertex 37.833 -33.2 -38.148\n      vertex 38.452 -36.2 -38.767\n      vertex 38.452 -33.2 -38.767\n    endloop\n  endfacet\n  facet normal 0.89098 0 0.45405\n    outer loop\n      vertex 37.833 -33.2 -38.148\n      vertex 37.435 -36.2 -37.367\n      vertex 37.833 -36.2 -38.148\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.941 11.60065 -14.64335\n      vertex 53.86082 11.55996 -14.49146\n      vertex 55.2 7.67736 0\n    endloop\n  endfacet\n  facet normal -0.70654 0 0.70768\n    outer loop\n      vertex 41.745 -33.2 -38.767\n      vertex 41.745 -36.2 -38.767\n      vertex 42.365 -36.2 -38.148\n    endloop\n  endfacet\n  facet normal -0.70654 0 0.70768\n    outer loop\n      vertex 41.745 -33.2 -38.767\n      vertex 42.365 -36.2 -38.148\n      vertex 42.365 -33.2 -38.148\n    endloop\n  endfacet\n  facet normal -0.45451 0 0.89074\n    outer loop\n      vertex 40.965 -33.2 -39.165\n      vertex 40.965 -36.2 -39.165\n      vertex 41.745 -36.2 -38.767\n    endloop\n  endfacet\n  facet normal -0.45451 0 0.89074\n    outer loop\n      vertex 40.965 -33.2 -39.165\n      vertex 41.745 -36.2 -38.767\n      vertex 41.745 -33.2 -38.767\n    endloop\n  endfacet\n  facet normal -0.15626 0 0.98772\n    outer loop\n      vertex 40.099 -33.2 -39.302\n      vertex 40.099 -36.2 -39.302\n      vertex 40.965 -36.2 -39.165\n    endloop\n  endfacet\n  facet normal -0.15626 0 0.98772\n    outer loop\n      vertex 40.099 -33.2 -39.302\n      vertex 40.965 -36.2 -39.165\n      vertex 40.965 -33.2 -39.165\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 51.741 8.35244 -2.51968\n      vertex 51.80941 8.37017 -2.58583\n      vertex 52.014 11.43882 -14.03931\n    endloop\n  endfacet\n  facet normal 0.89074 0 -0.45451\n    outer loop\n      vertex 37.833 -33.2 -34.855\n      vertex 37.833 -36.2 -34.855\n      vertex 37.435 -36.2 -35.635\n    endloop\n  endfacet\n  facet normal 0.89074 0 -0.45451\n    outer loop\n      vertex 37.833 -33.2 -34.855\n      vertex 37.435 -36.2 -35.635\n      vertex 37.435 -33.2 -35.635\n    endloop\n  endfacet\n  facet normal 0.70768 0 -0.70654\n    outer loop\n      vertex 38.452 -33.2 -34.235\n      vertex 38.452 -36.2 -34.235\n      vertex 37.833 -36.2 -34.855\n    endloop\n  endfacet\n  facet normal 0.70768 0 -0.70654\n    outer loop\n      vertex 38.452 -33.2 -34.235\n      vertex 37.833 -36.2 -34.855\n      vertex 37.833 -33.2 -34.855\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 46.1 7.67736 0\n      vertex 51.741 8.35244 -2.51968\n      vertex 52.014 11.43882 -14.03931\n    endloop\n  endfacet\n  facet normal 0.45405 0 -0.89098\n    outer loop\n      vertex 39.233 -33.2 -33.837\n      vertex 39.233 -36.2 -33.837\n      vertex 38.452 -36.2 -34.235\n    endloop\n  endfacet\n  facet normal 0.45405 0 -0.89098\n    outer loop\n      vertex 39.233 -33.2 -33.837\n      vertex 38.452 -36.2 -34.235\n      vertex 38.452 -33.2 -34.235\n    endloop\n  endfacet\n  facet normal 0.15626 0 -0.98772\n    outer loop\n      vertex 39.233 -36.2 -33.837\n      vertex 39.233 -33.2 -33.837\n      vertex 40.099 -33.2 -33.7\n    endloop\n  endfacet\n  facet normal 0.15626 0 -0.98772\n    outer loop\n      vertex 39.233 -36.2 -33.837\n      vertex 40.099 -33.2 -33.7\n      vertex 40.099 -36.2 -33.7\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.86082 11.55996 -14.49146\n      vertex 53.763 11.51035 -14.30631\n      vertex 55.2 7.67736 0\n    endloop\n  endfacet\n  facet normal -0.15626 0 -0.98772\n    outer loop\n      vertex 40.965 -33.2 -33.837\n      vertex 40.965 -36.2 -33.837\n      vertex 40.099 -36.2 -33.7\n    endloop\n  endfacet\n  facet normal -0.15626 0 -0.98772\n    outer loop\n      vertex 40.965 -33.2 -33.837\n      vertex 40.099 -36.2 -33.7\n      vertex 40.099 -33.2 -33.7\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.486 11.43882 -14.03931\n      vertex 53.55569 8.40608 -2.71986\n      vertex 53.6382 11.47814 -14.18608\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.637 8.9179 -16.99558\n      vertex 33.58934 8.91988 -17.00297\n      vertex 35.0753 9.443 -18.955\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.637 8.9179 -16.99558\n      vertex 35.0753 9.443 -18.955\n      vertex 33.94306 8.87754 -16.84498\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.6382 11.47814 -14.18608\n      vertex 53.764 8.35244 -2.51968\n      vertex 53.763 11.51035 -14.30631\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 51.80941 8.37017 -2.58583\n      vertex 52.017 8.42381 -2.78603\n      vertex 52.014 11.43882 -14.03931\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 52.017 8.42381 -2.78603\n      vertex 52.366 8.46988 -2.95801\n      vertex 52.363 11.39274 -13.86733\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 52.363 11.39274 -13.86733\n      vertex 52.014 11.43882 -14.03931\n      vertex 52.017 8.42381 -2.78603\n    endloop\n  endfacet\n  facet normal -0.99985 0.01727 0.00042\n    outer loop\n      vertex 34.13103 -38.66043 15.7701\n      vertex 34.13068 -38.684 15.919\n      vertex 34.17386 -36.2 16.56919\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.986 8.8719 -16.82394\n      vertex 35.0753 9.443 -18.955\n      vertex 34.2289 8.80913 -16.5897\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 55.2 12.534 -18.127\n      vertex 54.002 11.70084 -15.0173\n      vertex 55.2 7.67736 0\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.941 11.60065 -14.64335\n      vertex 55.2 7.67736 0\n      vertex 54.002 11.70084 -15.0173\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 55.2 7.67736 0\n      vertex 53.763 11.51035 -14.30631\n      vertex 53.941 8.26222 -2.18292\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 34.503 8.60981 -15.84596\n      vertex 34.49537 8.62211 -15.89185\n      vertex 51.559 8.70977 -16.21894\n    endloop\n  endfacet\n  facet normal -0.99985 0.0174 0.00001\n    outer loop\n      vertex 34.13206 -38.60025 15.21\n      vertex 34.13232 -38.586 15.3\n      vertex 34.17384 -36.2 15.21\n    endloop\n  endfacet\n  facet normal -0.99985 0.0174 0.00001\n    outer loop\n      vertex 34.17386 -36.2 16.56919\n      vertex 34.17384 -36.2 15.21\n      vertex 34.13232 -38.586 15.3\n    endloop\n  endfacet\n  facet normal -0.99985 0.0174 0.00001\n    outer loop\n      vertex 34.17386 -36.2 16.56919\n      vertex 34.13232 -38.586 15.3\n      vertex 34.13103 -38.66043 15.7701\n    endloop\n  endfacet\n  facet normal 0.45444 -0.23067 0.86039\n    outer loop\n      vertex 52.366 8.46988 -2.95801\n      vertex 52.017 5.33204 -3.61494\n      vertex 52.366 5.37813 -3.78692\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 34.17384 -36.2 15.21\n      vertex 34.17386 -36.2 16.56919\n      vertex 26.6 -36.2 20\n    endloop\n  endfacet\n  facet normal 0.15642 -0.25577 0.954\n    outer loop\n      vertex 52.752 5.39395 -3.84597\n      vertex 52.752 8.4857 -3.01706\n      vertex 52.366 5.37813 -3.78692\n    endloop\n  endfacet\n  facet normal 0.15642 -0.25577 0.954\n    outer loop\n      vertex 52.366 8.46988 -2.95801\n      vertex 52.366 5.37813 -3.78692\n      vertex 52.752 8.4857 -3.01706\n    endloop\n  endfacet\n  facet normal -0.15642 -0.25577 0.954\n    outer loop\n      vertex 52.752 5.39395 -3.84597\n      vertex 53.138 5.37813 -3.78692\n      vertex 52.752 8.4857 -3.01706\n    endloop\n  endfacet\n  facet normal -0.15642 -0.25577 0.954\n    outer loop\n      vertex 53.138 8.46988 -2.95801\n      vertex 52.752 8.4857 -3.01706\n      vertex 53.138 5.37813 -3.78692\n    endloop\n  endfacet\n  facet normal -0.99985 0.0174 -0.00001\n    outer loop\n      vertex 34.13206 -38.60025 15.21\n      vertex 34.17384 -36.2 15.21\n      vertex 34.13062 -38.684 14.681\n    endloop\n  endfacet\n  facet normal -0.45444 -0.23067 0.86039\n    outer loop\n      vertex 53.138 5.37813 -3.78692\n      vertex 53.487 5.33204 -3.61494\n      vertex 53.138 8.46988 -2.95801\n    endloop\n  endfacet\n  facet normal -0.99985 0.0174 -0.00001\n    outer loop\n      vertex 34.17386 -36.2 13.85081\n      vertex 34.13062 -38.684 14.681\n      vertex 34.17384 -36.2 15.21\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 34.263 8.41947 -15.13569\n      vertex 34.503 7.394 -11.30915\n      vertex 34.02007 8.35653 -14.90084\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 34.28491 8.43059 -15.17717\n      vertex 34.441 8.50982 -15.47284\n      vertex 51.498 8.60981 -15.84593\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 34.441 8.50982 -15.47284\n      vertex 34.44863 8.52215 -15.51884\n      vertex 51.498 8.60981 -15.84593\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 34.02007 8.35653 -14.90084\n      vertex 34.503 7.394 -11.30915\n      vertex 33.986 8.34773 -14.86798\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 25.539 -51.788 5.71296\n      vertex 34.539 -51.788 5.71296\n      vertex 34.616 -51.788 5.6\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 25.539 -51.788 5.71296\n      vertex 34.616 -51.788 5.6\n      vertex 25.4 -51.788 5.6\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.637 8.30164 -14.69601\n      vertex 34.503 7.394 -11.30915\n      vertex 33.25 8.28582 -14.63696\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.637 8.30164 -14.69601\n      vertex 33.986 8.34773 -14.86798\n      vertex 34.503 7.394 -11.30915\n    endloop\n  endfacet\n  facet normal -0.99985 0.01727 0.00042\n    outer loop\n      vertex 34.12746 -38.88013 16.30301\n      vertex 34.17386 -36.2 16.56919\n      vertex 34.13068 -38.684 15.919\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 34.49537 8.62211 -15.89185\n      vertex 34.441 8.71 -16.21979\n      vertex 51.559 8.70977 -16.21894\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 51.559 8.70977 -16.21894\n      vertex 51.498 8.60981 -15.84593\n      vertex 34.503 8.60981 -15.84596\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 35.0753 9.443 -18.955\n      vertex 51.559 8.70977 -16.21894\n      vertex 34.263 8.80029 -16.55671\n    endloop\n  endfacet\n  facet normal 0 -0.9877 -0.15637\n    outer loop\n      vertex 45.23247 -38.684 15.919\n      vertex 34.13103 -38.66043 15.7701\n      vertex 45.23417 -38.586 15.3\n    endloop\n  endfacet\n  facet normal -0.45451 0 -0.89074\n    outer loop\n      vertex 41.745 -33.2 -34.235\n      vertex 41.745 -36.2 -34.235\n      vertex 40.965 -36.2 -33.837\n    endloop\n  endfacet\n  facet normal -0.45451 0 -0.89074\n    outer loop\n      vertex 41.745 -33.2 -34.235\n      vertex 40.965 -36.2 -33.837\n      vertex 40.965 -33.2 -33.837\n    endloop\n  endfacet\n  facet normal -0.70711 0 -0.70711\n    outer loop\n      vertex 42.365 -33.2 -34.855\n      vertex 42.365 -36.2 -34.855\n      vertex 41.745 -36.2 -34.235\n    endloop\n  endfacet\n  facet normal -0.70711 0 -0.70711\n    outer loop\n      vertex 42.365 -33.2 -34.855\n      vertex 41.745 -36.2 -34.235\n      vertex 41.745 -33.2 -34.235\n    endloop\n  endfacet\n  facet normal 0 -0.15818 0.98741\n    outer loop\n      vertex 30.72 -51.87 8.596\n      vertex 25.4 -51.87 8.596\n      vertex 25.4 -52.488 8.497\n    endloop\n  endfacet\n  facet normal -0.89074 0 -0.45451\n    outer loop\n      vertex 42.763 -36.2 -35.635\n      vertex 42.365 -36.2 -34.855\n      vertex 42.365 -33.2 -34.855\n    endloop\n  endfacet\n  facet normal 0 -0.45295 0.89154\n    outer loop\n      vertex 30.72 -51.87 8.596\n      vertex 25.539 -51.788 8.63766\n      vertex 25.4 -51.87 8.596\n    endloop\n  endfacet\n  facet normal 0 -0.45295 0.89154\n    outer loop\n      vertex 25.4 -51.788 8.63766\n      vertex 25.4 -51.87 8.596\n      vertex 25.539 -51.788 8.63766\n    endloop\n  endfacet\n  facet normal -0.98772 0 0.15626\n    outer loop\n      vertex 42.763 -36.2 -37.367\n      vertex 42.9 -33.2 -36.501\n      vertex 42.763 -33.2 -37.367\n    endloop\n  endfacet\n  facet normal 0 -0.45295 -0.89154\n    outer loop\n      vertex 25.4 -51.788 12.36234\n      vertex 25.539 -51.788 12.36234\n      vertex 25.4 -51.87 12.404\n    endloop\n  endfacet\n  facet normal -0.89098 0 0.45405\n    outer loop\n      vertex 42.763 -33.2 -37.367\n      vertex 42.365 -33.2 -38.148\n      vertex 42.763 -36.2 -37.367\n    endloop\n  endfacet\n  facet normal -0.89098 0 0.45405\n    outer loop\n      vertex 42.365 -36.2 -38.148\n      vertex 42.763 -36.2 -37.367\n      vertex 42.365 -33.2 -38.148\n    endloop\n  endfacet\n  facet normal -0.89074 0 -0.45451\n    outer loop\n      vertex 42.763 -33.2 -35.635\n      vertex 42.763 -36.2 -35.635\n      vertex 42.365 -33.2 -34.855\n    endloop\n  endfacet\n  facet normal -0.98772 0 -0.15626\n    outer loop\n      vertex 42.9 -33.2 -36.501\n      vertex 42.9 -36.2 -36.501\n      vertex 42.763 -36.2 -35.635\n    endloop\n  endfacet\n  facet normal -0.98772 0 -0.15626\n    outer loop\n      vertex 42.9 -33.2 -36.501\n      vertex 42.763 -36.2 -35.635\n      vertex 42.763 -33.2 -35.635\n    endloop\n  endfacet\n  facet normal 0 -0.9877 0.15637\n    outer loop\n      vertex 34.13062 -38.684 14.681\n      vertex 45.23247 -38.684 14.681\n      vertex 34.13206 -38.60025 15.21\n    endloop\n  endfacet\n  facet normal -0.98772 0 0.15626\n    outer loop\n      vertex 42.9 -33.2 -36.501\n      vertex 42.763 -36.2 -37.367\n      vertex 42.9 -36.2 -36.501\n    endloop\n  endfacet\n  facet normal 0 0.9877 0.15637\n    outer loop\n      vertex 34.616 -54.491 10.5\n      vertex 34.616 -54.393 9.881\n      vertex 25.4 -54.491 10.5\n    endloop\n  endfacet\n  facet normal 0 -0.9877 -0.15637\n    outer loop\n      vertex 34.13232 -38.586 15.3\n      vertex 45.23417 -38.586 15.3\n      vertex 34.13103 -38.66043 15.7701\n    endloop\n  endfacet\n  facet normal 0 0.89121 0.45359\n    outer loop\n      vertex 25.4 -54.393 9.881\n      vertex 34.616 -54.393 9.881\n      vertex 25.4 -54.109 9.323\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.411 -33.2 -24.367\n      vertex 42.548 -33.2 -23.501\n      vertex 51.8 -33.2 -30.37797\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.013 -36.2 -21.855\n      vertex 42.411 -36.2 -22.635\n      vertex 52.2 -36.2 -10.48639\n    endloop\n  endfacet\n  facet normal 0 0.70711 0.70711\n    outer loop\n      vertex 34.616 -54.109 9.323\n      vertex 25.4 -53.666 8.88\n      vertex 25.4 -54.109 9.323\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 39.747 -33.2 -26.303\n      vertex 40.613 -33.2 -26.165\n      vertex 40.099 -33.2 -33.7\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 39.233 -33.2 -33.837\n      vertex 38.452 -33.2 -34.235\n      vertex 38.881 -33.2 -26.165\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 38.1 -33.2 -25.767\n      vertex 38.881 -33.2 -26.165\n      vertex 38.452 -33.2 -34.235\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.613 -33.2 -26.165\n      vertex 41.394 -33.2 -25.767\n      vertex 40.965 -33.2 -33.837\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 27.1 -33.2 0\n      vertex 37.337 -33.2 -11.367\n      vertex 37.481 -33.2 -21.855\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.735 -33.2 -12.148\n      vertex 38.355 -33.2 -12.767\n      vertex 38.1 -33.2 -21.235\n    endloop\n  endfacet\n  facet normal -0.99985 0.0174 0\n    outer loop\n      vertex 34.06285 -42.57675 15.21\n      vertex 34.019 -45.096 15.21\n      vertex 34.0626 -42.591 15.3\n    endloop\n  endfacet\n  facet normal -0.99985 0.0174 0\n    outer loop\n      vertex 34.019 -45.096 15.21\n      vertex 34.023 -44.866 16.665\n      vertex 34.0626 -42.591 15.3\n    endloop\n  endfacet\n  facet normal -0.99985 0.0174 0\n    outer loop\n      vertex 34.06424 -42.49669 15.89568\n      vertex 34.0626 -42.591 15.3\n      vertex 34.023 -44.866 16.665\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 34.441 8.71 -16.21979\n      vertex 34.263 8.80029 -16.55671\n      vertex 51.559 8.70977 -16.21894\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.986 8.8719 -16.82394\n      vertex 33.94306 8.87754 -16.84498\n      vertex 35.0753 9.443 -18.955\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 34.263 8.80029 -16.55671\n      vertex 34.2289 8.80913 -16.5897\n      vertex 35.0753 9.443 -18.955\n    endloop\n  endfacet\n  facet normal -0.99985 0.01729 -0.00003\n    outer loop\n      vertex 34.07881 -41.6651 16.97135\n      vertex 34.07707 -41.766 16.92\n      vertex 34.053 -43.154 19.02\n    endloop\n  endfacet\n  facet normal -0.99985 0.01729 -0.00003\n    outer loop\n      vertex 34.07 -42.17571 16.51029\n      vertex 34.035 -44.197 17.978\n      vertex 34.07707 -41.766 16.92\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 41.394 -33.2 -21.235\n      vertex 40.613 -33.2 -20.837\n      vertex 40.867 -33.2 -13.165\n    endloop\n  endfacet\n  facet normal -0.99985 0.01729 -0.00003\n    outer loop\n      vertex 34.053 -43.154 19.02\n      vertex 34.07707 -41.766 16.92\n      vertex 34.035 -44.197 17.978\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 38.355 -33.2 -12.767\n      vertex 39.135 -33.2 -13.165\n      vertex 38.881 -33.2 -20.837\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.487 5.33204 -3.61494\n      vertex 33.138 5.37813 -3.78692\n      vertex 34.503 7.394 -11.30915\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.138 5.37813 -3.78692\n      vertex 32.752 5.39395 -3.84597\n      vertex 34.503 7.394 -11.30915\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 34.503 7.394 -11.30915\n      vertex 34.263 8.41947 -15.13569\n      vertex 51.498 8.60981 -15.84593\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 38.881 -33.2 -20.837\n      vertex 38.1 -33.2 -21.235\n      vertex 38.355 -33.2 -12.767\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 51.498 8.60981 -15.84593\n      vertex 51.559 8.50959 -15.47199\n      vertex 34.503 7.394 -11.30915\n    endloop\n  endfacet\n  facet normal -0.99985 0.01717 0\n    outer loop\n      vertex 34.08972 -41.04183 17.23058\n      vertex 34.076 -41.841 19.689\n      vertex 34.0975 -40.589 17.303\n    endloop\n  endfacet\n  facet normal -0.99985 0.01717 0\n    outer loop\n      vertex 34.101 -40.385 19.92\n      vertex 34.0975 -40.589 17.303\n      vertex 34.076 -41.841 19.689\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.67405 5.28375 -3.43474\n      vertex 33.487 5.33204 -3.61494\n      vertex 51.559 8.50959 -15.47199\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.487 5.33204 -3.61494\n      vertex 34.503 7.394 -11.30915\n      vertex 51.559 8.50959 -15.47199\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.764 5.26059 -3.3483\n      vertex 33.67405 5.28375 -3.43474\n      vertex 51.559 8.50959 -15.47199\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.941 5.17042 -3.01184\n      vertex 33.8835 5.19975 -3.12129\n      vertex 51.737 8.41924 -15.13485\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.001 -33.2 -13.303\n      vertex 40.867 -33.2 -13.165\n      vertex 40.613 -33.2 -20.837\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.013 -33.2 -21.855\n      vertex 41.394 -33.2 -21.235\n      vertex 41.648 -33.2 -12.767\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.867 -33.2 -13.165\n      vertex 41.648 -33.2 -12.767\n      vertex 41.394 -33.2 -21.235\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.613 -33.2 -20.837\n      vertex 39.747 -33.2 -20.7\n      vertex 40.001 -33.2 -13.303\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 39.135 -33.2 -13.165\n      vertex 40.001 -33.2 -13.303\n      vertex 39.747 -33.2 -20.7\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 39.747 -33.2 -20.7\n      vertex 38.881 -33.2 -20.837\n      vertex 39.135 -33.2 -13.165\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.98219 5.10296 -2.76013\n      vertex 33.941 5.17042 -3.01184\n      vertex 51.54319 5.13795 -2.89068\n    endloop\n  endfacet\n  facet normal -0.99985 0.01747 0.0001\n    outer loop\n      vertex 34.07881 -41.6651 16.97135\n      vertex 34.053 -43.154 19.02\n      vertex 34.08682 -41.208 17.204\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.965 -33.2 -33.837\n      vertex 40.099 -33.2 -33.7\n      vertex 40.613 -33.2 -26.165\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 40.099 -33.2 -33.7\n      vertex 39.233 -33.2 -33.837\n      vertex 39.747 -33.2 -26.303\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 38.881 -33.2 -26.165\n      vertex 39.747 -33.2 -26.303\n      vertex 39.233 -33.2 -33.837\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.411 -33.2 -24.367\n      vertex 51.8 -33.2 -30.37797\n      vertex 42.013 -33.2 -25.148\n    endloop\n  endfacet\n  facet normal -0.99985 0.01747 0.0001\n    outer loop\n      vertex 34.08972 -41.04183 17.23058\n      vertex 34.08682 -41.208 17.204\n      vertex 34.076 -41.841 19.689\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.487 4.80894 -1.66297\n      vertex 33.764 4.88052 -1.93008\n      vertex 34.002 4.36328 0\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.487 4.80894 -1.66297\n      vertex 34.002 4.36328 0\n      vertex 33.138 4.7631 -1.49193\n    endloop\n  endfacet\n  facet normal -0.99985 0.01747 0.0001\n    outer loop\n      vertex 34.053 -43.154 19.02\n      vertex 34.076 -41.841 19.689\n      vertex 34.08682 -41.208 17.204\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 41.648 -33.2 -12.767\n      vertex 42.267 -33.2 -12.148\n      vertex 42.013 -33.2 -21.855\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 52.2 -33.2 20\n      vertex 51.8 -33.2 -30.37797\n      vertex 42.802 -33.2 -10.501\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.665 -33.2 -11.367\n      vertex 51.8 -33.2 -30.37797\n      vertex 42.267 -33.2 -12.148\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 34.263 8.41947 -15.13569\n      vertex 34.28491 8.43059 -15.17717\n      vertex 51.498 8.60981 -15.84593\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.665 -33.2 -11.367\n      vertex 42.802 -33.2 -10.501\n      vertex 51.8 -33.2 -30.37797\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.802 -33.2 -10.501\n      vertex 42.665 -33.2 -9.635\n      vertex 52.2 -33.2 20\n    endloop\n  endfacet\n  facet normal 0 0.15793 -0.98745\n    outer loop\n      vertex 34.0975 -40.589 17.303\n      vertex 43.008 -41.208 17.204\n      vertex 34.08972 -41.04183 17.23058\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.8835 5.19975 -3.12129\n      vertex 33.764 5.26059 -3.3483\n      vertex 51.737 8.41924 -15.13485\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.548 -33.2 -23.501\n      vertex 42.411 -33.2 -22.635\n      vertex 51.8 -33.2 -30.37797\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.013 -33.2 -21.855\n      vertex 42.267 -33.2 -12.148\n      vertex 42.411 -33.2 -22.635\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 41.745 -33.2 -34.235\n      vertex 41.394 -33.2 -25.767\n      vertex 51.8 -33.2 -30.37797\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.013 -33.2 -25.148\n      vertex 51.8 -33.2 -30.37797\n      vertex 41.394 -33.2 -25.767\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 42.411 -33.2 -22.635\n      vertex 42.267 -33.2 -12.148\n      vertex 51.8 -33.2 -30.37797\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 32.863 12.00881 -16.16679\n      vertex 30.2 12.534 -18.127\n      vertex 32.67122 11.98363 -16.0728\n    endloop\n  endfacet\n  facet normal -0.99985 0.01748 0.00023\n    outer loop\n      vertex 34.06424 -42.49669 15.89568\n      vertex 34.023 -44.866 16.665\n      vertex 34.06431 -42.493 15.919\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.03735 12.01594 -16.19339\n      vertex 30.2 12.534 -18.127\n      vertex 32.863 12.00881 -16.16679\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 39.747 -36.2 -26.303\n      vertex 40.099 -36.2 -33.7\n      vertex 40.613 -36.2 -26.165\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.42434 12.01764 -16.19975\n      vertex 30.2 12.534 -18.127\n      vertex 33.25 12.02477 -16.22635\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.637 12.00881 -16.16679\n      vertex 30.2 12.534 -18.127\n      vertex 33.42434 12.01764 -16.19975\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.25 12.02477 -16.22635\n      vertex 30.2 12.534 -18.127\n      vertex 33.03735 12.01594 -16.19339\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.986 11.9629 -15.99543\n      vertex 46.9 12.534 -18.127\n      vertex 33.79425 11.98808 -16.08941\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.79425 11.98808 -16.08941\n      vertex 46.9 12.534 -18.127\n      vertex 33.637 12.00881 -16.16679\n    endloop\n  endfacet\n  facet normal -0.99985 0.01748 0.00023\n    outer loop\n      vertex 34.07 -42.17571 16.51029\n      vertex 34.0694 -42.209 16.477\n      vertex 34.035 -44.197 17.978\n    endloop\n  endfacet\n  facet normal -0.99985 0.01748 0.00023\n    outer loop\n      vertex 34.023 -44.866 16.665\n      vertex 34.035 -44.197 17.978\n      vertex 34.0694 -42.209 16.477\n    endloop\n  endfacet\n  facet normal -0.99985 0.01748 0.00023\n    outer loop\n      vertex 34.0694 -42.209 16.477\n      vertex 34.06431 -42.493 15.919\n      vertex 34.023 -44.866 16.665\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 38.881 -36.2 -20.837\n      vertex 39.747 -36.2 -20.7\n      vertex 39.135 -36.2 -13.165\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.735 -36.2 -12.148\n      vertex 31.06376 -36.2 -10.48639\n      vertex 38.1 -36.2 -21.235\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.867 -36.2 -13.165\n      vertex 40.001 -36.2 -13.303\n      vertex 40.613 -36.2 -20.837\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 34.1108 11.93066 -15.87509\n      vertex 46.9 12.534 -18.127\n      vertex 33.986 11.9629 -15.99543\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 34.263 11.8912 -15.72781\n      vertex 46.9 12.534 -18.127\n      vertex 34.1108 11.93066 -15.87509\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 34.441 11.80093 -15.39088\n      vertex 46.9 12.534 -18.127\n      vertex 34.263 11.8912 -15.72781\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 34.46894 11.75579 -15.22239\n      vertex 46.9 12.534 -18.127\n      vertex 34.441 11.80093 -15.39088\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 34.503 11.70088 -15.01744\n      vertex 46.9 12.534 -18.127\n      vertex 34.46894 11.75579 -15.22239\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 46.1 7.67736 0\n      vertex 46.9 12.534 -18.127\n      vertex 34.441 11.6008 -14.64391\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 46.9 -36.2 -31.18159\n      vertex 52.2 -36.2 -10.48639\n      vertex 42.548 -36.2 -23.501\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 34.36081 11.5601 -14.492\n      vertex 46.1 7.67736 0\n      vertex 34.441 11.6008 -14.64391\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 34.47507 11.65585 -14.84938\n      vertex 34.441 11.6008 -14.64391\n      vertex 46.9 12.534 -18.127\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.735 -36.2 -12.148\n      vertex 38.1 -36.2 -21.235\n      vertex 38.355 -36.2 -12.767\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 31.997 11.14241 -12.933\n      vertex 32.863 11.39277 -13.86747\n      vertex 32.514 11.43885 -14.03945\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 34.263 11.5105 -14.30687\n      vertex 46.1 7.67736 0\n      vertex 34.36081 11.5601 -14.492\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 34.13818 11.47817 -14.1862\n      vertex 46.1 7.67736 0\n      vertex 34.263 11.5105 -14.30687\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.613 -36.2 -20.837\n      vertex 41.394 -36.2 -21.235\n      vertex 40.867 -36.2 -13.165\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.013 -36.2 -21.855\n      vertex 41.648 -36.2 -12.767\n      vertex 41.394 -36.2 -21.235\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 39.747 -36.2 -20.7\n      vertex 40.613 -36.2 -20.837\n      vertex 40.001 -36.2 -13.303\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.001 -36.2 -13.303\n      vertex 39.135 -36.2 -13.165\n      vertex 39.747 -36.2 -20.7\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 39.135 -36.2 -13.165\n      vertex 38.355 -36.2 -12.767\n      vertex 38.881 -36.2 -20.837\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 38.1 -36.2 -21.235\n      vertex 38.881 -36.2 -20.837\n      vertex 38.355 -36.2 -12.767\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 31.997 11.14241 -12.933\n      vertex 33.25 11.37695 -13.80842\n      vertex 32.863 11.39277 -13.86747\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 41.394 -36.2 -25.767\n      vertex 40.613 -36.2 -26.165\n      vertex 40.965 -36.2 -33.837\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 38.881 -36.2 -26.165\n      vertex 39.233 -36.2 -33.837\n      vertex 39.747 -36.2 -26.303\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 38.1 -36.2 -25.767\n      vertex 34.019 -36.2 -31.18159\n      vertex 38.881 -36.2 -26.165\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.481 -36.2 -25.148\n      vertex 34.019 -36.2 -31.18159\n      vertex 38.1 -36.2 -25.767\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 41.745 -36.2 -34.235\n      vertex 46.9 -36.2 -31.18159\n      vertex 41.394 -36.2 -25.767\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.98688 8.13752 -1.71749\n      vertex 33.941 8.06241 -1.43714\n      vertex 46.1 7.67736 0\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.764 7.97239 -1.10114\n      vertex 46.1 7.67736 0\n      vertex 33.941 8.06241 -1.43714\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.487 7.90082 -0.83403\n      vertex 46.1 7.67736 0\n      vertex 33.764 7.97239 -1.10114\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.138 7.85499 -0.66298\n      vertex 32.752 7.83917 -0.60393\n      vertex 46.1 7.67736 0\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 30.2 7.67736 0\n      vertex 46.1 7.67736 0\n      vertex 32.752 7.83917 -0.60393\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 41.648 -36.2 -12.767\n      vertex 42.013 -36.2 -21.855\n      vertex 42.267 -36.2 -12.148\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 41.648 -36.2 -12.767\n      vertex 40.867 -36.2 -13.165\n      vertex 41.394 -36.2 -21.235\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.138 8.46988 -2.95801\n      vertex 31.997 11.14241 -12.933\n      vertex 32.752 8.4857 -3.01706\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.802 -36.2 -10.501\n      vertex 52.2 -36.2 -10.48639\n      vertex 42.665 -36.2 -9.635\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.487 8.42381 -2.78603\n      vertex 33.637 11.39277 -13.86747\n      vertex 33.138 8.46988 -2.95801\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.764 8.35244 -2.51968\n      vertex 33.637 11.39277 -13.86747\n      vertex 33.55569 8.40608 -2.71986\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.55569 8.40608 -2.71986\n      vertex 33.637 11.39277 -13.86747\n      vertex 33.487 8.42381 -2.78603\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.941 8.26222 -2.18292\n      vertex 46.1 7.67736 0\n      vertex 33.80787 8.33011 -2.43633\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 46.1 7.67736 0\n      vertex 33.637 11.39277 -13.86747\n      vertex 33.764 8.35244 -2.51968\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.665 -36.2 -11.367\n      vertex 42.267 -36.2 -12.148\n      vertex 52.2 -36.2 -10.48639\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.013 -36.2 -21.855\n      vertex 52.2 -36.2 -10.48639\n      vertex 42.267 -36.2 -12.148\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.665 -36.2 -11.367\n      vertex 52.2 -36.2 -10.48639\n      vertex 42.802 -36.2 -10.501\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.95612 8.23746 -2.0905\n      vertex 46.1 7.67736 0\n      vertex 33.941 8.26222 -2.18292\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.80787 8.33011 -2.43633\n      vertex 46.1 7.67736 0\n      vertex 33.764 8.35244 -2.51968\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.411 -36.2 -22.635\n      vertex 42.548 -36.2 -23.501\n      vertex 52.2 -36.2 -10.48639\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.411 -36.2 -24.367\n      vertex 42.013 -36.2 -25.148\n      vertex 46.9 -36.2 -31.18159\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.965 -36.2 -33.837\n      vertex 41.745 -36.2 -34.235\n      vertex 41.394 -36.2 -25.767\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 42.548 -36.2 -23.501\n      vertex 42.411 -36.2 -24.367\n      vertex 46.9 -36.2 -31.18159\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.487 7.90082 -0.83403\n      vertex 33.138 7.85499 -0.66298\n      vertex 46.1 7.67736 0\n    endloop\n  endfacet\n  facet normal 0.15737 0 0.98754\n    outer loop\n      vertex 38.881 -33.2 -26.165\n      vertex 38.881 -36.2 -26.165\n      vertex 39.747 -36.2 -26.303\n    endloop\n  endfacet\n  facet normal 0.15737 0 0.98754\n    outer loop\n      vertex 38.881 -33.2 -26.165\n      vertex 39.747 -36.2 -26.303\n      vertex 39.747 -33.2 -26.303\n    endloop\n  endfacet\n  facet normal 0.45405 0 0.89098\n    outer loop\n      vertex 38.1 -33.2 -25.767\n      vertex 38.1 -36.2 -25.767\n      vertex 38.881 -36.2 -26.165\n    endloop\n  endfacet\n  facet normal 0.45405 0 0.89098\n    outer loop\n      vertex 38.1 -33.2 -25.767\n      vertex 38.881 -36.2 -26.165\n      vertex 38.881 -33.2 -26.165\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 34.002 8.1623 -1.80997\n      vertex 33.98688 8.13752 -1.71749\n      vertex 46.1 7.67736 0\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.95612 8.23746 -2.0905\n      vertex 34.002 8.1623 -1.80997\n      vertex 46.1 7.67736 0\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.637 11.39277 -13.86747\n      vertex 33.25 11.37695 -13.80842\n      vertex 33.138 8.46988 -2.95801\n    endloop\n  endfacet\n  facet normal 0.70711 0 0.70711\n    outer loop\n      vertex 38.1 -36.2 -25.767\n      vertex 38.1 -33.2 -25.767\n      vertex 37.481 -36.2 -25.148\n    endloop\n  endfacet\n  facet normal 0.70711 0 0.70711\n    outer loop\n      vertex 37.481 -33.2 -25.148\n      vertex 37.481 -36.2 -25.148\n      vertex 38.1 -33.2 -25.767\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 31.997 11.14241 -12.933\n      vertex 33.138 8.46988 -2.95801\n      vertex 33.25 11.37695 -13.80842\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 30.2 12.534 -18.127\n      vertex 30.2 7.67736 0\n      vertex 31.997 11.14241 -12.933\n    endloop\n  endfacet\n  facet normal -0.70711 0 0.70711\n    outer loop\n      vertex 41.394 -33.2 -25.767\n      vertex 41.394 -36.2 -25.767\n      vertex 42.013 -36.2 -25.148\n    endloop\n  endfacet\n  facet normal -0.70711 0 0.70711\n    outer loop\n      vertex 41.394 -33.2 -25.767\n      vertex 42.013 -36.2 -25.148\n      vertex 42.013 -33.2 -25.148\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 30.2 12.534 -18.127\n      vertex 33.637 12.00881 -16.16679\n      vertex 46.9 12.534 -18.127\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.986 11.43885 -14.03945\n      vertex 46.1 7.67736 0\n      vertex 34.13818 11.47817 -14.1862\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 34.503 11.70088 -15.01744\n      vertex 34.47507 11.65585 -14.84938\n      vertex 46.9 12.534 -18.127\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 33.986 11.43885 -14.03945\n      vertex 33.637 11.39277 -13.86747\n      vertex 46.1 7.67736 0\n    endloop\n  endfacet\n  facet normal -0.45405 0 0.89098\n    outer loop\n      vertex 40.613 -33.2 -26.165\n      vertex 40.613 -36.2 -26.165\n      vertex 41.394 -36.2 -25.767\n    endloop\n  endfacet\n  facet normal -0.45405 0 0.89098\n    outer loop\n      vertex 40.613 -33.2 -26.165\n      vertex 41.394 -36.2 -25.767\n      vertex 41.394 -33.2 -25.767\n    endloop\n  endfacet\n  facet normal -0.15737 0 0.98754\n    outer loop\n      vertex 39.747 -33.2 -26.303\n      vertex 39.747 -36.2 -26.303\n      vertex 40.613 -36.2 -26.165\n    endloop\n  endfacet\n  facet normal -0.15737 0 0.98754\n    outer loop\n      vertex 39.747 -33.2 -26.303\n      vertex 40.613 -36.2 -26.165\n      vertex 40.613 -33.2 -26.165\n    endloop\n  endfacet\n  facet normal 0.45248 -0.23096 0.86135\n    outer loop\n      vertex 32.863 12.00881 -16.16679\n      vertex 32.82001 8.91225 -16.97451\n      vertex 32.863 8.9179 -16.99558\n    endloop\n  endfacet\n  facet normal 0.70768 0 -0.70654\n    outer loop\n      vertex 37.481 -36.2 -21.855\n      vertex 37.481 -33.2 -21.855\n      vertex 38.1 -36.2 -21.235\n    endloop\n  endfacet\n  facet normal 0.70768 0 -0.70654\n    outer loop\n      vertex 38.1 -33.2 -21.235\n      vertex 38.1 -36.2 -21.235\n      vertex 37.481 -33.2 -21.855\n    endloop\n  endfacet\n  facet normal 0.45405 0 -0.89098\n    outer loop\n      vertex 38.881 -33.2 -20.837\n      vertex 38.881 -36.2 -20.837\n      vertex 38.1 -36.2 -21.235\n    endloop\n  endfacet\n  facet normal 0.45405 0 -0.89098\n    outer loop\n      vertex 38.881 -33.2 -20.837\n      vertex 38.1 -36.2 -21.235\n      vertex 38.1 -33.2 -21.235\n    endloop\n  endfacet\n  facet normal 0.15603 -0.25582 0.95405\n    outer loop\n      vertex 32.863 12.00881 -16.16679\n      vertex 32.863 8.9179 -16.99558\n      vertex 33.03735 12.01594 -16.19339\n    endloop\n  endfacet\n  facet normal 0.15603 -0.25582 0.95405\n    outer loop\n      vertex 33.20235 8.93177 -17.04736\n      vertex 33.03735 12.01594 -16.19339\n      vertex 32.863 8.9179 -16.99558\n    endloop\n  endfacet\n  facet normal 0.15626 0 -0.98772\n    outer loop\n      vertex 38.881 -36.2 -20.837\n      vertex 38.881 -33.2 -20.837\n      vertex 39.747 -33.2 -20.7\n    endloop\n  endfacet\n  facet normal 0.15626 0 -0.98772\n    outer loop\n      vertex 38.881 -36.2 -20.837\n      vertex 39.747 -33.2 -20.7\n      vertex 39.747 -36.2 -20.7\n    endloop\n  endfacet\n  facet normal -0.01725 -0.98758 0.15616\n    outer loop\n      vertex 45.075 -45.059 16.665\n      vertex 34.023 -44.866 16.665\n      vertex 34.019 -45.096 15.21\n    endloop\n  endfacet\n  facet normal -0.15626 0 -0.98772\n    outer loop\n      vertex 40.613 -33.2 -20.837\n      vertex 40.613 -36.2 -20.837\n      vertex 39.747 -36.2 -20.7\n    endloop\n  endfacet\n  facet normal -0.15626 0 -0.98772\n    outer loop\n      vertex 40.613 -33.2 -20.837\n      vertex 39.747 -36.2 -20.7\n      vertex 39.747 -33.2 -20.7\n    endloop\n  endfacet\n  facet normal 0.15843 -0.2556 0.95371\n    outer loop\n      vertex 33.25 8.93375 -17.05474\n      vertex 33.25 12.02477 -16.22635\n      vertex 33.20235 8.93177 -17.04736\n    endloop\n  endfacet\n  facet normal -0.45405 0 -0.89098\n    outer loop\n      vertex 41.394 -33.2 -21.235\n      vertex 41.394 -36.2 -21.235\n      vertex 40.613 -36.2 -20.837\n    endloop\n  endfacet\n  facet normal -0.45405 0 -0.89098\n    outer loop\n      vertex 41.394 -33.2 -21.235\n      vertex 40.613 -36.2 -20.837\n      vertex 40.613 -33.2 -20.837\n    endloop\n  endfacet\n  facet normal -0.15843 -0.25572 0.95368\n    outer loop\n      vertex 33.637 12.00881 -16.16679\n      vertex 33.58934 8.91988 -17.00297\n      vertex 33.637 8.9179 -16.99558\n    endloop\n  endfacet\n  facet normal -0.70768 0 -0.70654\n    outer loop\n      vertex 42.013 -33.2 -21.855\n      vertex 42.013 -36.2 -21.855\n      vertex 41.394 -36.2 -21.235\n    endloop\n  endfacet\n  facet normal -0.70768 0 -0.70654\n    outer loop\n      vertex 42.013 -33.2 -21.855\n      vertex 41.394 -36.2 -21.235\n      vertex 41.394 -33.2 -21.235\n    endloop\n  endfacet\n  facet normal -0.89074 0 -0.45451\n    outer loop\n      vertex 42.411 -33.2 -22.635\n      vertex 42.411 -36.2 -22.635\n      vertex 42.013 -36.2 -21.855\n    endloop\n  endfacet\n  facet normal -0.89074 0 -0.45451\n    outer loop\n      vertex 42.411 -33.2 -22.635\n      vertex 42.013 -36.2 -21.855\n      vertex 42.013 -33.2 -21.855\n    endloop\n  endfacet\n  facet normal -0.98772 0 -0.15626\n    outer loop\n      vertex 42.548 -36.2 -23.501\n      vertex 42.411 -36.2 -22.635\n      vertex 42.411 -33.2 -22.635\n    endloop\n  endfacet\n  facet normal -0.98772 0 -0.15626\n    outer loop\n      vertex 42.548 -36.2 -23.501\n      vertex 42.411 -33.2 -22.635\n      vertex 42.548 -33.2 -23.501\n    endloop\n  endfacet\n  facet normal -0.45391 -0.23077 0.86064\n    outer loop\n      vertex 33.94306 8.87754 -16.84498\n      vertex 33.79425 11.98808 -16.08941\n      vertex 33.637 8.9179 -16.99558\n    endloop\n  endfacet\n  facet normal -0.01234 -0.70661 0.7075\n    outer loop\n      vertex 34.035 -44.197 17.978\n      vertex 45.086 -44.39 17.978\n      vertex 34.053 -43.154 19.02\n    endloop\n  endfacet\n  facet normal -0.45248 -0.23088 0.86137\n    outer loop\n      vertex 33.986 11.9629 -15.99543\n      vertex 33.94306 8.87754 -16.84498\n      vertex 33.986 8.8719 -16.82394\n    endloop\n  endfacet\n  facet normal -0.89098 0 0.45405\n    outer loop\n      vertex 42.013 -33.2 -25.148\n      vertex 42.013 -36.2 -25.148\n      vertex 42.411 -36.2 -24.367\n    endloop\n  endfacet\n  facet normal -0.89098 0 0.45405\n    outer loop\n      vertex 42.013 -33.2 -25.148\n      vertex 42.411 -36.2 -24.367\n      vertex 42.411 -33.2 -24.367\n    endloop\n  endfacet\n  facet normal -0.70775 -0.18299 0.68235\n    outer loop\n      vertex 34.1108 11.93066 -15.87509\n      vertex 34.2289 8.80913 -16.5897\n      vertex 34.263 11.8912 -15.72781\n    endloop\n  endfacet\n  facet normal -0.70775 -0.18299 0.68235\n    outer loop\n      vertex 34.263 8.80029 -16.55671\n      vertex 34.263 11.8912 -15.72781\n      vertex 34.2289 8.80913 -16.5897\n    endloop\n  endfacet\n  facet normal 0.15737 0 0.98754\n    outer loop\n      vertex 40.001 -36.2 -13.303\n      vertex 40.001 -33.2 -13.303\n      vertex 39.135 -33.2 -13.165\n    endloop\n  endfacet\n  facet normal 0.15737 0 0.98754\n    outer loop\n      vertex 40.001 -36.2 -13.303\n      vertex 39.135 -33.2 -13.165\n      vertex 39.135 -36.2 -13.165\n    endloop\n  endfacet\n  facet normal 0.45451 0 0.89074\n    outer loop\n      vertex 39.135 -36.2 -13.165\n      vertex 39.135 -33.2 -13.165\n      vertex 38.355 -33.2 -12.767\n    endloop\n  endfacet\n  facet normal 0.45451 0 0.89074\n    outer loop\n      vertex 39.135 -36.2 -13.165\n      vertex 38.355 -33.2 -12.767\n      vertex 38.355 -36.2 -12.767\n    endloop\n  endfacet\n  facet normal -0.00793 -0.45386 0.89104\n    outer loop\n      vertex 34.053 -43.154 19.02\n      vertex 45.105 -43.347 19.02\n      vertex 34.076 -41.841 19.689\n    endloop\n  endfacet\n  facet normal 0.70654 0 0.70768\n    outer loop\n      vertex 37.735 -33.2 -12.148\n      vertex 37.735 -36.2 -12.148\n      vertex 38.355 -33.2 -12.767\n    endloop\n  endfacet\n  facet normal 0.70654 0 0.70768\n    outer loop\n      vertex 38.355 -36.2 -12.767\n      vertex 38.355 -33.2 -12.767\n      vertex 37.735 -36.2 -12.148\n    endloop\n  endfacet\n  facet normal -0.70652 -0.18322 0.68357\n    outer loop\n      vertex 34.2289 8.80913 -16.5897\n      vertex 34.1108 11.93066 -15.87509\n      vertex 33.986 8.8719 -16.82394\n    endloop\n  endfacet\n  facet normal -0.45405 0 0.89098\n    outer loop\n      vertex 40.867 -36.2 -13.165\n      vertex 41.648 -33.2 -12.767\n      vertex 40.867 -33.2 -13.165\n    endloop\n  endfacet\n  facet normal -0.15737 0 0.98754\n    outer loop\n      vertex 40.867 -36.2 -13.165\n      vertex 40.867 -33.2 -13.165\n      vertex 40.001 -33.2 -13.303\n    endloop\n  endfacet\n  facet normal -0.15737 0 0.98754\n    outer loop\n      vertex 40.867 -36.2 -13.165\n      vertex 40.001 -33.2 -13.303\n      vertex 40.001 -36.2 -13.303\n    endloop\n  endfacet\n  facet normal -0.89098 0 0.45405\n    outer loop\n      vertex 42.665 -36.2 -11.367\n      vertex 42.665 -33.2 -11.367\n      vertex 42.267 -36.2 -12.148\n    endloop\n  endfacet\n  facet normal -0.89098 0 0.45405\n    outer loop\n      vertex 42.267 -33.2 -12.148\n      vertex 42.267 -36.2 -12.148\n      vertex 42.665 -33.2 -11.367\n    endloop\n  endfacet\n  facet normal -0.70711 0 0.70711\n    outer loop\n      vertex 42.267 -36.2 -12.148\n      vertex 42.267 -33.2 -12.148\n      vertex 41.648 -33.2 -12.767\n    endloop\n  endfacet\n  facet normal -0.70711 0 0.70711\n    outer loop\n      vertex 42.267 -36.2 -12.148\n      vertex 41.648 -33.2 -12.767\n      vertex 41.648 -36.2 -12.767\n    endloop\n  endfacet\n  facet normal -0.45405 0 0.89098\n    outer loop\n      vertex 41.648 -36.2 -12.767\n      vertex 41.648 -33.2 -12.767\n      vertex 40.867 -36.2 -13.165\n    endloop\n  endfacet\n  facet normal -0.98772 0 0.15626\n    outer loop\n      vertex 42.411 -36.2 -24.367\n      vertex 42.548 -36.2 -23.501\n      vertex 42.548 -33.2 -23.501\n    endloop\n  endfacet\n  facet normal -0.98772 0 0.15626\n    outer loop\n      vertex 42.411 -36.2 -24.367\n      vertex 42.548 -33.2 -23.501\n      vertex 42.411 -33.2 -24.367\n    endloop\n  endfacet\n  facet normal -0.89073 -0.11774 0.43903\n    outer loop\n      vertex 34.263 11.8912 -15.72781\n      vertex 34.263 8.80029 -16.55671\n      vertex 34.441 8.71 -16.21979\n    endloop\n  endfacet\n  facet normal -0.98772 0 -0.15626\n    outer loop\n      vertex 42.802 -33.2 -10.501\n      vertex 42.802 -36.2 -10.501\n      vertex 42.665 -33.2 -9.635\n    endloop\n  endfacet\n  facet normal -0.98772 0 -0.15626\n    outer loop\n      vertex 42.665 -36.2 -9.635\n      vertex 42.665 -33.2 -9.635\n      vertex 42.802 -36.2 -10.501\n    endloop\n  endfacet\n  facet normal -0.98772 0 0.15626\n    outer loop\n      vertex 42.802 -36.2 -10.501\n      vertex 42.802 -33.2 -10.501\n      vertex 42.665 -33.2 -11.367\n    endloop\n  endfacet\n  facet normal -0.98772 0 0.15626\n    outer loop\n      vertex 42.802 -36.2 -10.501\n      vertex 42.665 -33.2 -11.367\n      vertex 42.665 -36.2 -11.367\n    endloop\n  endfacet\n  facet normal -0.98742 -0.04096 0.15274\n    outer loop\n      vertex 34.49537 8.62211 -15.89185\n      vertex 34.46894 11.75579 -15.22239\n      vertex 34.441 8.71 -16.21979\n    endloop\n  endfacet\n  facet normal -0.98736 -0.04104 0.15312\n    outer loop\n      vertex 34.503 8.60981 -15.84596\n      vertex 34.503 11.70088 -15.01744\n      vertex 34.49537 8.62211 -15.89185\n    endloop\n  endfacet\n  facet normal -0.98736 0.04104 -0.15312\n    outer loop\n      vertex 34.47507 11.65585 -14.84938\n      vertex 34.503 8.60981 -15.84596\n      vertex 34.44863 8.52215 -15.51884\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 51.559 8.50959 -15.47199\n      vertex 51.58089 8.49849 -15.43054\n      vertex 33.764 5.26059 -3.3483\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 34.44863 8.52215 -15.51884\n      vertex 34.503 8.60981 -15.84596\n      vertex 51.498 8.60981 -15.84593\n    endloop\n  endfacet\n  facet normal 0 0.70711 -0.70711\n    outer loop\n      vertex 34.0694 -42.209 16.477\n      vertex 34.07 -42.17571 16.51029\n      vertex 34.16879 -42.209 16.477\n    endloop\n  endfacet\n  facet normal -0.98742 0.04096 -0.15274\n    outer loop\n      vertex 34.441 8.50982 -15.47284\n      vertex 34.441 11.6008 -14.64391\n      vertex 34.44863 8.52215 -15.51884\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 52.2 -36.2 -58\n      vertex 26.6 -36.2 -58\n      vertex 52.2 -33.2 -58\n    endloop\n  endfacet\n  facet normal -0.99985 0.01755 0\n    outer loop\n      vertex 34.27425 -36.2 19.9\n      vertex 34.22632 -38.93073 19.689\n      vertex 34.22609 -38.94382 19.69108\n    endloop\n  endfacet\n  facet normal 0 0.25875 -0.96594\n    outer loop\n      vertex 35.0753 9.443 -18.955\n      vertex 46.9 12.534 -18.127\n      vertex 55.2 9.443 -18.955\n    endloop\n  endfacet\n  facet normal -0.99985 0.01755 0\n    outer loop\n      vertex 34.22609 -38.94382 19.69108\n      vertex 34.20298 -40.26068 19.9\n      vertex 34.27425 -36.2 19.9\n    endloop\n  endfacet\n  facet normal -0.70652 0.18322 -0.68357\n    outer loop\n      vertex 33.986 8.34773 -14.86798\n      vertex 33.986 11.43885 -14.03945\n      vertex 34.02007 8.35653 -14.90084\n    endloop\n  endfacet\n  facet normal 0 0.25875 -0.96594\n    outer loop\n      vertex 55.2 12.534 -18.127\n      vertex 55.2 9.443 -18.955\n      vertex 46.9 12.534 -18.127\n    endloop\n  endfacet\n  facet normal -0.70742 0.18305 -0.68268\n    outer loop\n      vertex 34.02007 8.35653 -14.90084\n      vertex 34.13818 11.47817 -14.1862\n      vertex 34.263 8.41947 -15.13569\n    endloop\n  endfacet\n  facet normal -0.99985 0.01755 0\n    outer loop\n      vertex 34.183 -41.399 19.7594\n      vertex 34.183 -41.399 19.9\n      vertex 34.19855 -40.5128 19.9\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 52.2 -36.2 -58\n      vertex 52.2 -36.2 -10.48639\n      vertex 46.9 -36.2 -31.18159\n    endloop\n  endfacet\n  facet normal 0.15603 0.25573 -0.95408\n    outer loop\n      vertex 32.863 8.30164 -14.69601\n      vertex 32.863 11.39277 -13.86747\n      vertex 33.25 8.28582 -14.63696\n    endloop\n  endfacet\n  facet normal -0.99985 0.01755 0\n    outer loop\n      vertex 34.27425 -36.2 19.9\n      vertex 34.24936 -37.61775 19.02\n      vertex 34.24915 -37.62968 19.02608\n    endloop\n  endfacet\n  facet normal -0.99985 0.01755 0\n    outer loop\n      vertex 34.22632 -38.93073 19.689\n      vertex 34.27425 -36.2 19.9\n      vertex 34.24915 -37.62968 19.02608\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 51.563 4.97056 -2.26607\n      vertex 51.741 4.88052 -1.93008\n      vertex 34.002 4.36328 0\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 51.52181 5.03807 -2.51797\n      vertex 51.563 4.97056 -2.26607\n      vertex 34.002 4.36328 0\n    endloop\n  endfacet\n  facet normal -0.99985 0.01755 0\n    outer loop\n      vertex 34.27425 -36.2 19.9\n      vertex 34.27425 -36.2 17.24055\n      vertex 34.26765 -36.57574 17.978\n    endloop\n  endfacet\n  facet normal -0.99985 0.01755 0\n    outer loop\n      vertex 34.27425 -36.2 19.9\n      vertex 34.26765 -36.57574 17.978\n      vertex 34.24936 -37.61775 19.02\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 34.002 4.36328 0\n      vertex 33.764 4.88052 -1.93008\n      vertex 51.502 5.0705 -2.639\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.941 4.97056 -2.26607\n      vertex 33.96081 5.003 -2.38713\n      vertex 51.502 5.0705 -2.639\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.764 4.88052 -1.93008\n      vertex 33.941 4.97056 -2.26607\n      vertex 51.502 5.0705 -2.639\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.96081 5.003 -2.38713\n      vertex 34.002 5.0705 -2.639\n      vertex 51.502 5.0705 -2.639\n    endloop\n  endfacet\n  facet normal -0.15603 0.25573 -0.95408\n    outer loop\n      vertex 33.25 11.37695 -13.80842\n      vertex 33.637 11.39277 -13.86747\n      vertex 33.25 8.28582 -14.63696\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 34.27425 -36.2 19.9\n      vertex 40.00412 -36.2 19.9\n      vertex 26.6 -36.2 20\n    endloop\n  endfacet\n  facet normal -0.00274 -0.15665 0.98765\n    outer loop\n      vertex 34.19855 -40.5128 19.9\n      vertex 45.153 -40.578 19.92\n      vertex 34.101 -40.385 19.92\n    endloop\n  endfacet\n  facet normal 0.15843 -0.2556 0.95371\n    outer loop\n      vertex 33.03735 12.01594 -16.19339\n      vertex 33.20235 8.93177 -17.04736\n      vertex 33.25 12.02477 -16.22635\n    endloop\n  endfacet\n  facet normal 0.00274 0.15665 0.98765\n    outer loop\n      vertex 45.153 -40.578 19.92\n      vertex 44.19837 -40.43523 19.9\n      vertex 34.101 -40.385 19.92\n    endloop\n  endfacet\n  facet normal -0.15843 -0.25572 0.95368\n    outer loop\n      vertex 33.42434 12.01764 -16.19975\n      vertex 33.58934 8.91988 -17.00297\n      vertex 33.637 12.00881 -16.16679\n    endloop\n  endfacet\n  facet normal 0 0.9877 0.15637\n    outer loop\n      vertex 25.4 -54.393 9.881\n      vertex 25.4 -54.491 10.5\n      vertex 34.616 -54.393 9.881\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 44.19837 -40.43523 19.9\n      vertex 40.00412 -36.2 19.9\n      vertex 34.20298 -40.26068 19.9\n    endloop\n  endfacet\n  facet normal 0 0.89121 0.45359\n    outer loop\n      vertex 34.616 -54.109 9.323\n      vertex 25.4 -54.109 9.323\n      vertex 34.616 -54.393 9.881\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 34.183 -41.399 19.9\n      vertex 45.15084 -40.70406 19.9\n      vertex 34.19855 -40.5128 19.9\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 45.182 -41.591 19.9\n      vertex 45.15084 -40.70406 19.9\n      vertex 34.183 -41.399 19.9\n    endloop\n  endfacet\n  facet normal 0 0.70711 -0.70711\n    outer loop\n      vertex 34.616 -54.109 11.677\n      vertex 25.4 -54.109 11.677\n      vertex 34.616 -53.666 12.12\n    endloop\n  endfacet\n  facet normal 0 0.70711 -0.70711\n    outer loop\n      vertex 25.4 -53.666 12.12\n      vertex 34.616 -53.666 12.12\n      vertex 25.4 -54.109 11.677\n    endloop\n  endfacet\n  facet normal 0 0.89121 -0.45359\n    outer loop\n      vertex 25.4 -54.109 11.677\n      vertex 34.616 -54.109 11.677\n      vertex 25.4 -54.393 11.119\n    endloop\n  endfacet\n  facet normal -0.01725 -0.98758 0.15616\n    outer loop\n      vertex 34.019 -45.096 15.21\n      vertex 45.071 -45.289 15.21\n      vertex 45.075 -45.059 16.665\n    endloop\n  endfacet\n  facet normal 0 0.9877 -0.15637\n    outer loop\n      vertex 34.616 -54.491 10.5\n      vertex 25.4 -54.491 10.5\n      vertex 25.4 -54.393 11.119\n    endloop\n  endfacet\n  facet normal -0.01556 -0.89084 0.45404\n    outer loop\n      vertex 34.035 -44.197 17.978\n      vertex 34.023 -44.866 16.665\n      vertex 45.075 -45.059 16.665\n    endloop\n  endfacet\n  facet normal -0.01556 -0.89085 0.45404\n    outer loop\n      vertex 34.035 -44.197 17.978\n      vertex 45.075 -45.059 16.665\n      vertex 45.086 -44.39 17.978\n    endloop\n  endfacet\n  facet normal -0.01234 -0.7066 0.7075\n    outer loop\n      vertex 45.086 -44.39 17.978\n      vertex 45.105 -43.347 19.02\n      vertex 34.053 -43.154 19.02\n    endloop\n  endfacet\n  facet normal 0 -0.45295 -0.89154\n    outer loop\n      vertex 25.4 -51.87 12.404\n      vertex 25.539 -51.788 12.36234\n      vertex 30.72 -51.87 12.404\n    endloop\n  endfacet\n  facet normal 0 -0.15818 -0.98741\n    outer loop\n      vertex 25.4 -51.87 12.404\n      vertex 30.72 -51.87 12.404\n      vertex 25.4 -52.488 12.503\n    endloop\n  endfacet\n  facet normal -0.98774 0.04043 -0.1508\n    outer loop\n      vertex 53.941 4.97056 -2.26607\n      vertex 53.941 8.06241 -1.43714\n      vertex 53.96081 5.003 -2.38713\n    endloop\n  endfacet\n  facet normal -0.98775 0.04041 -0.1507\n    outer loop\n      vertex 53.96081 5.003 -2.38713\n      vertex 53.98688 8.13752 -1.71749\n      vertex 54.002 5.0705 -2.639\n    endloop\n  endfacet\n  facet normal 0.15642 0.25577 -0.954\n    outer loop\n      vertex 52.366 4.7631 -1.49193\n      vertex 52.366 7.85499 -0.66298\n      vertex 52.752 4.74728 -1.43288\n    endloop\n  endfacet\n  facet normal -0.15603 -0.25569 0.95408\n    outer loop\n      vertex 33.58934 8.91988 -17.00297\n      vertex 33.42434 12.01764 -16.19975\n      vertex 33.25 8.93375 -17.05474\n    endloop\n  endfacet\n  facet normal -0.15603 -0.25569 0.95408\n    outer loop\n      vertex 33.25 12.02477 -16.22635\n      vertex 33.25 8.93375 -17.05474\n      vertex 33.42434 12.01764 -16.19975\n    endloop\n  endfacet\n  facet normal 0.45248 0.23093 -0.86136\n    outer loop\n      vertex 52.017 4.80894 -1.66297\n      vertex 52.017 7.90082 -0.83403\n      vertex 52.366 4.7631 -1.49193\n    endloop\n  endfacet\n  facet normal 0.45248 0.23093 -0.86136\n    outer loop\n      vertex 52.366 7.85499 -0.66298\n      vertex 52.366 4.7631 -1.49193\n      vertex 52.017 7.90082 -0.83403\n    endloop\n  endfacet\n  facet normal 0.70779 0.18293 -0.68232\n    outer loop\n      vertex 51.741 4.88052 -1.93008\n      vertex 51.741 7.97239 -1.10114\n      vertex 52.017 4.80894 -1.66297\n    endloop\n  endfacet\n  facet normal 0 0.9877 0.15637\n    outer loop\n      vertex 34.0626 -42.591 15.3\n      vertex 45.11796 -42.591 15.3\n      vertex 34.06285 -42.57675 15.21\n    endloop\n  endfacet\n  facet normal -0.45391 -0.23077 0.86064\n    outer loop\n      vertex 33.637 12.00881 -16.16679\n      vertex 33.637 8.9179 -16.99558\n      vertex 33.79425 11.98808 -16.08941\n    endloop\n  endfacet\n  facet normal -0.45248 -0.23088 0.86137\n    outer loop\n      vertex 33.79425 11.98808 -16.08941\n      vertex 33.94306 8.87754 -16.84498\n      vertex 33.986 11.9629 -15.99543\n    endloop\n  endfacet\n  facet normal 0 0.9877 -0.15637\n    outer loop\n      vertex 45.11963 -42.493 15.919\n      vertex 45.11944 -42.50613 15.83607\n      vertex 34.06431 -42.493 15.919\n    endloop\n  endfacet\n  facet normal -0.45248 0.23093 -0.86136\n    outer loop\n      vertex 53.138 7.85499 -0.66298\n      vertex 53.487 7.90082 -0.83403\n      vertex 53.138 4.7631 -1.49193\n    endloop\n  endfacet\n  facet normal -0.70652 -0.18322 0.68357\n    outer loop\n      vertex 33.986 11.9629 -15.99543\n      vertex 33.986 8.8719 -16.82394\n      vertex 34.1108 11.93066 -15.87509\n    endloop\n  endfacet\n  facet normal -0.15642 0.25577 -0.954\n    outer loop\n      vertex 52.752 4.74728 -1.43288\n      vertex 53.138 7.85499 -0.66298\n      vertex 53.138 4.7631 -1.49193\n    endloop\n  endfacet\n  facet normal -0.89073 -0.11774 0.43903\n    outer loop\n      vertex 34.441 8.71 -16.21979\n      vertex 34.441 11.80093 -15.39088\n      vertex 34.263 11.8912 -15.72781\n    endloop\n  endfacet\n  facet normal 0 0.70711 -0.70711\n    outer loop\n      vertex 34.07 -42.17571 16.51029\n      vertex 34.07707 -41.766 16.92\n      vertex 34.16879 -42.209 16.477\n    endloop\n  endfacet\n  facet normal -0.98742 -0.04096 0.15274\n    outer loop\n      vertex 34.46894 11.75579 -15.22239\n      vertex 34.441 11.80093 -15.39088\n      vertex 34.441 8.71 -16.21979\n    endloop\n  endfacet\n  facet normal 0 0.89121 -0.45359\n    outer loop\n      vertex 34.0694 -42.209 16.477\n      vertex 34.16879 -42.209 16.477\n      vertex 34.06431 -42.493 15.919\n    endloop\n  endfacet\n  facet normal -0.98736 -0.04104 0.15312\n    outer loop\n      vertex 34.46894 11.75579 -15.22239\n      vertex 34.49537 8.62211 -15.89185\n      vertex 34.503 11.70088 -15.01744\n    endloop\n  endfacet\n  facet normal 0 -0.9877 0.15637\n    outer loop\n      vertex 34.13232 -38.586 15.3\n      vertex 34.13206 -38.60025 15.21\n      vertex 45.23417 -38.586 15.3\n    endloop\n  endfacet\n  facet normal -0.98736 0.04104 -0.15312\n    outer loop\n      vertex 34.47507 11.65585 -14.84938\n      vertex 34.503 11.70088 -15.01744\n      vertex 34.503 8.60981 -15.84596\n    endloop\n  endfacet\n  facet normal -0.45444 -0.23067 0.86039\n    outer loop\n      vertex 53.487 5.33204 -3.61494\n      vertex 53.487 8.42381 -2.78603\n      vertex 53.138 8.46988 -2.95801\n    endloop\n  endfacet\n  facet normal -0.98742 0.04096 -0.15274\n    outer loop\n      vertex 34.47507 11.65585 -14.84938\n      vertex 34.44863 8.52215 -15.51884\n      vertex 34.441 11.6008 -14.64391\n    endloop\n  endfacet\n  facet normal -0.70618 -0.18335 0.68388\n    outer loop\n      vertex 53.67405 5.28375 -3.43474\n      vertex 53.55569 8.40608 -2.71986\n      vertex 53.487 5.33204 -3.61494\n    endloop\n  endfacet\n  facet normal -0.89073 0.11772 -0.43903\n    outer loop\n      vertex 34.263 8.41947 -15.13569\n      vertex 34.263 11.5105 -14.30687\n      vertex 34.28491 8.43059 -15.17717\n    endloop\n  endfacet\n  facet normal -0.70528 -0.18352 0.68477\n    outer loop\n      vertex 53.764 5.26059 -3.3483\n      vertex 53.764 8.35244 -2.51968\n      vertex 53.67405 5.28375 -3.43474\n    endloop\n  endfacet\n  facet normal -0.89086 0.11767 -0.43877\n    outer loop\n      vertex 34.441 11.6008 -14.64391\n      vertex 34.441 8.50982 -15.47284\n      vertex 34.36081 11.5601 -14.492\n    endloop\n  endfacet\n  facet normal -0.89086 0.11767 -0.43877\n    outer loop\n      vertex 34.28491 8.43059 -15.17717\n      vertex 34.36081 11.5601 -14.492\n      vertex 34.441 8.50982 -15.47284\n    endloop\n  endfacet\n  facet normal 0 -0.89056 -0.45486\n    outer loop\n      vertex 34.13068 -38.684 15.919\n      vertex 45.23247 -38.684 15.919\n      vertex 34.12746 -38.88013 16.30301\n    endloop\n  endfacet\n  facet normal -0.89176 -0.11718 0.43708\n    outer loop\n      vertex 53.941 5.17042 -3.01184\n      vertex 53.941 8.26222 -2.18292\n      vertex 53.8835 5.19975 -3.12129\n    endloop\n  endfacet\n  facet normal 0 -0.70711 -0.70711\n    outer loop\n      vertex 34.1258 -38.969 16.477\n      vertex 45.21983 -39.412 16.92\n      vertex 34.12057 -39.25577 16.76377\n    endloop\n  endfacet\n  facet normal -0.89139 -0.11733 0.43779\n    outer loop\n      vertex 53.764 8.35244 -2.51968\n      vertex 53.764 5.26059 -3.3483\n      vertex 53.80787 8.33011 -2.43633\n    endloop\n  endfacet\n  facet normal -0.89139 -0.11733 0.43779\n    outer loop\n      vertex 53.8835 5.19975 -3.12129\n      vertex 53.80787 8.33011 -2.43633\n      vertex 53.764 5.26059 -3.3483\n    endloop\n  endfacet\n  facet normal 0 -0.45359 -0.89121\n    outer loop\n      vertex 34.11798 -39.412 16.92\n      vertex 45.21014 -39.97 17.204\n      vertex 34.11198 -39.76991 17.10216\n    endloop\n  endfacet\n  facet normal 0 -0.15793 -0.98745\n    outer loop\n      vertex 45.21014 -39.97 17.204\n      vertex 45.1994 -40.589 17.303\n      vertex 34.10841 -39.97 17.204\n    endloop\n  endfacet\n  facet normal 0 -0.15793 -0.98745\n    outer loop\n      vertex 34.101 -40.385 17.27037\n      vertex 34.10841 -39.97 17.204\n      vertex 45.1994 -40.589 17.303\n    endloop\n  endfacet\n  facet normal 0.15603 0.25573 -0.95408\n    outer loop\n      vertex 33.25 11.37695 -13.80842\n      vertex 33.25 8.28582 -14.63696\n      vertex 32.863 11.39277 -13.86747\n    endloop\n  endfacet\n  facet normal 0 0.15793 -0.98745\n    outer loop\n      vertex 34.08682 -41.208 17.204\n      vertex 34.08972 -41.04183 17.23058\n      vertex 43.008 -41.208 17.204\n    endloop\n  endfacet\n  facet normal 0 0.15793 -0.98745\n    outer loop\n      vertex 45.1994 -40.589 17.303\n      vertex 43.008 -41.208 17.204\n      vertex 34.0975 -40.589 17.303\n    endloop\n  endfacet\n  facet normal 0.45444 0.23062 -0.86041\n    outer loop\n      vertex 32.863 8.30164 -14.69601\n      vertex 32.514 11.43885 -14.03945\n      vertex 32.863 11.39277 -13.86747\n    endloop\n  endfacet\n  facet normal -0.89073 0.11772 -0.43903\n    outer loop\n      vertex 34.36081 11.5601 -14.492\n      vertex 34.28491 8.43059 -15.17717\n      vertex 34.263 11.5105 -14.30687\n    endloop\n  endfacet\n  facet normal 0 0.45359 -0.89121\n    outer loop\n      vertex 34.08682 -41.208 17.204\n      vertex 43.008 -41.208 17.204\n      vertex 34.07881 -41.6651 16.97135\n    endloop\n  endfacet\n  facet normal -0.70652 0.18322 -0.68357\n    outer loop\n      vertex 34.13818 11.47817 -14.1862\n      vertex 34.02007 8.35653 -14.90084\n      vertex 33.986 11.43885 -14.03945\n    endloop\n  endfacet\n  facet normal 0.15642 0.25577 -0.954\n    outer loop\n      vertex 52.752 4.74728 -1.43288\n      vertex 52.366 7.85499 -0.66298\n      vertex 52.752 7.83917 -0.60393\n    endloop\n  endfacet\n  facet normal -0.70742 0.18305 -0.68268\n    outer loop\n      vertex 34.263 8.41947 -15.13569\n      vertex 34.13818 11.47817 -14.1862\n      vertex 34.263 11.5105 -14.30687\n    endloop\n  endfacet\n  facet normal -0.45444 0.23062 -0.86041\n    outer loop\n      vertex 33.637 11.39277 -13.86747\n      vertex 33.986 11.43885 -14.03945\n      vertex 33.637 8.30164 -14.69601\n    endloop\n  endfacet\n  facet normal -0.45444 0.23062 -0.86041\n    outer loop\n      vertex 33.986 8.34773 -14.86798\n      vertex 33.637 8.30164 -14.69601\n      vertex 33.986 11.43885 -14.03945\n    endloop\n  endfacet\n  facet normal -0.15603 0.25573 -0.95408\n    outer loop\n      vertex 33.637 8.30164 -14.69601\n      vertex 33.25 8.28582 -14.63696\n      vertex 33.637 11.39277 -13.86747\n    endloop\n  endfacet\n  facet normal -0.98775 -0.04041 0.1507\n    outer loop\n      vertex 54.002 8.1623 -1.80997\n      vertex 53.98219 5.10296 -2.76013\n      vertex 54.002 5.0705 -2.639\n    endloop\n  endfacet\n  facet normal -0.98774 0.04043 -0.1508\n    outer loop\n      vertex 53.98688 8.13752 -1.71749\n      vertex 53.96081 5.003 -2.38713\n      vertex 53.941 8.06241 -1.43714\n    endloop\n  endfacet\n  facet normal 0 0.15669 0.98765\n    outer loop\n      vertex 34.539 -52.37394 15\n      vertex 25.539 -52.37394 15\n      vertex 25.539 -52.5 15.02\n    endloop\n  endfacet\n  facet normal 0 0.15669 0.98765\n    outer loop\n      vertex 34.539 -52.37394 15\n      vertex 25.539 -52.5 15.02\n      vertex 34.539 -52.5 15.02\n    endloop\n  endfacet\n  facet normal -0.98775 0.04041 -0.1507\n    outer loop\n      vertex 54.002 5.0705 -2.639\n      vertex 53.98688 8.13752 -1.71749\n      vertex 54.002 8.1623 -1.80997\n    endloop\n  endfacet\n  facet normal 0 -0.15669 0.98765\n    outer loop\n      vertex 25.539 -52.5 15.02\n      vertex 25.539 -52.62606 15\n      vertex 34.539 -52.62606 15\n    endloop\n  endfacet\n  facet normal 0 -0.15669 0.98765\n    outer loop\n      vertex 25.539 -52.5 15.02\n      vertex 34.539 -52.62606 15\n      vertex 34.539 -52.5 15.02\n    endloop\n  endfacet\n  facet normal -0.89125 0.11744 -0.43804\n    outer loop\n      vertex 53.764 4.88052 -1.93008\n      vertex 53.764 7.97239 -1.10114\n      vertex 53.941 8.06241 -1.43714\n    endloop\n  endfacet\n  facet normal -0.89125 0.11744 -0.43804\n    outer loop\n      vertex 53.764 4.88052 -1.93008\n      vertex 53.941 8.06241 -1.43714\n      vertex 53.941 4.97056 -2.26607\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 25.4 -57 15\n      vertex 25.539 -52.62606 15\n      vertex 25.4 -51.788 15\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 34.539 -52.62606 15\n      vertex 25.539 -52.62606 15\n      vertex 34.616 -57 15\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 25.539 -52.62606 15\n      vertex 25.539 -52.37394 15\n      vertex 25.4 -51.788 15\n    endloop\n  endfacet\n  facet normal -0.70652 0.18326 -0.68356\n    outer loop\n      vertex 53.764 4.88052 -1.93008\n      vertex 53.487 4.80894 -1.66297\n      vertex 53.764 7.97239 -1.10114\n    endloop\n  endfacet\n  facet normal -0.70652 0.18326 -0.68356\n    outer loop\n      vertex 53.487 7.90082 -0.83403\n      vertex 53.764 7.97239 -1.10114\n      vertex 53.487 4.80894 -1.66297\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 34.616 -51.788 15\n      vertex 34.539 -52.37394 15\n      vertex 34.539 -52.62606 15\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 34.616 -51.788 15\n      vertex 34.539 -52.62606 15\n      vertex 34.616 -57 15\n    endloop\n  endfacet\n  facet normal -0.45248 0.23093 -0.86136\n    outer loop\n      vertex 53.487 4.80894 -1.66297\n      vertex 53.138 4.7631 -1.49193\n      vertex 53.487 7.90082 -0.83403\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 34.539 -52.37394 15\n      vertex 34.616 -51.788 15\n      vertex 25.539 -52.37394 15\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 25.4 -51.788 15\n      vertex 25.539 -52.37394 15\n      vertex 34.616 -51.788 15\n    endloop\n  endfacet\n  facet normal -0.15642 0.25577 -0.954\n    outer loop\n      vertex 52.752 4.74728 -1.43288\n      vertex 52.752 7.83917 -0.60393\n      vertex 53.138 7.85499 -0.66298\n    endloop\n  endfacet\n  facet normal 0.70656 -0.18325 0.68352\n    outer loop\n      vertex 51.80941 8.37017 -2.58583\n      vertex 51.92736 5.30887 -3.52849\n      vertex 52.017 8.42381 -2.78603\n    endloop\n  endfacet\n  facet normal 0.45444 -0.23067 0.86039\n    outer loop\n      vertex 52.017 5.33204 -3.61494\n      vertex 52.366 8.46988 -2.95801\n      vertex 52.017 8.42381 -2.78603\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 25.4 -57 15\n      vertex 34.616 -57 15\n      vertex 25.539 -52.62606 15\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 26.6 -33.2 20\n      vertex 26.6 -33.2 -58\n      vertex 26.6 -36.2 20\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 26.6 -33.2 -58\n      vertex 26.6 -33.2 20\n      vertex 27.1 -33.2 0\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 27.1 8 0\n      vertex 27.1 -3.2 0\n      vertex 27.1 -3.2 20\n    endloop\n  endfacet\n  facet normal -0.70618 -0.18335 0.68388\n    outer loop\n      vertex 53.487 8.42381 -2.78603\n      vertex 53.487 5.33204 -3.61494\n      vertex 53.55569 8.40608 -2.71986\n    endloop\n  endfacet\n  facet normal -0.70528 -0.18352 0.68477\n    outer loop\n      vertex 53.55569 8.40608 -2.71986\n      vertex 53.67405 5.28375 -3.43474\n      vertex 53.764 8.35244 -2.51968\n    endloop\n  endfacet\n  facet normal -0.89176 -0.11718 0.43708\n    outer loop\n      vertex 53.80787 8.33011 -2.43633\n      vertex 53.8835 5.19975 -3.12129\n      vertex 53.941 8.26222 -2.18292\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 26.6 -36.2 20\n      vertex 31.06376 -36.2 -10.48639\n      vertex 34.27425 -36.2 10.5\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 31.06376 -36.2 -10.48639\n      vertex 37.337 -36.2 -9.635\n      vertex 37.735 -36.2 -8.855\n    endloop\n  endfacet\n  facet normal -0.70652 0.18326 -0.68356\n    outer loop\n      vertex 33.487 4.80894 -1.66297\n      vertex 33.487 7.90082 -0.83403\n      vertex 33.764 7.97239 -1.10114\n    endloop\n  endfacet\n  facet normal -0.45248 0.23093 -0.86136\n    outer loop\n      vertex 33.138 4.7631 -1.49193\n      vertex 33.138 7.85499 -0.66298\n      vertex 33.487 7.90082 -0.83403\n    endloop\n  endfacet\n  facet normal -0.45248 0.23093 -0.86136\n    outer loop\n      vertex 33.487 4.80894 -1.66297\n      vertex 33.138 4.7631 -1.49193\n      vertex 33.487 7.90082 -0.83403\n    endloop\n  endfacet\n  facet normal -0.15642 0.25577 -0.954\n    outer loop\n      vertex 33.138 7.85499 -0.66298\n      vertex 33.138 4.7631 -1.49193\n      vertex 32.752 4.74728 -1.43288\n    endloop\n  endfacet\n  facet normal -0.15642 0.25577 -0.954\n    outer loop\n      vertex 33.138 7.85499 -0.66298\n      vertex 32.752 4.74728 -1.43288\n      vertex 32.752 7.83917 -0.60393\n    endloop\n  endfacet\n  facet normal -0.98774 -0.04043 0.1508\n    outer loop\n      vertex 53.98219 5.10296 -2.76013\n      vertex 53.95612 8.23746 -2.0905\n      vertex 53.941 5.17042 -3.01184\n    endloop\n  endfacet\n  facet normal -0.98774 -0.04043 0.1508\n    outer loop\n      vertex 53.941 8.26222 -2.18292\n      vertex 53.941 5.17042 -3.01184\n      vertex 53.95612 8.23746 -2.0905\n    endloop\n  endfacet\n  facet normal -0.15642 -0.25577 0.954\n    outer loop\n      vertex 32.752 5.39395 -3.84597\n      vertex 33.138 5.37813 -3.78692\n      vertex 32.752 8.4857 -3.01706\n    endloop\n  endfacet\n  facet normal -0.15642 -0.25577 0.954\n    outer loop\n      vertex 33.138 8.46988 -2.95801\n      vertex 32.752 8.4857 -3.01706\n      vertex 33.138 5.37813 -3.78692\n    endloop\n  endfacet\n  facet normal -0.98775 -0.04041 0.1507\n    outer loop\n      vertex 53.95612 8.23746 -2.0905\n      vertex 53.98219 5.10296 -2.76013\n      vertex 54.002 8.1623 -1.80997\n    endloop\n  endfacet\n  facet normal -0.45444 -0.23067 0.86039\n    outer loop\n      vertex 33.138 5.37813 -3.78692\n      vertex 33.487 5.33204 -3.61494\n      vertex 33.138 8.46988 -2.95801\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 32.8 8 3.01941\n      vertex 27.1 8 0\n      vertex 27.1 8 20\n    endloop\n  endfacet\n  facet normal -0.70618 -0.18335 0.68388\n    outer loop\n      vertex 33.487 8.42381 -2.78603\n      vertex 33.487 5.33204 -3.61494\n      vertex 33.55569 8.40608 -2.71986\n    endloop\n  endfacet\n  facet normal 0.70652 -0.18331 0.68354\n    outer loop\n      vertex 51.86177 11.92337 -15.84787\n      vertex 51.97988 8.86299 -16.79067\n      vertex 52.014 11.9627 -15.99467\n    endloop\n  endfacet\n  facet normal -0.70528 -0.18352 0.68477\n    outer loop\n      vertex 33.55569 8.40608 -2.71986\n      vertex 33.67405 5.28375 -3.43474\n      vertex 33.764 8.35244 -2.51968\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 30.25132 -0.802 -0.16196\n      vertex 29.097 -0.802 -0.17512\n      vertex 30.37071 -0.802 0\n    endloop\n  endfacet\n  facet normal 0.70742 -0.18301 0.68269\n    outer loop\n      vertex 51.97988 8.86299 -16.79067\n      vertex 51.86177 11.92337 -15.84787\n      vertex 51.737 8.80006 -16.55586\n    endloop\n  endfacet\n  facet normal -0.89176 -0.11718 0.43708\n    outer loop\n      vertex 33.80787 8.33011 -2.43633\n      vertex 33.8835 5.19975 -3.12129\n      vertex 33.941 8.26222 -2.18292\n    endloop\n  endfacet\n  facet normal 0.45248 -0.23099 0.86134\n    outer loop\n      vertex 52.32002 8.91199 -16.97355\n      vertex 52.17121 11.98334 -16.07172\n      vertex 52.014 8.8718 -16.82357\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 32.8 21.5208 2.02456\n      vertex 32.8 8 19.80394\n      vertex 32.8 22.60546 1.94475\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 32.8 22.60546 1.94475\n      vertex 32.8 8 19.80394\n      vertex 32.8 26.19 1.681\n    endloop\n  endfacet\n  facet normal 0.15603 -0.25585 0.95404\n    outer loop\n      vertex 52.70234 8.93177 -17.04733\n      vertex 52.75 8.93371 -17.0546\n      vertex 52.75 12.0246 -16.2257\n    endloop\n  endfacet\n  facet normal 0.15843 -0.25563 0.95371\n    outer loop\n      vertex 52.363 12.00867 -16.16623\n      vertex 52.363 8.91767 -16.99473\n      vertex 52.53732 12.0159 -16.19325\n    endloop\n  endfacet\n  facet normal -0.98774 -0.04043 0.1508\n    outer loop\n      vertex 33.98219 5.10296 -2.76013\n      vertex 33.95612 8.23746 -2.0905\n      vertex 33.941 5.17042 -3.01184\n    endloop\n  endfacet\n  facet normal -0.98774 -0.04043 0.1508\n    outer loop\n      vertex 33.941 8.26222 -2.18292\n      vertex 33.941 5.17042 -3.01184\n      vertex 33.95612 8.23746 -2.0905\n    endloop\n  endfacet\n  facet normal -0.98775 -0.04041 0.1507\n    outer loop\n      vertex 33.98219 5.10296 -2.76013\n      vertex 34.002 8.1623 -1.80997\n      vertex 33.95612 8.23746 -2.0905\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 32.8 22.603 1.874\n      vertex 32.8 21.5208 2.02456\n      vertex 32.8 22.60546 1.94475\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 32.8 8 3.01941\n      vertex 32.8 8 19.80394\n      vertex 32.8 21.5208 2.02456\n    endloop\n  endfacet\n  facet normal -0.15843 -0.25575 0.95367\n    outer loop\n      vertex 53.08934 8.91962 -17.002\n      vertex 52.92433 12.01736 -16.19868\n      vertex 52.75 8.93371 -17.0546\n    endloop\n  endfacet\n  facet normal 0 0.70786 0.70635\n    outer loop\n      vertex 37.8 8.01 19.9\n      vertex 37.8 26.19 1.681\n      vertex 32.8 8.01 19.9\n    endloop\n  endfacet\n  facet normal -0.15603 -0.25573 0.95408\n    outer loop\n      vertex 53.137 8.91767 -16.99473\n      vertex 53.137 12.00867 -16.16623\n      vertex 53.08934 8.91962 -17.002\n    endloop\n  endfacet\n  facet normal -0.45444 -0.23073 0.86038\n    outer loop\n      vertex 53.486 11.9627 -15.99467\n      vertex 53.44302 8.87748 -16.84475\n      vertex 53.486 8.8718 -16.82357\n    endloop\n  endfacet\n  facet normal -0.45248 -0.23088 0.86137\n    outer loop\n      vertex 53.137 12.00867 -16.16623\n      vertex 53.137 8.91767 -16.99473\n      vertex 53.2942 11.98802 -16.08918\n    endloop\n  endfacet\n  facet normal -0.70742 -0.18308 0.68267\n    outer loop\n      vertex 53.72891 8.80887 -16.58874\n      vertex 53.61079 11.93038 -15.87403\n      vertex 53.486 8.8718 -16.82357\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 27.1 -33.2 0\n      vertex 26.6 -33.2 20\n      vertex 36.966 -33.2 2.453\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 36.966 -36.2 0.721\n      vertex 36.829 -36.2 1.587\n      vertex 31.06376 -36.2 -10.48639\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 42.78952 20.77058 2.12893\n      vertex 42.392 20.83382 2.12013\n      vertex 46.1 22.603 1.874\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 42.32306 20.8227 2.12168\n      vertex 37.8 22.603 1.874\n      vertex 42.392 20.83382 2.12013\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 41.925 20.75938 2.13049\n      vertex 37.8 22.603 1.874\n      vertex 42.32306 20.8227 2.12168\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.8 8 3.01941\n      vertex 46.9 8 3.01932\n      vertex 27.1 8 0\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 32.8 8 3.01941\n      vertex 37.8 8 3.01941\n      vertex 27.1 8 0\n    endloop\n  endfacet\n  facet normal -0.89125 0.11744 -0.43804\n    outer loop\n      vertex 33.941 4.97056 -2.26607\n      vertex 33.764 4.88052 -1.93008\n      vertex 33.941 8.06241 -1.43714\n    endloop\n  endfacet\n  facet normal -0.89125 0.11744 -0.43804\n    outer loop\n      vertex 33.764 7.97239 -1.10114\n      vertex 33.941 8.06241 -1.43714\n      vertex 33.764 4.88052 -1.93008\n    endloop\n  endfacet\n  facet normal 0 -0.07338 -0.9973\n    outer loop\n      vertex 32.8 21.5208 2.02456\n      vertex 37.8 8 3.01941\n      vertex 32.8 8 3.01941\n    endloop\n  endfacet\n  facet normal -0.70652 0.18326 -0.68356\n    outer loop\n      vertex 33.764 4.88052 -1.93008\n      vertex 33.487 4.80894 -1.66297\n      vertex 33.764 7.97239 -1.10114\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 30.37071 -0.802 0\n      vertex 29.097 -0.802 20\n      vertex 34.616 -0.802 0\n    endloop\n  endfacet\n  facet normal 0 0.9877 -0.15637\n    outer loop\n      vertex 34.06424 -42.49669 15.89568\n      vertex 34.06431 -42.493 15.919\n      vertex 45.11944 -42.50613 15.83607\n    endloop\n  endfacet\n  facet normal -0.45444 -0.23067 0.86039\n    outer loop\n      vertex 33.487 8.42381 -2.78603\n      vertex 33.138 8.46988 -2.95801\n      vertex 33.487 5.33204 -3.61494\n    endloop\n  endfacet\n  facet normal 0 0.45359 -0.89121\n    outer loop\n      vertex 34.07707 -41.766 16.92\n      vertex 34.07881 -41.6651 16.97135\n      vertex 43.008 -41.208 17.204\n    endloop\n  endfacet\n  facet normal -0.70618 -0.18335 0.68388\n    outer loop\n      vertex 33.67405 5.28375 -3.43474\n      vertex 33.55569 8.40608 -2.71986\n      vertex 33.487 5.33204 -3.61494\n    endloop\n  endfacet\n  facet normal -0.70528 -0.18352 0.68477\n    outer loop\n      vertex 33.764 8.35244 -2.51968\n      vertex 33.67405 5.28375 -3.43474\n      vertex 33.764 5.26059 -3.3483\n    endloop\n  endfacet\n  facet normal 0 0.70711 -0.70711\n    outer loop\n      vertex 45.13241 -41.766 16.92\n      vertex 34.16879 -42.209 16.477\n      vertex 34.07707 -41.766 16.92\n    endloop\n  endfacet\n  facet normal -0.89176 -0.11718 0.43708\n    outer loop\n      vertex 33.941 5.17042 -3.01184\n      vertex 33.941 8.26222 -2.18292\n      vertex 33.8835 5.19975 -3.12129\n    endloop\n  endfacet\n  facet normal -0.89139 -0.11733 0.43779\n    outer loop\n      vertex 33.764 8.35244 -2.51968\n      vertex 33.764 5.26059 -3.3483\n      vertex 33.80787 8.33011 -2.43633\n    endloop\n  endfacet\n  facet normal 0 0.9877 0.15637\n    outer loop\n      vertex 34.06431 -42.493 14.681\n      vertex 34.06285 -42.57675 15.21\n      vertex 45.11821 -42.57675 15.21\n    endloop\n  endfacet\n  facet normal -0.89139 -0.11733 0.43779\n    outer loop\n      vertex 33.8835 5.19975 -3.12129\n      vertex 33.80787 8.33011 -2.43633\n      vertex 33.764 5.26059 -3.3483\n    endloop\n  endfacet\n  facet normal 0 0.89121 0.45359\n    outer loop\n      vertex 45.12437 -42.209 14.123\n      vertex 34.06937 -42.209 14.123\n      vertex 45.12037 -42.45247 14.60135\n    endloop\n  endfacet\n  facet normal 0 0.89121 0.45359\n    outer loop\n      vertex 34.06937 -42.209 14.123\n      vertex 34.06549 -42.42509 14.54757\n      vertex 45.12037 -42.45247 14.60135\n    endloop\n  endfacet\n  facet normal -0.98775 -0.04041 0.1507\n    outer loop\n      vertex 33.98219 5.10296 -2.76013\n      vertex 34.002 5.0705 -2.639\n      vertex 34.002 8.1623 -1.80997\n    endloop\n  endfacet\n  facet normal -0.98774 0.04043 -0.1508\n    outer loop\n      vertex 33.941 4.97056 -2.26607\n      vertex 33.941 8.06241 -1.43714\n      vertex 33.96081 5.003 -2.38713\n    endloop\n  endfacet\n  facet normal 0 0.9877 -0.15637\n    outer loop\n      vertex 45.11796 -42.591 15.3\n      vertex 34.0626 -42.591 15.3\n      vertex 45.11944 -42.50613 15.83607\n    endloop\n  endfacet\n  facet normal -0.98774 0.04043 -0.1508\n    outer loop\n      vertex 33.96081 5.003 -2.38713\n      vertex 33.941 8.06241 -1.43714\n      vertex 33.98688 8.13752 -1.71749\n    endloop\n  endfacet\n  facet normal -0.98775 0.04041 -0.1507\n    outer loop\n      vertex 33.96081 5.003 -2.38713\n      vertex 33.98688 8.13752 -1.71749\n      vertex 34.002 5.0705 -2.639\n    endloop\n  endfacet\n  facet normal -0.98775 0.04041 -0.1507\n    outer loop\n      vertex 34.002 8.1623 -1.80997\n      vertex 34.002 5.0705 -2.639\n      vertex 33.98688 8.13752 -1.71749\n    endloop\n  endfacet\n  facet normal 0 0.89121 -0.45359\n    outer loop\n      vertex 34.06431 -42.493 15.919\n      vertex 34.16879 -42.209 16.477\n      vertex 45.11963 -42.493 15.919\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 58.2 -3.2 0\n      vertex 58.18832 -0.78834 0\n      vertex 58.2 8 0\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 58.18832 -0.78834 0\n      vertex 58.02918 7.60273 0\n      vertex 58.2 8 0\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 58.02918 7.60273 0\n      vertex 56.1422 7.57173 0\n      vertex 58.2 8 0\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 58.01508 -0.79136 0\n      vertex 58.2 -3.2 0\n      vertex 55.33844 -0.84055 0\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 27.1 -3.2 0\n      vertex 34.616 -0.802 0\n      vertex 58.2 -3.2 0\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 55.2 6.45898 0\n      vertex 55.27692 2.403 0\n      vertex 55.2 4.36328 0\n    endloop\n  endfacet\n  facet normal -0.01745 -0.99985 0\n    outer loop\n      vertex 45.182 -41.591 17.00907\n      vertex 45.182 -41.591 19.9\n      vertex 45.13562 -41.59019 18.32374\n    endloop\n  endfacet\n  facet normal -0.01745 -0.99985 0\n    outer loop\n      vertex 45.13549 -41.59019 17.00948\n      vertex 45.182 -41.591 17.00907\n      vertex 45.13562 -41.59019 18.32374\n    endloop\n  endfacet\n  facet normal -0.01745 -0.99985 0\n    outer loop\n      vertex 45.13562 -41.59019 18.32374\n      vertex 45.182 -41.591 19.9\n      vertex 45.13562 -41.59019 19.75941\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 55.2 7.55657 0\n      vertex 55.2 7.67736 0\n      vertex 56.1422 7.57173 0\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 58.2 8 0\n      vertex 56.1422 7.57173 0\n      vertex 55.2 7.67736 0\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 58.18832 -0.78834 0\n      vertex 58.2 -3.2 0\n      vertex 58.01508 -0.79136 0\n    endloop\n  endfacet\n  facet normal -0.01745 -0.99985 0\n    outer loop\n      vertex 45.182 -41.591 19.9\n      vertex 34.183 -41.399 19.9\n      vertex 45.13562 -41.59019 19.75941\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 55.3377 -0.802 0\n      vertex 55.33844 -0.84055 0\n      vertex 34.616 -0.802 0\n    endloop\n  endfacet\n  facet normal -0.01745 -0.99985 0\n    outer loop\n      vertex 34.183 -41.399 19.7594\n      vertex 45.13562 -41.59019 19.75941\n      vertex 34.183 -41.399 19.9\n    endloop\n  endfacet\n  facet normal 0 -0.15637 0.9877\n    outer loop\n      vertex 45.21014 -39.97 13.396\n      vertex 34.10841 -39.97 13.396\n      vertex 45.1994 -40.589 13.298\n    endloop\n  endfacet\n  facet normal 0 -0.89056 0.45486\n    outer loop\n      vertex 34.13062 -38.684 14.681\n      vertex 34.13044 -38.69427 14.66089\n      vertex 45.23247 -38.684 14.681\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 27.52565 -1.10702 0\n      vertex 30.32389 -1.05663 0\n      vertex 27.1 -3.2 0\n    endloop\n  endfacet\n  facet normal 0 -0.45359 -0.89121\n    outer loop\n      vertex 34.10841 -39.97 17.204\n      vertex 34.11198 -39.76991 17.10216\n      vertex 45.21014 -39.97 17.204\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 30.32389 -1.05663 0\n      vertex 30.37554 -1.05573 0\n      vertex 27.1 -3.2 0\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 30.2 7.67736 0\n      vertex 27.36013 7.59525 0\n      vertex 27.1 8 0\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 30.2 7.64091 0\n      vertex 27.36013 7.59525 0\n      vertex 30.2 7.67736 0\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 58.2 8 0\n      vertex 46.1 7.67736 0\n      vertex 27.1 8 0\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 27.36013 7.59525 0\n      vertex 27.52565 -1.10702 0\n      vertex 27.1 8 0\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 27.1 -3.2 0\n      vertex 27.1 8 0\n      vertex 27.52565 -1.10702 0\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 30.37071 -0.802 0\n      vertex 34.616 -0.802 0\n      vertex 30.37554 -1.05573 0\n    endloop\n  endfacet\n  facet normal 0 -0.9877 -0.15637\n    outer loop\n      vertex 34.13068 -38.684 15.919\n      vertex 34.13103 -38.66043 15.7701\n      vertex 45.23247 -38.684 15.919\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 27.1 -3.2 0\n      vertex 30.37554 -1.05573 0\n      vertex 34.616 -0.802 0\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 30.27247 4.36328 0\n      vertex 34.002 4.36328 0\n      vertex 30.30975 2.403 0\n    endloop\n  endfacet\n  facet normal 0 -0.89056 -0.45486\n    outer loop\n      vertex 45.23247 -38.684 15.919\n      vertex 45.22752 -38.969 16.477\n      vertex 34.12746 -38.88013 16.30301\n    endloop\n  endfacet\n  facet normal 0 -0.70711 -0.70711\n    outer loop\n      vertex 34.11798 -39.412 16.92\n      vertex 34.12057 -39.25577 16.76377\n      vertex 45.21983 -39.412 16.92\n    endloop\n  endfacet\n  facet normal 0 -0.45359 -0.89121\n    outer loop\n      vertex 34.11798 -39.412 16.92\n      vertex 45.21983 -39.412 16.92\n      vertex 45.21014 -39.97 17.204\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 30.2 7.67736 0\n      vertex 27.1 8 0\n      vertex 46.1 7.67736 0\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 55.33844 -0.84055 0\n      vertex 58.2 -3.2 0\n      vertex 34.616 -0.802 0\n    endloop\n  endfacet\n  facet normal 0 0.45359 -0.89121\n    outer loop\n      vertex 45.13241 -41.766 16.92\n      vertex 34.07707 -41.766 16.92\n      vertex 43.008 -41.208 17.204\n    endloop\n  endfacet\n  facet normal 0 -0.9877 0.15637\n    outer loop\n      vertex 45.937 -50.486 10.5\n      vertex 54.937 -50.584 9.881\n      vertex 54.937 -50.486 10.5\n    endloop\n  endfacet\n  facet normal 0 -0.9877 -0.15637\n    outer loop\n      vertex 54.937 -50.486 10.5\n      vertex 45.937 -50.584 11.119\n      vertex 45.937 -50.486 10.5\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 30.30975 2.403 0\n      vertex 34.002 4.36328 0\n      vertex 55.27692 2.403 0\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 58.2 8 0\n      vertex 55.2 7.67736 0\n      vertex 46.1 7.67736 0\n    endloop\n  endfacet\n  facet normal 0 -0.89121 0.45359\n    outer loop\n      vertex 45.937 -50.868 9.323\n      vertex 54.937 -50.868 9.323\n      vertex 54.937 -50.584 9.881\n    endloop\n  endfacet\n  facet normal 0 -0.70711 -0.70711\n    outer loop\n      vertex 54.937 -51.311 12.12\n      vertex 45.937 -51.311 12.12\n      vertex 54.937 -50.868 11.677\n    endloop\n  endfacet\n  facet normal 0 -0.70711 0.70711\n    outer loop\n      vertex 54.937 -50.868 9.323\n      vertex 45.937 -50.868 9.323\n      vertex 54.937 -51.311 8.88\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 55.2 4.36328 0\n      vertex 55.27692 2.403 0\n      vertex 34.002 4.36328 0\n    endloop\n  endfacet\n  facet normal 0 -0.70711 -0.70711\n    outer loop\n      vertex 34.1258 -38.969 16.477\n      vertex 45.22752 -38.969 16.477\n      vertex 45.21983 -39.412 16.92\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 20.1 -60 0\n      vertex 20.1 -57 0\n      vertex 61 -60 0\n    endloop\n  endfacet\n  facet normal 0 -0.9877 -0.15637\n    outer loop\n      vertex 54.937 -50.584 11.119\n      vertex 45.937 -50.584 11.119\n      vertex 54.937 -50.486 10.5\n    endloop\n  endfacet\n  facet normal 0 -0.89121 -0.45359\n    outer loop\n      vertex 54.937 -50.868 11.677\n      vertex 45.937 -50.584 11.119\n      vertex 54.937 -50.584 11.119\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 61 -57 0\n      vertex 61 -60 0\n      vertex 20.1 -57 0\n    endloop\n  endfacet\n  facet normal 0 0.15793 -0.98745\n    outer loop\n      vertex 45.18865 -41.208 17.204\n      vertex 43.008 -41.208 17.204\n      vertex 45.1994 -40.589 17.303\n    endloop\n  endfacet\n  facet normal 0 0.45359 -0.89121\n    outer loop\n      vertex 45.18865 -41.208 17.204\n      vertex 45.13549 -41.59019 17.00948\n      vertex 43.008 -41.208 17.204\n    endloop\n  endfacet\n  facet normal 0 -0.45359 0.89121\n    outer loop\n      vertex 45.21983 -39.412 13.68\n      vertex 34.11792 -39.412 13.68\n      vertex 45.21014 -39.97 13.396\n    endloop\n  endfacet\n  facet normal 0.15538 0.25579 -0.95416\n    outer loop\n      vertex 52.57563 11.38408 -13.83503\n      vertex 52.4106 8.29969 -14.68874\n      vertex 52.363 11.39274 -13.86733\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 54.821 -51.7 15\n      vertex 54.821 -51.7 14.85944\n      vertex 46.1 -51.7 14.85944\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 54.821 -51.7 15\n      vertex 46.1 -51.7 14.85944\n      vertex 46.1 -51.7 15\n    endloop\n  endfacet\n  facet normal 0.45444 0.23065 -0.8604\n    outer loop\n      vertex 52.014 8.34772 -14.86795\n      vertex 52.014 11.43882 -14.03931\n      vertex 52.363 8.30163 -14.69598\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 54.821 -51.7 5.6\n      vertex 46.1 -51.7 5.6\n      vertex 54.821 -51.7 5.76056\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 46.1 -51.7 5.76056\n      vertex 54.821 -51.7 5.76056\n      vertex 46.1 -51.7 5.6\n    endloop\n  endfacet\n  facet normal 0 -0.89056 -0.45486\n    outer loop\n      vertex 34.1258 -38.969 16.477\n      vertex 34.12746 -38.88013 16.30301\n      vertex 45.22752 -38.969 16.477\n    endloop\n  endfacet\n  facet normal 0.70742 -0.18301 0.68269\n    outer loop\n      vertex 51.737 11.89105 -15.72725\n      vertex 51.737 8.80006 -16.55586\n      vertex 51.86177 11.92337 -15.84787\n    endloop\n  endfacet\n  facet normal -0.70652 -0.18325 0.68356\n    outer loop\n      vertex 53.61079 11.93038 -15.87403\n      vertex 53.72891 8.80887 -16.58874\n      vertex 53.763 11.89105 -15.72725\n    endloop\n  endfacet\n  facet normal 0 0.45359 -0.89121\n    outer loop\n      vertex 45.182 -41.591 17.00907\n      vertex 45.13549 -41.59019 17.00948\n      vertex 45.18865 -41.208 17.204\n    endloop\n  endfacet\n  facet normal -0.89073 -0.1177 0.43904\n    outer loop\n      vertex 53.941 11.80078 -15.39032\n      vertex 53.763 11.89105 -15.72725\n      vertex 53.941 8.70977 -16.21894\n    endloop\n  endfacet\n  facet normal 0 0.45295 -0.89154\n    outer loop\n      vertex 34.616 -53.666 12.12\n      vertex 25.4 -53.666 12.12\n      vertex 25.4 -53.107 12.404\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 41.735 -3.2 9.135\n      vertex 40.955 -3.2 9.533\n      vertex 27.1 -3.2 0\n    endloop\n  endfacet\n  facet normal -0.98775 -0.0404 0.1507\n    outer loop\n      vertex 53.941 8.70977 -16.21894\n      vertex 54.002 8.60981 -15.84593\n      vertex 53.941 11.80078 -15.39032\n    endloop\n  endfacet\n  facet normal -0.98775 -0.0404 0.1507\n    outer loop\n      vertex 54.002 11.70084 -15.0173\n      vertex 53.941 11.80078 -15.39032\n      vertex 54.002 8.60981 -15.84593\n    endloop\n  endfacet\n  facet normal -0.98781 0.0403 -0.15034\n    outer loop\n      vertex 53.941 8.50959 -15.47199\n      vertex 53.941 11.60065 -14.64335\n      vertex 54.002 11.70084 -15.0173\n    endloop\n  endfacet\n  facet normal -0.98781 0.0403 -0.15034\n    outer loop\n      vertex 53.941 8.50959 -15.47199\n      vertex 54.002 11.70084 -15.0173\n      vertex 54.002 8.60981 -15.84593\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 27.1 -3.2 20\n      vertex 27.1 -3.2 0\n      vertex 39.8 -3.2 11.799\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.335 -3.2 10.152\n      vertex 39.937 -3.2 10.933\n      vertex 27.1 -3.2 0\n    endloop\n  endfacet\n  facet normal 0 0.15793 0.98745\n    outer loop\n      vertex 25.4 -52.488 8.497\n      vertex 25.4 -53.107 8.596\n      vertex 34.616 -52.488 8.497\n    endloop\n  endfacet\n  facet normal -0.89086 0.11763 -0.43878\n    outer loop\n      vertex 53.78491 8.43036 -15.17632\n      vertex 53.86082 11.55996 -14.49146\n      vertex 53.941 8.50959 -15.47199\n    endloop\n  endfacet\n  facet normal 0 -0.15818 0.98741\n    outer loop\n      vertex 25.4 -52.488 8.497\n      vertex 34.616 -52.488 8.497\n      vertex 30.72 -51.87 8.596\n    endloop\n  endfacet\n  facet normal -0.70618 0.18331 -0.68389\n    outer loop\n      vertex 53.6382 11.47814 -14.18608\n      vertex 53.763 8.41924 -15.13485\n      vertex 53.52008 8.35653 -14.90081\n    endloop\n  endfacet\n  facet normal -0.70652 0.18325 -0.68356\n    outer loop\n      vertex 53.486 8.34772 -14.86795\n      vertex 53.486 11.43882 -14.03931\n      vertex 53.52008 8.35653 -14.90081\n    endloop\n  endfacet\n  facet normal 0 -0.45295 -0.89154\n    outer loop\n      vertex 25.539 -51.788 12.36234\n      vertex 25.539 -51.311 12.12\n      vertex 30.72 -51.87 12.404\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 58.2 -3.2 20\n      vertex 45.402 -3.2 11.799\n      vertex 58.2 -3.2 0\n    endloop\n  endfacet\n  facet normal -0.45444 0.23065 -0.8604\n    outer loop\n      vertex 53.137 11.39274 -13.86733\n      vertex 53.486 11.43882 -14.03931\n      vertex 53.137 8.30163 -14.69598\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 45.265 -3.2 10.933\n      vertex 44.867 -3.2 10.152\n      vertex 58.2 -3.2 0\n    endloop\n  endfacet\n  facet normal 0 0.45295 -0.89154\n    outer loop\n      vertex 25.4 -53.107 12.404\n      vertex 34.616 -53.107 12.404\n      vertex 34.616 -53.666 12.12\n    endloop\n  endfacet\n  facet normal 0.15603 0.25573 -0.95408\n    outer loop\n      vertex 52.4106 8.29969 -14.68874\n      vertex 52.57563 11.38408 -13.83503\n      vertex 52.75 8.28582 -14.63696\n    endloop\n  endfacet\n  facet normal 0.15603 0.25573 -0.95408\n    outer loop\n      vertex 52.75 11.37695 -13.80842\n      vertex 52.75 8.28582 -14.63696\n      vertex 52.57563 11.38408 -13.83503\n    endloop\n  endfacet\n  facet normal 0.15538 0.25579 -0.95416\n    outer loop\n      vertex 52.363 8.30163 -14.69598\n      vertex 52.363 11.39274 -13.86733\n      vertex 52.4106 8.29969 -14.68874\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 43.467 -3.2 9.135\n      vertex 42.601 -3.2 8.998\n      vertex 58.2 -3.2 0\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 44.867 -3.2 10.152\n      vertex 44.248 -3.2 9.533\n      vertex 58.2 -3.2 0\n    endloop\n  endfacet\n  facet normal 0 0.70711 0.70711\n    outer loop\n      vertex 34.616 -53.666 8.88\n      vertex 25.4 -53.666 8.88\n      vertex 34.616 -54.109 9.323\n    endloop\n  endfacet\n  facet normal 0 0.45295 0.89154\n    outer loop\n      vertex 34.616 -53.107 8.596\n      vertex 25.4 -53.107 8.596\n      vertex 34.616 -53.666 8.88\n    endloop\n  endfacet\n  facet normal -0.15538 0.25575 -0.95417\n    outer loop\n      vertex 52.75 8.28582 -14.63696\n      vertex 52.75 11.37695 -13.80842\n      vertex 52.79762 8.28775 -14.64419\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 42.78952 20.77058 2.12893\n      vertex 46.1 22.603 1.874\n      vertex 42.859 20.75938 2.13049\n    endloop\n  endfacet\n  facet normal -0.15603 0.25576 -0.95407\n    outer loop\n      vertex 52.79762 8.28775 -14.64419\n      vertex 52.96266 11.38561 -13.84073\n      vertex 53.137 8.30163 -14.69598\n    endloop\n  endfacet\n  facet normal 0 0.89121 -0.45359\n    outer loop\n      vertex 25.4 -54.393 11.119\n      vertex 34.616 -54.109 11.677\n      vertex 34.616 -54.393 11.119\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 46.1 22.603 1.874\n      vertex 42.392 20.83382 2.12013\n      vertex 37.8 22.603 1.874\n    endloop\n  endfacet\n  facet normal 0 0.9877 -0.15637\n    outer loop\n      vertex 25.4 -54.393 11.119\n      vertex 34.616 -54.393 11.119\n      vertex 34.616 -54.491 10.5\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 46.9 21.60559 2.01276\n      vertex 46.9 8 3.9056\n      vertex 43.828 18.83489 2.39823\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 46.9 21.60559 2.01276\n      vertex 43.902 19.30637 2.33263\n      vertex 43.88871 19.39119 2.32083\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 43.28 20.54247 2.16067\n      vertex 42.859 20.75938 2.13049\n      vertex 46.1 22.603 1.874\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 43.28 20.54247 2.16067\n      vertex 46.1 22.603 1.874\n      vertex 43.614 20.20472 2.20765\n    endloop\n  endfacet\n  facet normal 0 0.45295 0.89154\n    outer loop\n      vertex 25.4 -53.666 8.88\n      vertex 34.616 -53.666 8.88\n      vertex 25.4 -53.107 8.596\n    endloop\n  endfacet\n  facet normal 0 0.15793 0.98745\n    outer loop\n      vertex 34.616 -52.488 8.497\n      vertex 25.4 -53.107 8.596\n      vertex 34.616 -53.107 8.596\n    endloop\n  endfacet\n  facet normal 0.70652 -0.18331 0.68354\n    outer loop\n      vertex 52.014 8.8718 -16.82357\n      vertex 52.014 11.9627 -15.99467\n      vertex 51.97988 8.86299 -16.79067\n    endloop\n  endfacet\n  facet normal 0 -0.15818 0.98741\n    outer loop\n      vertex 34.616 -51.87 8.596\n      vertex 30.72 -51.87 8.596\n      vertex 34.616 -52.488 8.497\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 40.956 19.77882 2.26691\n      vertex 37.8 21.5208 2.02456\n      vertex 41.17 20.20472 2.20765\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 40.89557 19.21993 2.34466\n      vertex 37.8 21.5208 2.02456\n      vertex 40.882 19.30637 2.33263\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 37.8 22.603 1.874\n      vertex 41.17 20.20472 2.20765\n      vertex 37.8 21.5208 2.02456\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 37.8 22.603 1.874\n      vertex 37.8 21.5208 2.02456\n      vertex 32.8 21.5208 2.02456\n    endloop\n  endfacet\n  facet normal 0 -0.45295 0.89154\n    outer loop\n      vertex 34.539 -51.788 8.63766\n      vertex 30.72 -51.87 8.596\n      vertex 34.616 -51.87 8.596\n    endloop\n  endfacet\n  facet normal 0 -0.45295 0.89154\n    outer loop\n      vertex 34.616 -51.788 8.63766\n      vertex 34.539 -51.788 8.63766\n      vertex 34.616 -51.87 8.596\n    endloop\n  endfacet\n  facet normal 0.45248 -0.23099 0.86134\n    outer loop\n      vertex 52.014 11.9627 -15.99467\n      vertex 52.014 8.8718 -16.82357\n      vertex 52.17121 11.98334 -16.07172\n    endloop\n  endfacet\n  facet normal 0.45444 -0.23062 0.86041\n    outer loop\n      vertex 52.363 8.91767 -16.99473\n      vertex 52.363 12.00867 -16.16623\n      vertex 52.32002 8.91199 -16.97355\n    endloop\n  endfacet\n  facet normal 0.45444 -0.23062 0.86041\n    outer loop\n      vertex 52.17121 11.98334 -16.07172\n      vertex 52.32002 8.91199 -16.97355\n      vertex 52.363 12.00867 -16.16623\n    endloop\n  endfacet\n  facet normal 0 -0.45295 -0.89154\n    outer loop\n      vertex 30.72 -51.87 12.404\n      vertex 34.539 -51.788 12.36234\n      vertex 34.616 -51.87 12.404\n    endloop\n  endfacet\n  facet normal 0 -0.45295 -0.89154\n    outer loop\n      vertex 34.616 -51.788 12.36234\n      vertex 34.616 -51.87 12.404\n      vertex 34.539 -51.788 12.36234\n    endloop\n  endfacet\n  facet normal 0.15603 -0.25585 0.95404\n    outer loop\n      vertex 52.53732 12.0159 -16.19325\n      vertex 52.70234 8.93177 -17.04733\n      vertex 52.75 12.0246 -16.2257\n    endloop\n  endfacet\n  facet normal 0 -0.15818 -0.98741\n    outer loop\n      vertex 30.72 -51.87 12.404\n      vertex 34.616 -51.87 12.404\n      vertex 34.616 -52.488 12.503\n    endloop\n  endfacet\n  facet normal 0 -0.15818 -0.98741\n    outer loop\n      vertex 25.4 -52.488 12.503\n      vertex 30.72 -51.87 12.404\n      vertex 34.616 -52.488 12.503\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01736 0\n    outer loop\n      vertex 45.182 -41.591 13.59093\n      vertex 45.182 -41.591 10.5\n      vertex 45.18865 -41.208 13.396\n    endloop\n  endfacet\n  facet normal 0 0.15793 -0.98745\n    outer loop\n      vertex 34.616 -52.488 12.503\n      vertex 34.616 -53.107 12.404\n      vertex 25.4 -52.488 12.503\n    endloop\n  endfacet\n  facet normal 0 0.15793 -0.98745\n    outer loop\n      vertex 25.4 -53.107 12.404\n      vertex 25.4 -52.488 12.503\n      vertex 34.616 -53.107 12.404\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01736 0\n    outer loop\n      vertex 45.1994 -40.589 13.298\n      vertex 45.182 -41.591 10.5\n      vertex 45.21014 -39.97 13.396\n    endloop\n  endfacet\n  facet normal 0.15843 -0.25563 0.95371\n    outer loop\n      vertex 52.70234 8.93177 -17.04733\n      vertex 52.53732 12.0159 -16.19325\n      vertex 52.363 8.91767 -16.99473\n    endloop\n  endfacet\n  facet normal -0.15843 -0.25575 0.95367\n    outer loop\n      vertex 52.75 12.0246 -16.2257\n      vertex 52.75 8.93371 -17.0546\n      vertex 52.92433 12.01736 -16.19868\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -48.9 7.542\n      vertex 45.937 -50.868 9.323\n      vertex 45.937 -48.231 8.855\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -48.231 8.855\n      vertex 45.937 -50.584 9.881\n      vertex 45.937 -48 10.31\n    endloop\n  endfacet\n  facet normal -0.15603 -0.25573 0.95408\n    outer loop\n      vertex 53.08934 8.91962 -17.002\n      vertex 53.137 12.00867 -16.16623\n      vertex 52.92433 12.01736 -16.19868\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -50.486 10.5\n      vertex 45.937 -50.584 11.119\n      vertex 45.937 -48.231 11.765\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -48.231 11.765\n      vertex 45.937 -48 10.31\n      vertex 45.937 -50.486 10.5\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01736 0\n    outer loop\n      vertex 45.21014 -39.97 13.396\n      vertex 45.274 -36.292 10.5\n      vertex 45.21983 -39.412 13.68\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01736 0\n    outer loop\n      vertex 45.18865 -41.208 13.396\n      vertex 45.182 -41.591 10.5\n      vertex 45.1994 -40.589 13.298\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01736 0\n    outer loop\n      vertex 45.274 -36.292 10.5\n      vertex 45.21014 -39.97 13.396\n      vertex 45.182 -41.591 10.5\n    endloop\n  endfacet\n  facet normal -0.45248 -0.23088 0.86137\n    outer loop\n      vertex 53.44302 8.87748 -16.84475\n      vertex 53.2942 11.98802 -16.08918\n      vertex 53.137 8.91767 -16.99473\n    endloop\n  endfacet\n  facet normal -0.45444 -0.23073 0.86038\n    outer loop\n      vertex 53.2942 11.98802 -16.08918\n      vertex 53.44302 8.87748 -16.84475\n      vertex 53.486 11.9627 -15.99467\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 41.897 -36.2 3.234\n      vertex 42.295 -36.2 2.453\n      vertex 45.22932 -36.2 13.55481\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 45.274 -36.292 10.5\n      vertex 45.182 -41.591 10.5\n      vertex 40.00412 -36.2 10.5\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 34.20077 -40.38674 10.5\n      vertex 40.00412 -36.2 10.5\n      vertex 45.182 -41.591 10.5\n    endloop\n  endfacet\n  facet normal -0.70742 -0.18308 0.68267\n    outer loop\n      vertex 53.486 11.9627 -15.99467\n      vertex 53.486 8.8718 -16.82357\n      vertex 53.61079 11.93038 -15.87403\n    endloop\n  endfacet\n  facet normal -0.70652 -0.18325 0.68356\n    outer loop\n      vertex 53.763 8.80006 -16.55586\n      vertex 53.763 11.89105 -15.72725\n      vertex 53.72891 8.80887 -16.58874\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 52.2 -36.2 -10.48639\n      vertex 45.22932 -36.2 13.55481\n      vertex 42.295 -36.2 2.453\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 41.277 -33.2 3.853\n      vertex 40.496 -33.2 4.251\n      vertex 52.2 -33.2 20\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -54.109 11.677\n      vertex 45.937 -54.393 11.119\n      vertex 45.937 -56.524 13.078\n    endloop\n  endfacet\n  facet normal -0.89073 -0.1177 0.43904\n    outer loop\n      vertex 53.763 8.80006 -16.55586\n      vertex 53.941 8.70977 -16.21894\n      vertex 53.763 11.89105 -15.72725\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 51.97988 8.86299 -16.79067\n      vertex 51.737 8.80006 -16.55586\n      vertex 35.0753 9.443 -18.955\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -54.491 10.5\n      vertex 45.937 -57 12.14379\n      vertex 45.937 -54.393 11.119\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -57 12.14379\n      vertex 45.937 -56.524 13.078\n      vertex 45.937 -54.393 11.119\n    endloop\n  endfacet\n  facet normal -0.89073 0.11768 -0.43904\n    outer loop\n      vertex 53.763 8.41924 -15.13485\n      vertex 53.763 11.51035 -14.30631\n      vertex 53.78491 8.43036 -15.17632\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -52.489 8.497\n      vertex 45.937 -52.712 5.6\n      vertex 45.937 -53.107 8.596\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -53.107 8.596\n      vertex 45.937 -54.168 5.831\n      vertex 45.937 -53.666 8.88\n    endloop\n  endfacet\n  facet normal -0.89086 0.11763 -0.43878\n    outer loop\n      vertex 53.941 11.60065 -14.64335\n      vertex 53.941 8.50959 -15.47199\n      vertex 53.86082 11.55996 -14.49146\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 51.6832 5.23127 -3.23889\n      vertex 51.563 5.17042 -3.01184\n      vertex 33.941 5.17042 -3.01184\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 52.363 8.30163 -14.69598\n      vertex 52.017 5.33204 -3.61494\n      vertex 52.014 8.34772 -14.86795\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 51.741 5.26059 -3.3483\n      vertex 51.6832 5.23127 -3.23889\n      vertex 33.941 5.17042 -3.01184\n    endloop\n  endfacet\n  facet normal -0.70652 0.18325 -0.68356\n    outer loop\n      vertex 53.6382 11.47814 -14.18608\n      vertex 53.52008 8.35653 -14.90081\n      vertex 53.486 11.43882 -14.03931\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -50.486 10.5\n      vertex 45.937 -48 10.31\n      vertex 45.937 -50.584 9.881\n    endloop\n  endfacet\n  facet normal 0.45444 0.23065 -0.8604\n    outer loop\n      vertex 52.363 11.39274 -13.86733\n      vertex 52.363 8.30163 -14.69598\n      vertex 52.014 11.43882 -14.03931\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -50.584 11.119\n      vertex 45.937 -50.868 11.677\n      vertex 45.937 -48.9 13.078\n    endloop\n  endfacet\n  facet normal 0.70618 0.18333 -0.68388\n    outer loop\n      vertex 52.014 8.34772 -14.86795\n      vertex 51.88922 11.47102 -14.15952\n      vertex 52.014 11.43882 -14.03931\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -50.868 11.677\n      vertex 45.937 -51.311 12.12\n      vertex 45.937 -48.9 13.078\n    endloop\n  endfacet\n  facet normal -0.89073 0.11768 -0.43904\n    outer loop\n      vertex 53.86082 11.55996 -14.49146\n      vertex 53.78491 8.43036 -15.17632\n      vertex 53.763 11.51035 -14.30631\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -51.256 14.789\n      vertex 45.937 -49.942 14.12\n      vertex 45.937 -51.87 12.404\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 35.0753 9.443 -18.955\n      vertex 52.014 8.8718 -16.82357\n      vertex 51.97988 8.86299 -16.79067\n    endloop\n  endfacet\n  facet normal -0.70618 0.18331 -0.68389\n    outer loop\n      vertex 53.763 11.51035 -14.30631\n      vertex 53.763 8.41924 -15.13485\n      vertex 53.6382 11.47814 -14.18608\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -52.489 12.503\n      vertex 45.937 -51.256 14.789\n      vertex 45.937 -51.87 12.404\n    endloop\n  endfacet\n  facet normal -0.45444 0.23065 -0.8604\n    outer loop\n      vertex 53.486 8.34772 -14.86795\n      vertex 53.137 8.30163 -14.69598\n      vertex 53.486 11.43882 -14.03931\n    endloop\n  endfacet\n  facet normal -0.15538 0.25575 -0.95417\n    outer loop\n      vertex 52.96266 11.38561 -13.84073\n      vertex 52.79762 8.28775 -14.64419\n      vertex 52.75 11.37695 -13.80842\n    endloop\n  endfacet\n  facet normal -0.15603 0.25576 -0.95407\n    outer loop\n      vertex 53.137 11.39274 -13.86733\n      vertex 53.137 8.30163 -14.69598\n      vertex 52.96266 11.38561 -13.84073\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -56.524 13.078\n      vertex 45.937 -55.482 14.12\n      vertex 45.937 -54.109 11.677\n    endloop\n  endfacet\n  facet normal -0.99982 -0.01896 -0.00193\n    outer loop\n      vertex 55.3377 -0.802 0\n      vertex 55.33775 -0.802 -0.0242\n      vertex 55.33844 -0.84055 0\n    endloop\n  endfacet\n  facet normal -0.99982 -0.01896 -0.00193\n    outer loop\n      vertex 55.27692 2.403 0\n      vertex 55.2 6.45898 0\n      vertex 55.28085 2.403 -2.0364\n    endloop\n  endfacet\n  facet normal -0.99982 -0.01896 -0.00193\n    outer loop\n      vertex 55.2 6.95722 -4.89569\n      vertex 55.28085 2.403 -2.0364\n      vertex 55.2 6.45898 0\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 55.2 7.55657 0\n      vertex 55.2 9.32366 -6.38096\n      vertex 55.2 7.67736 0\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 55.2 12.534 -18.127\n      vertex 55.2 7.67736 0\n      vertex 55.2 9.32366 -6.38096\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 51.92736 5.30887 -3.52849\n      vertex 52.014 8.34772 -14.86795\n      vertex 52.017 5.33204 -3.61494\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 51.502 5.0705 -2.639\n      vertex 51.52181 5.03807 -2.51797\n      vertex 34.002 4.36328 0\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 52.752 4.74728 -1.43288\n      vertex 55.2 4.36328 0\n      vertex 52.366 4.7631 -1.49193\n    endloop\n  endfacet\n  facet normal -0.0155 0.96361 0.26685\n    outer loop\n      vertex 55.2 7.55657 0\n      vertex 56.1422 7.57173 0\n      vertex 55.2 9.32366 -6.38096\n    endloop\n  endfacet\n  facet normal -0.0155 0.96361 0.26685\n    outer loop\n      vertex 58.008 9.368 -6.378\n      vertex 55.2 9.32366 -6.38096\n      vertex 56.1422 7.57173 0\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 55.2 9.17432 -6.2872\n      vertex 55.2 7.74214 -12.60822\n      vertex 55.2 9.32366 -6.38096\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 55.2 12.534 -18.127\n      vertex 55.2 9.32366 -6.38096\n      vertex 55.2 7.74214 -12.60822\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -51.256 14.789\n      vertex 45.937 -52.489 12.503\n      vertex 45.937 -52.712 15.02\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -54.168 14.789\n      vertex 45.937 -52.712 15.02\n      vertex 45.937 -53.107 12.404\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -53.107 12.404\n      vertex 45.937 -52.712 15.02\n      vertex 45.937 -52.489 12.503\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -53.107 12.404\n      vertex 45.937 -53.666 12.12\n      vertex 45.937 -54.168 14.789\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 51.58089 8.49849 -15.43054\n      vertex 51.737 8.41924 -15.13485\n      vertex 33.764 5.26059 -3.3483\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 51.92736 5.30887 -3.52849\n      vertex 51.741 5.26059 -3.3483\n      vertex 52.014 8.34772 -14.86795\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.941 5.17042 -3.01184\n      vertex 52.014 8.34772 -14.86795\n      vertex 51.741 5.26059 -3.3483\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 51.7711 8.41043 -15.10197\n      vertex 52.014 8.34772 -14.86795\n      vertex 33.941 5.17042 -3.01184\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 51.737 8.41924 -15.13485\n      vertex 51.7711 8.41043 -15.10197\n      vertex 33.941 5.17042 -3.01184\n    endloop\n  endfacet\n  facet normal 0.00929 -0.53167 -0.8469\n    outer loop\n      vertex 58.008 9.368 -6.378\n      vertex 55.2 9.17432 -6.2872\n      vertex 55.2 9.32366 -6.38096\n    endloop\n  endfacet\n  facet normal -0.01583 0.96363 0.26676\n    outer loop\n      vertex 58.008 9.368 -6.378\n      vertex 56.1422 7.57173 0\n      vertex 58.02918 7.60273 0\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 55.2 7.74214 -12.60822\n      vertex 55.2 9.443 -18.955\n      vertex 55.2 12.534 -18.127\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 55.2 6.95722 -4.89569\n      vertex 55.2 7.74214 -12.60822\n      vertex 55.2 9.17432 -6.2872\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -50.584 9.881\n      vertex 45.937 -48.231 8.855\n      vertex 45.937 -50.868 9.323\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -48.9 13.078\n      vertex 45.937 -48.231 11.765\n      vertex 45.937 -50.584 11.119\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -51.311 12.12\n      vertex 45.937 -51.87 12.404\n      vertex 45.937 -49.942 14.12\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -48.9 13.078\n      vertex 45.937 -51.311 12.12\n      vertex 45.937 -49.942 14.12\n    endloop\n  endfacet\n  facet normal 0.00977 -0.53157 -0.84696\n    outer loop\n      vertex 55.33775 -0.802 -0.0242\n      vertex 56.103 -0.802 -0.01538\n      vertex 55.33844 -0.84055 0\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 41.897 -36.2 3.234\n      vertex 45.22932 -36.2 13.55481\n      vertex 41.277 -36.2 3.853\n    endloop\n  endfacet\n  facet normal 0.00977 -0.53157 -0.84696\n    outer loop\n      vertex 55.28085 2.403 -2.0364\n      vertex 55.2 6.95722 -4.89569\n      vertex 56.103 2.403 -2.02692\n    endloop\n  endfacet\n  facet normal 0.00977 -0.53157 -0.84696\n    outer loop\n      vertex 55.2 9.17432 -6.2872\n      vertex 58.01508 -0.79136 0\n      vertex 55.2 6.95722 -4.89569\n    endloop\n  endfacet\n  facet normal 0.00977 -0.53157 -0.84696\n    outer loop\n      vertex 58.01508 -0.79136 0\n      vertex 55.33844 -0.84055 0\n      vertex 56.103 -0.802 -0.01538\n    endloop\n  endfacet\n  facet normal 0.00977 -0.53157 -0.84696\n    outer loop\n      vertex 58.01508 -0.79136 0\n      vertex 56.103 -0.802 -0.01538\n      vertex 56.103 2.403 -2.02692\n    endloop\n  endfacet\n  facet normal 0.00977 -0.53157 -0.84696\n    outer loop\n      vertex 56.103 2.403 -2.02692\n      vertex 55.2 6.95722 -4.89569\n      vertex 58.01508 -0.79136 0\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -54.168 5.831\n      vertex 45.937 -55.482 6.5\n      vertex 45.937 -53.666 8.88\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -49.942 6.5\n      vertex 45.937 -51.256 5.831\n      vertex 45.937 -51.87 8.596\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -51.311 8.88\n      vertex 45.937 -49.942 6.5\n      vertex 45.937 -51.87 8.596\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -49.942 6.5\n      vertex 45.937 -51.311 8.88\n      vertex 45.937 -48.9 7.542\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -50.868 9.323\n      vertex 45.937 -48.9 7.542\n      vertex 45.937 -51.311 8.88\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -52.489 8.497\n      vertex 45.937 -51.87 8.596\n      vertex 45.937 -51.256 5.831\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -51.256 5.831\n      vertex 45.937 -52.712 5.6\n      vertex 45.937 -52.489 8.497\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -54.168 5.831\n      vertex 45.937 -53.107 8.596\n      vertex 45.937 -52.712 5.6\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 41.277 -36.2 3.853\n      vertex 45.22932 -36.2 13.55481\n      vertex 40.496 -36.2 4.251\n    endloop\n  endfacet\n  facet normal 0.00929 -0.53167 -0.8469\n    outer loop\n      vertex 55.2 9.17432 -6.2872\n      vertex 58.008 9.368 -6.378\n      vertex 58.01508 -0.79136 0\n    endloop\n  endfacet\n  facet normal 0.00929 -0.53167 -0.8469\n    outer loop\n      vertex 58.18832 -0.78834 0\n      vertex 58.01508 -0.79136 0\n      vertex 58.008 9.368 -6.378\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 55.3377 -0.802 0\n      vertex 56.103 -0.802 20\n      vertex 56.103 -0.802 -0.01538\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 55.3377 -0.802 0\n      vertex 56.103 -0.802 -0.01538\n      vertex 55.33775 -0.802 -0.0242\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 55.28085 2.403 -2.0364\n      vertex 56.103 2.403 -2.02692\n      vertex 55.27692 2.403 0\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 56.103 2.403 20\n      vertex 55.27692 2.403 0\n      vertex 56.103 2.403 -2.02692\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -54.393 9.881\n      vertex 45.937 -54.109 9.323\n      vertex 45.937 -57 8.47621\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -56.524 7.542\n      vertex 45.937 -57 8.47621\n      vertex 45.937 -54.109 9.323\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -54.109 9.323\n      vertex 45.937 -53.666 8.88\n      vertex 45.937 -55.482 6.5\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -55.482 6.5\n      vertex 45.937 -56.524 7.542\n      vertex 45.937 -54.109 9.323\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -54.491 10.5\n      vertex 45.937 -54.393 9.881\n      vertex 45.937 -57 8.47621\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -57 12.14379\n      vertex 45.937 -54.491 10.5\n      vertex 45.937 -57 8.47621\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 56.103 -0.802 -0.01538\n      vertex 56.103 -0.802 20\n      vertex 56.103 2.403 20\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 56.103 2.403 -2.02692\n      vertex 56.103 -0.802 -0.01538\n      vertex 56.103 2.403 20\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.00412 -36.2 13.37578\n      vertex 40.00412 -36.2 10.5\n      vertex 45.22932 -36.2 13.55481\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.00412 -36.2 10.5\n      vertex 40.496 -36.2 4.251\n      vertex 45.22932 -36.2 13.55481\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -54.168 14.789\n      vertex 45.937 -53.666 12.12\n      vertex 45.937 -55.482 14.12\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 45.937 -53.666 12.12\n      vertex 45.937 -54.109 11.677\n      vertex 45.937 -55.482 14.12\n    endloop\n  endfacet\n  facet normal 0 0.1378 0.99046\n    outer loop\n      vertex 42.60231 17.91433 5.32779\n      vertex 42.392 17.88087 5.33245\n      vertex 46.9 8.051 6.7\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 44.248 -3.2 9.533\n      vertex 43.467 -3.2 9.135\n      vertex 58.2 -3.2 0\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 52.2 -33.2 -58\n      vertex 51.8 -33.2 -30.37797\n      vertex 52.2 -33.2 20\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 46.9 8 3.01932\n      vertex 37.8 8 3.01941\n      vertex 46.9 8 3.9056\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 58.2 8 0\n      vertex 27.1 8 0\n      vertex 46.9 8 3.01932\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 30.30975 2.403 0\n      vertex 55.27692 2.403 0\n      vertex 42.601 2.403 8.998\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 46.9 21.60559 2.01276\n      vertex 43.614 20.20472 2.20765\n      vertex 46.1 22.603 1.874\n    endloop\n  endfacet\n  facet normal 0.01746 0.99985 0\n    outer loop\n      vertex 45.274 -36.292 10.5\n      vertex 40.00412 -36.2 10.5\n      vertex 45.22783 -36.29119 13.37583\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 34.002 5.0705 -2.639\n      vertex 33.98219 5.10296 -2.76013\n      vertex 51.502 5.0705 -2.639\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 52.017 5.33204 -3.61494\n      vertex 52.363 8.30163 -14.69598\n      vertex 52.366 5.37813 -3.78692\n    endloop\n  endfacet\n  facet normal 0 -0.9994 0.03477\n    outer loop\n      vertex 46.9 8.051 6.7\n      vertex 37.8 8.051 6.7\n      vertex 46.9 8 5.23414\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 34.002 4.36328 0\n      vertex 52.366 4.7631 -1.49193\n      vertex 55.2 4.36328 0\n    endloop\n  endfacet\n  facet normal 0 0.9994 -0.03477\n    outer loop\n      vertex 37.8 22.603 1.874\n      vertex 37.8 22.60546 1.94475\n      vertex 46.1 22.603 1.874\n    endloop\n  endfacet\n  facet normal 0.01746 0.99985 0\n    outer loop\n      vertex 40.00412 -36.2 13.37578\n      vertex 45.22783 -36.29119 13.37583\n      vertex 40.00412 -36.2 10.5\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 51.741 4.88052 -1.93008\n      vertex 52.017 4.80894 -1.66297\n      vertex 34.002 4.36328 0\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 52.017 4.80894 -1.66297\n      vertex 52.366 4.7631 -1.49193\n      vertex 34.002 4.36328 0\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 45.2292 -36.2 15.21\n      vertex 52.2 -36.2 20\n      vertex 45.22923 -36.2 16.63187\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 37.8 8 5.23414\n      vertex 42.601 8 8.998\n      vertex 46.9 8 5.23414\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 44.867 -0.802 10.152\n      vertex 55.3377 -0.802 0\n      vertex 44.248 -0.802 9.533\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 45.265 -0.802 10.933\n      vertex 55.3377 -0.802 0\n      vertex 44.867 -0.802 10.152\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01747 0.0001\n    outer loop\n      vertex 45.13562 -41.59019 12.09626\n      vertex 45.13548 -41.59019 13.59052\n      vertex 45.105 -43.347 11.4\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01747 0.0001\n    outer loop\n      vertex 45.13337 -41.71049 13.65175\n      vertex 45.105 -43.347 11.4\n      vertex 45.13548 -41.59019 13.59052\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 51.559 8.70977 -16.21894\n      vertex 35.0753 9.443 -18.955\n      vertex 51.737 8.80006 -16.55586\n    endloop\n  endfacet\n  facet normal 0.99985 -0.01747 0.0001\n    outer loop\n      vertex 45.128 -42.034 10.731\n      vertex 45.13562 -41.59019 12.09626\n      vertex 45.105 -43.347 11.4\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 52.014 8.8718 -16.82357\n      vertex 35.0753 9.443 -18.955\n      vertex 52.32002 8.91199 -16.97355\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 51.563 5.17042 -3.01184\n      vertex 51.54319 5.13795 -2.89068\n      vertex 33.941 5.17042 -3.01184\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 52.2 -36.2 -10.48639\n      vertex 52.2 -36.2 20\n      vertex 45.22932 -36.2 13.55481\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 52.79762 8.28775 -14.64419\n      vertex 52.366 5.37813 -3.78692\n      vertex 52.75 8.28582 -14.63696\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 34.616 -0.802 0\n      vertex 42.601 -0.802 8.998\n      vertex 55.3377 -0.802 0\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 52.75 8.28582 -14.63696\n      vertex 52.366 5.37813 -3.78692\n      vertex 52.4106 8.29969 -14.68874\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 43.467 2.403 9.135\n      vertex 55.27692 2.403 0\n      vertex 44.248 2.403 9.533\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 43.467 2.403 9.135\n      vertex 42.601 2.403 8.998\n      vertex 55.27692 2.403 0\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 52.4106 8.29969 -14.68874\n      vertex 52.366 5.37813 -3.78692\n      vertex 52.363 8.30163 -14.69598\n    endloop\n  endfacet\n  facet normal 0 -0.9994 0.03477\n    outer loop\n      vertex 46.9 8 5.23414\n      vertex 37.8 8.051 6.7\n      vertex 37.8 8 5.23414\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 52.70234 8.93177 -17.04733\n      vertex 52.363 8.91767 -16.99473\n      vertex 55.2 9.443 -18.955\n    endloop\n  endfacet\n  facet normal 0 0.98763 0.1568\n    outer loop\n      vertex 54.937 -48 10.31\n      vertex 45.937 -48 10.31\n      vertex 54.937 -48.231 11.765\n    endloop\n  endfacet\n  facet normal 0 0.98763 0.1568\n    outer loop\n      vertex 45.937 -48.231 11.765\n      vertex 54.937 -48.231 11.765\n      vertex 45.937 -48 10.31\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 52.752 5.39395 -3.84597\n      vertex 52.366 5.37813 -3.78692\n      vertex 55.2 7.74214 -12.60822\n    endloop\n  endfacet\n  facet normal 0 0.89101 0.45399\n    outer loop\n      vertex 45.937 -48.9 13.078\n      vertex 54.937 -48.231 11.765\n      vertex 45.937 -48.231 11.765\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 51.741 7.97239 -1.10114\n      vertex 46.1 7.67736 0\n      vertex 52.017 7.90082 -0.83403\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.137 11.39274 -13.86733\n      vertex 52.96266 11.38561 -13.84073\n      vertex 53.138 8.46988 -2.95801\n    endloop\n  endfacet\n  facet normal 0 0.98763 -0.1568\n    outer loop\n      vertex 54.937 -48 10.31\n      vertex 45.937 -48.231 8.855\n      vertex 45.937 -48 10.31\n    endloop\n  endfacet\n  facet normal 0.99984 -0.01784 0.00037\n    outer loop\n      vertex 45.12532 -42.15262 14.06662\n      vertex 45.086 -44.39 12.442\n      vertex 45.13237 -41.766 13.68\n    endloop\n  endfacet\n  facet normal 0 0.70711 0.70711\n    outer loop\n      vertex 54.937 -49.942 14.12\n      vertex 45.937 -48.9 13.078\n      vertex 45.937 -49.942 14.12\n    endloop\n  endfacet\n  facet normal 0.99984 -0.01784 0.00037\n    outer loop\n      vertex 45.086 -44.39 12.442\n      vertex 45.105 -43.347 11.4\n      vertex 45.13237 -41.766 13.68\n    endloop\n  endfacet\n  facet normal 0.99984 -0.01784 0.00037\n    outer loop\n      vertex 45.13337 -41.71049 13.65175\n      vertex 45.13237 -41.766 13.68\n      vertex 45.105 -43.347 11.4\n    endloop\n  endfacet\n  facet normal 0 0.45371 0.89115\n    outer loop\n      vertex 54.937 -49.942 14.12\n      vertex 45.937 -49.942 14.12\n      vertex 45.937 -51.256 14.789\n    endloop\n  endfacet\n  facet normal 0 0.15669 0.98765\n    outer loop\n      vertex 46.1 -52.58594 15\n      vertex 46.1 -51.7 14.85944\n      vertex 45.937 -52.712 15.02\n    endloop\n  endfacet\n  facet normal 0 0.15669 0.98765\n    outer loop\n      vertex 45.937 -51.256 14.789\n      vertex 45.937 -52.712 15.02\n      vertex 46.1 -51.7 14.85944\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 52.366 7.85499 -0.66298\n      vertex 52.017 7.90082 -0.83403\n      vertex 46.1 7.67736 0\n    endloop\n  endfacet\n  facet normal 0 -0.15669 0.98765\n    outer loop\n      vertex 46.1 -54.168 14.789\n      vertex 46.1 -52.83806 15\n      vertex 45.937 -54.168 14.789\n    endloop\n  endfacet\n  facet normal 0 -0.15669 0.98765\n    outer loop\n      vertex 45.937 -52.712 15.02\n      vertex 45.937 -54.168 14.789\n      vertex 46.1 -52.83806 15\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 52.17121 11.98334 -16.07172\n      vertex 52.363 12.00867 -16.16623\n      vertex 46.9 12.534 -18.127\n    endloop\n  endfacet\n  facet normal 0 -0.45371 0.89115\n    outer loop\n      vertex 46.1 -54.168 14.789\n      vertex 45.937 -54.168 14.789\n      vertex 45.937 -55.482 14.12\n    endloop\n  endfacet\n  facet normal 0 -0.45371 0.89115\n    outer loop\n      vertex 46.1 -54.168 14.789\n      vertex 45.937 -55.482 14.12\n      vertex 46.1 -55.482 14.12\n    endloop\n  endfacet\n  facet normal 0 -0.70711 0.70711\n    outer loop\n      vertex 45.937 -55.482 14.12\n      vertex 45.937 -56.524 13.078\n      vertex 46.1 -56.524 13.078\n    endloop\n  endfacet\n  facet normal 0 -0.70711 0.70711\n    outer loop\n      vertex 45.937 -55.482 14.12\n      vertex 46.1 -56.524 13.078\n      vertex 46.1 -55.482 14.12\n    endloop\n  endfacet\n  facet normal -0.01556 -0.89085 -0.45404\n    outer loop\n      vertex 45.075 -45.059 13.755\n      vertex 34.023 -44.866 13.755\n      vertex 45.086 -44.39 12.442\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 46.9 12.534 -18.127\n      vertex 51.86177 11.92337 -15.84787\n      vertex 52.014 11.9627 -15.99467\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 51.737 11.89105 -15.72725\n      vertex 51.86177 11.92337 -15.84787\n      vertex 46.9 12.534 -18.127\n    endloop\n  endfacet\n  facet normal 0 -0.89101 0.45399\n    outer loop\n      vertex 46.1 -57 12.14379\n      vertex 46.1 -56.524 13.078\n      vertex 45.937 -57 12.14379\n    endloop\n  endfacet\n  facet normal 0 -0.89101 0.45399\n    outer loop\n      vertex 45.937 -56.524 13.078\n      vertex 45.937 -57 12.14379\n      vertex 46.1 -56.524 13.078\n    endloop\n  endfacet\n  facet normal -0.01725 -0.98758 -0.15616\n    outer loop\n      vertex 45.071 -45.289 15.21\n      vertex 34.019 -45.096 15.21\n      vertex 45.075 -45.059 13.755\n    endloop\n  endfacet\n  facet normal 0 -0.89101 -0.45399\n    outer loop\n      vertex 45.937 -56.524 7.542\n      vertex 46.1 -56.524 7.542\n      vertex 46.1 -57 8.47621\n    endloop\n  endfacet\n  facet normal 0 -0.89101 -0.45399\n    outer loop\n      vertex 45.937 -56.524 7.542\n      vertex 46.1 -57 8.47621\n      vertex 45.937 -57 8.47621\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 55.2 12.534 -18.127\n      vertex 46.9 12.534 -18.127\n      vertex 52.53732 12.0159 -16.19325\n    endloop\n  endfacet\n  facet normal 0 -0.70711 -0.70711\n    outer loop\n      vertex 45.937 -56.524 7.542\n      vertex 45.937 -55.482 6.5\n      vertex 46.1 -55.482 6.5\n    endloop\n  endfacet\n  facet normal 0 -0.70711 -0.70711\n    outer loop\n      vertex 45.937 -56.524 7.542\n      vertex 46.1 -55.482 6.5\n      vertex 46.1 -56.524 7.542\n    endloop\n  endfacet\n  facet normal 0 0.45359 0.89121\n    outer loop\n      vertex 45.13237 -41.766 13.68\n      vertex 45.13337 -41.71049 13.65175\n      vertex 37.8 -41.766 13.68\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 52.75 12.0246 -16.2257\n      vertex 55.2 12.534 -18.127\n      vertex 52.53732 12.0159 -16.19325\n    endloop\n  endfacet\n  facet normal 0 -0.45371 -0.89115\n    outer loop\n      vertex 46.1 -55.482 6.5\n      vertex 45.937 -54.168 5.831\n      vertex 46.1 -54.168 5.831\n    endloop\n  endfacet\n  facet normal 0 0.45359 0.89121\n    outer loop\n      vertex 45.13337 -41.71049 13.65175\n      vertex 45.13548 -41.59019 13.59052\n      vertex 37.8 -41.766 13.68\n    endloop\n  endfacet\n  facet normal 0 -0.45371 -0.89115\n    outer loop\n      vertex 45.937 -55.482 6.5\n      vertex 45.937 -54.168 5.831\n      vertex 46.1 -55.482 6.5\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 51.88922 11.47102 -14.15952\n      vertex 46.1 7.67736 0\n      vertex 52.014 11.43882 -14.03931\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 51.737 11.51035 -14.30631\n      vertex 46.1 7.67736 0\n      vertex 51.88922 11.47102 -14.15952\n    endloop\n  endfacet\n  facet normal 0 -0.15669 -0.98765\n    outer loop\n      vertex 45.937 -54.168 5.831\n      vertex 45.937 -52.712 5.6\n      vertex 46.1 -52.712 5.6\n    endloop\n  endfacet\n  facet normal 0 -0.15669 -0.98765\n    outer loop\n      vertex 45.937 -54.168 5.831\n      vertex 46.1 -52.712 5.6\n      vertex 46.1 -54.168 5.831\n    endloop\n  endfacet\n  facet normal 0 0.45359 0.89121\n    outer loop\n      vertex 45.18865 -41.208 13.396\n      vertex 37.8 -41.766 13.68\n      vertex 45.13548 -41.59019 13.59052\n    endloop\n  endfacet\n  facet normal -0.00793 -0.45386 -0.89104\n    outer loop\n      vertex 34.053 -43.154 11.4\n      vertex 34.076 -41.841 10.731\n      vertex 45.105 -43.347 11.4\n    endloop\n  endfacet\n  facet normal 0 0.15669 -0.98765\n    outer loop\n      vertex 46.1 -52.712 5.6\n      vertex 45.937 -52.712 5.6\n      vertex 46.1 -51.7 5.76056\n    endloop\n  endfacet\n  facet normal 0 0.15669 -0.98765\n    outer loop\n      vertex 45.937 -51.256 5.831\n      vertex 46.1 -51.7 5.76056\n      vertex 45.937 -52.712 5.6\n    endloop\n  endfacet\n  facet normal 0 0.45371 -0.89115\n    outer loop\n      vertex 45.937 -49.942 6.5\n      vertex 54.937 -49.942 6.5\n      vertex 45.937 -51.256 5.831\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 51.559 11.60065 -14.64335\n      vertex 46.1 7.67736 0\n      vertex 51.6568 11.55105 -14.45823\n    endloop\n  endfacet\n  facet normal 0 0.70711 -0.70711\n    outer loop\n      vertex 54.937 -49.942 6.5\n      vertex 45.937 -49.942 6.5\n      vertex 45.937 -48.9 7.542\n    endloop\n  endfacet\n  facet normal -0.01234 -0.70661 -0.7075\n    outer loop\n      vertex 34.035 -44.197 12.442\n      vertex 34.053 -43.154 11.4\n      vertex 45.105 -43.347 11.4\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 53.486 11.43882 -14.03931\n      vertex 53.137 11.39274 -13.86733\n      vertex 53.138 8.46988 -2.95801\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 52.92433 12.01736 -16.19868\n      vertex 55.2 12.534 -18.127\n      vertex 52.75 12.0246 -16.2257\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 52.014 11.9627 -15.99467\n      vertex 52.17121 11.98334 -16.07172\n      vertex 46.9 12.534 -18.127\n    endloop\n  endfacet\n  facet normal -0.01234 -0.7066 -0.7075\n    outer loop\n      vertex 45.086 -44.39 12.442\n      vertex 34.035 -44.197 12.442\n      vertex 45.105 -43.347 11.4\n    endloop\n  endfacet\n  facet normal 0.70656 -0.18325 0.68352\n    outer loop\n      vertex 52.017 5.33204 -3.61494\n      vertex 52.017 8.42381 -2.78603\n      vertex 51.92736 5.30887 -3.52849\n    endloop\n  endfacet\n  facet normal 0.70746 -0.18295 0.68266\n    outer loop\n      vertex 51.92736 5.30887 -3.52849\n      vertex 51.80941 8.37017 -2.58583\n      vertex 51.741 5.26059 -3.3483\n    endloop\n  endfacet\n  facet normal 0.70779 0.18293 -0.68232\n    outer loop\n      vertex 52.017 7.90082 -0.83403\n      vertex 52.017 4.80894 -1.66297\n      vertex 51.741 7.97239 -1.10114\n    endloop\n  endfacet\n  facet normal -0.01745 -0.99985 0\n    outer loop\n      vertex 45.13562 -41.59019 10.66059\n      vertex 45.182 -41.591 10.5\n      vertex 45.13562 -41.59019 12.09626\n    endloop\n  endfacet\n  facet normal -0.01745 -0.99985 0\n    outer loop\n      vertex 45.182 -41.591 13.59093\n      vertex 45.13562 -41.59019 12.09626\n      vertex 45.182 -41.591 10.5\n    endloop\n  endfacet\n  facet normal 0.70652 0.18322 -0.68357\n    outer loop\n      vertex 51.737 8.41924 -15.13485\n      vertex 51.737 11.51035 -14.30631\n      vertex 51.7711 8.41043 -15.10197\n    endloop\n  endfacet\n  facet normal -0.01745 -0.99985 0\n    outer loop\n      vertex 45.182 -41.591 13.59093\n      vertex 45.13548 -41.59019 13.59052\n      vertex 45.13562 -41.59019 12.09626\n    endloop\n  endfacet\n  facet normal 0.70618 0.18333 -0.68388\n    outer loop\n      vertex 51.88922 11.47102 -14.15952\n      vertex 52.014 8.34772 -14.86795\n      vertex 51.7711 8.41043 -15.10197\n    endloop\n  endfacet\n  facet normal 0 0.15637 0.9877\n    outer loop\n      vertex 45.1994 -40.589 13.298\n      vertex 34.0975 -40.589 13.298\n      vertex 45.18865 -41.208 13.396\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 51.54787 8.08719 -1.52965\n      vertex 46.1 7.67736 0\n      vertex 51.563 8.06241 -1.43714\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 51.502 8.1623 -1.80997\n      vertex 46.1 7.67736 0\n      vertex 51.54787 8.08719 -1.52965\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 51.563 8.06241 -1.43714\n      vertex 46.1 7.67736 0\n      vertex 51.741 7.97239 -1.10114\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 51.51712 8.18705 -1.90237\n      vertex 51.563 8.26222 -2.18292\n      vertex 46.1 7.67736 0\n    endloop\n  endfacet\n  facet normal 0.70652 0.18322 -0.68357\n    outer loop\n      vertex 51.88922 11.47102 -14.15952\n      vertex 51.7711 8.41043 -15.10197\n      vertex 51.737 11.51035 -14.30631\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 51.563 8.26222 -2.18292\n      vertex 51.60713 8.28455 -2.26628\n      vertex 46.1 7.67736 0\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 46.1 7.67736 0\n      vertex 51.60713 8.28455 -2.26628\n      vertex 51.741 8.35244 -2.51968\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 52.57563 11.38408 -13.83503\n      vertex 52.363 11.39274 -13.86733\n      vertex 52.366 8.46988 -2.95801\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 52.75 11.37695 -13.80842\n      vertex 52.57563 11.38408 -13.83503\n      vertex 52.752 8.4857 -3.01706\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 52.366 8.46988 -2.95801\n      vertex 52.752 8.4857 -3.01706\n      vertex 52.57563 11.38408 -13.83503\n    endloop\n  endfacet\n  facet normal 0.99982 0.01902 0.00189\n    outer loop\n      vertex 30.2 8.79181 -6.23478\n      vertex 30.188 9.465 -6.661\n      vertex 30.2 8.47575 -3.04825\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 52.752 8.4857 -3.01706\n      vertex 53.138 8.46988 -2.95801\n      vertex 52.96266 11.38561 -13.84073\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 52.96266 11.38561 -13.84073\n      vertex 52.75 11.37695 -13.80842\n      vertex 52.752 8.4857 -3.01706\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.955 -3.2 14.065\n      vertex 27.1 -3.2 20\n      vertex 40.335 -3.2 13.445\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 41.735 -3.2 14.463\n      vertex 42.601 -3.2 14.6\n      vertex 27.1 -3.2 20\n    endloop\n  endfacet\n  facet normal -0.99982 -0.01902 -0.00189\n    outer loop\n      vertex 27.36013 7.59525 0\n      vertex 27.338 9.42 -6.664\n      vertex 27.52565 -1.10702 0\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 58.2 -3.2 20\n      vertex 27.1 -3.2 20\n      vertex 42.601 -3.2 14.6\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 40.955 -3.2 14.065\n      vertex 41.735 -3.2 14.463\n      vertex 27.1 -3.2 20\n    endloop\n  endfacet\n  facet normal -0.0155 0.96437 0.26412\n    outer loop\n      vertex 30.188 9.465 -6.661\n      vertex 27.338 9.42 -6.664\n      vertex 30.2 8.47575 -3.04825\n    endloop\n  endfacet\n  facet normal -0.0155 0.96437 0.26412\n    outer loop\n      vertex 27.36013 7.59525 0\n      vertex 30.2 8.47575 -3.04825\n      vertex 27.338 9.42 -6.664\n    endloop\n  endfacet\n  facet normal -0.0155 0.96437 0.26412\n    outer loop\n      vertex 30.2 7.64091 0\n      vertex 30.2 8.47575 -3.04825\n      vertex 27.36013 7.59525 0\n    endloop\n  endfacet\n  facet normal 0 0.89121 -0.45359\n    outer loop\n      vertex 45.937 -54.109 11.677\n      vertex 54.937 -54.109 11.677\n      vertex 54.937 -54.393 11.119\n    endloop\n  endfacet\n  facet normal 0.00963 -0.53473 -0.84497\n    outer loop\n      vertex 29.33788 2.403 -2.20061\n      vertex 29.097 2.403 -2.20335\n      vertex 27.338 9.42 -6.664\n    endloop\n  endfacet\n  facet normal 0.00963 -0.53473 -0.84497\n    outer loop\n      vertex 29.097 -0.802 -0.17512\n      vertex 27.52565 -1.10702 0\n      vertex 29.097 2.403 -2.20335\n    endloop\n  endfacet\n  facet normal 0.00963 -0.53473 -0.84497\n    outer loop\n      vertex 27.338 9.42 -6.664\n      vertex 29.097 2.403 -2.20335\n      vertex 27.52565 -1.10702 0\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 29.097 -0.802 20\n      vertex 29.097 -0.802 -0.17512\n      vertex 29.097 2.403 20\n    endloop\n  endfacet\n  facet normal 0.00933 -0.53479 -0.84493\n    outer loop\n      vertex 30.2592 5.47062 -4.13203\n      vertex 30.31388 2.403 -2.18983\n      vertex 30.2 5.47083 -4.13282\n    endloop\n  endfacet\n  facet normal 0.00933 -0.53479 -0.84493\n    outer loop\n      vertex 30.2 8.79181 -6.23478\n      vertex 30.2 5.47083 -4.13282\n      vertex 27.338 9.42 -6.664\n    endloop\n  endfacet\n  facet normal 0.00933 -0.53479 -0.84493\n    outer loop\n      vertex 30.188 9.465 -6.661\n      vertex 30.2 8.79181 -6.23478\n      vertex 27.338 9.42 -6.664\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 29.33788 2.403 -2.20061\n      vertex 30.30975 2.403 0\n      vertex 29.097 2.403 -2.20335\n    endloop\n  endfacet\n  facet normal 1 0 0\n    outer loop\n      vertex 29.097 2.403 -2.20335\n      vertex 29.097 2.403 20\n      vertex 29.097 -0.802 -0.17512\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 30.2 9.443 -18.955\n      vertex 30.2 8.79181 -6.23478\n      vertex 30.2 12.534 -18.127\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 30.2 8.79181 -6.23478\n      vertex 30.2 8.47575 -3.04825\n      vertex 30.2 12.534 -18.127\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 30.2 7.67736 0\n      vertex 30.2 12.534 -18.127\n      vertex 30.2 8.47575 -3.04825\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 30.2 8.47575 -3.04825\n      vertex 30.2 7.64091 0\n      vertex 30.2 7.67736 0\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 30.2 5.47083 -4.13282\n      vertex 30.2 8.79181 -6.23478\n      vertex 30.2 9.443 -18.955\n    endloop\n  endfacet\n  facet normal 0 -0.45295 -0.89154\n    outer loop\n      vertex 45.937 -51.311 12.12\n      vertex 54.937 -51.311 12.12\n      vertex 54.937 -51.87 12.404\n    endloop\n  endfacet\n  facet normal 0.99982 0.01902 0.00189\n    outer loop\n      vertex 30.37554 -1.05573 0\n      vertex 30.37101 -0.802 -0.16064\n      vertex 30.37071 -0.802 0\n    endloop\n  endfacet\n  facet normal 0 0.89121 -0.45359\n    outer loop\n      vertex 45.937 -54.109 11.677\n      vertex 54.937 -54.393 11.119\n      vertex 45.937 -54.393 11.119\n    endloop\n  endfacet\n  facet normal 0.99982 0.01902 0.00189\n    outer loop\n      vertex 30.30975 2.403 0\n      vertex 30.31388 2.403 -2.18983\n      vertex 30.27247 4.36328 0\n    endloop\n  endfacet\n  facet normal 0 0.9877 -0.15637\n    outer loop\n      vertex 54.937 -54.393 11.119\n      vertex 45.937 -54.491 10.5\n      vertex 45.937 -54.393 11.119\n    endloop\n  endfacet\n  facet normal 0.00963 -0.53473 -0.84497\n    outer loop\n      vertex 30.25132 -0.802 -0.16196\n      vertex 30.32389 -1.05663 0\n      vertex 29.097 -0.802 -0.17512\n    endloop\n  endfacet\n  facet normal 0.00963 -0.53473 -0.84497\n    outer loop\n      vertex 27.52565 -1.10702 0\n      vertex 29.097 -0.802 -0.17512\n      vertex 30.32389 -1.05663 0\n    endloop\n  endfacet\n  facet normal 0 0.45295 0.89154\n    outer loop\n      vertex 54.937 -53.107 8.596\n      vertex 45.937 -53.107 8.596\n      vertex 45.937 -53.666 8.88\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 29.097 -0.802 20\n      vertex 30.37071 -0.802 0\n      vertex 29.097 -0.802 -0.17512\n    endloop\n  endfacet\n  facet normal 0 0.89121 0.45359\n    outer loop\n      vertex 45.937 -54.393 9.881\n      vertex 54.937 -54.109 9.323\n      vertex 45.937 -54.109 9.323\n    endloop\n  endfacet\n  facet normal 0.00933 -0.53479 -0.84493\n    outer loop\n      vertex 30.25132 -0.802 -0.16196\n      vertex 30.37101 -0.802 -0.16064\n      vertex 30.32389 -1.05663 0\n    endloop\n  endfacet\n  facet normal 0.00933 -0.53479 -0.84493\n    outer loop\n      vertex 30.37554 -1.05573 0\n      vertex 30.32389 -1.05663 0\n      vertex 30.37101 -0.802 -0.16064\n    endloop\n  endfacet\n  facet normal 0 0.15818 0.98741\n    outer loop\n      vertex 45.937 -53.107 8.596\n      vertex 54.937 -53.107 8.596\n      vertex 45.937 -52.489 8.497\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 30.37101 -0.802 -0.16064\n      vertex 30.25132 -0.802 -0.16196\n      vertex 30.37071 -0.802 0\n    endloop\n  endfacet\n  facet normal 0 0.70711 0.70711\n    outer loop\n      vertex 45.937 -54.109 9.323\n      vertex 54.937 -54.109 9.323\n      vertex 45.937 -53.666 8.88\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 29.097 2.403 20\n      vertex 29.097 2.403 -2.20335\n      vertex 30.30975 2.403 0\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 30.30975 2.403 0\n      vertex 29.33788 2.403 -2.20061\n      vertex 30.31388 2.403 -2.18983\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 27.1 -33.2 0\n      vertex 37.298 -33.2 -36.501\n      vertex 26.6 -33.2 -58\n    endloop\n  endfacet\n  facet normal 0 -0.45295 0.89154\n    outer loop\n      vertex 54.937 -51.311 8.88\n      vertex 45.937 -51.311 8.88\n      vertex 45.937 -51.87 8.596\n    endloop\n  endfacet\n  facet normal 0 0.25875 -0.96594\n    outer loop\n      vertex 35.0753 9.443 -18.955\n      vertex 30.2 9.443 -18.955\n      vertex 30.2 12.534 -18.127\n    endloop\n  endfacet\n  facet normal 0 0.25875 -0.96594\n    outer loop\n      vertex 46.9 12.534 -18.127\n      vertex 35.0753 9.443 -18.955\n      vertex 30.2 12.534 -18.127\n    endloop\n  endfacet\n  facet normal 0 -0.70711 0.70711\n    outer loop\n      vertex 54.937 -51.311 8.88\n      vertex 45.937 -50.868 9.323\n      vertex 45.937 -51.311 8.88\n    endloop\n  endfacet\n  facet normal 0 -0.89121 0.45359\n    outer loop\n      vertex 54.937 -50.584 9.881\n      vertex 45.937 -50.584 9.881\n      vertex 45.937 -50.868 9.323\n    endloop\n  endfacet\n  facet normal 0 -0.1378 -0.99046\n    outer loop\n      vertex 32.8 22.603 1.874\n      vertex 37.8 22.603 1.874\n      vertex 32.8 21.5208 2.02456\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 31.06376 -36.2 -10.48639\n      vertex 26.6 -36.2 -58\n      vertex 34.019 -36.2 -31.18159\n    endloop\n  endfacet\n  facet normal 0 -0.9877 0.15637\n    outer loop\n      vertex 45.937 -50.584 9.881\n      vertex 54.937 -50.584 9.881\n      vertex 45.937 -50.486 10.5\n    endloop\n  endfacet\n  facet normal 0.99982 0.01902 0.00189\n    outer loop\n      vertex 30.2592 5.47062 -4.13203\n      vertex 30.27247 4.36328 0\n      vertex 30.31388 2.403 -2.18983\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 37.735 -36.2 -8.855\n      vertex 37.984 -36.2 -0.679\n      vertex 31.06376 -36.2 -10.48639\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 26.6 -36.2 20\n      vertex 26.6 -36.2 -58\n      vertex 31.06376 -36.2 -10.48639\n    endloop\n  endfacet\n  facet normal 0.00933 -0.53479 -0.84493\n    outer loop\n      vertex 30.31388 2.403 -2.18983\n      vertex 29.33788 2.403 -2.20061\n      vertex 30.2 5.47083 -4.13282\n    endloop\n  endfacet\n  facet normal 0.00933 -0.53479 -0.84493\n    outer loop\n      vertex 27.338 9.42 -6.664\n      vertex 30.2 5.47083 -4.13282\n      vertex 29.33788 2.403 -2.20061\n    endloop\n  endfacet\n  facet normal 0 -0.89121 -0.45359\n    outer loop\n      vertex 54.937 -50.868 11.677\n      vertex 45.937 -50.868 11.677\n      vertex 45.937 -50.584 11.119\n    endloop\n  endfacet\n  facet normal 0 -0.07338 -0.9973\n    outer loop\n      vertex 37.8 22.60546 1.94475\n      vertex 32.8 22.60546 1.94475\n      vertex 37.8 26.19 1.681\n    endloop\n  endfacet\n  facet normal 0 -0.07338 -0.9973\n    outer loop\n      vertex 32.8 26.19 1.681\n      vertex 37.8 26.19 1.681\n      vertex 32.8 22.60546 1.94475\n    endloop\n  endfacet\n  facet normal 0 0.70786 0.70635\n    outer loop\n      vertex 32.8 26.19 1.681\n      vertex 32.8 8.01 19.9\n      vertex 37.8 26.19 1.681\n    endloop\n  endfacet\n  facet normal 0 -0.70711 -0.70711\n    outer loop\n      vertex 45.937 -51.311 12.12\n      vertex 45.937 -50.868 11.677\n      vertex 54.937 -50.868 11.677\n    endloop\n  endfacet\n  facet normal 0 0.9994 -0.03477\n    outer loop\n      vertex 32.8 22.60546 1.94475\n      vertex 37.8 22.60546 1.94475\n      vertex 37.8 22.603 1.874\n    endloop\n  endfacet\n  facet normal 0 0.9994 -0.03477\n    outer loop\n      vertex 32.8 22.60546 1.94475\n      vertex 37.8 22.603 1.874\n      vertex 32.8 22.603 1.874\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 32.47992 8.86306 -16.79096\n      vertex 32.237 8.80029 -16.55671\n      vertex 30.2 9.443 -18.955\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 32.514 8.8719 -16.82394\n      vertex 32.47992 8.86306 -16.79096\n      vertex 30.2 9.443 -18.955\n    endloop\n  endfacet\n  facet normal 0 -0.45295 -0.89154\n    outer loop\n      vertex 45.937 -51.87 12.404\n      vertex 45.937 -51.311 12.12\n      vertex 54.937 -51.87 12.404\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 32.514 8.8719 -16.82394\n      vertex 30.2 9.443 -18.955\n      vertex 32.82001 8.91225 -16.97451\n    endloop\n  endfacet\n  facet normal 0 -0.15793 -0.98745\n    outer loop\n      vertex 45.937 -51.87 12.404\n      vertex 54.937 -51.87 12.404\n      vertex 45.937 -52.489 12.503\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 34.616 -51.788 5.6\n      vertex 25.4 -57 5.6\n      vertex 25.4 -51.788 5.6\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 32.863 8.30164 -14.69601\n      vertex 34.503 7.394 -11.30915\n      vertex 30.2 5.47083 -4.13282\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 32.514 8.34773 -14.86798\n      vertex 32.863 8.30164 -14.69601\n      vertex 30.2 5.47083 -4.13282\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 32.237 8.41947 -15.13569\n      vertex 32.2711 8.41066 -15.10281\n      vertex 30.2 5.47083 -4.13282\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 32.2711 8.41066 -15.10281\n      vertex 32.514 8.34773 -14.86798\n      vertex 30.2 5.47083 -4.13282\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 32.0809 8.49871 -15.43139\n      vertex 32.237 8.41947 -15.13569\n      vertex 30.2 5.47083 -4.13282\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 46.1 -51.7 15\n      vertex 46.1 -51.7 14.85944\n      vertex 46.1 -52.58594 15\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 34.616 -57 5.6\n      vertex 25.4 -57 5.6\n      vertex 34.616 -51.788 5.6\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 32.059 8.50982 -15.47284\n      vertex 32.0809 8.49871 -15.43139\n      vertex 30.2 5.47083 -4.13282\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.539 -50.584 9.881\n      vertex 25.539 -50.486 10.5\n      vertex 25.539 -47.788 10.31\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.539 -50.868 9.323\n      vertex 25.539 -50.584 9.881\n      vertex 25.539 -48.019 8.855\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.539 -48.019 8.855\n      vertex 25.539 -48.688 7.542\n      vertex 25.539 -50.868 9.323\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.539 -49.73 6.5\n      vertex 25.539 -51.311 8.88\n      vertex 25.539 -48.688 7.542\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 46.1 -52.712 5.6\n      vertex 46.1 -57 5.6\n      vertex 46.1 -54.168 5.831\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 31.997 8.60981 -15.84596\n      vertex 30.2 9.443 -18.955\n      vertex 32.05137 8.69769 -16.17389\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.539 -51.311 8.88\n      vertex 25.539 -49.73 6.5\n      vertex 25.539 -51.788 8.63766\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 32.05137 8.69769 -16.17389\n      vertex 30.2 9.443 -18.955\n      vertex 32.059 8.71 -16.21979\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 32.237 8.80029 -16.55671\n      vertex 32.059 8.71 -16.21979\n      vertex 30.2 9.443 -18.955\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.539 -50.868 9.323\n      vertex 25.539 -48.688 7.542\n      vertex 25.539 -51.311 8.88\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 46.1 -51.7 5.76056\n      vertex 46.1 -51.7 5.6\n      vertex 46.1 -52.712 5.6\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 46.1 -52.83806 15\n      vertex 46.1 -54.168 14.789\n      vertex 46.1 -57 15\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 46.1 -54.168 14.789\n      vertex 46.1 -55.482 14.12\n      vertex 46.1 -57 15\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.539 -49.73 6.5\n      vertex 25.539 -51.044 5.831\n      vertex 25.539 -51.788 8.63766\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.25 8.28582 -14.63696\n      vertex 34.503 7.394 -11.30915\n      vertex 32.863 8.30164 -14.69601\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.539 -48.019 11.765\n      vertex 25.539 -47.788 10.31\n      vertex 25.539 -50.486 10.5\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.539 -47.788 10.31\n      vertex 25.539 -48.019 8.855\n      vertex 25.539 -50.584 9.881\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 30.2592 5.47062 -4.13203\n      vertex 30.2 5.47083 -4.13282\n      vertex 34.503 7.394 -11.30915\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.539 -51.311 12.12\n      vertex 25.539 -51.788 12.36234\n      vertex 25.539 -51.044 14.789\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.539 -50.868 11.677\n      vertex 25.539 -51.311 12.12\n      vertex 25.539 -49.73 14.12\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.539 -51.044 14.789\n      vertex 25.539 -49.73 14.12\n      vertex 25.539 -51.311 12.12\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 32.017 5.33204 -3.61494\n      vertex 31.92735 5.30887 -3.52849\n      vertex 30.2592 5.47062 -4.13203\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.539 -49.73 14.12\n      vertex 25.539 -48.688 13.078\n      vertex 25.539 -50.868 11.677\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.539 -51.788 14.90704\n      vertex 25.539 -51.044 14.789\n      vertex 25.539 -51.788 12.36234\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 30.2592 5.47062 -4.13203\n      vertex 34.503 7.394 -11.30915\n      vertex 32.017 5.33204 -3.61494\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 32.366 5.37813 -3.78692\n      vertex 32.017 5.33204 -3.61494\n      vertex 34.503 7.394 -11.30915\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 32.752 5.39395 -3.84597\n      vertex 32.366 5.37813 -3.78692\n      vertex 34.503 7.394 -11.30915\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 34.002 4.36328 0\n      vertex 30.27247 4.36328 0\n      vertex 32.752 4.74728 -1.43288\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.539 -50.584 11.119\n      vertex 25.539 -50.868 11.677\n      vertex 25.539 -48.688 13.078\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.539 -48.688 13.078\n      vertex 25.539 -48.019 11.765\n      vertex 25.539 -50.584 11.119\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.539 -50.486 10.5\n      vertex 25.539 -50.584 11.119\n      vertex 25.539 -48.019 11.765\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 32.366 4.7631 -1.49193\n      vertex 32.752 4.74728 -1.43288\n      vertex 30.27247 4.36328 0\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 32.017 4.80894 -1.66297\n      vertex 32.366 4.7631 -1.49193\n      vertex 30.27247 4.36328 0\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 33.138 4.7631 -1.49193\n      vertex 34.002 4.36328 0\n      vertex 32.752 4.74728 -1.43288\n    endloop\n  endfacet\n  facet normal -1 0 0\n    outer loop\n      vertex 25.539 -51.788 5.71296\n      vertex 25.539 -51.788 8.63766\n      vertex 25.539 -51.044 5.831\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 31.563 4.97056 -2.26607\n      vertex 30.27247 4.36328 0\n      vertex 31.52181 5.03807 -2.51797\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 31.54319 5.13795 -2.89068\n      vertex 31.502 5.0705 -2.639\n      vertex 30.2592 5.47062 -4.13203\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 30.27247 4.36328 0\n      vertex 30.2592 5.47062 -4.13203\n      vertex 31.502 5.0705 -2.639\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 31.563 5.17042 -3.01184\n      vertex 30.2592 5.47062 -4.13203\n      vertex 31.6832 5.23127 -3.23889\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 30.2592 5.47062 -4.13203\n      vertex 31.92735 5.30887 -3.52849\n      vertex 31.741 5.26059 -3.3483\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 31.741 5.26059 -3.3483\n      vertex 31.6832 5.23127 -3.23889\n      vertex 30.2592 5.47062 -4.13203\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 31.741 4.88052 -1.93008\n      vertex 32.017 4.80894 -1.66297\n      vertex 30.27247 4.36328 0\n    endloop\n  endfacet\n  facet normal 0 0.9877 0.15637\n    outer loop\n      vertex 45.11796 -42.591 15.3\n      vertex 45.11821 -42.57675 15.21\n      vertex 34.06285 -42.57675 15.21\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 30.27247 4.36328 0\n      vertex 31.563 4.97056 -2.26607\n      vertex 31.741 4.88052 -1.93008\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 32.00463 8.59749 -15.79996\n      vertex 32.059 8.50982 -15.47284\n      vertex 30.2 9.443 -18.955\n    endloop\n  endfacet\n  facet normal 0 0.70711 0.70711\n    outer loop\n      vertex 34.07707 -41.766 13.68\n      vertex 34.0718 -42.07143 13.98543\n      vertex 37.8 -41.766 13.68\n    endloop\n  endfacet\n  facet normal 0 0.70711 0.70711\n    outer loop\n      vertex 34.0718 -42.07143 13.98543\n      vertex 34.06937 -42.209 14.123\n      vertex 37.8 -41.766 13.68\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 31.563 5.17042 -3.01184\n      vertex 31.54319 5.13795 -2.89068\n      vertex 30.2592 5.47062 -4.13203\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 31.502 5.0705 -2.639\n      vertex 31.52181 5.03807 -2.51797\n      vertex 30.27247 4.36328 0\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 31.997 8.60981 -15.84596\n      vertex 32.00463 8.59749 -15.79996\n      vertex 30.2 9.443 -18.955\n    endloop\n  endfacet\n  facet normal 0 -0.96592 -0.25885\n    outer loop\n      vertex 30.2 9.443 -18.955\n      vertex 32.059 8.50982 -15.47284\n      vertex 30.2 5.47083 -4.13282\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 32.059 11.6008 -14.64391\n      vertex 31.997 11.14241 -12.933\n      vertex 32.1568 11.55121 -14.4588\n    endloop\n  endfacet\n  facet normal 0 0.96593 0.2588\n    outer loop\n      vertex 31.997 11.70088 -15.01744\n      vertex 30.2 12.534 -18.127\n      vertex 32.03106 11.64583 -14.81199\n    endloop\n  endfacet\n  facet normal 0 0.15818 0.98741\n    outer loop\n      vertex 45.937 -52.489 8.497\n      vertex 54.937 -53.107 8.596\n      vertex 54.937 -52.489 8.497\n    endloop\n  endfacet\n  facet normal 0 -0.45359 0.89121\n    outer loop\n      vertex 34.10841 -39.97 13.396\n      vertex 45.21014 -39.97 13.396\n      vertex 34.11109 -39.82012 13.47229\n    endloop\n  endfacet\n  facet normal 0 -0.15793 0.98745\n    outer loop\n      vertex 45.937 -52.489 8.497\n      vertex 54.937 -52.489 8.497\n      vertex 45.937 -51.87 8.596\n    endloop\n  endfacet\n  facet normal 0 -0.70711 0.70711\n    outer loop\n      vertex 34.11926 -39.33152 13.76047\n      vertex 45.21983 -39.412 13.68\n      vertex 34.12587 -38.969 14.123\n    endloop\n  endfacet\n  facet normal 0 -0.15793 -0.98745\n    outer loop\n      vertex 54.937 -52.489 12.503\n      vertex 45.937 -52.489 12.503\n      vertex 54.937 -51.87 12.404\n    endloop\n  endfacet\n  facet normal 0 0.15818 -0.98741\n    outer loop\n      vertex 54.937 -52.489 12.503\n      vertex 54.937 -53.107 12.404\n      vertex 45.937 -52.489 12.503\n    endloop\n  endfacet\n  facet normal 0 0.9877 0.15637\n    outer loop\n      vertex 54.937 -54.393 9.881\n      vertex 45.937 -54.393 9.881\n      vertex 45.937 -54.491 10.5\n    endloop\n  endfacet\n  facet normal 0 -0.9877 0.15637\n    outer loop\n      vertex 45.23417 -38.586 15.3\n      vertex 34.13206 -38.60025 15.21\n      vertex 45.23247 -38.684 14.681\n    endloop\n  endfacet\n  facet normal 0 0.45295 0.89154\n    outer loop\n      vertex 45.937 -53.666 8.88\n      vertex 54.937 -53.666 8.88\n      vertex 54.937 -53.107 8.596\n    endloop\n  endfacet\n  facet normal 0 0.70711 -0.70711\n    outer loop\n      vertex 54.937 -54.109 11.677\n      vertex 45.937 -54.109 11.677\n      vertex 45.937 -53.666 12.12\n    endloop\n  endfacet\n  facet normal 0 -0.15793 0.98745\n    outer loop\n      vertex 54.937 -51.87 8.596\n      vertex 45.937 -51.87 8.596\n      vertex 54.937 -52.489 8.497\n    endloop\n  endfacet\n  facet normal 0 -0.45295 0.89154\n    outer loop\n      vertex 54.937 -51.311 8.88\n      vertex 45.937 -51.87 8.596\n      vertex 54.937 -51.87 8.596\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 38.765 -33.2 4.251\n      vertex 37.984 -33.2 3.853\n      vertex 26.6 -33.2 20\n    endloop\n  endfacet\n  facet normal 0 0.15818 -0.98741\n    outer loop\n      vertex 45.937 -53.107 12.404\n      vertex 45.937 -52.489 12.503\n      vertex 54.937 -53.107 12.404\n    endloop\n  endfacet\n  facet normal 0 0.45295 -0.89154\n    outer loop\n      vertex 54.937 -53.107 12.404\n      vertex 45.937 -53.666 12.12\n      vertex 45.937 -53.107 12.404\n    endloop\n  endfacet\n  facet normal 0 0.9877 0.15637\n    outer loop\n      vertex 54.937 -54.393 9.881\n      vertex 45.937 -54.491 10.5\n      vertex 54.937 -54.491 10.5\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 34.183 -41.399 10.5\n      vertex 34.20077 -40.38674 10.5\n      vertex 45.182 -41.591 10.5\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 34.27425 -36.2 10.5\n      vertex 40.00412 -36.2 10.5\n      vertex 34.20077 -40.38674 10.5\n    endloop\n  endfacet\n  facet normal 0 0.89121 0.45359\n    outer loop\n      vertex 45.937 -54.393 9.881\n      vertex 54.937 -54.393 9.881\n      vertex 54.937 -54.109 9.323\n    endloop\n  endfacet\n  facet normal 0 0.70711 0.70711\n    outer loop\n      vertex 45.937 -53.666 8.88\n      vertex 54.937 -54.109 9.323\n      vertex 54.937 -53.666 8.88\n    endloop\n  endfacet\n  facet normal -0.00274 -0.15665 -0.98765\n    outer loop\n      vertex 45.13562 -41.59019 10.66059\n      vertex 45.128 -42.034 10.731\n      vertex 34.183 -41.399 10.6606\n    endloop\n  endfacet\n  facet normal -0.00274 -0.15665 -0.98765\n    outer loop\n      vertex 34.076 -41.841 10.731\n      vertex 34.183 -41.399 10.6606\n      vertex 45.128 -42.034 10.731\n    endloop\n  endfacet\n  facet normal 0 0.70711 -0.70711\n    outer loop\n      vertex 45.937 -53.666 12.12\n      vertex 54.937 -53.666 12.12\n      vertex 54.937 -54.109 11.677\n    endloop\n  endfacet\n  facet normal -0.01745 -0.99985 0\n    outer loop\n      vertex 45.182 -41.591 10.5\n      vertex 45.13562 -41.59019 10.66059\n      vertex 34.183 -41.399 10.5\n    endloop\n  endfacet\n  facet normal 0 0.9877 -0.15637\n    outer loop\n      vertex 54.937 -54.393 11.119\n      vertex 54.937 -54.491 10.5\n      vertex 45.937 -54.491 10.5\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 26.6 -33.2 20\n      vertex 52.2 -33.2 20\n      vertex 39.63 -33.2 4.388\n    endloop\n  endfacet\n  facet normal 0 0.45295 -0.89154\n    outer loop\n      vertex 45.937 -53.666 12.12\n      vertex 54.937 -53.107 12.404\n      vertex 54.937 -53.666 12.12\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 53.765 -57 18.06\n      vertex 34.539 -57 20\n      vertex 53.96 -57 18.444\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 54.937 -57 12.14379\n      vertex 55.882 -57 16.522\n      vertex 61 -57 0\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 61 -57 20\n      vertex 61 -57 0\n      vertex 56.381 -57 17.21\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 55.073 -57 19.011\n      vertex 54.937 -57 20\n      vertex 55.498 -57 18.943\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 54.937 -57 20\n      vertex 61 -57 20\n      vertex 55.498 -57 18.943\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 55.073 -57 19.011\n      vertex 54.648 -57 18.943\n      vertex 54.937 -57 20\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 54.648 -57 18.943\n      vertex 54.265 -57 18.748\n      vertex 54.937 -57 20\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 34.539 -57 20\n      vertex 54.937 -57 20\n      vertex 54.265 -57 18.748\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 54.265 -57 18.748\n      vertex 53.96 -57 18.444\n      vertex 34.539 -57 20\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 56.449 -57 17.635\n      vertex 61 -57 20\n      vertex 56.381 -57 17.21\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 56.449 -57 17.635\n      vertex 56.381 -57 18.06\n      vertex 61 -57 20\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 61 -57 20\n      vertex 56.381 -57 18.06\n      vertex 56.186 -57 18.444\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 61 -57 20\n      vertex 56.186 -57 18.444\n      vertex 55.882 -57 18.748\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 55.882 -57 18.748\n      vertex 55.498 -57 18.943\n      vertex 61 -57 20\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 56.186 -57 16.827\n      vertex 56.381 -57 17.21\n      vertex 61 -57 0\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 56.186 -57 16.827\n      vertex 61 -57 0\n      vertex 55.882 -57 16.522\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 54.937 -57 12.14379\n      vertex 54.821 -57 15\n      vertex 55.882 -57 16.522\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 54.937 -57 8.47621\n      vertex 54.937 -57 12.14379\n      vertex 61 -57 0\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 55.498 -57 16.327\n      vertex 55.882 -57 16.522\n      vertex 54.821 -57 15\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 20.1 -57 0\n      vertex 46.1 -57 5.6\n      vertex 61 -57 0\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 55.073 -57 16.259\n      vertex 55.498 -57 16.327\n      vertex 54.821 -57 15\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 54.821 -57 15\n      vertex 54.648 -57 16.327\n      vertex 55.073 -57 16.259\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 54.821 -57 15\n      vertex 54.937 -57 12.14379\n      vertex 54.821 -57 12.14379\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 54.821 -57 5.6\n      vertex 54.937 -57 8.47621\n      vertex 61 -57 0\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 54.821 -57 8.47621\n      vertex 54.937 -57 8.47621\n      vertex 54.821 -57 5.6\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 25.246 -57 16.559\n      vertex 25.4 -57 15\n      vertex 24.884 -57 16.617\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 26.362 -57 17.37\n      vertex 34.616 -57 15\n      vertex 26.195 -57 17.043\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 24.13 -57 18.095\n      vertex 20.1 -57 20\n      vertex 24.297 -57 18.422\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 25.609 -57 18.849\n      vertex 25.246 -57 18.906\n      vertex 34.539 -57 20\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 20.1 -57 20\n      vertex 34.539 -57 20\n      vertex 25.246 -57 18.906\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 20.1 -57 20\n      vertex 25.246 -57 18.906\n      vertex 24.884 -57 18.849\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 24.557 -57 18.682\n      vertex 20.1 -57 20\n      vertex 24.884 -57 18.849\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 34.539 -57 20\n      vertex 34.616 -57 15\n      vertex 26.419 -57 17.733\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 34.539 -57 20\n      vertex 26.419 -57 17.733\n      vertex 26.362 -57 18.095\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 34.539 -57 20\n      vertex 26.362 -57 18.095\n      vertex 26.195 -57 18.422\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 34.539 -57 20\n      vertex 26.195 -57 18.422\n      vertex 25.936 -57 18.682\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 25.936 -57 18.682\n      vertex 25.609 -57 18.849\n      vertex 34.539 -57 20\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 53.698 -57 17.635\n      vertex 46.1 -57 15\n      vertex 53.765 -57 18.06\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 53.96 -57 16.827\n      vertex 46.1 -57 15\n      vertex 53.765 -57 17.21\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 53.765 -57 17.21\n      vertex 46.1 -57 15\n      vertex 53.698 -57 17.635\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 34.539 -57 20\n      vertex 46.1 -57 15\n      vertex 34.616 -57 15\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 45.937 -57 8.47621\n      vertex 46.1 -57 5.6\n      vertex 34.616 -57 5.6\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 34.616 -57 15\n      vertex 45.937 -57 8.47621\n      vertex 34.616 -57 5.6\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 45.937 -57 8.47621\n      vertex 34.616 -57 15\n      vertex 45.937 -57 12.14379\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 45.937 -57 12.14379\n      vertex 34.616 -57 15\n      vertex 46.1 -57 15\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 26.362 -57 17.37\n      vertex 26.419 -57 17.733\n      vertex 34.616 -57 15\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 24.557 -57 16.784\n      vertex 24.884 -57 16.617\n      vertex 25.4 -57 15\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 25.4 -57 15\n      vertex 20.1 -57 0\n      vertex 24.557 -57 16.784\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 25.4 -57 5.6\n      vertex 20.1 -57 0\n      vertex 25.4 -57 15\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 25.936 -57 16.784\n      vertex 26.195 -57 17.043\n      vertex 34.616 -57 15\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 34.616 -57 15\n      vertex 25.4 -57 15\n      vertex 25.936 -57 16.784\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 25.609 -57 16.617\n      vertex 25.936 -57 16.784\n      vertex 25.4 -57 15\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 25.246 -57 16.559\n      vertex 25.609 -57 16.617\n      vertex 25.4 -57 15\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 20.1 -57 0\n      vertex 25.4 -57 5.6\n      vertex 34.616 -57 5.6\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 20.1 -57 0\n      vertex 34.616 -57 5.6\n      vertex 46.1 -57 5.6\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 34.539 -57 20\n      vertex 53.765 -57 18.06\n      vertex 46.1 -57 15\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 46.1 -57 12.14379\n      vertex 45.937 -57 12.14379\n      vertex 46.1 -57 15\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 46.1 -57 5.6\n      vertex 45.937 -57 8.47621\n      vertex 46.1 -57 8.47621\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 53.96 -57 16.827\n      vertex 54.265 -57 16.522\n      vertex 46.1 -57 15\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 54.648 -57 16.327\n      vertex 54.821 -57 15\n      vertex 54.265 -57 16.522\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 46.1 -57 15\n      vertex 54.265 -57 16.522\n      vertex 54.821 -57 15\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 54.821 -57 5.6\n      vertex 61 -57 0\n      vertex 46.1 -57 5.6\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 24.557 -57 18.682\n      vertex 24.297 -57 18.422\n      vertex 20.1 -57 20\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 24.073 -57 17.733\n      vertex 20.1 -57 20\n      vertex 24.13 -57 18.095\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 20.1 -57 0\n      vertex 20.1 -57 20\n      vertex 24.13 -57 17.37\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 24.297 -57 17.043\n      vertex 20.1 -57 0\n      vertex 24.13 -57 17.37\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 24.297 -57 17.043\n      vertex 24.557 -57 16.784\n      vertex 20.1 -57 0\n    endloop\n  endfacet\n  facet normal 0 1 0\n    outer loop\n      vertex 24.073 -57 17.733\n      vertex 24.13 -57 17.37\n      vertex 20.1 -57 20\n    endloop\n  endfacet\n  facet normal 0.9878 0 -0.15572\n    outer loop\n      vertex 53.698 -57 17.635\n      vertex 53.765 -60 18.06\n      vertex 53.698 -60 17.635\n    endloop\n  endfacet\n  facet normal 0.9878 0 0.15572\n    outer loop\n      vertex 53.698 -57 17.635\n      vertex 53.698 -60 17.635\n      vertex 53.765 -60 17.21\n    endloop\n  endfacet\n  facet normal 0.15799 0 0.98744\n    outer loop\n      vertex 54.648 -57 16.327\n      vertex 54.648 -60 16.327\n      vertex 55.073 -60 16.259\n    endloop\n  endfacet\n  facet normal -0.15799 0 0.98744\n    outer loop\n      vertex 55.498 -57 16.327\n      vertex 55.073 -60 16.259\n      vertex 55.498 -60 16.327\n    endloop\n  endfacet\n  facet normal -0.45278 0 0.89162\n    outer loop\n      vertex 55.882 -60 16.522\n      vertex 55.498 -57 16.327\n      vertex 55.498 -60 16.327\n    endloop\n  endfacet\n  facet normal 0.15799 0 -0.98744\n    outer loop\n      vertex 55.073 -60 19.011\n      vertex 54.648 -60 18.943\n      vertex 55.073 -57 19.011\n    endloop\n  endfacet\n  facet normal 0.89115 0 0.45372\n    outer loop\n      vertex 53.96 -60 16.827\n      vertex 53.96 -57 16.827\n      vertex 53.765 -60 17.21\n    endloop\n  endfacet\n  facet normal 0.70711 0 0.70711\n    outer loop\n      vertex 53.96 -57 16.827\n      vertex 53.96 -60 16.827\n      vertex 54.265 -60 16.522\n    endloop\n  endfacet\n  facet normal -0.15799 0 -0.98744\n    outer loop\n      vertex 55.498 -57 18.943\n      vertex 55.498 -60 18.943\n      vertex 55.073 -57 19.011\n    endloop\n  endfacet\n  facet normal -0.70827 0 0.70594\n    outer loop\n      vertex 56.186 -57 16.827\n      vertex 55.882 -57 16.522\n      vertex 56.186 -60 16.827\n    endloop\n  endfacet\n  facet normal -0.89115 0 0.45372\n    outer loop\n      vertex 56.381 -60 17.21\n      vertex 56.381 -57 17.21\n      vertex 56.186 -60 16.827\n    endloop\n  endfacet\n  facet normal -0.98744 0 -0.15799\n    outer loop\n      vertex 56.381 -57 18.06\n      vertex 56.449 -57 17.635\n      vertex 56.381 -60 18.06\n    endloop\n  endfacet\n  facet normal -0.89162 0 -0.45278\n    outer loop\n      vertex 56.186 -60 18.444\n      vertex 56.186 -57 18.444\n      vertex 56.381 -60 18.06\n    endloop\n  endfacet\n  facet normal -0.70711 0 -0.70711\n    outer loop\n      vertex 56.186 -57 18.444\n      vertex 56.186 -60 18.444\n      vertex 55.882 -57 18.748\n    endloop\n  endfacet\n  facet normal -0.45278 0 -0.89162\n    outer loop\n      vertex 55.498 -57 18.943\n      vertex 55.882 -57 18.748\n      vertex 55.498 -60 18.943\n    endloop\n  endfacet\n  facet normal 0.45372 0 0.89115\n    outer loop\n      vertex 54.265 -57 16.522\n      vertex 54.265 -60 16.522\n      vertex 54.648 -57 16.327\n    endloop\n  endfacet\n  facet normal 0.15799 0 0.98744\n    outer loop\n      vertex 55.073 -57 16.259\n      vertex 54.648 -57 16.327\n      vertex 55.073 -60 16.259\n    endloop\n  endfacet\n  facet normal -0.15799 0 0.98744\n    outer loop\n      vertex 55.498 -57 16.327\n      vertex 55.073 -57 16.259\n      vertex 55.073 -60 16.259\n    endloop\n  endfacet\n  facet normal 0.15799 0 -0.98744\n    outer loop\n      vertex 54.648 -60 18.943\n      vertex 54.648 -57 18.943\n      vertex 55.073 -57 19.011\n    endloop\n  endfacet\n  facet normal 0.45372 0 -0.89115\n    outer loop\n      vertex 54.648 -57 18.943\n      vertex 54.648 -60 18.943\n      vertex 54.265 -60 18.748\n    endloop\n  endfacet\n  facet normal 0.45372 0 -0.89115\n    outer loop\n      vertex 54.648 -57 18.943\n      vertex 54.265 -60 18.748\n      vertex 54.265 -57 18.748\n    endloop\n  endfacet\n  facet normal 0.70594 0 -0.70827\n    outer loop\n      vertex 53.96 -60 18.444\n      vertex 53.96 -57 18.444\n      vertex 54.265 -60 18.748\n    endloop\n  endfacet\n  facet normal 0.70594 0 -0.70827\n    outer loop\n      vertex 54.265 -57 18.748\n      vertex 54.265 -60 18.748\n      vertex 53.96 -57 18.444\n    endloop\n  endfacet\n  facet normal 0.89162 0 -0.45278\n    outer loop\n      vertex 53.765 -60 18.06\n      vertex 53.765 -57 18.06\n      vertex 53.96 -60 18.444\n    endloop\n  endfacet\n  facet normal 0.89162 0 -0.45278\n    outer loop\n      vertex 53.96 -57 18.444\n      vertex 53.96 -60 18.444\n      vertex 53.765 -57 18.06\n    endloop\n  endfacet\n  facet normal 0.9878 0 -0.15572\n    outer loop\n      vertex 53.765 -60 18.06\n      vertex 53.698 -57 17.635\n      vertex 53.765 -57 18.06\n    endloop\n  endfacet\n  facet normal 0.9878 0 0.15572\n    outer loop\n      vertex 53.698 -57 17.635\n      vertex 53.765 -60 17.21\n      vertex 53.765 -57 17.21\n    endloop\n  endfacet\n  facet normal 0.89115 0 0.45372\n    outer loop\n      vertex 53.765 -57 17.21\n      vertex 53.765 -60 17.21\n      vertex 53.96 -57 16.827\n    endloop\n  endfacet\n  facet normal 0.70711 0 0.70711\n    outer loop\n      vertex 53.96 -57 16.827\n      vertex 54.265 -60 16.522\n      vertex 54.265 -57 16.522\n    endloop\n  endfacet\n  facet normal 0.45372 0 0.89115\n    outer loop\n      vertex 54.648 -57 16.327\n      vertex 54.265 -60 16.522\n      vertex 54.648 -60 16.327\n    endloop\n  endfacet\n  facet normal -0.45278 0 0.89162\n    outer loop\n      vertex 55.882 -60 16.522\n      vertex 55.882 -57 16.522\n      vertex 55.498 -57 16.327\n    endloop\n  endfacet\n  facet normal -0.70827 0 0.70594\n    outer loop\n      vertex 55.882 -60 16.522\n      vertex 56.186 -60 16.827\n      vertex 55.882 -57 16.522\n    endloop\n  endfacet\n  facet normal -0.89115 0 0.45372\n    outer loop\n      vertex 56.186 -57 16.827\n      vertex 56.186 -60 16.827\n      vertex 56.381 -57 17.21\n    endloop\n  endfacet\n  facet normal -0.98744 0 0.15799\n    outer loop\n      vertex 56.449 -60 17.635\n      vertex 56.449 -57 17.635\n      vertex 56.381 -60 17.21\n    endloop\n  endfacet\n  facet normal -0.98744 0 0.15799\n    outer loop\n      vertex 56.381 -57 17.21\n      vertex 56.381 -60 17.21\n      vertex 56.449 -57 17.635\n    endloop\n  endfacet\n  facet normal -0.98744 0 -0.15799\n    outer loop\n      vertex 56.449 -60 17.635\n      vertex 56.381 -60 18.06\n      vertex 56.449 -57 17.635\n    endloop\n  endfacet\n  facet normal -0.89162 0 -0.45278\n    outer loop\n      vertex 56.381 -57 18.06\n      vertex 56.381 -60 18.06\n      vertex 56.186 -57 18.444\n    endloop\n  endfacet\n  facet normal -0.70711 0 -0.70711\n    outer loop\n      vertex 55.882 -60 18.748\n      vertex 55.882 -57 18.748\n      vertex 56.186 -60 18.444\n    endloop\n  endfacet\n  facet normal -0.45278 0 -0.89162\n    outer loop\n      vertex 55.882 -60 18.748\n      vertex 55.498 -60 18.943\n      vertex 55.882 -57 18.748\n    endloop\n  endfacet\n  facet normal -0.15799 0 -0.98744\n    outer loop\n      vertex 55.073 -60 19.011\n      vertex 55.073 -57 19.011\n      vertex 55.498 -60 18.943\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 20.1 -59.097 10.097\n      vertex 20.1 -60 10.097\n      vertex 61 -59.097 10.097\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 61 -59.097 16.003\n      vertex 61 -60 16.003\n      vertex 53.698 -60 16.003\n    endloop\n  endfacet\n  facet normal 0.70711 0 -0.70711\n    outer loop\n      vertex 24.297 -57 18.422\n      vertex 24.557 -57 18.682\n      vertex 24.297 -60 18.422\n    endloop\n  endfacet\n  facet normal 0.89058 0 -0.45482\n    outer loop\n      vertex 24.13 -60 18.095\n      vertex 24.13 -57 18.095\n      vertex 24.297 -60 18.422\n    endloop\n  endfacet\n  facet normal 0.45482 0 0.89058\n    outer loop\n      vertex 24.884 -57 16.617\n      vertex 24.557 -60 16.784\n      vertex 24.884 -60 16.617\n    endloop\n  endfacet\n  facet normal 0.1582 0 0.98741\n    outer loop\n      vertex 25.246 -60 16.559\n      vertex 25.246 -57 16.559\n      vertex 24.884 -60 16.617\n    endloop\n  endfacet\n  facet normal 0.1582 0 0.98741\n    outer loop\n      vertex 24.884 -57 16.617\n      vertex 24.884 -60 16.617\n      vertex 25.246 -57 16.559\n    endloop\n  endfacet\n  facet normal -0.15778 0 0.98747\n    outer loop\n      vertex 25.246 -60 16.559\n      vertex 25.609 -60 16.617\n      vertex 25.246 -57 16.559\n    endloop\n  endfacet\n  facet normal -0.45482 0 0.89058\n    outer loop\n      vertex 25.936 -60 16.784\n      vertex 25.936 -57 16.784\n      vertex 25.609 -60 16.617\n    endloop\n  endfacet\n  facet normal -0.70711 0 0.70711\n    outer loop\n      vertex 26.195 -60 17.043\n      vertex 25.936 -57 16.784\n      vertex 25.936 -60 16.784\n    endloop\n  endfacet\n  facet normal -0.89058 0 0.45482\n    outer loop\n      vertex 26.362 -60 17.37\n      vertex 26.362 -57 17.37\n      vertex 26.195 -60 17.043\n    endloop\n  endfacet\n  facet normal -0.9879 0 0.15512\n    outer loop\n      vertex 26.362 -60 17.37\n      vertex 26.419 -60 17.733\n      vertex 26.362 -57 17.37\n    endloop\n  endfacet\n  facet normal 0.45482 0 -0.89058\n    outer loop\n      vertex 24.884 -57 18.849\n      vertex 24.884 -60 18.849\n      vertex 24.557 -57 18.682\n    endloop\n  endfacet\n  facet normal -0.70847 0 -0.70574\n    outer loop\n      vertex 25.936 -60 18.682\n      vertex 25.936 -57 18.682\n      vertex 26.195 -60 18.422\n    endloop\n  endfacet\n  facet normal -0.45482 0 -0.89058\n    outer loop\n      vertex 25.609 -57 18.849\n      vertex 25.936 -57 18.682\n      vertex 25.609 -60 18.849\n    endloop\n  endfacet\n  facet normal -0.15512 0 -0.9879\n    outer loop\n      vertex 25.246 -60 18.906\n      vertex 25.246 -57 18.906\n      vertex 25.609 -60 18.849\n    endloop\n  endfacet\n  facet normal 0.89058 0 -0.45482\n    outer loop\n      vertex 24.297 -57 18.422\n      vertex 24.297 -60 18.422\n      vertex 24.13 -57 18.095\n    endloop\n  endfacet\n  facet normal 0.98783 0 -0.15554\n    outer loop\n      vertex 24.073 -57 17.733\n      vertex 24.13 -57 18.095\n      vertex 24.073 -60 17.733\n    endloop\n  endfacet\n  facet normal 0.98783 0 -0.15554\n    outer loop\n      vertex 24.13 -60 18.095\n      vertex 24.073 -60 17.733\n      vertex 24.13 -57 18.095\n    endloop\n  endfacet\n  facet normal 0.9879 0 0.15512\n    outer loop\n      vertex 24.13 -60 17.37\n      vertex 24.13 -57 17.37\n      vertex 24.073 -60 17.733\n    endloop\n  endfacet\n  facet normal 0.9879 0 0.15512\n    outer loop\n      vertex 24.073 -57 17.733\n      vertex 24.073 -60 17.733\n      vertex 24.13 -57 17.37\n    endloop\n  endfacet\n  facet normal 0.89058 0 0.45482\n    outer loop\n      vertex 24.13 -57 17.37\n      vertex 24.13 -60 17.37\n      vertex 24.297 -60 17.043\n    endloop\n  endfacet\n  facet normal 0.89058 0 0.45482\n    outer loop\n      vertex 24.13 -57 17.37\n      vertex 24.297 -60 17.043\n      vertex 24.297 -57 17.043\n    endloop\n  endfacet\n  facet normal 0.70574 0 0.70847\n    outer loop\n      vertex 24.557 -60 16.784\n      vertex 24.557 -57 16.784\n      vertex 24.297 -57 17.043\n    endloop\n  endfacet\n  facet normal 0.70574 0 0.70847\n    outer loop\n      vertex 24.557 -60 16.784\n      vertex 24.297 -57 17.043\n      vertex 24.297 -60 17.043\n    endloop\n  endfacet\n  facet normal 0.45482 0 0.89058\n    outer loop\n      vertex 24.884 -57 16.617\n      vertex 24.557 -57 16.784\n      vertex 24.557 -60 16.784\n    endloop\n  endfacet\n  facet normal -0.15778 0 0.98747\n    outer loop\n      vertex 25.609 -60 16.617\n      vertex 25.609 -57 16.617\n      vertex 25.246 -57 16.559\n    endloop\n  endfacet\n  facet normal -0.45482 0 0.89058\n    outer loop\n      vertex 25.936 -57 16.784\n      vertex 25.609 -57 16.617\n      vertex 25.609 -60 16.617\n    endloop\n  endfacet\n  facet normal -0.70711 0 0.70711\n    outer loop\n      vertex 26.195 -60 17.043\n      vertex 26.195 -57 17.043\n      vertex 25.936 -57 16.784\n    endloop\n  endfacet\n  facet normal -0.89058 0 0.45482\n    outer loop\n      vertex 26.362 -57 17.37\n      vertex 26.195 -57 17.043\n      vertex 26.195 -60 17.043\n    endloop\n  endfacet\n  facet normal -0.9879 0 0.15512\n    outer loop\n      vertex 26.362 -57 17.37\n      vertex 26.419 -60 17.733\n      vertex 26.419 -57 17.733\n    endloop\n  endfacet\n  facet normal -0.98783 0 -0.15554\n    outer loop\n      vertex 26.362 -60 18.095\n      vertex 26.362 -57 18.095\n      vertex 26.419 -57 17.733\n    endloop\n  endfacet\n  facet normal -0.98783 0 -0.15554\n    outer loop\n      vertex 26.362 -60 18.095\n      vertex 26.419 -57 17.733\n      vertex 26.419 -60 17.733\n    endloop\n  endfacet\n  facet normal -0.89058 0 -0.45482\n    outer loop\n      vertex 26.362 -60 18.095\n      vertex 26.195 -60 18.422\n      vertex 26.362 -57 18.095\n    endloop\n  endfacet\n  facet normal -0.89058 0 -0.45482\n    outer loop\n      vertex 26.195 -57 18.422\n      vertex 26.362 -57 18.095\n      vertex 26.195 -60 18.422\n    endloop\n  endfacet\n  facet normal 0.15554 0 -0.98783\n    outer loop\n      vertex 24.884 -60 18.849\n      vertex 24.884 -57 18.849\n      vertex 25.246 -60 18.906\n    endloop\n  endfacet\n  facet normal 0.15554 0 -0.98783\n    outer loop\n      vertex 25.246 -57 18.906\n      vertex 25.246 -60 18.906\n      vertex 24.884 -57 18.849\n    endloop\n  endfacet\n  facet normal 0.45482 0 -0.89058\n    outer loop\n      vertex 24.557 -60 18.682\n      vertex 24.557 -57 18.682\n      vertex 24.884 -60 18.849\n    endloop\n  endfacet\n  facet normal 0.70711 0 -0.70711\n    outer loop\n      vertex 24.557 -60 18.682\n      vertex 24.297 -60 18.422\n      vertex 24.557 -57 18.682\n    endloop\n  endfacet\n  facet normal -0.70847 0 -0.70574\n    outer loop\n      vertex 26.195 -57 18.422\n      vertex 26.195 -60 18.422\n      vertex 25.936 -57 18.682\n    endloop\n  endfacet\n  facet normal -0.45482 0 -0.89058\n    outer loop\n      vertex 25.936 -60 18.682\n      vertex 25.609 -60 18.849\n      vertex 25.936 -57 18.682\n    endloop\n  endfacet\n  facet normal -0.15512 0 -0.9879\n    outer loop\n      vertex 25.609 -57 18.849\n      vertex 25.609 -60 18.849\n      vertex 25.246 -57 18.906\n    endloop\n  endfacet\n  facet normal 0 0 1\n    outer loop\n      vertex 61 -60 10.097\n      vertex 61 -59.097 10.097\n      vertex 20.1 -60 10.097\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 24.073 -60 16.003\n      vertex 20.1 -59.097 16.003\n      vertex 53.698 -60 16.003\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 20.1 -59.097 10.097\n      vertex 61 -59.097 10.097\n      vertex 61 -59.097 16.003\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 61 -59.097 16.003\n      vertex 53.698 -60 16.003\n      vertex 20.1 -59.097 16.003\n    endloop\n  endfacet\n  facet normal 0 0 -1\n    outer loop\n      vertex 20.1 -59.097 16.003\n      vertex 24.073 -60 16.003\n      vertex 20.1 -60 16.003\n    endloop\n  endfacet\n  facet normal 0 -1 0\n    outer loop\n      vertex 61 -59.097 16.003\n      vertex 20.1 -59.097 16.003\n      vertex 20.1 -59.097 10.097\n    endloop\n  endfacet\nendsolid stl_item0\n"
  },
  {
    "path": "robotics/donkey-car/line_follower_main.py",
    "content": "# This file is part of the OpenMV project.\n# Copyright (c) 2013-2017 Ibrahim Abdelkader <iabdalkader@openmv.io> & Kwabena W. Agyeman <kwagyeman@openmv.io>\n# Support for OpenMV Motor Shield by Chris Anderson, DIY Robocars\n# This work is licensed under the MIT license, see the file LICENSE for details.\n\nimport sensor, image, time, math, pyb\n\n\n###########\n# Settings\n###########\n\nCOLOR_LINE_FOLLOWING = True # False to use grayscale thresholds, true to use color thresholds.\nCOLOR_THRESHOLDS = [( 94, 100,  -27,    1,   20,  127)] # Yellow Line.\nGRAYSCALE_THRESHOLDS = [(240, 255)] # White Line.\nCOLOR_HIGH_LIGHT_THRESHOLDS = [(80, 100, -10, 10, -10, 10)]\nGRAYSCALE_HIGH_LIGHT_THRESHOLDS = [(250, 255)]\nBINARY_VIEW = False # Helps debugging but costs FPS if on.\nDO_NOTHING = False # Just capture frames...\nFRAME_SIZE = sensor.QQVGA # Frame size.\nFRAME_REGION = 0.75 # Percentage of the image from the bottom (0 - 1.0).\nFRAME_WIDE = 1.0 # Percentage of the frame width.\n\nAREA_THRESHOLD = 0 # Raise to filter out false detections.\nPIXELS_THRESHOLD = 40 # Raise to filter out false detections.\nMAG_THRESHOLD = 4 # Raise to filter out false detections.\nMIXING_RATE = 0.9 # Percentage of a new line detection to mix into current steering.\n\n# Tweak these values for your robocar.\nTHROTTLE_CUT_OFF_ANGLE = 1.0 # Maximum angular distance from 90 before we cut speed [0.0-90.0).\nTHROTTLE_CUT_OFF_RATE = 0.5 # How much to cut our speed boost (below) once the above is passed (0.0-1.0].\nTHROTTLE_GAIN = 0.0 # e.g. how much to speed up on a straight away\nTHROTTLE_OFFSET = 30.0 # e.g. default speed (0 to 100)\nTHROTTLE_P_GAIN = 1.0\nTHROTTLE_I_GAIN = 0.0\nTHROTTLE_I_MIN = -0.0\nTHROTTLE_I_MAX = 0.0\nTHROTTLE_D_GAIN = 0.0\n\n# Tweak these values for your robocar.\nSTEERING_OFFSET = 90 # Change this if you need to fix an imbalance in your car (0 to 180).\nSTEERING_P_GAIN = -15.0 # Make this smaller as you increase your speed and vice versa.\nSTEERING_I_GAIN = 0.0\nSTEERING_I_MIN = -0.0\nSTEERING_I_MAX = 0.0\nSTEERING_D_GAIN = -12 # Make this larger as you increase your speed and vice versa.\n\n# Selects motor/servo controller method...\nARDUINO_SERVO_CONTROLLER = False\nNATIVE_SERVO_CONTROLLER = True\nNATIVE_MOTOR_CONTROLLER = False\n\n# Tweak these values for your robocar if you're using servos.\nTHROTTLE_SERVO_MIN_US = 1500\nTHROTTLE_SERVO_MAX_US = 2000\n\n# Tweak these values for your robocar.\nSTEERING_SERVO_MIN_US = 700\nSTEERING_SERVO_MAX_US = 2300\n\n###########\n# Setup\n###########\n\nFRAME_REGION = max(min(FRAME_REGION, 1.0), 0.0)\nFRAME_WIDE = max(min(FRAME_WIDE, 1.0), 0.0)\nMIXING_RATE = max(min(MIXING_RATE, 1.0), 0.0)\n\nTHROTTLE_CUT_OFF_ANGLE = max(min(THROTTLE_CUT_OFF_ANGLE, 89.99), 0)\nTHROTTLE_CUT_OFF_RATE = max(min(THROTTLE_CUT_OFF_RATE, 1.0), 0.01)\n\nTHROTTLE_OFFSET = max(min(THROTTLE_OFFSET, 100), 0)\nSTEERING_OFFSET = max(min(STEERING_OFFSET, 180), 0)\n\n# Handle if these were reversed...\ntmp = max(THROTTLE_SERVO_MIN_US, THROTTLE_SERVO_MAX_US)\nTHROTTLE_SERVO_MIN_US = min(THROTTLE_SERVO_MIN_US, THROTTLE_SERVO_MAX_US)\nTHROTTLE_SERVO_MAX_US = tmp\n\n# Handle if these were reversed...\ntmp = max(STEERING_SERVO_MIN_US, STEERING_SERVO_MAX_US)\nSTEERING_SERVO_MIN_US = min(STEERING_SERVO_MIN_US, STEERING_SERVO_MAX_US)\nSTEERING_SERVO_MAX_US = tmp\n\ndevice = None\n\nif ARDUINO_SERVO_CONTROLLER:\n    device = pyb.UART(3, 19200, timeout_char = 1000)\n\nif NATIVE_SERVO_CONTROLLER:\n    import servo\n    import machine\n    device = servo.Servos(machine.I2C(sda = machine.Pin(\"P5\"), scl = machine.Pin(\"P4\")), address = 0x40, freq = 50)\n\nif NATIVE_MOTOR_CONTROLLER:\n    from pyb import Pin, Timer\n\n    # these are motor driver pins, which set the direction of each motor\n    pinADir0 = pyb.Pin('P0', pyb.Pin.OUT_PP, pyb.Pin.PULL_NONE)\n    pinADir1 = pyb.Pin('P1', pyb.Pin.OUT_PP, pyb.Pin.PULL_NONE)\n    pinBDir0 = pyb.Pin('P2', pyb.Pin.OUT_PP, pyb.Pin.PULL_NONE)\n    pinBDir1 = pyb.Pin('P3', pyb.Pin.OUT_PP, pyb.Pin.PULL_NONE)\n\n    # Dir0/1 must be not equal to each other for forward or backwards\n    # operation. If they are equal then that's a brake operation.\n    # If they are not equal then the motor will spin one way other the\n    # other depending on its hookup and the value of channel 0.\n\n    pinBDir0.value(0)\n    pinBDir1.value(1)\n\n    tim = Timer(4, freq=1000) # Frequency in Hz\n    ch1 = tim.channel(1, pyb.Timer.PWM, pin=pyb.Pin(\"P7\"))\n    ch2 = tim.channel(2, pyb.Timer.PWM, pin=pyb.Pin(\"P8\"))\n    cruise_speed = 50\n    radians_degrees = 57.3 # constant to convert from radians to degrees\n    steering_direction = 1   # use this to reverse the steering if your car goes in the wrong direction\n    steering_gain = 1.0  # calibration for your car's steering sensitivity\n    steering_center = 0  # set to your car's steering center point\n\ndef constrain(value, min, max):\n    if value < min :\n        return min\n    if value > max :\n        return max\n    else:\n        return value\n\ndef steer(throttle, angle):\n    global steering_gain, cruise_speed, steering_center\n    angle = int(round(angle+steering_center))\n    angle = constrain(angle, 0, 180)\n    angle = angle - 90\n    angle = radians_degrees * math.tan(angle/radians_degrees) # take the tangent to create a non-linear response curver\n    angle = angle * steering_gain\n    print (\"Calculated angle\", angle)\n    left = angle*steering_direction + throttle + cruise_speed\n    left = constrain (left, 0, 100)\n    right = -1*angle*steering_direction + throttle + cruise_speed\n    right = constrain (right, 0, 100)\n    print (\"left: \", left)\n    print (\"right: \", right)\n    # Generate a 1KHz square wave on TIM4 with each channel\n    ch1.pulse_width_percent(left)\n    ch2.pulse_width_percent(right)\n\n\n# This function maps the output of the linear regression function to a driving vector for steering\n# the robocar. See https://openmv.io/blogs/news/linear-regression-line-following for more info.\n\nold_cx_normal = None\ndef figure_out_my_steering(line, img):\n    global old_cx_normal\n\n    # Rho is computed using the inverse of this code below in the actual OpenMV Cam code.\n    # This formula comes from the Hough line detection formula (see the wikipedia page for more).\n    # Anyway, the output of this calculations below are a point centered vertically in the middle\n    # of the image and to the left or right such that the line goes through it (cx may be off the image).\n    cy = img.height() / 2\n    cx = (line.rho() - (cy * math.sin(math.radians(line.theta())))) / math.cos(math.radians(line.theta()))\n\n    # \"cx_middle\" is now the distance from the center of the line. This is our error method to stay\n    # on the line. \"cx_normal\" normalizes the error to something like -1/+1 (it will go over this).\n    cx_middle = cx - (img.width() / 2)\n    cx_normal = cx_middle / (img.width() / 2)\n    # Note that \"cx_normal\" may be larger than -1/+1. When the value is between -1/+1 this means the\n    # robot is driving basically straight and needs to only turn lightly left or right. When the value\n    # is outside -1/+1 it means you need to turn VERY hard to the left or right to get back on the\n    # line. This maps to the case of the robot driving into a horizontal line. \"cx_normal\" will\n    # then approach -inf/+inf depending on how horizontal the line is. What's nice is that this\n    # is exactly the behavior we want and it gets up back on the line!\n\n    if old_cx_normal != None: old_cx_normal = (cx_normal * MIXING_RATE) + (old_cx_normal * (1.0 - MIXING_RATE))\n    else: old_cx_normal = cx_normal\n    return old_cx_normal\n\n# Solve: THROTTLE_CUT_OFF_RATE = pow(sin(90 +/- THROTTLE_CUT_OFF_ANGLE), x) for x...\n#        -> sin(90 +/- THROTTLE_CUT_OFF_ANGLE) = cos(THROTTLE_CUT_OFF_ANGLE)\nt_power = math.log(THROTTLE_CUT_OFF_RATE) / math.log(math.cos(math.radians(THROTTLE_CUT_OFF_ANGLE)))\n\ndef figure_out_my_throttle(steering): # steering -> [0:180]\n\n    # pow(sin()) of the steering angle is only non-zero when driving straight... e.g. steering ~= 90\n    t_result = math.pow(math.sin(math.radians(max(min(steering, 179.99), 0.0))), t_power)\n\n    return (t_result * THROTTLE_GAIN) + THROTTLE_OFFSET\n\n#\n# Servo Control Code\n#\n\n\n\n# throttle [0:100] (101 values) -> [THROTTLE_SERVO_MIN_US, THROTTLE_SERVO_MAX_US]\n# steering [0:180] (181 values) -> [STEERING_SERVO_MIN_US, STEERING_SERVO_MAX_US]\ndef set_servos(throttle, steering):\n    if NATIVE_MOTOR_CONTROLLER:\n        steer(throttle, steering)\n    if ARDUINO_SERVO_CONTROLLER:\n        throttle = THROTTLE_SERVO_MIN_US + ((throttle * (THROTTLE_SERVO_MAX_US - THROTTLE_SERVO_MIN_US + 1)) / 101)\n        steering = STEERING_SERVO_MIN_US + ((steering * (STEERING_SERVO_MAX_US - STEERING_SERVO_MIN_US + 1)) / 181)\n        device.write(\"{%05d,%05d}\\r\\n\" % (throttle, steering))\n    if NATIVE_SERVO_CONTROLLER:\n        throttle = THROTTLE_SERVO_MIN_US + ((throttle * (THROTTLE_SERVO_MAX_US - THROTTLE_SERVO_MIN_US + 1)) / 101)\n        steering = STEERING_SERVO_MIN_US + ((steering * (STEERING_SERVO_MAX_US - STEERING_SERVO_MIN_US + 1)) / 181)\n        device.position(0, us=throttle)\n        device.position(1, us=steering)\n\n#\n# Camera Control Code\n#\n\nsensor.reset()\nsensor.set_pixformat(sensor.RGB565 if COLOR_LINE_FOLLOWING else sensor.GRAYSCALE)\nsensor.set_framesize(FRAME_SIZE)\nsensor.set_vflip(True)\nsensor.set_hmirror(True)\nsensor.set_windowing((int((sensor.width() / 2) - ((sensor.width() / 2) * FRAME_WIDE)), int(sensor.height() * (1.0 - FRAME_REGION)), \\\n                     int((sensor.width() / 2) + ((sensor.width() / 2) * FRAME_WIDE)), int(sensor.height() * FRAME_REGION)))\nsensor.skip_frames(time = 200)\nif COLOR_LINE_FOLLOWING: sensor.set_auto_gain(False)\nif COLOR_LINE_FOLLOWING: sensor.set_auto_whitebal(False)\nclock = time.clock()\n#sensor.set_auto_exposure(False, \\\n#    exposure_us = 300)\n\n\n###########\n# Loop\n###########\n\nold_time = pyb.millis()\n\nthrottle_old_result = None\nthrottle_i_output = 0\nthrottle_output = THROTTLE_OFFSET\n\nsteering_old_result = None\nsteering_i_output = 0\nsteering_output = STEERING_OFFSET\n\nwhile True:\n    clock.tick()\n    img = sensor.snapshot()\n    img.binary(COLOR_HIGH_LIGHT_THRESHOLDS if COLOR_LINE_FOLLOWING else GRAYSCALE_HIGH_LIGHT_THRESHOLDS, zero = True)\n    img.histeq()\n\n    if BINARY_VIEW: img = img.binary(COLOR_THRESHOLDS if COLOR_LINE_FOLLOWING else GRAYSCALE_THRESHOLDS)\n    if BINARY_VIEW: img.erode(1, threshold = 5).dilate(1, threshold = 1)\n    if DO_NOTHING: continue\n\n    # We call get regression below to get a robust linear regression of the field of view.\n    # This returns a line object which we can use to steer the robocar.\n    line = img.get_regression(([(50, 100, -128, 127, -128, 127)] if BINARY_VIEW else COLOR_THRESHOLDS) if COLOR_LINE_FOLLOWING \\\n        else ([(127, 255)] if BINARY_VIEW else GRAYSCALE_THRESHOLDS), \\\n        area_threshold = AREA_THRESHOLD, pixels_threshold = PIXELS_THRESHOLD, \\\n        robust = True)\n\n    print_string = \"\"\n    if line and (line.magnitude() >= MAG_THRESHOLD):\n        img.draw_line(line.line(), color = (127, 127, 127) if COLOR_LINE_FOLLOWING else 127)\n\n        new_time = pyb.millis()\n        delta_time = new_time - old_time\n        old_time = new_time\n\n        #\n        # Figure out steering and do steering PID\n        #\n\n        steering_new_result = figure_out_my_steering(line, img)\n        steering_delta_result = (steering_new_result - steering_old_result) if (steering_old_result != None) else 0\n        steering_old_result = steering_new_result\n\n        steering_p_output = steering_new_result # Standard PID Stuff here... nothing particularly interesting :)\n        steering_i_output = max(min(steering_i_output + steering_new_result, STEERING_I_MAX), STEERING_I_MIN)\n        steering_d_output = ((steering_delta_result * 1000) / delta_time) if delta_time else 0\n        steering_pid_output = (STEERING_P_GAIN * steering_p_output) + \\\n                              (STEERING_I_GAIN * steering_i_output) + \\\n                              (STEERING_D_GAIN * steering_d_output)\n\n        # Steering goes from [-90,90] but we need to output [0,180] for the servos.\n        steering_output = STEERING_OFFSET + max(min(round(steering_pid_output), 180 - STEERING_OFFSET), STEERING_OFFSET - 180)\n\n        #\n        # Figure out throttle and do throttle PID\n        #\n\n        throttle_new_result = figure_out_my_throttle(steering_output)\n        throttle_delta_result = (throttle_new_result - throttle_old_result) if (throttle_old_result != None) else 0\n        throttle_old_result = throttle_new_result\n\n        throttle_p_output = throttle_new_result # Standard PID Stuff here... nothing particularly interesting :)\n        throttle_i_output = max(min(throttle_i_output + throttle_new_result, THROTTLE_I_MAX), THROTTLE_I_MIN)\n        throttle_d_output = ((throttle_delta_result * 1000) / delta_time) if delta_time else 0\n        throttle_pid_output = (THROTTLE_P_GAIN * throttle_p_output) + \\\n                              (THROTTLE_I_GAIN * throttle_i_output) + \\\n                              (THROTTLE_D_GAIN * throttle_d_output)\n\n        # Throttle goes from 0% to 100%.\n        throttle_output = max(min(round(throttle_pid_output), 100), 0)\n\n        print_string = \"Line Ok - throttle %d, steering %d - line t: %d, r: %d\" % \\\n            (throttle_output , steering_output, line.theta(), line.rho())\n\n    else:\n        print_string = \"Line Lost - throttle %d, steering %d\" % (throttle_output , steering_output)\n\n    set_servos(throttle_output, steering_output)\n    print(\"FPS %f - %s\" % (clock.fps(), print_string))\n"
  },
  {
    "path": "robotics/donkey-car/pca9685.py",
    "content": "import utime\nimport ustruct\n\nclass PCA9685:\n    def __init__(self, i2c, address=0x40):\n        self.i2c = i2c\n        self.address = address\n        self.reset()\n\n    def _write(self, address, value):\n        self.i2c.writeto_mem(self.address, address, bytearray([value]))\n\n    def _read(self, address):\n        return self.i2c.readfrom_mem(self.address, address, 1)[0]\n\n    def reset(self):\n        self._write(0x00, 0x00) # Mode1\n\n    def freq(self, freq=None):\n        if freq is None:\n            return int(25000000.0 / 4096 / (self._read(0xfe) - 0.5))\n        prescale = int(25000000.0 / 4096.0 / freq + 0.5)\n        old_mode = self._read(0x00) # Mode 1\n        self._write(0x00, (old_mode & 0x7F) | 0x10) # Mode 1, sleep\n        self._write(0xfe, prescale) # Prescale\n        self._write(0x00, old_mode) # Mode 1\n        utime.sleep_us(5)\n        self._write(0x00, old_mode | 0xa1) # Mode 1, autoincrement on\n\n    def pwm(self, index, on=None, off=None):\n        if on is None or off is None:\n            data = self.i2c.readfrom_mem(self.address, 0x06 + 4 * index, 4)\n            return ustruct.unpack('<HH', data)\n        data = ustruct.pack('<HH', on, off)\n        self.i2c.writeto_mem(self.address, 0x06 + 4 * index,  data)\n\n    def duty(self, index, value=None, invert=False):\n        if value is None:\n            pwm = self.pwm(index)\n            if pwm == (0, 4096):\n                value = 0\n            elif pwm == (4096, 0):\n                value = 4095\n            value = pwm[1]\n            if invert:\n                value = 4095 - value\n            return value\n        if not 0 <= value <= 4095:\n            raise ValueError(\"Out of range\")\n        if invert:\n            value = 4095 - value\n        if value == 0:\n            self.pwm(index, 0, 4096)\n        elif value == 4095:\n            self.pwm(index, 4096, 0)\n        else:\n            self.pwm(index, 0, value)\n\n"
  },
  {
    "path": "robotics/donkey-car/servo.py",
    "content": "import pca9685\nimport math\n\nclass Servos:\n    def __init__(self, i2c, address=0x40, freq=50, min_us=600, max_us=2400, degrees=180):\n        self.period = 1000000 / freq\n        self.min_duty = self._us2duty(min_us)\n        self.max_duty = self._us2duty(max_us)\n        self.degrees = degrees\n        self.freq = freq\n        self.pca9685 = pca9685.PCA9685(i2c, address)\n        self.pca9685.freq(freq)\n\n    def _us2duty(self, value):\n        return int(4095 * value / self.period)\n\n    def position(self, index, degrees=None, radians=None, us=None, duty=None):\n        span = self.max_duty - self.min_duty\n        if degrees is not None:\n            duty = self.min_duty + span * degrees / self.degrees\n        elif radians is not None:\n            duty = self.min_duty + span * radians / math.radians(self.degrees)\n        elif us is not None:\n            duty = self._us2duty(us)\n        elif duty is not None:\n            pass\n        else:\n            return self.pca9685.duty(index)\n        duty = min(self.max_duty, max(self.min_duty, int(duty)))\n        self.pca9685.duty(index, duty)\n\n    def release(self, index):\n        self.pca9685.duty(index, 0)\n"
  },
  {
    "path": "robotics/donkey-car/servo_controller/servo_controller.ino",
    "content": "// This file is part of the OpenMV project.\n// Copyright (c) 2013-2017 Ibrahim Abdelkader <iabdalkader@openmv.io> & Kwabena W. Agyeman <kwagyeman@openmv.io>\n// This work is licensed under the MIT license, see the file LICENSE for details.\n\n#include <Servo.h>\n\n#define SERIAL_RX_PIN 0\n#define SERIAL_TX_PIN 1\n#define THROTTLE_SERVO_PIN 6\n#define STEERING_SERVO_PIN 10\n#define RC_THROTTLE_SERVO_PIN 11\n#define RC_STEERING_SERVO_PIN 5\n\n#define SERIAL_BUAD_RATE 19200\n\n#define RC_THROTTLE_SERVO_REFRESH_RATE 20000UL // in us\n#define SERIAL_THROTTLE_SERVO_REFRESH_RATE 1000000UL // in us\n#define RC_THROTTLE_DEAD_ZONE_MIN 1400UL // in us\n#define RC_THROTTLE_DEAD_ZONE_MAX 1600UL // in us\n\n#define RC_STEERING_SERVO_REFRESH_RATE 20000UL // in us\n#define SERIAL_STEERING_SERVO_REFRESH_RATE 1000000UL // in us\n#define RC_STEERING_DEAD_ZONE_MIN 1400UL // in us\n#define RC_STEERING_DEAD_ZONE_MAX 1600UL // in us\n\nServo throttle_servo, steering_servo;\n\nunsigned long last_microseconds;\nbool last_rc_throttle_pin_state, last_rc_steering_pin_state;\nunsigned long last_rc_throttle_microseconds, last_rc_steering_microseconds;\nunsigned long rc_throttle_servo_pulse_length = 0, rc_steering_servo_pulse_length = 0;\nunsigned long rc_throttle_servo_pulse_refreshed = 0, rc_steering_servo_pulse_refreshed = 0;\n\nchar serial_buffer[16] = {};\nunsigned long serial_throttle_servo_pulse_length = 0, serial_steering_servo_pulse_length = 0;\nunsigned long serial_throttle_servo_pulse_refreshed = 0, serial_steering_servo_pulse_refreshed = 0;\n\nvoid setup()\n{\n    Serial.begin(SERIAL_BUAD_RATE);\n    pinMode(LED_BUILTIN, OUTPUT);\n\n    last_microseconds = micros();\n    last_rc_throttle_pin_state = digitalRead(RC_THROTTLE_SERVO_PIN) == HIGH;\n    last_rc_steering_pin_state = digitalRead(RC_STEERING_SERVO_PIN) == HIGH;\n    last_rc_throttle_microseconds = last_microseconds;\n    last_rc_steering_microseconds = last_microseconds;\n}\n\nvoid loop()\n{\n    unsigned long microseconds = micros();\n    bool rc_throttle_pin_state = digitalRead(RC_THROTTLE_SERVO_PIN) == HIGH;\n    bool rc_steering_pin_state = digitalRead(RC_STEERING_SERVO_PIN) == HIGH;\n\n    if(rc_throttle_pin_state && (!last_rc_throttle_pin_state)) // rising edge\n    {\n        last_rc_throttle_microseconds = microseconds;\n    }\n\n    if((!rc_throttle_pin_state) && last_rc_throttle_pin_state) // falling edge\n    {\n        unsigned long temp = microseconds - last_rc_throttle_microseconds;\n\n        if(!rc_throttle_servo_pulse_length)\n        {\n           rc_throttle_servo_pulse_length = temp;\n        }\n        else\n        {\n           rc_throttle_servo_pulse_length = ((rc_throttle_servo_pulse_length * 3) + temp) >> 2;\n        }\n\n        rc_throttle_servo_pulse_refreshed = microseconds;\n    }\n\n    if(rc_throttle_servo_pulse_length // zero servo if not refreshed\n    && ((microseconds - rc_throttle_servo_pulse_refreshed) > (2UL * RC_THROTTLE_SERVO_REFRESH_RATE)))\n    {\n        rc_throttle_servo_pulse_length = 0;\n    }\n\n    if(rc_steering_pin_state && (!last_rc_steering_pin_state)) // rising edge\n    {\n        last_rc_steering_microseconds = microseconds;\n    }\n\n    if((!rc_steering_pin_state) && last_rc_steering_pin_state) // falling edge\n    {\n        unsigned long temp = microseconds - last_rc_steering_microseconds;\n\n        if(!rc_steering_servo_pulse_length)\n        {\n           rc_steering_servo_pulse_length = temp;\n        }\n        else\n        {\n           rc_steering_servo_pulse_length = ((rc_steering_servo_pulse_length * 3) + temp) >> 2;\n        }\n\n        rc_steering_servo_pulse_refreshed = microseconds;\n    }\n\n    if(rc_steering_servo_pulse_length // zero servo if not refreshed\n    && ((microseconds - rc_steering_servo_pulse_refreshed) > (2UL * RC_STEERING_SERVO_REFRESH_RATE)))\n    {\n        rc_steering_servo_pulse_length = 0;\n    }\n\n    last_microseconds = microseconds;\n    last_rc_throttle_pin_state = rc_throttle_pin_state;\n    last_rc_steering_pin_state = rc_steering_pin_state;\n\n    while(Serial.available())\n    {\n        int c = Serial.read();\n        memmove(serial_buffer, serial_buffer + 1, sizeof(serial_buffer) - 2);\n        serial_buffer[sizeof(serial_buffer) - 2] = c;\n\n        if(c == '\\n')\n        {\n            unsigned long serial_throttle_servo_pulse_length_tmp, serial_steering_servo_pulse_length_tmp;\n\n            if(sscanf(serial_buffer, \"{%lu,%lu}\", &serial_throttle_servo_pulse_length_tmp, &serial_steering_servo_pulse_length_tmp) == 2)\n            {\n                if(!serial_throttle_servo_pulse_length)\n                {\n                   serial_throttle_servo_pulse_length = serial_throttle_servo_pulse_length_tmp;\n                }\n                else\n                {\n                   serial_throttle_servo_pulse_length = ((serial_throttle_servo_pulse_length * 3) + serial_throttle_servo_pulse_length_tmp) >> 2;\n                }\n\n                serial_throttle_servo_pulse_refreshed = microseconds;\n\n                if(!serial_steering_servo_pulse_length)\n                {\n                   serial_steering_servo_pulse_length = serial_steering_servo_pulse_length_tmp;\n                }\n                else\n                {\n                   serial_steering_servo_pulse_length = ((serial_steering_servo_pulse_length * 3) + serial_steering_servo_pulse_length_tmp) >> 2;\n                }\n\n                serial_steering_servo_pulse_refreshed = microseconds;\n\n                digitalWrite(LED_BUILTIN, (digitalRead(LED_BUILTIN) == HIGH) ? LOW : HIGH);\n            }\n            else\n            {\n                serial_throttle_servo_pulse_length = 0;\n                serial_steering_servo_pulse_length = 0;\n            }\n        }\n    }\n\n    if(serial_throttle_servo_pulse_length // zero servo if not refreshed\n    && ((microseconds - serial_throttle_servo_pulse_refreshed) > (2UL * SERIAL_THROTTLE_SERVO_REFRESH_RATE)))\n    {\n        serial_throttle_servo_pulse_length = 0;\n    }\n\n    if(serial_steering_servo_pulse_length // zero servo if not refreshed\n    && ((microseconds - serial_steering_servo_pulse_refreshed) > (2UL * SERIAL_STEERING_SERVO_REFRESH_RATE)))\n    {\n        serial_steering_servo_pulse_length = 0;\n    }\n\n    if(rc_steering_servo_pulse_length)\n    {\n        if(!steering_servo.attached())\n        {\n            throttle_servo.attach(THROTTLE_SERVO_PIN);\n            steering_servo.attach(STEERING_SERVO_PIN);\n        }\n\n        if(serial_steering_servo_pulse_length)\n        {\n            if((rc_throttle_servo_pulse_length < RC_THROTTLE_DEAD_ZONE_MIN)\n            || (rc_throttle_servo_pulse_length > RC_THROTTLE_DEAD_ZONE_MAX))\n            {\n                throttle_servo.writeMicroseconds(serial_throttle_servo_pulse_length);\n            }\n            else\n            {\n                throttle_servo.writeMicroseconds(1500);    \n            }\n\n            if((rc_steering_servo_pulse_length < RC_STEERING_DEAD_ZONE_MIN)\n            || (rc_steering_servo_pulse_length > RC_STEERING_DEAD_ZONE_MAX))\n            {\n                steering_servo.writeMicroseconds(rc_steering_servo_pulse_length);\n            }\n            else\n            {\n                steering_servo.writeMicroseconds(serial_steering_servo_pulse_length);\n            }\n        }\n        else\n        {\n            throttle_servo.writeMicroseconds(rc_throttle_servo_pulse_length);\n            steering_servo.writeMicroseconds(rc_steering_servo_pulse_length);\n        }\n    }\n    else if(steering_servo.attached())\n    {\n        throttle_servo.detach();\n        steering_servo.detach();\n    }\n}\n"
  },
  {
    "path": "tools/README.md",
    "content": "# OpenMV PC Tools\n\nDesktop GUI applications that pair with an OpenMV Cam over USB serial. Each tool runs a companion MicroPython script on the camera that handles capture and streaming, while the PC side provides real-time visualization, analysis, and parameter tuning.\n\nAll tools are built with [DearPyGui](https://github.com/hoffstadt/DearPyGui) and communicate with the camera via the [openmv](https://pypi.org/project/openmv/) Python package.\n\n> **Platform note:** macOS and Linux give the best performance. On Windows, GUI rendering and USB transfer throughput can be lower, which may reduce frame or event rates at high data volumes.\n\n---\n\n## [GenX320 Event Streaming](genx320-event-streaming/README.md)\n\nReal-time streaming and visualization for the [Prophesee GenX320](https://www.prophesee.ai/event-camera-genx320/) event camera sensor attached to an OpenMV Cam. Events are displayed as an accumulation canvas alongside a per-pixel frequency map computed in real time using a second-order IIR bandpass filter (FrequencyCam algorithm).\n\n![GenX320 Event Streaming GUI](genx320-event-streaming/genx320-event-streaming.png)\n\n**Key features:**\n- Dual visualization: event canvas + frequency heatmap side by side\n- Raw streaming mode (default) sends unprocessed 4-byte EVT 2.0 words vs 12-byte decoded structs — 3× less data over USB\n- Adaptive layout that maximizes image size as the window resizes\n- Colorbar legend with log or linear frequency scale\n- Save event CSV and frequency PNG to disk\n- Configurable FIFO depths, event buffer size, contrast, and colormap\n\n```\npip install dearpygui numpy pyserial Pillow openmv\npython genx320-event-streaming/genx320_event_mode_streaming_on_pc.py\n```\n\n---\n\n## [GenX320 Overlay Calibration](genx320-overlay-calibration/README.md)\n\nStreams a color frame and a 320×320 grayscale histogram frame from the GenX320 event camera simultaneously and composites them into a calibrated overlay. Supports manual 4-point picking or automatic blob-grid checkerboard detection to compute a perspective homography for pixel-accurate alignment.\n\n![GenX320 Overlay Calibration GUI](genx320-overlay-calibration/genx320_overlay_calibration.jpeg)\n\n**Key features:**\n- Dual live preview: main camera + GenX320 histogram side by side at matched display height\n- Composite view with adjustable alpha blending (0–100%)\n- Manual alignment: click 4 matching landmarks on each image\n- Automatic alignment: blob-grid detection with median filtering, Otsu thresholding, and RANSAC homography — includes a flickering calibration pattern window for event generation\n- GenX320 always operates in histogram mode (320×320 grayscale) — no format controls needed\n- Copyable 3×3 transform matrix displayed after calibration\n- Save main, GenX320, composite PNGs and transform TXT to disk\n\n```\npip install dearpygui numpy pyserial Pillow openmv opencv-python\npython genx320-overlay-calibration/genx320_overlay_calibration_on_pc.py\n```\n\n---\n\n## [Thermal Overlay Calibration](thermal-overlay-calibration/README.md)\n\nStreams color and thermal (FLIR Lepton) frames simultaneously and composites them into a calibrated overlay. Supports manual 4-point picking or automatic heated-checkerboard detection to compute a perspective homography for pixel-accurate alignment.\n\n![Thermal Overlay Calibration GUI](thermal-overlay-calibration/thermal-overlay-calibration.jpeg)\n\n**Key features:**\n- Dual live preview: main camera + Lepton side by side at matched display height\n- Composite view with adjustable alpha blending (0–100%)\n- Manual alignment: click 4 matching landmarks on each image\n- Automatic alignment: heated checkerboard detection with CLAHE, Otsu thresholding, per-channel analysis, and RANSAC homography using all corners\n- Configurable pixel format (RGB565/GRAYSCALE) and color palette (IRONBOW/RAINBOW) per camera\n- Copyable 3×3 transform matrix displayed after calibration\n- Save main, Lepton, composite PNGs and transform TXT to disk\n\n```\npip install dearpygui numpy pyserial Pillow openmv opencv-python\npython thermal-overlay-calibration/thermal_overlay_calibration_on_pc.py\n```\n\n---\n\n## [CCM Tuning](ccm-tuning/README.md)\n\nAn interactive Color Correction Matrix (CCM) tuner for the OpenMV N6 camera. Streams raw Bayer frames over USB and applies a full software replica of the N6 ISP pipeline — debayer, black level, auto white balance, CCM, brightness/contrast/gamma — so you can tune every parameter live without reflashing.\n\n![CCM Tuning GUI](ccm-tuning/ccm-tuning.jpg)\n\n**Key features:**\n- Live ISP pipeline: Raw Bayer → Debayer → Black Level → AWB → CCM → BCG\n- ColorChecker Classic solver: click four corners, get a least-squares CCM instantly\n- Multi-illuminant workflow: solve under each light source, record R/G and B/G ratios for piecewise interpolation in firmware\n- Save processed frame (BMP) and full pipeline state (TXT) to disk\n\n```\npip install dearpygui opencv-python numpy pyserial Pillow openmv\npython ccm-tuning/ccm_tuning_on_pc.py\n```\n"
  },
  {
    "path": "tools/ccm-tuning/README.md",
    "content": "# CCM Tuning GUI for OpenMV N6\n\nA PC-side GUI tool for tuning the Color Correction Matrix (CCM) and related ISP parameters for the OpenMV N6 camera. It streams raw Bayer frames from the camera over USB serial, applies a software replica of the N6 ISP pipeline in real time, and displays the corrected image alongside live statistics.\n\n![CCM Tuning GUI](ccm-tuning.jpg)\n\n## Platform Notes\n\nmacOS and Linux are recommended for the best GUI performance and frame throughput. On Windows, DearPyGui rendering can be noticeably slower, which may reduce the effective frame rate. The camera script and serial protocol work on all platforms, but if you experience a sluggish UI or low frame rate, consider switching to a Mac or Linux machine.\n\nOn macOS and Linux the companion script's `read` method is automatically renamed to `readp` before execution (this is handled transparently by the PC script).\n\nCRC is disabled by default on macOS and Linux for better USB throughput. It is enabled by default on Windows where it improves reliability. Override with `--crc`.\n\n## ISP Pipeline\n\nThe tool mimics the N6 ISP pipeline in this order:\n\n```\nRaw Bayer → Debayer → Black Level Correction → AWB → CCM → BCG (Brightness / Contrast / Gamma LUT)\n```\n\nAll parameters are applied in software on the PC so you can tune them interactively without reflashing the camera.\n\n## Prerequisites\n\n1. **OpenMV IDE** v4.8.4 or later — used to initially set up the camera firmware.\n2. **OpenMV Cam Firmware** v5.0.0 or later.\n3. **Python dependencies:**\n\n```\npip install dearpygui opencv-python numpy pyserial Pillow openmv\n```\n\n## Running\n\n```\npython ccm_tuning_on_pc.py\n```\n\nThe companion camera script (`ccm_tuning_on_cam.py`, located in the same folder) is loaded automatically. You can override any option from the command line:\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--port PORT` | *(GUI selector)* | Serial port to connect on |\n| `--script PATH` | `ccm_tuning_on_cam.py` | MicroPython script to run on the camera |\n| `--baudrate N` | `921600` | Serial baud rate |\n| `--crc` | off (Linux/Mac), on (Windows) | Enable CRC on the serial protocol |\n| `--seq` | on | Enable sequence numbers |\n| `--ack` | off | Enable per-packet ACKs |\n| `--quiet` | off | Suppress camera stdout |\n| `--debug` | off | Enable verbose logging |\n| `--benchmark` | off | Headless throughput benchmark (no GUI) |\n\n## Benchmark Mode\n\nRun without the GUI to measure raw USB frame throughput:\n\n```\npython ccm_tuning_on_pc.py --benchmark\npython ccm_tuning_on_pc.py --benchmark --port /dev/ttyACM0\n```\n\nPrints at 10 Hz:\n\n```\nelapsed=4.1s    fps=12.3    bw=3.76 MB/s    res=640x480    total=50 frames\n```\n\nPress **Ctrl+C** to stop.\n\n## GUI Overview\n\n### Connection Bar (top of right panel)\n\n- **Script** — path to the MicroPython script that runs on the camera. Click the folder icon to browse.\n- **Port** — serial port drop-down. Hit the **R** button to refresh the list.\n- **Connect / Disconnect** — starts or stops the camera worker thread.\n\n### Live Stats Display\n\nA read-only selectable text box showing the current ISP state on every frame:\n\n```\nRaw    R  56.5   G  88.4   B  70.2\n       L  76.8  R/G  0.639  B/G  0.793\n\nBlack  R      0  G      0  B      0\n\nAWB    R  1.359  G  0.869  B  1.095\n\nCCM    R:   1.479   -0.449   -0.030\n       G:  -0.318    1.280    0.038\n       B:  -0.086   -0.880    1.966\n\nSum    R  1.000  G  1.000  B  1.000\n\nOffset R   0.00  G   0.00  B   0.00\n\nBCG    B  0.000  C  1.000  G  2.200\n```\n\n- **Raw** — mean R/G/B of the raw Bayer frame before any processing. **L** is luminance. **R/G** and **B/G** are the raw channel ratios — these are the illuminant fingerprint used for piecewise CCM interpolation across different light sources.\n- **Black** — black level subtracted per channel.\n- **AWB** — auto white balance gains (or manual gains when AWB is set to manual).\n- **CCM** — the 3×3 color correction matrix currently applied.\n- **Sum** — row sums of the CCM (should be 1.000 for each row when correctly normalized).\n- **Offset** — per-channel additive offset applied after the CCM.\n- **BCG** — brightness, contrast, and gamma values applied via a LUT.\n\n### Black Level\n\nPer-channel (R, G, B) integer black level offsets subtracted from the raw frame before debayering.\n\n### Auto White Balance\n\n- **Auto** checkbox — when enabled, AWB gains are computed automatically each frame from the raw channel means and displayed live.\n- **R / G / B gain** sliders — when Auto is off, set manual gains here.\n\n### 3×3 Matrix Per-Channel Offsets\n\nThe CCM is a 3×3 matrix where each row applies to one output channel (R, G, B). Rows are color-coded. Each row should sum to 1 (achromatic constraint). The per-channel offsets below the matrix add a fixed bias after the CCM multiply.\n\n### BCG (Brightness / Contrast / Gamma)\n\n- **B** — brightness offset (additive, applied before contrast).\n- **C** — contrast multiplier.\n- **G** — gamma exponent (no upper limit; values > 1 darken midtones, < 1 brighten midtones).\n\n### ColorChecker CCM Solver (bottom of right panel)\n\nUsed to automatically compute a CCM from a physical X-Rite ColorChecker Classic card placed in front of the camera.\n\n#### Workflow\n\n1. Place the ColorChecker Classic card in the camera's field of view under the target light source.\n2. Click **Pick ColorChecker** — the button changes to **Reset** while picking is active.\n3. Click the **four outer corners of the card** in order: top-left → top-right → bottom-right → bottom-left. The status line guides you through each click. A green grid overlay appears showing the 24 patch cells with yellow dots at each patch center.\n4. Click **Compute CCM** — the tool samples the pre-CCM (post-AWB) frame at each patch center, runs a least-squares solve against the X-Rite D65 reference values, normalizes the result so each row sums to 1, and writes it into the CCM matrix fields immediately.\n5. The grid overlay stays visible so you can verify the patch alignment. Click **Reset** (was Pick ColorChecker) to clear the corners and start over.\n6. Click **Reset CCM to Identity** at any time to restore the CCM to the identity matrix (no color correction).\n\n> **Tip for multi-illuminant tuning:** Repeat the ColorChecker solve under each target light source (e.g. TL84 ~3800 K, D65 ~6700 K). Record the solved CCM and the **R/G** and **B/G** raw ratios for each. These ratios are the illuminant fingerprint (measured before AWB normalizes them) and can be used to build a piecewise linear interpolation table between CCMs in firmware.\n\n### Save Image + Settings\n\nSaves the current processed frame and all ISP parameters to disk:\n\n- `ccm_frame_<timestamp>.bmp` — the displayed (post-BCG) RGB image.\n- `ccm_params_<timestamp>.txt` — the full live stats text (same content as the stats box).\n\nBoth files are written at the same time. If no image has been captured yet, a message is shown in the status line. These files are excluded from git via `.gitignore`.\n\n## Output File Format\n\n`ccm_params_*.txt` contains the complete pipeline state at the moment of saving, which can be pasted directly into firmware:\n\n```\nRaw    R  56.5   G  88.4   B  70.2\n       L  76.8  R/G  0.639  B/G  0.793\n\nBlack  R      0  G      0  B      0\n...\nCCM    R:   1.479   -0.449   -0.030\n       G:  -0.318    1.280    0.038\n       B:  -0.086   -0.880    1.966\n...\n```\n\n## Notes\n\n- The tool works on Windows, macOS, and Linux. See **Platform Notes** above for performance guidance.\n- The CCM solver uses the pre-CCM (post-AWB) image so that the solved matrix corrects sensor metamerism independently of the white balance.\n- CCM rows are normalized to sum to 1 after solving, enforcing the achromatic constraint (neutral surfaces stay neutral).\n- Clicking the image while **Pick ColorChecker** is active places corner markers. Clicking **Reset** at any point clears all corners and the overlay.\n"
  },
  {
    "path": "tools/ccm-tuning/ccm_tuning_on_cam.py",
    "content": "# This work is licensed under the MIT license.\n# Copyright (c) 2013-2026 OpenMV LLC. All rights reserved.\n# https://github.com/openmv/openmv/blob/master/LICENSE\n#\n# This shows off how to get the RAW image for color matrix tuning.\n#\n# This script is meant to be run using https://github.com/openmv/openmv-python\n# from a PC using desktop tools. No visualization or text output is generated\n# by this script for OpenMV IDE.\n\nimport csi\nimport protocol\nimport json\n\n# Bayer type string to integer mapping\n# Maps camera's internal Bayer naming to integer pattern IDs.\n#\n# IMPORTANT: Camera's naming differs from OpenCV's by a 180° rotation.\n# The PC-side script handles the conversion:\n#   Camera BGGR (0) → OpenCV RGGB\n#   Camera GBRG (1) → OpenCV GRBG\n#   Camera GRBG (2) → OpenCV GBRG\n#   Camera RGGB (3) → OpenCV BGGR\nBAYER_TYPE_MAP = {\n    'bayer_bggr': 0,\n    'bayer_gbrg': 1,\n    'bayer_grbg': 2,\n    'bayer_rggb': 3,\n}\n\n# Initialize the sensor.\ncsi0 = csi.CSI()\ncsi0.reset()\ncsi0.pixformat(csi.BAYER)\ncsi0.framesize(csi.HD)\ncsi0.framebuffers(1)\nimg = csi0.snapshot()\nimg_mv = memoryview(img.bytearray())\nframe_available = False\n\n# Parse image info from string representation\nimg_info = json.loads(str(img))\nimg_width = img_info['w']\nimg_height = img_info['h']\nimg_type = img_info['type']\nimg_size = img_info['size']\nbayer_pattern = BAYER_TYPE_MAP.get(img_type, 0)  # Default to BGGR if unknown\n\n# How to read/write sensor registers in python:\n# csi.write_reg(0x00, 0x01)  # Example: Write 0x01 to register 0x00\n# reg_value = csi.read_reg(0x00)  # Example: Read register\n\n\nclass BayerChannel:\n    def size(self):\n        return img_size\n\n    def shape(self):\n        return (img_height, img_width, bayer_pattern, img_size)\n\n    def read(self, offset, size):\n        global frame_available\n\n        if frame_available:\n            end = offset + size\n            mv = img_mv[offset:end]\n            if end == img_size:\n                frame_available = False\n            return mv\n        return bytes(size)\n\n    def poll(self):\n        return frame_available\n\n\nprotocol.register(name='bayer', backend=BayerChannel())\n\nwhile True:\n    if not frame_available:\n        csi0.snapshot()\n        frame_available = True\n"
  },
  {
    "path": "tools/ccm-tuning/ccm_tuning_on_pc.py",
    "content": "#!/usr/bin/env python3\n#\n# This work is licensed under the MIT license.\n# Copyright (c) 2013-2026 OpenMV LLC. All rights reserved.\n# https://github.com/openmv/openmv/blob/master/LICENSE\n#\n# CCM tuning GUI for OpenMV cameras on PC.\n# Requires: pip install dearpygui\n#\n# Pipeline (mimics N6 ISP):\n#   Raw Bayer stats → Debayer → Black Level → AWB → CCM → BCG LUT\n#\n\nimport sys\nimport os\nimport argparse\nimport time\nimport logging\nimport signal\nimport threading\nimport queue\nimport numpy as np\nimport cv2\nimport serial.tools.list_ports\nimport dearpygui.dearpygui as dpg\nfrom openmv.camera import Camera\n\n\nCOLOR_CAMERA = \"\\033[32m\"\nCOLOR_RESET  = \"\\033[0m\"\n\n# Bayer pattern integer to OpenCV conversion code mapping\n#\n# IMPORTANT: Camera's Bayer naming differs from OpenCV's by a 180° rotation.\n# This mapping converts from camera's pattern IDs to OpenCV's color codes:\n#   0 (Camera BGGR) → OpenCV RGGB (COLOR_BAYER_RG2RGB)\n#   1 (Camera GBRG) → OpenCV GRBG (COLOR_BAYER_GR2RGB)\n#   2 (Camera GRBG) → OpenCV GBRG (COLOR_BAYER_GB2RGB)\n#   3 (Camera RGGB) → OpenCV BGGR (COLOR_BAYER_BG2RGB)\nBAYER_PATTERNS = {\n    0: cv2.COLOR_BAYER_RG2RGB,\n    1: cv2.COLOR_BAYER_GR2RGB,\n    2: cv2.COLOR_BAYER_GB2RGB,\n    3: cv2.COLOR_BAYER_BG2RGB,\n}\n\n# For each bayer pattern ID, the (row, col) offset within the 2x2 block for R and B.\n# G occupies the other two positions: (r_row, b_col) and (b_row, r_col).\n#   Pattern 0 (Camera BGGR → OpenCV RGGB): B G / G R → R at [1,1], B at [0,0]\n#   Pattern 1 (Camera GBRG → OpenCV GRBG): G B / R G → R at [1,0], B at [0,1]\n#   Pattern 2 (Camera GRBG → OpenCV GBRG): G R / B G → R at [0,1], B at [1,0]\n#   Pattern 3 (Camera RGGB → OpenCV BGGR): R G / G B → R at [0,0], B at [1,1]\nBAYER_CHANNEL_POS = {\n    0: ((1, 1), (0, 0)),\n    1: ((1, 0), (0, 1)),\n    2: ((0, 1), (1, 0)),\n    3: ((0, 0), (1, 1)),\n}\n\nCTRL_WIDTH  = 340\nTEXTURE_TAG = \"cam_tex\"\nTEX_REG_TAG = \"tex_reg\"\nINIT_W      = 1280\nINIT_H      = 800\n\n# X-Rite ColorChecker Classic reference sRGB values (D65, 2-degree observer)\n# Row order top→bottom, left→right: Dark Skin … Black\nCOLORCHECKER_SRGB = np.array([\n    [115,  82,  68], [194, 150, 130], [ 98, 122, 157],\n    [ 87, 108,  67], [133, 128, 177], [103, 189, 170],\n    [214, 126,  44], [ 80,  91, 166], [193,  90,  99],\n    [ 94,  60, 108], [157, 188,  64], [224, 163,  46],\n    [ 56,  61, 150], [ 70, 148,  73], [175,  54,  60],\n    [231, 199,  31], [187,  86, 149], [  8, 133, 161],\n    [243, 243, 242], [200, 200, 200], [160, 160, 160],\n    [122, 122, 121], [ 85,  85,  85], [ 52,  52,  52],\n], dtype=np.float32)\n\n\ndef list_com_ports():\n    \"\"\"Return sorted list of available COM port device strings.\"\"\"\n    return sorted(p.device for p in serial.tools.list_ports.comports())\n\n\n# ---------------------------------------------------------------------------\n# ISP pipeline helpers\n# ---------------------------------------------------------------------------\n\ndef bayer_channel_stats(bayer_raw, bayer_pattern):\n    \"\"\"Return per-channel (R, G, B) mean values from raw Bayer uint8 image.\"\"\"\n    (r_row, r_col), (b_row, b_col) = BAYER_CHANNEL_POS[bayer_pattern]\n    avg_r = float(bayer_raw[r_row::2, r_col::2].mean())\n    avg_b = float(bayer_raw[b_row::2, b_col::2].mean())\n    # G occupies two off-diagonal planes of equal size — average their means\n    avg_g = (float(bayer_raw[r_row::2, b_col::2].mean()) +\n             float(bayer_raw[b_row::2, r_col::2].mean())) * 0.5\n    return avg_r, avg_g, avg_b\n\n\ndef compute_awb(avg_r, avg_g, avg_b):\n    \"\"\"\n    Compute AWB gains and luminance matching the N6 ISP algorithm.\n    Luminance: L = R*0.299 + G*0.587 + B*0.114\n    Per-channel gain: gain_i = L / max(avg_i, 1)\n    Matches stm_isp_update_awb: multi = round(L * 128 / avg), effective gain = L / avg.\n    Returns: (gain_r, gain_g, gain_b), luminance\n    \"\"\"\n    luminance = avg_r * 0.299 + avg_g * 0.587 + avg_b * 0.114\n    return (\n        (luminance / max(avg_r, 1.0),\n         luminance / max(avg_g, 1.0),\n         luminance / max(avg_b, 1.0)),\n        luminance,\n    )\n\n\ndef build_bcg_lut(brightness, contrast, gamma):\n    \"\"\"\n    Build uint8[256] LUT for brightness/contrast/gamma correction.\n    Formula (from imlib_update_gamma_table):\n      out = clamp(round((pow(i/255, 1/gamma) * contrast + brightness) * 255), 0, 255)\n    \"\"\"\n    i = np.arange(256, dtype=np.float64)\n    v = (np.power(i / 255.0, 1.0 / gamma) * contrast + brightness) * 255.0\n    return np.clip(np.round(v), 0, 255).astype(np.uint8)\n\n\ndef process_frame(bayer_raw, bayer_pattern, state, lut=None):\n    \"\"\"\n    Run the full ISP pipeline on one raw Bayer frame.\n    Returns (rgb_uint8 HxWx3, stats dict).\n    lut: pre-built BCG lookup table; built from state if not provided.\n    \"\"\"\n    # Step 1: Raw Bayer stats (before any modification, for display)\n    avg_r, avg_g, avg_b = bayer_channel_stats(bayer_raw, bayer_pattern)\n    # AWB gains must be computed from BL-corrected means (AWB runs after BL in the N6)\n    bl = state['black_level']\n    bl_avg_r = max(avg_r - bl[0], 0.0)\n    bl_avg_g = max(avg_g - bl[1], 0.0)\n    bl_avg_b = max(avg_b - bl[2], 0.0)\n    (gain_r, gain_g, gain_b), luminance = compute_awb(bl_avg_r, bl_avg_g, bl_avg_b)\n\n    # Step 2: Debayer\n    rgb = cv2.cvtColor(bayer_raw, BAYER_PATTERNS[bayer_pattern])\n    px  = rgb.astype(np.float32)\n\n    # Step 3: Black level correction (per channel, clamped)\n    if bl[0] or bl[1] or bl[2]:  # skip if all zero\n        px[:, :, 0] = np.clip(px[:, :, 0] - bl[0], 0, 255)\n        px[:, :, 1] = np.clip(px[:, :, 1] - bl[1], 0, 255)\n        px[:, :, 2] = np.clip(px[:, :, 2] - bl[2], 0, 255)\n\n    # Step 4: White balance (auto-computed or manual gains)\n    if state['awb_auto']:\n        gr, gg, gb = gain_r, gain_g, gain_b\n    else:\n        gr, gg, gb = state['awb_gains']\n    px[:, :, 0] = np.clip(px[:, :, 0] * gr, 0, 255)\n    px[:, :, 1] = np.clip(px[:, :, 1] * gg, 0, 255)\n    px[:, :, 2] = np.clip(px[:, :, 2] * gb, 0, 255)\n\n    pre_ccm = px.clip(0, 255).astype(np.uint8)\n\n    # Step 5: Color correction matrix\n    if state['ccm_enabled']:\n        flat = px.reshape(-1, 3) @ state['ccm'].T\n        off  = state['ccm_offsets']\n        if off[0] or off[1] or off[2]:\n            flat += np.array(off, dtype=np.float32)\n        px = np.clip(flat, 0, 255).reshape(px.shape)\n\n    # Step 6: Brightness / contrast / gamma LUT\n    if lut is None:\n        lut = build_bcg_lut(state['brightness'], state['contrast'], state['gamma'])\n    out = lut[px.astype(np.uint8)]\n\n    stats = {\n        'avg_r':     avg_r,   'avg_g':     avg_g,   'avg_b':  avg_b,\n        'luminance': luminance,\n        'gain_r':    gain_r,  'gain_g':    gain_g,  'gain_b': gain_b,\n    }\n    return out, stats, pre_ccm\n\n\ndef compute_homography(src, dst):\n    \"\"\"DLT homography from 4 src points to 4 dst points (each [4,2] float).\"\"\"\n    A = []\n    for (x, y), (u, v) in zip(src, dst):\n        A.append([-x, -y, -1,  0,  0,  0, u*x, u*y, u])\n        A.append([ 0,  0,  0, -x, -y, -1, v*x, v*y, v])\n    _, _, Vt = np.linalg.svd(np.array(A, dtype=np.float64))\n    H = Vt[-1].reshape(3, 3)\n    return H / H[2, 2]\n\n\n# ---------------------------------------------------------------------------\n# Camera background thread\n# ---------------------------------------------------------------------------\n\ndef camera_worker(args, state_lock, state, frame_q, stop_evt):\n    try:\n        # Per-connection caches (reset on each connect)\n        lut_key  = None\n        lut      = None\n        tex_buf  = None   # pre-allocated float32 RGBA, reused every frame\n        tex_shape = (0, 0)\n\n        with Camera(\n            args.port, baudrate=args.baudrate, crc=args.crc, seq=args.seq,\n            ack=args.ack, events=args.events, timeout=args.timeout,\n            max_retry=args.max_retry, max_payload=args.max_payload,\n            drop_rate=args.drop_rate,\n        ) as camera:\n            logging.info(f\"Connected to OpenMV on {args.port}\")\n            camera.stop()\n            time.sleep(0.5)\n\n            with open(args.script) as f:\n                script = f.read()\n            if sys.platform != 'win32':\n                script = script.replace('def read(self, offset, size):',\n                                        'def readp(self, offset, size):')\n            camera.exec(script)\n            logging.info(\"Script running, streaming frames...\")\n\n            while not stop_evt.is_set():\n                status = camera.read_status()\n\n                if not args.quiet and status and status.get('stdout'):\n                    if text := camera.read_stdout():\n                        print(f\"{COLOR_CAMERA}{text}{COLOR_RESET}\", end='')\n\n                if not camera.has_channel('bayer') or not status.get('bayer'):\n                    time.sleep(0.01)\n                    continue\n\n                size = camera.channel_size('bayer')\n                if size <= 0:\n                    time.sleep(0.01)\n                    continue\n\n                shape = camera._channel_shape(camera.get_channel(name=\"bayer\"))\n                if not shape or len(shape) < 3:\n                    time.sleep(0.01)\n                    continue\n\n                h, w, bayer_pat = shape[0], shape[1], shape[2]\n                if bayer_pat not in BAYER_PATTERNS:\n                    logging.error(f\"Unknown bayer pattern: {bayer_pat}\")\n                    time.sleep(0.01)\n                    continue\n\n                # Ensure a full frame is available before reading\n                expected = h * w\n                if size < expected:\n                    time.sleep(0.01)\n                    continue\n\n                data = camera.channel_read('bayer', expected)\n                if len(data) < expected:\n                    time.sleep(0.01)\n                    continue\n                bayer_raw = np.frombuffer(data, dtype=np.uint8).reshape(h, w)\n\n                # Snapshot state under lock\n                with state_lock:\n                    s = {\n                        'awb_auto':    state['awb_auto'],\n                        'awb_gains':   list(state['awb_gains']),\n                        'black_level': list(state['black_level']),\n                        'ccm_enabled': state['ccm_enabled'],\n                        'ccm':         state['ccm'].copy(),\n                        'ccm_offsets': list(state['ccm_offsets']),\n                        'brightness':  state['brightness'],\n                        'contrast':    state['contrast'],\n                        'gamma':       state['gamma'],\n                    }\n\n                # Rebuild BCG LUT only when parameters change\n                new_lut_key = (s['brightness'], s['contrast'], s['gamma'])\n                if new_lut_key != lut_key:\n                    lut_key = new_lut_key\n                    lut = build_bcg_lut(*lut_key)\n\n                rgb_out, stats, pre_ccm = process_frame(bayer_raw, bayer_pat, s, lut)\n\n                # Fill pre-allocated RGBA float32 buffer (avoid per-frame allocation)\n                h_out, w_out = rgb_out.shape[:2]\n                if (h_out, w_out) != tex_shape:\n                    tex_buf   = np.ones((h_out, w_out, 4), dtype=np.float32)\n                    tex_shape = (h_out, w_out)\n                tex_buf[:, :, :3] = rgb_out * (1.0 / 255.0)\n                tex_data = tex_buf.ravel()  # view — no extra allocation\n\n                # Keep only the latest frame\n                if frame_q.full():\n                    try:\n                        frame_q.get_nowait()\n                    except queue.Empty:\n                        pass\n                frame_q.put((w, h, tex_data, stats, rgb_out, pre_ccm))\n\n    except Exception as e:\n        logging.error(f\"Camera error: {e}\")\n        if args.debug:\n            import traceback\n            logging.error(traceback.format_exc())\n\n\n# ---------------------------------------------------------------------------\n# Argument parsing\n# ---------------------------------------------------------------------------\n\ndef str2bool(v):\n    if isinstance(v, bool):\n        return v\n    if v.lower() in ('yes', 'true', 't', 'y', '1'):\n        return True\n    if v.lower() in ('no', 'false', 'f', 'n', '0'):\n        return False\n    raise argparse.ArgumentTypeError('Boolean value expected.')\n\n\ndef parse_args():\n    p = argparse.ArgumentParser(\n        description='OpenMV CCM tuning GUI (mimics N6 ISP pipeline)')\n\n    # Connection\n    p.add_argument('--port',        default=None,\n                   help='Serial port (auto-selected in GUI if omitted)')\n    p.add_argument('--script',      default=None,\n                   help='MicroPython script to run on the camera '\n                        '(defaults to ccm_tuning_on_cam.py next to this file)')\n    p.add_argument('--baudrate',    type=int, default=921600)\n    p.add_argument('--timeout',     type=float, default=1.0)\n    p.add_argument('--crc',         type=str2bool, nargs='?', const=True,\n                   default=(sys.platform == 'win32'))\n    p.add_argument('--seq',         type=str2bool, nargs='?', const=True, default=True)\n    p.add_argument('--ack',         type=str2bool, nargs='?', const=True, default=False)\n    p.add_argument('--events',      type=str2bool, nargs='?', const=True, default=True)\n    p.add_argument('--max-retry',   type=int, default=3)\n    p.add_argument('--max-payload', type=int, default=4096)\n    p.add_argument('--drop-rate',   type=float, default=0.0)\n    p.add_argument('--quiet',       action='store_true',\n                   help='Suppress camera stdout')\n    p.add_argument('--debug',       action='store_true')\n    p.add_argument('--benchmark',   action='store_true',\n                   help='Headless mode: print frame rate and bandwidth stats, no GUI')\n\n    return p.parse_args()\n\n\n# ---------------------------------------------------------------------------\n# Benchmark (headless)\n# ---------------------------------------------------------------------------\n\nEMA_ALPHA = 0.2\n\ndef run_benchmark(args):\n    \"\"\"Headless benchmark: camera thread only, frame rate and bandwidth printed to terminal.\"\"\"\n    if not args.port:\n        ports = [p.device for p in serial.tools.list_ports.comports()]\n        if not ports:\n            print(\"No serial ports found. Use --port to specify one.\")\n            sys.exit(1)\n        args.port = ports[0]\n        print(f\"Auto-selected port: {args.port}\")\n\n    if args.script is None:\n        args.script = os.path.join(os.path.dirname(os.path.abspath(__file__)),\n                                   'ccm_tuning_on_cam.py')\n\n    stop_evt = threading.Event()\n\n    def handle_exit(signum, frame):\n        stop_evt.set()\n\n    signal.signal(signal.SIGINT,  handle_exit)\n    signal.signal(signal.SIGTERM, handle_exit)\n\n    frame_q = queue.Queue(maxsize=4)\n    state_lock = threading.Lock()\n    state = {\n        'awb_auto':    True,\n        'awb_gains':   [1.0, 1.0, 1.0],\n        'black_level': [0, 0, 0],\n        'ccm_enabled': False,\n        'ccm':         np.eye(3, dtype=np.float32),\n        'ccm_offsets': [0.0, 0.0, 0.0],\n        'brightness':  0.0,\n        'contrast':    1.0,\n        'gamma':       1.0,\n    }\n\n    cam_t = threading.Thread(\n        target=camera_worker,\n        args=(args, state_lock, state, frame_q, stop_evt),\n        daemon=True,\n    )\n\n    print(f\"Connecting to {args.port} ...\")\n    cam_t.start()\n\n    total_frames  = 0\n    total_bytes   = 0\n    fps_ema       = 0.0\n    mbps_ema      = 0.0\n    last_time     = time.perf_counter()\n    start_time    = last_time\n    last_print    = last_time\n\n    while not stop_evt.is_set():\n        try:\n            w, h, _tex, _stats, _rgb, _pre = frame_q.get(timeout=0.05)\n        except queue.Empty:\n            if not cam_t.is_alive():\n                if not stop_evt.is_set():\n                    print(\"Camera thread died unexpectedly.\")\n                break\n            continue\n\n        now       = time.perf_counter()\n        dt        = now - last_time\n        last_time = now\n        if dt <= 0.0:\n            continue\n\n        frame_bytes = w * h\n        fps_inst    = 1.0 / dt\n        mbps_inst   = frame_bytes / 1048576.0 / dt\n        fps_ema     = fps_inst  if fps_ema  == 0.0 else fps_ema  * (1 - EMA_ALPHA) + fps_inst  * EMA_ALPHA\n        mbps_ema    = mbps_inst if mbps_ema == 0.0 else mbps_ema * (1 - EMA_ALPHA) + mbps_inst * EMA_ALPHA\n        total_frames += 1\n        total_bytes  += frame_bytes\n\n        if now - last_print >= 0.1:\n            last_print = now\n            elapsed = now - start_time\n            print(f\"elapsed={elapsed:.1f}s\\t\"\n                  f\"fps={fps_ema:.1f}\\t\"\n                  f\"bw={mbps_ema:.2f} MB/s\\t\"\n                  f\"res={w}x{h}\\t\"\n                  f\"total={total_frames:,} frames\")\n\n    stop_evt.set()\n    print(\"\\nDone.\")\n\n\n# ---------------------------------------------------------------------------\n# main\n# ---------------------------------------------------------------------------\n\ndef main(args=None):\n    if args is None:\n        args = parse_args()\n\n    if args.script is None:\n        args.script = os.path.join(os.path.dirname(os.path.abspath(__file__)),\n                                   'ccm_tuning_on_cam.py')\n\n    logging.basicConfig(\n        format=\"%(relativeCreated)010.3f - %(message)s\",\n        level=logging.DEBUG if args.debug else logging.INFO,\n    )\n\n    # Default tuning values (all adjustable live in the GUI)\n    init_ccm         = np.eye(3, dtype=np.float32)\n    init_ccm_offsets = [0.0, 0.0, 0.0]\n    init_black_level = [0, 0, 0]\n\n    # Shared mutable state (accessed by both GUI callbacks and camera thread)\n    state_lock = threading.Lock()\n    # Latest frames for saving/CCM computation\n    last_frame     = [None]   # latest post-processed HxWx3 uint8\n    last_pre_ccm   = [None]   # latest pre-CCM HxWx3 uint8\n    # ColorChecker corner picking state\n    cc_state = {'corners': [], 'picking': False}\n    state = {\n        'awb_auto':    True,\n        'awb_gains':   [1.0, 1.0, 1.0],  # used when awb_auto is False\n        'black_level': init_black_level,\n        'ccm_enabled': True,\n        'ccm':         init_ccm,\n        'ccm_offsets': init_ccm_offsets,\n        'brightness':  0.0,\n        'contrast':    1.0,\n        'gamma':       2.2,\n    }\n\n    frame_q = queue.Queue(maxsize=1)\n\n    # Connection state (mutated by GUI callbacks and checked in render loop)\n    conn = {'thread': None, 'stop_evt': None}\n\n    # -----------------------------------------------------------------------\n    # Dear PyGui setup\n    # -----------------------------------------------------------------------\n    dpg.create_context()\n\n    # File dialog for script selection (created before the main window)\n    def cb_file_selected(sender, app_data):\n        path = app_data.get('file_path_name', '')\n        if path:\n            args.script = path\n            dpg.set_value(\"script_path\", path)\n\n    with dpg.file_dialog(directory_selector=False, show=False,\n                         callback=cb_file_selected, tag=\"file_dialog\",\n                         width=700, height=450,\n                         default_path=os.path.dirname(args.script) if args.script else os.getcwd()):\n        dpg.add_file_extension(\".py\",  color=(100, 255, 100, 255))\n        dpg.add_file_extension(\".*\",   color=(255, 255, 255, 255))\n\n    # Placeholder dark-gray texture shown before camera connects\n    placeholder = np.full(INIT_W * INIT_H * 4, 0.05, dtype=np.float32)\n    placeholder[3::4] = 1.0\n    with dpg.texture_registry(tag=TEX_REG_TAG):\n        dpg.add_dynamic_texture(INIT_W, INIT_H, placeholder, tag=TEXTURE_TAG)\n    tex_wh = [INIT_W, INIT_H]\n\n    # ---- Callbacks --------------------------------------------------------\n    # Generic scalar state key setter\n    def cb(key):\n        def _cb(s, v, u=None):\n            with state_lock:\n                state[key] = v\n        return _cb\n\n    # List-element setter (for black_level, ccm_offsets)\n    def cb_idx(key, idx):\n        def _cb(s, v, u=None):\n            with state_lock:\n                state[key][idx] = v\n        return _cb\n\n    # CCM matrix cell setter (user_data = (row, col))\n    def cb_ccm_cell(s, v, user_data):\n        r, c = user_data\n        with state_lock:\n            state['ccm'][r, c] = v\n\n\n    # ---- Connection callbacks ---------------------------------------------\n    def do_connect(port):\n        args.port     = port\n        stop_evt      = threading.Event()\n        conn['stop_evt'] = stop_evt\n        t = threading.Thread(\n            target=camera_worker,\n            args=(args, state_lock, state, frame_q, stop_evt),\n            daemon=True,\n        )\n        t.start()\n        conn['thread'] = t\n        dpg.configure_item(\"connect_btn\", label=\"Disconnect\")\n        logging.info(f\"Connecting to {port}...\")\n\n    def do_disconnect():\n        if conn['stop_evt']:\n            conn['stop_evt'].set()\n        conn['thread'] = None\n        conn['stop_evt'] = None\n        dpg.configure_item(\"connect_btn\", label=\"Connect\")\n\n    def cb_refresh(s, v, u=None):\n        items = list_com_ports()\n        dpg.configure_item(\"port_combo\", items=items)\n        if items and not dpg.get_value(\"port_combo\"):\n            dpg.set_value(\"port_combo\", items[0])\n\n    def cb_connect(s, v, u=None):\n        if conn['thread'] and conn['thread'].is_alive():\n            do_disconnect()\n        else:\n            if not args.script:\n                return\n            port = dpg.get_value(\"port_combo\")\n            if not port:\n                return\n            do_connect(port)\n\n    # ---- ColorChecker / Save callbacks ------------------------------------\n    def cb_save(s=None, v=None, u=None):\n        frame = last_frame[0]\n        if frame is None:\n            dpg.set_value(\"cc_status\", \"No image captured yet.\")\n            return\n        ts = int(time.time())\n        try:\n            from PIL import Image\n            bmp_name = f\"ccm_frame_{ts}.bmp\"\n            Image.fromarray(frame, 'RGB').save(bmp_name)\n            print(f\"Saved BMP: {bmp_name}\")\n        except ImportError:\n            print(\"pip install Pillow  to enable BMP saving.\")\n        txt_name = f\"ccm_params_{ts}.txt\"\n        with open(txt_name, 'w') as f:\n            f.write(dpg.get_value(\"stat_line\") + \"\\n\")\n        print(f\"Saved text: {txt_name}\")\n\n    def cb_pick_cc(s=None, v=None, u=None):\n        if cc_state['picking'] or cc_state['corners']:\n            # Reset mode\n            cc_state['corners'] = []\n            cc_state['picking'] = False\n            dpg.configure_item(\"btn_pick_cc\", label=\"Pick ColorChecker\")\n            dpg.set_value(\"cc_status\", \"\")\n            dpg.delete_item(\"vp_overlay\", children_only=True)\n        else:\n            # Start picking\n            if last_frame[0] is None:\n                dpg.set_value(\"cc_status\", \"No image captured yet.\")\n                return\n            cc_state['corners'] = []\n            cc_state['picking'] = True\n            dpg.configure_item(\"btn_pick_cc\", label=\"Reset\")\n            dpg.set_value(\"cc_status\", \"Click top-left outer corner of card\")\n\n    def cb_compute_ccm(s=None, v=None, u=None):\n        frame = last_pre_ccm[0]\n        corners = cc_state['corners']\n        if len(corners) != 4:\n            dpg.set_value(\"cc_status\", \"Pick 4 corners first.\")\n            return\n        if frame is None:\n            dpg.set_value(\"cc_status\", \"No frame captured yet.\")\n            return\n        src = np.float64(corners)\n        # dst: outer corners of 6-col × 4-row grid\n        dst = np.float64([(0, 0), (6, 0), (6, 4), (0, 4)])\n        H_fwd = compute_homography(src, dst)\n        H_inv = np.linalg.inv(H_fwd)\n        fh, fw = frame.shape[:2]\n        measured = []\n        for row in range(4):\n            for col in range(6):\n                cx, cy = col + 0.5, row + 0.5\n                vals = []\n                for dy in np.linspace(-0.3, 0.3, 7):\n                    for dx in np.linspace(-0.3, 0.3, 7):\n                        pt = H_inv @ np.array([cx+dx, cy+dy, 1.0])\n                        px_x = int(round(pt[0] / pt[2]))\n                        px_y = int(round(pt[1] / pt[2]))\n                        if 0 <= px_x < fw and 0 <= px_y < fh:\n                            vals.append(frame[px_y, px_x].astype(np.float64))\n                measured.append(np.mean(vals, axis=0) if vals else np.zeros(3))\n        measured = np.array(measured, dtype=np.float64)          # [24,3]\n        ref_lin  = np.power(COLORCHECKER_SRGB / 255.0, 2.2) * 255.0\n        ccm_new, _, _, _ = np.linalg.lstsq(measured, ref_lin, rcond=None)\n        ccm_new = ccm_new.T.astype(np.float32)                   # [3,3]\n        # Normalize rows to sum to 1 (achromatic constraint)\n        for i in range(3):\n            ccm_new[i] /= ccm_new[i].sum()\n        with state_lock:\n            state['ccm'] = ccm_new\n        for r in range(3):\n            for c in range(3):\n                dpg.set_value(f\"ccm_{r}{c}\", float(ccm_new[r, c]))\n        print(f\"CCM solved:\\n{ccm_new}\")\n        dpg.set_value(\"cc_status\", \"CCM applied.\")\n        cc_state['picking'] = False\n        dpg.configure_item(\"btn_pick_cc\", label=\"Reset\")\n\n    def cb_reset_ccm(s=None, v=None, u=None):\n        identity = np.eye(3, dtype=np.float32)\n        with state_lock:\n            state['ccm'] = identity.copy()\n        for r in range(3):\n            for c in range(3):\n                dpg.set_value(f\"ccm_{r}{c}\", float(identity[r, c]))\n        dpg.set_value(\"cc_status\", \"CCM reset to identity.\")\n\n    def cb_image_click(s=None, v=None, u=None):\n        if not cc_state['picking']:\n            return\n        if last_frame[0] is None:\n            return\n        mx, my = dpg.get_mouse_pos(local=False)\n        try:\n            imin = dpg.get_item_rect_min(\"cam_img\")\n            imax = dpg.get_item_rect_max(\"cam_img\")\n        except Exception:\n            return\n        if not (imin[0] <= mx <= imax[0] and imin[1] <= my <= imax[1]):\n            return\n        fw, fh = tex_wh\n        dw = imax[0] - imin[0]\n        dh = imax[1] - imin[1]\n        fx = int((mx - imin[0]) / dw * fw)\n        fy = int((my - imin[1]) / dh * fh)\n        cc_state['corners'].append((fx, fy))\n        n = len(cc_state['corners'])\n        labels = [\"top-left\", \"top-right\", \"bottom-right\", \"bottom-left\"]\n        if n < 4:\n            dpg.set_value(\"cc_status\", f\"Click {labels[n]} outer corner of card\")\n        else:\n            cc_state['picking'] = False\n            dpg.set_value(\"cc_status\", \"4 corners set - click Compute CCM\")\n\n    # ---- UI layout --------------------------------------------------------\n    cell_w = (CTRL_WIDTH - 36) // 3\n\n    with dpg.window(tag=\"main_win\", no_scrollbar=True, no_title_bar=True):\n        with dpg.table(\n            header_row=False, resizable=True,\n            borders_innerV=True, tag=\"layout_table\",\n            scrollX=False, scrollY=False,\n        ):\n            dpg.add_table_column(init_width_or_weight=1.0)          # camera panel\n            dpg.add_table_column(init_width_or_weight=CTRL_WIDTH,\n                                 width_fixed=True)                   # controls\n\n            with dpg.table_row():\n\n                # ── Left: camera preview + stats bar ──────────────────────\n                with dpg.table_cell():\n                    dpg.add_image(TEXTURE_TAG, tag=\"cam_img\",\n                                  width=INIT_W, height=INIT_H)\n                    dpg.add_separator()\n                    dpg.add_input_text(\n                        tag=\"stat_line\",\n                        default_value=\"Waiting for camera...\",\n                        multiline=True, readonly=True,\n                        width=-1, height=226)\n\n                # ── Right: control panel ───────────────────────────────────\n                with dpg.table_cell():\n                    with dpg.child_window(width=CTRL_WIDTH, border=False):\n\n                        # ── Windows performance warning ─────────────────────\n                        if sys.platform == 'win32':\n                            dpg.add_text(\n                                \"Warning: Windows reduces transfer speed.\\n\"\n                                \"Use macOS or Linux for best performance.\",\n                                color=(255, 200, 0, 255))\n                            dpg.add_separator()\n\n                        # ── Connection ─────────────────────────────────────\n                        with dpg.group():\n                            # Script picker\n                            with dpg.group(horizontal=True):\n                                dpg.add_text(\"Script\", indent=0)\n                                dpg.add_input_text(\n                                    tag=\"script_path\", default_value=args.script,\n                                    hint=\"select a .py script...\",\n                                    width=CTRL_WIDTH - 112, readonly=True)\n                                dpg.add_button(\n                                    label=\"...\", width=28,\n                                    callback=lambda: dpg.show_item(\"file_dialog\"))\n\n                            # Port picker\n                            init_ports = list_com_ports()\n                            init_port  = args.port or (init_ports[0] if init_ports else \"\")\n                            with dpg.group(horizontal=True):\n                                dpg.add_text(\"Port  \")\n                                dpg.add_combo(\n                                    items=init_ports,\n                                    default_value=init_port,\n                                    tag=\"port_combo\",\n                                    width=CTRL_WIDTH - 112)\n                                dpg.add_button(label=\"Ref\", callback=cb_refresh,\n                                               width=28)\n                            dpg.add_button(label=\"Connect\", tag=\"connect_btn\",\n                                           callback=cb_connect, width=-1)\n\n                        # ── White Balance ──────────────────────────────────\n                        dpg.add_separator()\n                        with dpg.group():\n                            dpg.add_text(\"Black Level (per channel, 0-255)\")\n                            for lbl, idx, color in [\n                                (\"R\", 0, (255,  80,  80, 255)),\n                                (\"G\", 1, ( 80, 200,  80, 255)),\n                                (\"B\", 2, ( 80, 130, 255, 255)),\n                            ]:\n                                with dpg.group(horizontal=True):\n                                    dpg.add_text(lbl, color=color)\n                                    dpg.add_input_int(\n                                        label=f\"##{lbl}bl\",\n                                        default_value=init_black_level[idx],\n                                        min_value=0, max_value=255,\n                                        min_clamped=True, max_clamped=True,\n                                        step=1, step_fast=10,\n                                        callback=cb_idx('black_level', idx),\n                                        width=-1)\n\n                            dpg.add_separator()\n                            dpg.add_text(\"AWB Gains\")\n\n                            def cb_awb_auto(s, v, u=None):\n                                with state_lock:\n                                    state['awb_auto'] = v\n                                    if not v:\n                                        # Snapshot current displayed gains so they\n                                        # apply immediately without needing an edit\n                                        state['awb_gains'] = [\n                                            dpg.get_value(\"wb_gain_r\"),\n                                            dpg.get_value(\"wb_gain_g\"),\n                                            dpg.get_value(\"wb_gain_b\"),\n                                        ]\n                                ro = v  # readonly when auto\n                                for tag in ('wb_gain_r', 'wb_gain_g', 'wb_gain_b'):\n                                    dpg.configure_item(tag, readonly=ro)\n\n                            dpg.add_checkbox(label=\"Auto\", default_value=True,\n                                             callback=cb_awb_auto, tag=\"wb_auto_cb\")\n                            for lbl, idx, color, tag in [\n                                (\"R\", 0, (255,  80,  80, 255), \"wb_gain_r\"),\n                                (\"G\", 1, ( 80, 200,  80, 255), \"wb_gain_g\"),\n                                (\"B\", 2, ( 80, 130, 255, 255), \"wb_gain_b\"),\n                            ]:\n                                with dpg.group(horizontal=True):\n                                    dpg.add_text(lbl, color=color)\n                                    dpg.add_input_float(\n                                        tag=tag, label=f\"##{lbl}wb\",\n                                        default_value=1.0,\n                                        min_value=0.0, max_value=16.0,\n                                        min_clamped=True, max_clamped=True,\n                                        step=0.001, step_fast=0.1,\n                                        format=\"%.3f\",\n                                        readonly=True,   # starts in auto mode\n                                        callback=cb_idx('awb_gains', idx),\n                                        width=-1)\n\n                        # ── Color Correction Matrix ────────────────────────\n                        dpg.add_separator()\n                        with dpg.group():\n                            dpg.add_text(\"3x3 Matrix  (drag  |  dbl-click to type)\")\n                            row_colors = [\n                                (\"R\", (255,  80,  80, 255)),\n                                (\"G\", ( 80, 200,  80, 255)),\n                                (\"B\", ( 80, 130, 255, 255)),\n                            ]\n                            for r, (lbl, color) in enumerate(row_colors):\n                                with dpg.group(horizontal=True):\n                                    dpg.add_text(lbl, color=color)\n                                    for c in range(3):\n                                        dpg.add_drag_float(\n                                            tag=f\"ccm_{r}{c}\",\n                                            default_value=float(init_ccm[r, c]),\n                                            speed=0.005,\n                                            min_value=-4.0, max_value=4.0,\n                                            format=\"%.3f\",\n                                            width=cell_w,\n                                            callback=cb_ccm_cell,\n                                            user_data=(r, c))\n\n                            dpg.add_separator()\n                            dpg.add_text(\"3x3 Matrix Per-Channel Offsets\")\n                            for lbl, idx, color in [\n                                (\"R\", 0, (255,  80,  80, 255)),\n                                (\"G\", 1, ( 80, 200,  80, 255)),\n                                (\"B\", 2, ( 80, 130, 255, 255)),\n                            ]:\n                                with dpg.group(horizontal=True):\n                                    dpg.add_text(lbl, color=color)\n                                    dpg.add_input_float(\n                                        label=f\"##{lbl}off\",\n                                        default_value=init_ccm_offsets[idx],\n                                        min_value=-64.0, max_value=64.0,\n                                        min_clamped=True, max_clamped=True,\n                                        step=0.1, step_fast=1.0,\n                                        format=\"%.2f\",\n                                        callback=cb_idx('ccm_offsets', idx),\n                                        width=-1)\n\n                        # ── Brightness / Contrast / Gamma ──────────────────\n                        dpg.add_separator()\n                        dpg.add_text(\"Brightness / Contrast / Gamma\")\n                        with dpg.group():\n                            with dpg.group(horizontal=True):\n                                dpg.add_text(\"Brightness\")\n                                dpg.add_input_float(\n                                    label=\"##brightness\",\n                                    default_value=0.0,\n                                    min_value=-1.0, max_value=1.0,\n                                    min_clamped=True, max_clamped=True,\n                                    step=0.01, step_fast=0.1,\n                                    format=\"%.2f\",\n                                    callback=cb('brightness'), width=-1)\n                            with dpg.group(horizontal=True):\n                                dpg.add_text(\"Contrast  \")\n                                dpg.add_input_float(\n                                    label=\"##contrast\",\n                                    default_value=1.0,\n                                    min_value=0.0, max_value=3.0,\n                                    min_clamped=True, max_clamped=True,\n                                    step=0.01, step_fast=0.1,\n                                    format=\"%.2f\",\n                                    callback=cb('contrast'), width=-1)\n                            with dpg.group(horizontal=True):\n                                dpg.add_text(\"Gamma     \")\n                                dpg.add_input_float(\n                                    label=\"##gamma\",\n                                    default_value=2.2,\n                                    min_value=0.1,\n                                    min_clamped=True,\n                                    step=0.01, step_fast=0.1,\n                                    format=\"%.2f\",\n                                    callback=cb('gamma'), width=-1)\n\n                        # ── ColorChecker / Save ────────────────────────────\n                        dpg.add_separator()\n                        dpg.add_button(label=\"Pick ColorChecker\",\n                                       tag=\"btn_pick_cc\",\n                                       callback=cb_pick_cc, width=-1)\n                        dpg.add_button(label=\"Compute CCM\", tag=\"btn_compute_ccm\",\n                                       callback=cb_compute_ccm, width=-1)\n                        dpg.add_button(label=\"Reset CCM to Identity\",\n                                       callback=cb_reset_ccm, width=-1)\n                        dpg.add_button(label=\"Save Image + Settings\",\n                                       tag=\"btn_save\", callback=cb_save,\n                                       width=-1)\n                        dpg.add_text(\"\", tag=\"cc_status\")\n\n    with dpg.handler_registry():\n        dpg.add_mouse_click_handler(button=0, callback=cb_image_click)\n\n    dpg.create_viewport(title=\"OpenMV CCM Tuner\",\n                        width=1280, height=900, resizable=True)\n    dpg.setup_dearpygui()\n    dpg.show_viewport()\n    dpg.set_primary_window(\"main_win\", True)\n\n    def handle_exit(signum, frame):\n        if conn['stop_evt']:\n            conn['stop_evt'].set()\n        dpg.stop_dearpygui()\n\n    signal.signal(signal.SIGINT,  handle_exit)\n    signal.signal(signal.SIGTERM, handle_exit)\n\n    # Auto-connect if --port (and --script) were supplied on the command line\n    if args.port and args.script:\n        do_connect(args.port)\n\n    # Track display size to avoid redundant configure_item calls\n    disp_wh = [0, 0]\n\n    def fit_image():\n        \"\"\"Resize cam_img to fill the left panel while keeping aspect ratio.\"\"\"\n        fw, fh = tex_wh\n        if fw <= 0 or fh <= 0:\n            return\n        avail_w = max(dpg.get_viewport_width()  - CTRL_WIDTH - 30, 1)\n        avail_h = max(dpg.get_viewport_height() - 60, 1)\n        scale   = min(avail_w / fw, avail_h / fh)\n        dw, dh  = max(int(fw * scale), 1), max(int(fh * scale), 1)\n        if [dw, dh] != disp_wh:\n            disp_wh[0], disp_wh[1] = dw, dh\n            dpg.configure_item(\"cam_img\", width=dw, height=dh)\n\n    dpg.set_viewport_resize_callback(lambda: fit_image())\n    fit_image()\n    dpg.add_viewport_drawlist(tag=\"vp_overlay\", front=True)\n\n    # -----------------------------------------------------------------------\n    # Render loop\n    # -----------------------------------------------------------------------\n    while dpg.is_dearpygui_running():\n        # Detect thread death (e.g. camera unplugged)\n        t = conn['thread']\n        if t is not None and not t.is_alive():\n            conn['thread']   = None\n            conn['stop_evt'] = None\n            dpg.configure_item(\"connect_btn\", label=\"Connect\")\n    \n        try:\n            w, h, tex_data, stats, rgb_out, pre_ccm = frame_q.get_nowait()\n            last_frame[0]   = rgb_out\n            last_pre_ccm[0] = pre_ccm\n\n            # Recreate texture when frame dimensions change\n            if w != tex_wh[0] or h != tex_wh[1]:\n                tex_wh[0], tex_wh[1] = w, h\n                dpg.delete_item(TEXTURE_TAG)\n                dpg.remove_alias(TEXTURE_TAG)\n                dpg.add_dynamic_texture(w, h, tex_data,\n                                        tag=TEXTURE_TAG, parent=TEX_REG_TAG)\n                dpg.configure_item(\"cam_img\", texture_tag=TEXTURE_TAG)\n                fit_image()\n            else:\n                dpg.set_value(TEXTURE_TAG, tex_data)\n                fit_image()\n\n            # Update live parameter display\n            s = stats\n            with state_lock:\n                ccm  = state['ccm'].copy()\n                off  = state['ccm_offsets'][:]\n                bl   = state['black_level'][:]\n                br   = state['brightness']\n                co   = state['contrast']\n                ga   = state['gamma']\n                awb_auto  = state['awb_auto']\n                awb_gains = state['awb_gains'][:]\n            gr, gg, gb = (s['gain_r'], s['gain_g'], s['gain_b']) if awb_auto else (awb_gains[0], awb_gains[1], awb_gains[2])\n            # R/G and B/G ratios use BL-corrected means (illuminant fingerprint)\n            bl_r = max(s['avg_r'] - bl[0], 0.0)\n            bl_g = max(s['avg_g'] - bl[1], 0.0)\n            bl_b = max(s['avg_b'] - bl[2], 0.0)\n            avg_g = bl_g if bl_g > 0 else 1.0\n            rg = bl_r / avg_g\n            bg = bl_b / avg_g\n            rs = float(ccm[0].sum())\n            gs = float(ccm[1].sum())\n            bs = float(ccm[2].sum())\n            dpg.set_value(\"stat_line\", \"\\n\".join([\n                f\"Raw    R {s['avg_r']:6.3f}   G {s['avg_g']:6.3f}   B {s['avg_b']:6.3f}\",\n                f\"       L {s['luminance']:6.3f}  R/G {rg:6.3f}  B/G {bg:6.3f}\",\n                \"\",\n                f\"Black  R {bl[0]:6d}  G {bl[1]:6d}  B {bl[2]:6d}\",\n                \"\",\n                f\"AWB    R {gr:6.3f}  G {gg:6.3f}  B {gb:6.3f}\",\n                \"\",\n                f\"CCM    R: {ccm[0,0]:7.3f}  {ccm[0,1]:7.3f}  {ccm[0,2]:7.3f}\",\n                f\"       G: {ccm[1,0]:7.3f}  {ccm[1,1]:7.3f}  {ccm[1,2]:7.3f}\",\n                f\"       B: {ccm[2,0]:7.3f}  {ccm[2,1]:7.3f}  {ccm[2,2]:7.3f}\",\n                \"\",\n                f\"Sum    R {rs:6.3f}  G {gs:6.3f}  B {bs:6.3f}\",\n                \"\",\n                f\"Offset R {off[0]:6.2f}  G {off[1]:6.2f}  B {off[2]:6.2f}\",\n                \"\",\n                f\"BCG    B {br:6.3f}  C {co:6.3f}  G {ga:6.3f}\",\n            ]))\n\n            # Push auto-computed gains into the gain fields\n            if dpg.get_value(\"wb_auto_cb\"):\n                dpg.set_value(\"wb_gain_r\", s['gain_r'])\n                dpg.set_value(\"wb_gain_g\", s['gain_g'])\n                dpg.set_value(\"wb_gain_b\", s['gain_b'])\n\n        except queue.Empty:\n            pass\n\n        # Draw ColorChecker corner overlays (runs every frame, camera or not)\n        dpg.delete_item(\"vp_overlay\", children_only=True)\n        if cc_state['corners']:\n            try:\n                imin = dpg.get_item_rect_min(\"cam_img\")\n                imax = dpg.get_item_rect_max(\"cam_img\")\n                fw, fh = tex_wh\n                dw = imax[0] - imin[0]\n                dh = imax[1] - imin[1]\n                labels = [\"TL\", \"TR\", \"BR\", \"BL\"]\n                colors = [(0,255,0,255),(255,255,0,255),(255,165,0,255),(255,0,0,255)]\n                for i, (fx, fy) in enumerate(cc_state['corners']):\n                    sx = imin[0] + fx / fw * dw\n                    sy = imin[1] + fy / fh * dh\n                    dpg.draw_circle([sx, sy], 8, color=colors[i],\n                                    thickness=2, parent=\"vp_overlay\")\n                    dpg.draw_text([sx+10, sy-8], labels[i], size=14,\n                                  color=colors[i], parent=\"vp_overlay\")\n                if len(cc_state['corners']) == 4:\n                    # Draw the grid lines across all 4 corners\n                    src = np.float64(cc_state['corners'])\n                    dst = np.float64([(0,0),(6,0),(6,4),(0,4)])\n                    H_inv = np.linalg.inv(compute_homography(src, dst))\n                    def warp(cx, cy):\n                        pt = H_inv @ np.array([cx, cy, 1.0])\n                        gx = pt[0]/pt[2]; gy = pt[1]/pt[2]\n                        return [imin[0]+gx/fw*dw, imin[1]+gy/fh*dh]\n                    for r in range(5):  # 5 lines = 4 rows of patches\n                        dpg.draw_line(warp(0, r), warp(6, r),\n                                      color=(0,255,0,128), parent=\"vp_overlay\")\n                    for c in range(7):  # 7 lines = 6 columns of patches\n                        dpg.draw_line(warp(c, 0), warp(c, 4),\n                                      color=(0,255,0,128), parent=\"vp_overlay\")\n                    for row in range(4):\n                        for col in range(6):\n                            dpg.draw_circle(warp(col + 0.5, row + 0.5), 3,\n                                            color=(255,255,0,255),\n                                            parent=\"vp_overlay\")\n            except Exception:\n                pass\n\n        # Reset UI if the camera thread died unexpectedly (e.g. connection error)\n        if conn['thread'] and not conn['thread'].is_alive():\n            do_disconnect()\n\n        dpg.render_dearpygui_frame()\n\n    if conn['stop_evt']:\n        conn['stop_evt'].set()\n    dpg.destroy_context()\n\n\nif __name__ == '__main__':\n    _args = parse_args()\n    if _args.benchmark:\n        run_benchmark(_args)\n    else:\n        main(_args)\n"
  },
  {
    "path": "tools/genx320-event-streaming/README.md",
    "content": "# GenX320 Event Streaming\n\nA PC-side GUI for streaming and visualizing events from a Prophesee GenX320 event camera sensor attached to an OpenMV Cam. Two real-time visualizations run side by side: an event accumulation canvas and a per-pixel frequency map.\n\n![GenX320 Event Streaming GUI](genx320-event-streaming.png)\n\n## Platform Notes\n\nmacOS and Linux are recommended for the best GUI performance and throughput. On Windows, DearPyGui rendering can be noticeably slower, which may reduce the effective event visualization frame rate at high event rates. The camera script and serial protocol work on all platforms, but if you experience sluggish UI or dropped frames, consider switching to a Mac or Linux machine.\n\nOn macOS and Linux the companion script's `read` method is automatically renamed to `readp` before execution (this is handled transparently by the PC script).\n\nCRC is disabled by default on macOS and Linux for better USB throughput. It is enabled by default on Windows where it improves reliability. Override with `--crc`.\n\n## Prerequisites\n\n1. **OpenMV IDE** v4.8.8 or later.\n2. **OpenMV Cam Firmware** v5.0.0 or later. Update via `Tools → Install Latest Development Release` in the IDE.\n3. **Python dependencies:**\n\n```\npip install dearpygui numpy numba pyserial Pillow openmv\n```\n\nNumba is required for the GIL-free IIR frequency camera update. On first run it JIT-compiles the inner loop (a few seconds); subsequent runs use the cached build.\n\n## Running\n\n```\npython genx320_event_mode_streaming_on_pc.py\n```\n\nThe camera script is selected automatically based on the **Stream** mode chosen in the GUI. You can override any option from the command line:\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--port PORT` | *(GUI selector)* | Serial port to connect on |\n| `--script PATH` | *(set by Stream mode)* | MicroPython script to run on the camera |\n| `--baudrate N` | `921600` | Serial baud rate |\n| `--crc` | off (Linux/Mac), on (Windows) | Enable CRC on the serial protocol |\n| `--seq` | on | Enable sequence numbers |\n| `--ack` | off | Enable per-packet ACKs |\n| `--quiet` | off | Suppress camera stdout |\n| `--debug` | off | Enable verbose logging |\n| `--benchmark` | off | Headless throughput benchmark (no GUI) |\n\n## Benchmark Mode\n\nRun without the GUI to measure raw USB throughput:\n\n```\npython genx320_event_mode_streaming_on_pc.py --benchmark\npython genx320_event_mode_streaming_on_pc.py --benchmark --port /dev/ttyACM0\n```\n\nPrints at 10 Hz:\n\n```\nelapsed=3.2s    rate=1,243,500 ev/s    bw=8.94 MB/s    total=3,982,400\n```\n\nPress **Ctrl+C** to stop.\n\n## GUI Overview\n\nThe window has two panes: a **left image area** and a **right control panel**. The two images resize and reflow automatically — side by side when the window is wide, stacked when tall — to maximize how large they appear. When Frequency Visualization is disabled, the event canvas expands to fill the full image area.\n\n### Connection\n\n- **Script** — path to the MicroPython script. Click `...` to browse.\n- **Port** — serial port drop-down. Hit **Ref** to refresh.\n- **Connect / Disconnect** — starts or stops the camera worker thread.\n\n### Camera Parameters *(applied at connect)*\n\nThese patch the on-camera script before it is executed. They are locked while connected.\n\n| Control | Default | Description |\n|---------|---------|-------------|\n| Stream | Raw (fastest) | **Raw (fastest)** — streams unprocessed EVT 2.0 words, decoded on the PC; **Processed** — camera decodes events before sending |\n| CSI FIFO | 8 | Depth of the hardware CSI receive buffer |\n| EVT FIFO | 8 | Depth of the software event FIFO (Processed mode only) |\n| EVT Buffer | 8192 | Event array size (must be a power of two, 1024–65536) |\n\n### Event Visualization\n\nControls for the accumulation canvas (left image).\n\n| Control | Default | Description |\n|---------|---------|-------------|\n| Contrast | 16 | Per-event brightness step added to the canvas (±) |\n| Color | Grayscale | Color LUT: **Grayscale**, **Evt Dark**, or **Evt Light** (OpenMV rainbow palette) |\n| Mode | Sliding Window | **Sliding Window** — shows the last N batches live; **Canvas** — accumulates until N batches then auto-clears (0 = manual clear only) |\n| Window | 4 | Number of batches kept or accumulated |\n| Clear | *(button)* | Available in Canvas mode with Window = 0; manually clears the canvas |\n\nThe canvas is initialized to mid-gray (128). Each event adds `±contrast` to its pixel and the result is clamped to [0, 255].\n\n#### Frequency Visualization\n\nReal-time per-pixel frequency map (right image) using a second-order IIR bandpass filter that reconstructs approximate brightness from the polarity event stream and measures the time between zero crossings. Uncheck **Frequency Visualization** to hide the frequency image entirely and expand the event canvas — this also reduces CPU load and disables frequency image saving.\n\nAlgorithm based on: [FrequencyCam — Imaging Periodic Signals in Real-Time](https://arxiv.org/abs/2211.00198)\n\n| Control | Default | Description |\n|---------|---------|-------------|\n| Cutoff T | 5.0 | Filter cutoff period in events. Higher values smooth more but respond slower. Reference recommends 5.0. |\n| Min Hz | 10 | Lowest frequency shown (pixels below this are black) |\n| Max Hz | 1000 | Highest frequency shown |\n| Timeout | 2 | Number of silent periods before a pixel goes dark |\n| Log frequency scale | on | Log₁₀ color mapping (recommended for wide frequency ranges) |\n| Overlay active pixels | off | Show pixels that have event activity but no locked frequency in grey |\n| Show legend | on | Display a colorbar on the right edge of the frequency image |\n| Bins | 11 | Number of labeled color patches in the legend |\n| Reset | *(button)* | Clear all per-pixel filter state |\n\nColors run blue (low frequency) → red (high frequency). Black pixels either have no events yet or have timed out.\n\n### Save Images and Events\n\nSaves the current state to disk. The button label reflects whether frequency visualization is enabled.\n\n- `events_<timestamp>_evt.png` — the event canvas rendered with the current color LUT.\n- `events_<timestamp>_freq.png` — the frequency image (only saved when Frequency Visualization is enabled). If the legend is enabled it is composited onto the right side of the image.\n- `events_<timestamp>.csv` — all events that built the current canvas (`type, sec, ms, us, x, y`). See **Camera Script Event Format** below for type values.\n\nThese files are excluded from git via `.gitignore`.\n\n### Statistics\n\nLive event throughput, updated at 5 Hz:\n\n| Field | Description |\n|-------|-------------|\n| Events/batch | Raw event count in the most recent batch |\n| Rate | Exponential moving average event rate (events/sec) |\n| Bandwidth | EMA data rate (MB/s) |\n| Total events | Cumulative event count since connect |\n| Uptime | Seconds since connect |\n\n## Architecture\n\nThe script uses a three-thread pipeline to keep USB throughput high while running the GUI:\n\n```\ncamera_worker  →  raw_q  →  processing_worker  →  result_q  →  render loop\n```\n\n- **camera_worker** — reads raw event packets from the camera as fast as possible and drops them onto `raw_q`. Does no processing, never blocks on GUI.\n- **processing_worker** — pulls batches from `raw_q`, accumulates the canvas, and runs the per-pixel IIR frequency filter via a Numba-compiled `nogil` function so it does not block the camera thread.\n- **render loop** — drains `result_q`, uploads textures to DearPyGui, and updates the stats panel.\n\n## Camera Script Event Format\n\nBoth camera scripts produce the same event format on the PC side — a stream of 6 × uint16 little-endian rows:\n\n| Column | Value |\n|--------|-------|\n| 0 | Type — see table below |\n| 1 | Timestamp — whole seconds |\n| 2 | Timestamp — milliseconds within the second (0–999) |\n| 3 | Timestamp — microseconds within the millisecond (0–999) |\n| 4 | X coordinate (0–319); 0 for trigger events |\n| 5 | Y coordinate (0–319); 0 for trigger events |\n\n| Type value | Meaning |\n|------------|---------|\n| 0 | Pixel off event (decrease in illumination) |\n| 1 | Pixel on event (increase in illumination) |\n| 2 | External trigger — falling edge |\n| 3 | External trigger — rising edge |\n| 4 | Reset trigger — falling edge |\n| 5 | Reset trigger — rising edge |\n\n**Raw mode** (`genx320_raw_event_mode_streaming_on_cam.py`) streams unprocessed 32-bit EVT 2.0 words from the sensor (4 bytes/event vs 12 bytes/event in processed mode — 3× less data over USB). The PC decodes them vectorized using numpy with no Python loop. The decoded output is identical to processed mode.\n\n**Processed mode** (`genx320_event_mode_streaming_on_cam.py`) has the camera firmware decode each event before transmission. The event buffer size, CSI FIFO depth, and (in processed mode) event FIFO depth are patched into the script at connect time from the GUI values.\n"
  },
  {
    "path": "tools/genx320-event-streaming/genx320_event_mode_streaming_on_cam.py",
    "content": "# This work is licensed under the MIT license.\n# Copyright (c) 2013-2025 OpenMV LLC. All rights reserved.\n# https://github.com/openmv/openmv/blob/master/LICENSE\n#\n# This example shows off using the genx320 event camera from Prophesee\n# using event streaming mode and sending the data back to the PC.\n#\n# This script is meant to be run using https://github.com/openmv/openmv-python\n# from a PC using desktop tools. No visualization or text output is generated\n# by this script for OpenMV IDE.\n\nimport csi\nimport protocol\n# https://micropython-ulab.readthedocs.io/en/latest/index.html\nfrom ulab import numpy as np\n\n# Event buffers arrive from the camera and are stored in\n# a fifo buffer before being processed by python.\nCSI_FIFO_DEPTH = 8\n\n# Raw events post-processed by python, put into another\n# fifo buffer, and then sent to the PC.\nEVENT_FIFO_DEPTH = 8\n\n# Must be a power of two between 1024 and 65536.\nEVT_RES = 8192\n\n# Stores camera events (8 buffers)\n# Shape: (EVT_RES, 6) where EVT_RES is the event resolution\n# Columns:\n#   [0]  Event type\n#   [1]  Seconds timestamp\n#   [2]  Milliseconds timestamp\n#   [3]  Microseconds timestamp\n#   [4]  X coordinate 0 to 319 for GENX320\n#   [5]  Y coordinate 0 to 319 for GENX320\nevents = [np.zeros((EVT_RES, 6), dtype=np.uint16) for i in range(EVENT_FIFO_DEPTH)]\nevent_counts = [0 for i in range(EVENT_FIFO_DEPTH)]\n\n# ULAB .tobytes() creates shallow copy bytearrays. Wrap these in memoryviews\n# for fast slicing without copies.\nmv_events = [memoryview(events[i].tobytes()) for i in range(EVENT_FIFO_DEPTH)]\n\n# Event buffer fifo pointers.\nwr_index = 0\nrd_index = 0\n\n\ndef read_available():\n    a = wr_index - rd_index\n    if a < 0:\n        a += EVENT_FIFO_DEPTH\n    return a\n\n\ndef write_available():\n    return EVENT_FIFO_DEPTH - 1 - read_available()\n\n\n# Initialize the sensor.\ncsi0 = csi.CSI(cid=csi.GENX320)\ncsi0.reset()\ncsi0.ioctl(csi.IOCTL_GENX320_SET_MODE, csi.GENX320_MODE_EVENT, events[0].shape[0])\ncsi0.framebuffers(CSI_FIFO_DEPTH)\n\n\nclass EventChannel:\n    def size(self):\n        if read_available():\n            return event_counts[rd_index] * 12\n        return 0\n\n    def read(self, offset, size):\n        global rd_index\n\n        if read_available():\n            end = offset + size\n            mv = mv_events[rd_index][offset:end]\n            # Free the buffer after all data has been read.\n            if end == event_counts[rd_index] * 12:\n                rd_index = (rd_index + 1) % EVENT_FIFO_DEPTH\n            return mv\n        return bytes(size)\n\n    def poll(self):\n        return read_available()\n\n\nprotocol.register(name='events', backend=EventChannel())\n\nwhile True:\n    if (write_available()):\n        # Reads up to 32768 events from the camera.\n        # Returns the number of valid events (0-32768) or a negative error code.\n        # Note that old events in the buffer are not cleared to save CPU time.\n        event_counts[wr_index] = csi0.ioctl(csi.IOCTL_GENX320_READ_EVENTS, events[wr_index])\n        wr_index = (wr_index + 1) % EVENT_FIFO_DEPTH\n"
  },
  {
    "path": "tools/genx320-event-streaming/genx320_event_mode_streaming_on_pc.py",
    "content": "#!/usr/bin/env python3\n#\n# This work is licensed under the MIT license.\n# Copyright (c) 2013-2026 OpenMV LLC. All rights reserved.\n# https://github.com/openmv/openmv/blob/master/LICENSE\n#\n# GenX320 event camera visualization GUI for PC.\n# Requires: pip install dearpygui numpy numba Pillow pyserial\n#\n# Two threads: camera_worker (receives events) and render loop (draws).\n# Canvas initialized to 128; events add contrast*polarity until clamping at 0/255.\n# Color modes: Grayscale, Evt Dark LUT, Evt Light LUT (RGB565 → RGB888).\n#\n\nimport sys\nimport os\nimport argparse\nimport time\nimport logging\nimport signal\nimport threading\nimport queue\nfrom collections import deque\nimport numpy as np\nimport numba\ntry:\n    from PIL import Image, ImageDraw\n    _PIL_AVAILABLE = True\nexcept ImportError:\n    _PIL_AVAILABLE = False\nimport serial.tools.list_ports\nimport dearpygui.dearpygui as dpg\nfrom openmv.camera import Camera\n\n\nCOLOR_CAMERA = \"\\033[32m\"\nCOLOR_RESET  = \"\\033[0m\"\n\n# GENX320 sensor resolution\nSENSOR_W = 320\nSENSOR_H = 320\n\nCTRL_WIDTH  = 300\nLEGEND_DW   = 80     # legend display width in pixels\nTEXTURE_TAG = \"evt_tex\"\nTEX_REG_TAG = \"tex_reg\"\n\n# ---------------------------------------------------------------------------\n# Color lookup tables (RGB565, 256 entries each)\n# Source: https://github.com/openmv/openmv/blob/master/lib/imlib/rainbow_tab.c\n# evt_dark_table  @ L104\n# evt_light_table @ L138\n# Conversion: https://github.com/openmv/openmv/blob/master/lib/imlib/draw.c#L713\n# ---------------------------------------------------------------------------\n\n_EVT_DARK_565 = np.array([\n    0xD6FD, 0xD6FC, 0xD6DC, 0xD6DC, 0xD6DC, 0xCEBC, 0xCEBC, 0xCE9B,\n    0xCE9B, 0xCE9B, 0xC67B, 0xC67B, 0xC67B, 0xC65A, 0xC65A, 0xC65A,\n    0xBE3A, 0xBE3A, 0xBE1A, 0xBE19, 0xBE19, 0xB5F9, 0xB5F9, 0xB5F9,\n    0xB5D8, 0xB5D8, 0xB5D8, 0xADB8, 0xADB8, 0xAD98, 0xAD97, 0xAD97,\n    0xAD77, 0xA577, 0xA577, 0xA556, 0xA556, 0xA556, 0x9D36, 0x9D36,\n    0x9D36, 0x9D16, 0x9D15, 0x9D15, 0x94F5, 0x94F5, 0x94F5, 0x94D4,\n    0x94D4, 0x94B4, 0x8CB4, 0x8CB4, 0x8C94, 0x8C93, 0x8C93, 0x8C73,\n    0x8473, 0x8473, 0x8452, 0x8452, 0x8432, 0x7C32, 0x7C32, 0x7C12,\n    0x7C12, 0x7C11, 0x7BF1, 0x73F1, 0x73F1, 0x73D1, 0x73D0, 0x73B0,\n    0x6BB0, 0x6BB0, 0x6B90, 0x6B90, 0x6B8F, 0x6B6F, 0x636F, 0x636F,\n    0x634F, 0x634E, 0x632E, 0x632E, 0x5B2E, 0x5B0E, 0x5B0E, 0x5B0D,\n    0x5AED, 0x52ED, 0x52ED, 0x52CD, 0x52CD, 0x52AC, 0x52AC, 0x4AAC,\n    0x4AAC, 0x4A8C, 0x4A8C, 0x4A8B, 0x4A6B, 0x426B, 0x424B, 0x424B,\n    0x424A, 0x422A, 0x3A2A, 0x3A2A, 0x3A0A, 0x3A0A, 0x3A09, 0x39E9,\n    0x31E9, 0x31C9, 0x31C9, 0x31C9, 0x31A8, 0x29A8, 0x29A8, 0x2988,\n    0x2988, 0x2988, 0x2967, 0x2167, 0x2147, 0x2147, 0x2147, 0x2126,\n    0x2126, 0x2126, 0x2127, 0x2147, 0x2147, 0x2147, 0x2147, 0x2147,\n    0x2147, 0x2168, 0x2168, 0x2168, 0x2168, 0x2168, 0x2168, 0x2188,\n    0x2189, 0x2189, 0x2189, 0x2189, 0x2189, 0x21A9, 0x21A9, 0x21A9,\n    0x21AA, 0x21AA, 0x21CA, 0x21CA, 0x21CA, 0x21CA, 0x21CA, 0x29CB,\n    0x29EB, 0x29EB, 0x29EB, 0x29EB, 0x29EB, 0x29EC, 0x2A0C, 0x2A0C,\n    0x2A0C, 0x2A0C, 0x2A0C, 0x2A0C, 0x2A2D, 0x2A2D, 0x2A2D, 0x2A2D,\n    0x2A2D, 0x2A4D, 0x2A4D, 0x2A4D, 0x2A4E, 0x2A4E, 0x2A4E, 0x2A6E,\n    0x2A6E, 0x2A6E, 0x2A6E, 0x2A6F, 0x2A6F, 0x328F, 0x328F, 0x328F,\n    0x328F, 0x328F, 0x3290, 0x32B0, 0x32B0, 0x32B0, 0x32B0, 0x32B0,\n    0x32B0, 0x32B1, 0x32D1, 0x32D1, 0x32D1, 0x32D1, 0x32D1, 0x32D1,\n    0x32F2, 0x32F2, 0x32F2, 0x32F2, 0x32F2, 0x3312, 0x3312, 0x3313,\n    0x3313, 0x3313, 0x3313, 0x3B33, 0x3B33, 0x3B33, 0x3B34, 0x3B34,\n    0x3B34, 0x3B54, 0x3B54, 0x3B54, 0x3B54, 0x3B55, 0x3B55, 0x3B75,\n    0x3B75, 0x3B75, 0x3B75, 0x3B75, 0x3B96, 0x3B96, 0x3B96, 0x3B96,\n    0x3B96, 0x3B96, 0x3BB6, 0x3BB6, 0x3BB7, 0x3BB7, 0x3BB7, 0x3BB7,\n    0x3BD7, 0x43D7, 0x43D8, 0x43D8, 0x43D8, 0x43D8, 0x43F8, 0x43F8,\n], dtype=np.uint16)\n\n_EVT_LIGHT_565 = np.array([\n    0x43F8, 0x43F8, 0x43F8, 0x4418, 0x4419, 0x4419, 0x4C19, 0x4C19,\n    0x4C39, 0x4C39, 0x4C39, 0x4C39, 0x4C39, 0x5439, 0x5459, 0x5459,\n    0x5459, 0x5459, 0x5459, 0x5479, 0x5C79, 0x5C79, 0x5C79, 0x5C79,\n    0x5C99, 0x5C99, 0x5C99, 0x6499, 0x6499, 0x6499, 0x64B9, 0x64B9,\n    0x64B9, 0x6CBA, 0x6CBA, 0x6CDA, 0x6CDA, 0x6CDA, 0x6CDA, 0x6CDA,\n    0x6CFA, 0x74FA, 0x74FA, 0x74FA, 0x74FA, 0x751A, 0x751A, 0x751A,\n    0x7D1A, 0x7D1A, 0x7D1A, 0x7D3A, 0x7D3A, 0x7D3A, 0x853A, 0x853A,\n    0x855A, 0x855A, 0x855A, 0x855A, 0x855A, 0x8D5A, 0x8D5A, 0x8D7B,\n    0x8D7B, 0x8D7B, 0x8D7B, 0x8D7B, 0x959B, 0x959B, 0x959B, 0x959B,\n    0x959B, 0x95BB, 0x95BB, 0x9DBB, 0x9DBB, 0x9DBB, 0x9DDB, 0x9DDB,\n    0x9DDB, 0x9DDB, 0xA5DB, 0xA5DB, 0xA5FB, 0xA5FB, 0xA5FB, 0xA5FB,\n    0xA5FB, 0xAE1B, 0xAE1B, 0xAE1B, 0xAE1B, 0xAE1B, 0xAE3B, 0xAE3B,\n    0xB63C, 0xB63C, 0xB63C, 0xB65C, 0xB65C, 0xB65C, 0xB65C, 0xBE5C,\n    0xBE5C, 0xBE7C, 0xBE7C, 0xBE7C, 0xBE7C, 0xBE7C, 0xC69C, 0xC69C,\n    0xC69C, 0xC69C, 0xC69C, 0xC6BC, 0xC6BC, 0xCEBC, 0xCEBC, 0xCEBC,\n    0xCEBC, 0xCEDC, 0xCEDC, 0xD6DC, 0xD6DC, 0xD6DD, 0xD6FD, 0xD6FD,\n    0xD6FD, 0xD6FC, 0xD6DC, 0xD6DC, 0xD6DC, 0xCEBC, 0xCEBC, 0xCE9B,\n    0xCE9B, 0xCE9B, 0xC67B, 0xC67B, 0xC67B, 0xC65A, 0xC65A, 0xC65A,\n    0xBE3A, 0xBE3A, 0xBE1A, 0xBE19, 0xBE19, 0xB5F9, 0xB5F9, 0xB5F9,\n    0xB5D8, 0xB5D8, 0xB5D8, 0xADB8, 0xADB8, 0xAD98, 0xAD97, 0xAD97,\n    0xAD77, 0xA577, 0xA577, 0xA556, 0xA556, 0xA556, 0x9D36, 0x9D36,\n    0x9D36, 0x9D16, 0x9D15, 0x9D15, 0x94F5, 0x94F5, 0x94F5, 0x94D4,\n    0x94D4, 0x94B4, 0x8CB4, 0x8CB4, 0x8C94, 0x8C93, 0x8C93, 0x8C73,\n    0x8473, 0x8473, 0x8452, 0x8452, 0x8432, 0x7C32, 0x7C32, 0x7C12,\n    0x7C12, 0x7C11, 0x7BF1, 0x73F1, 0x73F1, 0x73D1, 0x73D0, 0x73B0,\n    0x6BB0, 0x6BB0, 0x6B90, 0x6B90, 0x6B8F, 0x6B6F, 0x636F, 0x636F,\n    0x634F, 0x634E, 0x632E, 0x632E, 0x5B2E, 0x5B0E, 0x5B0E, 0x5B0D,\n    0x5AED, 0x52ED, 0x52ED, 0x52CD, 0x52CD, 0x52AC, 0x52AC, 0x4AAC,\n    0x4AAC, 0x4A8C, 0x4A8C, 0x4A8B, 0x4A6B, 0x426B, 0x424B, 0x424B,\n    0x424A, 0x422A, 0x3A2A, 0x3A2A, 0x3A0A, 0x3A0A, 0x3A09, 0x39E9,\n    0x31E9, 0x31C9, 0x31C9, 0x31C9, 0x31A8, 0x29A8, 0x29A8, 0x2988,\n    0x2988, 0x2988, 0x2967, 0x2167, 0x2147, 0x2147, 0x2147, 0x2126,\n], dtype=np.uint16)\n\n\ndef _rgb565_to_rgb888(table565):\n    \"\"\"Convert a 256-entry RGB565 LUT to a (256, 3) uint8 RGB888 array.\n\n    Bit-replication matches the COLOR_RGB565_TO_R8/G8/B8 macros in draw.c:\n      R8 = (R5 << 3) | (R5 >> 2)\n      G8 = (G6 << 2) | (G6 >> 4)\n      B8 = (B5 << 3) | (B5 >> 2)\n    \"\"\"\n    v  = table565.astype(np.uint32)\n    r5 = (v >> 11) & 0x1F\n    g6 = (v >>  5) & 0x3F\n    b5 =  v        & 0x1F\n    r8 = ((r5 << 3) | (r5 >> 2)).astype(np.uint8)\n    g8 = ((g6 << 2) | (g6 >> 4)).astype(np.uint8)\n    b8 = ((b5 << 3) | (b5 >> 2)).astype(np.uint8)\n    return np.stack([r8, g8, b8], axis=1)   # (256, 3) uint8\n\n\nEVT_DARK_RGB  = _rgb565_to_rgb888(_EVT_DARK_565)\nEVT_LIGHT_RGB = _rgb565_to_rgb888(_EVT_LIGHT_565)\n\nCOLOR_MODES = [\"Grayscale\", \"Evt Dark\", \"Evt Light\"]\n\n\ndef _canvas_to_texture(canvas_u8, color_mode):\n    \"\"\"Convert a uint8 canvas (H×W) to a flat float32 RGBA array for DearPyGui.\"\"\"\n    if color_mode == \"Grayscale\":\n        rgb = np.stack([canvas_u8, canvas_u8, canvas_u8], axis=-1)\n    elif color_mode == \"Evt Dark\":\n        rgb = EVT_DARK_RGB[canvas_u8]\n    else:  # Evt Light\n        rgb = EVT_LIGHT_RGB[canvas_u8]\n    rgba = np.ones((SENSOR_H, SENSOR_W, 4), dtype=np.float32)\n    rgba[:, :, :3] = rgb * (1.0 / 255.0)\n    return rgba.ravel()\n\n\ndef _draw_freq_legend(tag, dh, min_freq, max_freq, use_log, n_bins):\n    \"\"\"Redraw a DPG drawlist with a frequency colorbar legend (high freq at top).\"\"\"\n    import dearpygui.dearpygui as _dpg\n    _dpg.delete_item(tag, children_only=True)\n    if n_bins < 2 or dh <= 0:\n        return\n    # Dark background\n    _dpg.draw_rectangle(pmin=(0, 0), pmax=(LEGEND_DW, dh),\n                        color=(30, 30, 30, 255), fill=(30, 30, 30, 255), parent=tag)\n    color_w = 16        # width of the colored band\n    text_x  = color_w + 4\n    bin_h   = dh / n_bins\n\n    if use_log:\n        lo = np.log10(max(min_freq, 1e-9))\n        hi = np.log10(max(max_freq, min_freq * 1.001 + 1e-9))\n        vals_tf = np.linspace(hi, lo, n_bins)   # high freq at top → low at bottom\n        freq_labels = 10.0 ** vals_tf\n        idx_vals = np.clip(((vals_tf - lo) / (hi - lo + 1e-12)) * 255, 0, 255).astype(np.uint8)\n    else:\n        freq_labels = np.linspace(max_freq, min_freq, n_bins)\n        rng = max(max_freq - min_freq, 1e-9)\n        idx_vals = np.clip((freq_labels - min_freq) / rng * 255, 0, 255).astype(np.uint8)\n\n    for i in range(n_bins):\n        y0 = int(i * bin_h)\n        y1 = max(int((i + 1) * bin_h), y0 + 1)\n        rgb = FREQ_LUT[idx_vals[i]]\n        col = (int(rgb[0]), int(rgb[1]), int(rgb[2]), 255)\n        _dpg.draw_rectangle(pmin=(0, y0), pmax=(color_w, y1),\n                            color=col, fill=col, parent=tag)\n        f = float(freq_labels[i])\n        if f >= 10000:\n            label = f\"{f / 1000:.0f}k\"\n        elif f >= 1000:\n            label = f\"{f / 1000:.1f}k\"\n        elif f >= 100:\n            label = f\"{f:.0f}\"\n        elif f >= 10:\n            label = f\"{f:.1f}\"\n        else:\n            label = f\"{f:.2f}\"\n        text_y = y0 + max(int(bin_h) // 2 - 6, 0)\n        _dpg.draw_text(pos=(text_x, text_y), text=label,\n                       color=(210, 210, 210, 255), size=12, parent=tag)\n\n\ndef _make_freq_legend_pil(height, min_freq, max_freq, use_log, n_bins):\n    \"\"\"Render the frequency colorbar legend as a PIL Image (height × LEGEND_DW).\"\"\"\n    img  = Image.new('RGB', (LEGEND_DW, height), color=(30, 30, 30))\n    draw = ImageDraw.Draw(img)\n    color_w = 16\n    bin_h   = height / max(n_bins, 1)\n\n    if use_log:\n        lo = np.log10(max(min_freq, 1e-9))\n        hi = np.log10(max(max_freq, min_freq * 1.001 + 1e-9))\n        vals_tf    = np.linspace(hi, lo, n_bins)\n        freq_labels = 10.0 ** vals_tf\n        idx_vals    = np.clip(((vals_tf - lo) / (hi - lo + 1e-12)) * 255, 0, 255).astype(np.uint8)\n    else:\n        freq_labels = np.linspace(max_freq, min_freq, n_bins)\n        rng      = max(max_freq - min_freq, 1e-9)\n        idx_vals = np.clip((freq_labels - min_freq) / rng * 255, 0, 255).astype(np.uint8)\n\n    for i in range(n_bins):\n        y0  = int(i * bin_h)\n        y1  = max(int((i + 1) * bin_h), y0 + 1)\n        rgb = FREQ_LUT[idx_vals[i]]\n        draw.rectangle([(0, y0), (color_w - 1, y1 - 1)],\n                       fill=(int(rgb[0]), int(rgb[1]), int(rgb[2])))\n        f = float(freq_labels[i])\n        if   f >= 10000: label = f\"{f / 1000:.0f}k\"\n        elif f >= 1000:  label = f\"{f / 1000:.1f}k\"\n        elif f >= 100:   label = f\"{f:.0f}\"\n        elif f >= 10:    label = f\"{f:.1f}\"\n        else:            label = f\"{f:.2f}\"\n        draw.text((color_w + 3, y0 + max(int(bin_h) // 2 - 6, 0)),\n                  label, fill=(210, 210, 210))\n    return img\n\n\ndef list_com_ports():\n    return sorted(p.device for p in serial.tools.list_ports.comports())\n\n\n# ---------------------------------------------------------------------------\n# Frequency camera helpers\n# Reference: https://github.com/ros-event-camera/frequency_cam\n# ---------------------------------------------------------------------------\n\nFREQ_TEX_TAG = \"freq_tex\"\n\n\ndef _make_freq_lut():\n    \"\"\"HSV colormap: index 0 → blue (low freq), 255 → red (high freq).\"\"\"\n    import colorsys\n    lut = np.zeros((256, 3), dtype=np.uint8)\n    for i in range(256):\n        hue = (1.0 - i / 255.0) * (240.0 / 360.0)\n        r, g, b = colorsys.hsv_to_rgb(hue, 1.0, 1.0)\n        lut[i] = [int(r * 255), int(g * 255), int(b * 255)]\n    return lut\n\n\nFREQ_LUT = _make_freq_lut()\n\n\ndef _freq_filter_coeffs(cutoff_period):\n    \"\"\"Compute second-order IIR bandpass coefficients (c1, c2, c3).\n\n    Matches the reference implementation exactly:\n      omega = 2π/T,  phi = 2 - cos(omega)\n      alpha = (1 - sin(omega)) / cos(omega)\n      beta  = phi - sqrt(phi² - 1)\n      c1 = alpha + beta,  c2 = -alpha·beta,  c3 = 0.5·(1 + beta)\n    Filter: L_k = c1·L_{k-1} + c2·L_{k-2} + c3·(p - p_prev)\n    \"\"\"\n    T     = max(cutoff_period, 1.0)\n    omega = 2.0 * np.pi / T\n    phi   = 2.0 - np.cos(omega)\n    alpha = (1.0 - np.sin(omega)) / np.cos(omega)\n    beta  = phi - np.sqrt(max(phi * phi - 1.0, 0.0))\n    c1 =  alpha + beta\n    c2 = -alpha * beta   # negative — used as L_k = c1·L1 + c2·L2 + c3·dp\n    c3 =  0.5 * (1.0 + beta)\n    return c1, c2, c3\n\n\n@numba.njit(nogil=True, cache=True)\ndef _update_freq_cam(xs, ys, pols, ts_f,\n                     fc_L2, fc_L1, fc_p1,\n                     fc_t_ud, fc_t_du, fc_per,\n                     c1, c2, c3,\n                     fc_dt_min, fc_dt_max,\n                     fc_dt_min_half, fc_dt_max_half,\n                     fc_n_to):\n    \"\"\"Per-event sequential IIR frequency camera update.\n\n    Compiled with nogil=True so the camera reader thread runs concurrently.\n    Returns the timestamp of the last processed event (or -1.0 if empty).\n    \"\"\"\n    n = xs.shape[0]\n    if n == 0:\n        return -1.0\n    for i in range(n):\n        px = xs[i];  py = ys[i]\n        p  = pols[i] * 2.0 - 1.0\n        t  = ts_f[i]\n        l2 = fc_L2[py, px]\n        l1 = fc_L1[py, px]\n        dp = p - fc_p1[py, px]\n        l_new = c1 * l1 + c2 * l2 + c3 * dp\n        if not (abs(l_new) < 1e4):\n            l_new = 0.0\n            l1    = 0.0\n        fc_L2[py, px] = l1\n        fc_L1[py, px] = l_new\n        fc_p1[py, px] = p\n\n        if l1 > 0.0 and l_new < 0.0:\n            dt_ud = t - fc_t_ud[py, px]\n            dt_du = t - fc_t_du[py, px]\n            if fc_dt_min <= dt_ud <= fc_dt_max:\n                fc_per[py, px] = dt_ud\n            else:\n                cur = fc_per[py, px]\n                if cur > 0.0:\n                    if dt_ud > cur * fc_n_to and dt_du > 0.5 * cur * fc_n_to:\n                        fc_per[py, px] = 0.0\n                else:\n                    if fc_dt_min_half <= dt_du <= fc_dt_max_half:\n                        fc_per[py, px] = 2.0 * dt_du\n            fc_t_ud[py, px] = t\n\n        elif l1 < 0.0 and l_new > 0.0:\n            dt_du = t - fc_t_du[py, px]\n            dt_ud = t - fc_t_ud[py, px]\n            cur   = fc_per[py, px]\n            if fc_dt_min <= dt_du <= fc_dt_max and cur <= 0.0:\n                fc_per[py, px] = dt_du\n            else:\n                if cur > 0.0:\n                    if dt_du > cur * fc_n_to and dt_ud > 0.5 * cur * fc_n_to:\n                        fc_per[py, px] = 0.0\n                else:\n                    if fc_dt_min_half <= dt_ud <= fc_dt_max_half:\n                        fc_per[py, px] = 2.0 * dt_ud\n            fc_t_du[py, px] = t\n\n    return ts_f[n - 1]\n\n\ndef _freq_to_texture(fc_per, fc_t_ud, fc_t_du, t_now, n_timeout, min_freq, max_freq,\n                     use_log=True, overlay_events=False):\n    \"\"\"Convert per-pixel frequency state to a flat float32 RGBA for DearPyGui.\n\n    Timeout: pixel is inactive when t_now - max(t_ud, t_du) exceeds n_timeout periods.\n    Two-condition check matches reference: dt < dtMax·n_timeout² AND dt·freq < n_timeout.\n    use_log:        log10 frequency color scale (True) vs linear (False).\n    overlay_events: grey pixels that have had crossings but no active frequency.\n    \"\"\"\n    last_cross = np.maximum(fc_t_ud, fc_t_du)\n    dt         = t_now - last_cross                          # seconds since last crossing\n    dt_max     = 1.0 / max(min_freq, 1e-9)\n\n    safe_per = np.where(fc_per > 0.0, fc_per, 1.0)\n    freq     = np.where(fc_per > 0.0, 1.0 / safe_per, 0.0).astype(np.float32)\n\n    active = (fc_per > 0.0) & (dt < dt_max * n_timeout * n_timeout) & (\n              dt.astype(np.float32) * freq < n_timeout)\n\n    in_range = active & (freq >= min_freq) & (freq <= max_freq)\n\n    idx = np.zeros((SENSOR_H, SENSOR_W), dtype=np.uint8)\n    if in_range.any():\n        clipped = np.where(in_range, np.clip(freq, min_freq, max_freq), min_freq)\n        if use_log:\n            lo = np.log10(max(min_freq, 1e-9))\n            hi = np.log10(max(max_freq, min_freq * 1.001 + 1e-9))\n            vals = (np.log10(clipped) - lo) / (hi - lo) * 255.0\n        else:\n            rng = max(max_freq - min_freq, 1e-9)\n            vals = (clipped - min_freq) / rng * 255.0\n        idx[in_range] = np.clip(vals[in_range], 0, 255).astype(np.uint8)\n\n    rgba = np.zeros((SENSOR_H, SENSOR_W, 4), dtype=np.float32)\n    rgba[:, :, 3] = 1.0\n    rgba[:, :, :3] = FREQ_LUT[idx].astype(np.float32) * (1.0 / 255.0)\n    rgba[~active, :3] = 0.0\n\n    if overlay_events:\n        # Grey out pixels with crossing history but no active frequency\n        has_crossed = (fc_t_ud > 0.0) | (fc_t_du > 0.0)\n        rgba[has_crossed & ~active, :3] = 0.5\n\n    return rgba.ravel()\n\n\n# ---------------------------------------------------------------------------\n# Camera background thread  (receives data, puts onto queue)\n# ---------------------------------------------------------------------------\n\nEMA_ALPHA = 0.2\n\nEVT_RES_OPTIONS = [1024, 2048, 4096, 8192, 16384, 32768, 65536]\n\n\ndef patch_script(script, csi_fifo_depth, evt_fifo_depth, evt_res, raw_mode=False):\n    \"\"\"Patch the on-camera script with GUI-controlled parameters before exec.\n\n    Substitutions made (processed mode):\n      CSI_FIFO_DEPTH   = <value>\n      EVENT_FIFO_DEPTH = <value>\n      np.zeros((EVT_RES, 6), ...)  — the array shape (EVT_RES constant)\n      def read / def readp         — use readp on Mac/Linux, read on Windows\n\n    Substitutions made (raw mode):\n      CSI_FIFO_DEPTH = <value>\n      EVT_RES        = <value>   — only the constant assignment\n      def read / def readp\n    \"\"\"\n    import re\n\n    script = re.sub(r'CSI_FIFO_DEPTH\\s*=\\s*\\d+',\n                    f'CSI_FIFO_DEPTH = {csi_fifo_depth}', script)\n\n    if raw_mode:\n        script = re.sub(r'EVT_RES\\s*=\\s*\\d+',\n                        f'EVT_RES = {evt_res}', script)\n    else:\n        script = re.sub(r'EVENT_FIFO_DEPTH\\s*=\\s*\\d+',\n                        f'EVENT_FIFO_DEPTH = {evt_fifo_depth}', script)\n        script = re.sub(r'np\\.zeros\\(\\((?:\\d+|EVT_RES),\\s*6\\)',\n                        f'np.zeros(({evt_res}, 6)', script)\n\n    if sys.platform != 'win32':\n        script = script.replace('def read(self, offset, size):',\n                                'def readp(self, offset, size):')\n\n    return script\n\n\ndef decode_raw_events(buf, time_high_ref):\n    \"\"\"Vectorized EVT 2.0 decoder.\n\n    Decodes a buffer of raw 32-bit little-endian EVT 2.0 words into an (N, 6)\n    uint16 array matching the ec_event_t layout from the processed cam script:\n      [0] type   — EC_PIX_OFF_EVENT(0), EC_PIX_ON_EVENT(1),\n                   EC_EXT_TRIGGER_FALLING(2), EC_EXT_TRIGGER_RISING(3),\n                   EC_RST_TRIGGER_FALLING(4), EC_RST_TRIGGER_RISING(5)\n      [1] ts_s   — whole seconds of timestamp\n      [2] ts_ms  — milliseconds within the second (0-999)\n      [3] ts_us  — microseconds within the millisecond (0-999)\n      [4] x      — pixel column (0 for trigger events)\n      [5] y      — pixel row    (0 for trigger events)\n\n    Handles TD pixel events (0x0/0x1) and EXT_TRIGGER events (0xA).\n    EV_TIME_HIGH (0x8) words update the running timestamp accumulator.\n\n    time_high_ref is a one-element list carrying the running EV_TIME_HIGH\n    value across consecutive calls (updated in-place).\n    \"\"\"\n    n_words = len(buf) // 4\n    if n_words == 0:\n        return np.zeros((0, 6), dtype=np.uint16)\n\n    words = np.frombuffer(buf, dtype=np.uint32)\n    types = (words >> 28) & 0xF\n\n    # --- EV_TIME_HIGH (0x8): update running timestamp accumulator ---\n    th_mask = types == 0x8\n    th_idx  = np.where(th_mask)[0]\n    th_vals = ((words[th_mask] & 0x0FFFFFFF).astype(np.uint64)) << 6\n\n    # --- all output events: TD pixel (0x0, 0x1) + EXT_TRIGGER (0xA) ---\n    evt_mask = (types <= 0x1) | (types == 0xA)\n    evt_idx  = np.where(evt_mask)[0]\n\n    if evt_idx.size == 0:\n        if th_vals.size > 0:\n            time_high_ref[0] = int(th_vals[-1])\n        return np.zeros((0, 6), dtype=np.uint16)\n\n    # --- assign the correct time_high to every event (vectorized) ---\n    # The applicable time_high for event at position i is the last EV_TIME_HIGH\n    # whose stream position is strictly before i.\n    if th_idx.size > 0:\n        ins = np.searchsorted(th_idx, evt_idx, side='right') - 1\n        th_for_evt = np.empty(evt_idx.size, dtype=np.uint64)\n        before_first = ins < 0\n        th_for_evt[before_first]  = time_high_ref[0]\n        th_for_evt[~before_first] = th_vals[ins[~before_first]]\n        time_high_ref[0] = int(th_vals[-1])\n    else:\n        th_for_evt = np.full(evt_idx.size, time_high_ref[0], dtype=np.uint64)\n\n    # --- reconstruct full microsecond timestamp ---\n    evt_words = words[evt_idx]\n    evt_types = types[evt_idx]\n    ts_low = ((evt_words >> 22) & 0x3F).astype(np.uint64)\n    t_us   = th_for_evt | ts_low\n\n    ts_s  = (t_us // 1_000_000).astype(np.uint16)\n    ts_ms = ((t_us // 1_000) % 1_000).astype(np.uint16)\n    ts_us = (t_us % 1_000).astype(np.uint16)\n\n    # --- pixel events: type is 0 (off) or 1 (on), x/y from bit fields ---\n    out_type = evt_types.astype(np.uint16)   # 0 or 1 for TD events\n    x = ((evt_words >> 11) & 0x7FF).astype(np.uint16)\n    y = (evt_words & 0x7FF).astype(np.uint16)\n\n    # --- trigger events: remap type to EC_TRIGGER_EVENT(id, polarity) ---\n    # EC_TRIGGER_EVENT = EC_EXT_TRIGGER_FALLING(2) + ((id & 1) << 1) + polarity\n    # x and y are 0 for trigger events (no pixel coordinate).\n    is_trig = evt_types == 0xA\n    if is_trig.any():\n        tw       = evt_words[is_trig]\n        trig_id  = ((tw >> 8) & 0x1F).astype(np.uint16)\n        trig_pol = (tw & 0x1).astype(np.uint16)\n        out_type[is_trig] = 2 + ((trig_id & 1) << 1) + trig_pol\n        x[is_trig] = 0\n        y[is_trig] = 0\n\n    return np.stack([out_type, ts_s, ts_ms, ts_us, x, y], axis=1)\n\n\ndef camera_worker(args, state_lock, state, event_q, stop_evt):\n    try:\n        with Camera(\n            args.port, baudrate=args.baudrate, crc=args.crc, seq=args.seq,\n            ack=args.ack, events=args.events, timeout=args.timeout,\n            max_retry=args.max_retry, max_payload=args.max_payload,\n            drop_rate=args.drop_rate,\n        ) as camera:\n            logging.info(f\"Connected to OpenMV on {args.port}\")\n            camera.stop()\n            time.sleep(0.5)\n\n            with open(args.script) as f:\n                script = f.read()\n            with state_lock:\n                csi_fifo    = state['csi_fifo_depth']\n                evt_fifo    = state['evt_fifo_depth']\n                evt_res     = state['evt_res']\n                raw_mode    = state['stream_mode'] == 'Raw (fastest)'\n            script = patch_script(script, csi_fifo, evt_fifo, evt_res, raw_mode)\n            logging.debug(f\"Patched script: CSI_FIFO={csi_fifo} EVT_FIFO={evt_fifo} \"\n                          f\"EVT_RES={evt_res} raw={raw_mode} \"\n                          f\"readp={'yes' if sys.platform != 'win32' else 'no'}\")\n            camera.exec(script)\n            logging.info(f\"Script running, streaming events ({'raw' if raw_mode else 'processed'})...\")\n\n            channel        = 'raw_events' if raw_mode else 'events'\n            time_high_ref  = [0]   # running EV_TIME_HIGH accumulator for raw decoding\n\n            start_time     = time.perf_counter()\n            last_time      = start_time\n            total_events   = 0\n            total_bytes    = 0\n            event_rate_ema = 0.0\n            mbps_ema       = 0.0\n\n            while not stop_evt.is_set():\n                status = camera.read_status()\n\n                if not args.quiet and status and status.get('stdout'):\n                    if text := camera.read_stdout():\n                        print(f\"{COLOR_CAMERA}{text}{COLOR_RESET}\", end='')\n\n                if not camera.has_channel(channel):\n                    time.sleep(0.01)\n                    continue\n\n                if not status or not status.get(channel):\n                    time.sleep(0.01)\n                    continue\n\n                size = camera.channel_size(channel)\n                if size <= 0:\n                    time.sleep(0.01)\n                    continue\n\n                now       = time.perf_counter()\n                dt        = now - last_time\n                last_time = now\n                if dt <= 0.0:\n                    continue\n\n                data = camera.channel_read(channel, size)\n\n                if raw_mode:\n                    if (len(data) % 4) != 0:\n                        logging.warning(f\"Misaligned raw packet: {len(data)} bytes (not multiple of 4)\")\n                        continue\n                    events = decode_raw_events(data, time_high_ref)\n                else:\n                    if (len(data) % 12) != 0:\n                        logging.warning(f\"Misaligned packet: {len(data)} bytes (not multiple of 12)\")\n                        continue\n                    # Each event row: 6 × uint16 little-endian\n                    # [0] polarity (0=neg, 1=pos)  [1] sec  [2] ms  [3] us  [4] x  [5] y\n                    events = np.frombuffer(data, dtype='<u2').reshape(-1, 6)\n\n                event_count = events.shape[0]\n\n                events_per_sec = event_count / dt\n                mb_per_sec     = len(data) / 1048576.0 / dt\n\n                if event_rate_ema == 0.0:\n                    event_rate_ema = events_per_sec\n                else:\n                    event_rate_ema = event_rate_ema * (1.0 - EMA_ALPHA) + events_per_sec * EMA_ALPHA\n\n                if mbps_ema == 0.0:\n                    mbps_ema = mb_per_sec\n                else:\n                    mbps_ema = mbps_ema * (1.0 - EMA_ALPHA) + mb_per_sec * EMA_ALPHA\n\n                total_events += event_count\n                total_bytes  += len(data)\n                elapsed       = now - start_time\n\n                stats = {\n                    'event_count':  event_count,\n                    'event_rate':   event_rate_ema,\n                    'mbps':         mbps_ema,\n                    'total_events': total_events,\n                    'elapsed':      elapsed,\n                }\n\n                # Drop oldest if render loop is falling behind\n                if event_q.full():\n                    try:\n                        event_q.get_nowait()\n                    except queue.Empty:\n                        pass\n                event_q.put((events, stats))\n\n    except Exception as e:\n        logging.error(f\"Camera error: {e}\")\n        if args.debug:\n            import traceback\n            logging.error(traceback.format_exc())\n\n\n# ---------------------------------------------------------------------------\n# Processing thread  (IIR freq-cam + canvas accumulation; GIL-free hot path)\n# ---------------------------------------------------------------------------\n\ndef processing_worker(state_lock, state, raw_q, result_q, stop_evt,\n                      fc_L2, fc_L1, fc_p1, fc_t_ud, fc_t_du, fc_per,\n                      fc_coeffs_ref, fc_t_now, reset_evt):\n    \"\"\"Pulls raw event batches, runs IIR filter (nogil) and canvas update, pushes results.\"\"\"\n\n    canvas    = np.full((SENSOR_H, SENSOR_W), 128, dtype=np.int32)\n    slide_buf = deque()\n    event_buf = deque()\n    batch_counter = 0\n\n    while not stop_evt.is_set():\n        # Check for reset request from render thread\n        if reset_evt.is_set():\n            reset_evt.clear()\n            canvas[:] = 128\n            batch_counter = 0\n            slide_buf.clear()\n            event_buf.clear()\n            fc_L2[:] = 0.0;  fc_L1[:] = 0.0;  fc_p1[:] = -1.0\n            fc_t_ud[:] = 0.0; fc_t_du[:] = 0.0\n            fc_per[:] = -1.0\n            fc_t_now[0] = 0.0\n\n        try:\n            events, stats = raw_q.get(timeout=0.02)\n        except queue.Empty:\n            continue\n\n        xs   = events[:, 4].astype(np.int32)\n        ys   = events[:, 5].astype(np.int32)\n        pols = events[:, 0].astype(np.int32)\n\n        valid = (xs >= 0) & (xs < SENSOR_W) & (ys >= 0) & (ys < SENSOR_H)\n        xs, ys, pols = xs[valid], ys[valid], pols[valid]\n\n        batch_delta = None\n        if xs.size > 0:\n            signs    = pols * 2 - 1\n            flat_idx = ys * SENSOR_W + xs\n            pos = np.bincount(flat_idx[signs > 0], minlength=SENSOR_H * SENSOR_W)\n            neg = np.bincount(flat_idx[signs < 0], minlength=SENSOR_H * SENSOR_W)\n            batch_delta = (pos.astype(np.int32) - neg.astype(np.int32)).reshape(SENSOR_H, SENSOR_W)\n\n            with state_lock:\n                fc_enabled = state['fc_enabled']\n                fc_min  = state['fc_min_freq']\n                fc_max  = state['fc_max_freq']\n                fc_n_to = state['fc_n_timeout']\n\n            if fc_enabled:\n                ts_f = (events[valid, 1].astype(np.float64)\n                        + events[valid, 2].astype(np.float64) * 1e-3\n                        + events[valid, 3].astype(np.float64) * 1e-6)\n                c1, c2, c3 = fc_coeffs_ref[0], fc_coeffs_ref[1], fc_coeffs_ref[2]\n                fc_dt_min      = 1.0 / max(fc_max, 1e-9)\n                fc_dt_max      = 1.0 / max(fc_min, 1e-9)\n                fc_dt_min_half = 0.5 * fc_dt_min\n                fc_dt_max_half = 0.5 * fc_dt_max\n\n                # GIL-free compiled IIR update\n                t_last = _update_freq_cam(\n                    xs.astype(np.int32), ys.astype(np.int32),\n                    pols.astype(np.float64), ts_f,\n                    fc_L2, fc_L1, fc_p1,\n                    fc_t_ud, fc_t_du, fc_per,\n                    c1, c2, c3,\n                    fc_dt_min, fc_dt_max,\n                    fc_dt_min_half, fc_dt_max_half,\n                    float(fc_n_to),\n                )\n                if t_last >= 0.0:\n                    fc_t_now[0] = t_last\n\n        with state_lock:\n            contrast = state['contrast']\n            mode     = state['mode']\n            window   = state['window']\n            do_clear = state['clear']\n            if do_clear:\n                state['clear'] = False\n\n        if do_clear:\n            canvas[:] = 128\n            batch_counter = 0\n            slide_buf.clear()\n            event_buf.clear()\n\n        if mode == 'Canvas':\n            if window > 0 and batch_counter >= window:\n                canvas[:] = 128\n                batch_counter = 0\n                event_buf.clear()\n            batch_counter += 1\n            if batch_delta is not None:\n                canvas += batch_delta * contrast\n                np.clip(canvas, 0, 255, out=canvas)\n                event_buf.append(events)\n        else:  # Sliding Window\n            w = max(1, window)\n            if batch_delta is not None:\n                slide_buf.append(batch_delta)\n                event_buf.append(events)\n            while len(slide_buf) > w:\n                slide_buf.popleft()\n                event_buf.popleft()\n            canvas[:] = 128\n            for d in slide_buf:\n                canvas += d * contrast\n                np.clip(canvas, 0, 255, out=canvas)\n\n        # Only snapshot and enqueue a result if the render loop has room.\n        # This avoids three expensive 320×320 array copies on every batch\n        # when the render thread is already backed up.\n        if not result_q.full():\n            canvas_u8 = canvas.astype(np.uint8)\n            result = {\n                'canvas_u8':  canvas_u8,\n                'fc_enabled': fc_enabled,\n                'fc_per':     fc_per.copy() if fc_enabled else None,\n                'fc_t_ud':    fc_t_ud.copy() if fc_enabled else None,\n                'fc_t_du':    fc_t_du.copy() if fc_enabled else None,\n                'fc_t_now':   fc_t_now[0],\n                'event_buf':  list(event_buf),\n                'stats':      stats,\n            }\n            result_q.put(result)\n\n\n# ---------------------------------------------------------------------------\n# Argument parsing\n# ---------------------------------------------------------------------------\n\ndef str2bool(v):\n    if isinstance(v, bool):\n        return v\n    if v.lower() in ('yes', 'true', 't', 'y', '1'):\n        return True\n    if v.lower() in ('no', 'false', 'f', 'n', '0'):\n        return False\n    raise argparse.ArgumentTypeError('Boolean value expected.')\n\n\ndef parse_args():\n    p = argparse.ArgumentParser(\n        description='GenX320 event camera visualization GUI')\n\n    p.add_argument('--port',        default=None,\n                   help='Serial port (auto-selected in GUI if omitted)')\n    p.add_argument('--script',      default=None,\n                   help='MicroPython script to run on the camera '\n                        '(defaults to genx320_event_mode_streaming_on_cam.py next to this file)')\n    p.add_argument('--baudrate',    type=int,   default=921600)\n    p.add_argument('--timeout',     type=float, default=1.0)\n    p.add_argument('--crc',         type=str2bool, nargs='?', const=True,\n                   default=(sys.platform == 'win32'))\n    p.add_argument('--seq',         type=str2bool, nargs='?', const=True, default=True)\n    p.add_argument('--ack',         type=str2bool, nargs='?', const=True, default=False)\n    p.add_argument('--events',      type=str2bool, nargs='?', const=True, default=True)\n    p.add_argument('--max-retry',   type=int,   default=3)\n    p.add_argument('--max-payload', type=int,   default=4096)\n    p.add_argument('--drop-rate',   type=float, default=0.0)\n    p.add_argument('--quiet',       action='store_true',\n                   help='Suppress camera stdout')\n    p.add_argument('--debug',       action='store_true')\n    p.add_argument('--benchmark',   action='store_true',\n                   help='Headless mode: print throughput stats, no GUI')\n    p.add_argument('--raw',         type=str2bool, nargs='?', const=True, default=True,\n                   help='Use raw event streaming (default: true)')\n    p.add_argument('--evt-res',     type=int,   default=8192,\n                   help='Event buffer resolution (default: 8192)')\n    return p.parse_args()\n\n\n# ---------------------------------------------------------------------------\n# main  (render / GUI thread)\n# ---------------------------------------------------------------------------\n\ndef run_benchmark(args):\n    \"\"\"Headless benchmark: camera + processing threads, stats printed to terminal.\"\"\"\n    if not args.port:\n        ports = list_com_ports()\n        if not ports:\n            print(\"No serial ports found. Use --port to specify one.\")\n            sys.exit(1)\n        args.port = ports[0]\n        print(f\"Auto-selected port: {args.port}\")\n\n    state_lock = threading.Lock()\n    state = {\n        'stream_mode':    'Raw (fastest)' if args.raw else 'Processed',\n        'csi_fifo_depth': 8,\n        'evt_fifo_depth': 8,\n        'evt_res':        args.evt_res,\n        'contrast':       16,\n        'color_mode':     'Grayscale',\n        'mode':           'Sliding Window',\n        'window':         4,\n        'clear':          False,\n        'fc_cutoff_period': 5.0,\n        'fc_enabled':       True,\n        'fc_min_freq':      10.0,\n        'fc_max_freq':      1000.0,\n        'fc_n_timeout':     2,\n        'fc_log_freq':      True,\n        'fc_overlay':       False,\n        'fc_legend_show':   False,\n        'fc_legend_bins':   11,\n    }\n\n    if args.script is None:\n        raw_mode = state['stream_mode'] == 'Raw (fastest)'\n        args.script = os.path.join(\n            os.path.dirname(os.path.abspath(__file__)),\n            'genx320_raw_event_mode_streaming_on_cam.py' if raw_mode\n            else 'genx320_event_mode_streaming_on_cam.py',\n        )\n\n    fc_L2        = np.zeros((SENSOR_H, SENSOR_W), dtype=np.float32)\n    fc_L1        = np.zeros((SENSOR_H, SENSOR_W), dtype=np.float32)\n    fc_p1        = np.full((SENSOR_H, SENSOR_W), -1.0, dtype=np.float32)\n    fc_t_ud      = np.zeros((SENSOR_H, SENSOR_W), dtype=np.float64)\n    fc_t_du      = np.zeros((SENSOR_H, SENSOR_W), dtype=np.float64)\n    fc_per       = np.full((SENSOR_H, SENSOR_W), -1.0, dtype=np.float64)\n    fc_coeffs = list(_freq_filter_coeffs(state['fc_cutoff_period']))\n    fc_t_now  = [0.0]\n\n    raw_q    = queue.Queue(maxsize=8)\n    result_q = queue.Queue(maxsize=4)\n    reset_evt = threading.Event()\n    stop_evt  = threading.Event()\n\n    def handle_exit(signum, frame):\n        stop_evt.set()\n\n    signal.signal(signal.SIGINT,  handle_exit)\n    signal.signal(signal.SIGTERM, handle_exit)\n\n    cam_t = threading.Thread(\n        target=camera_worker,\n        args=(args, state_lock, state, raw_q, stop_evt),\n        daemon=True,\n    )\n    proc_t = threading.Thread(\n        target=processing_worker,\n        args=(state_lock, state, raw_q, result_q, stop_evt,\n              fc_L2, fc_L1, fc_p1, fc_t_ud, fc_t_du, fc_per,\n              fc_coeffs, fc_t_now, reset_evt),\n        daemon=True,\n    )\n\n    print(f\"Connecting to {args.port} ...\")\n\n    cam_t.start()\n    proc_t.start()\n\n    last_print = time.perf_counter()\n    while not stop_evt.is_set():\n        try:\n            result = result_q.get(timeout=0.05)\n        except queue.Empty:\n            if not cam_t.is_alive():\n                if not stop_evt.is_set():\n                    print(\"Camera thread died unexpectedly.\")\n                break\n            continue\n\n        now = time.perf_counter()\n        if now - last_print >= 0.1:\n            last_print = now\n            s = result['stats']\n            print(f\"elapsed={s['elapsed']:.1f}s\\t\"\n                  f\"rate={s['event_rate']:,.0f} ev/s\\t\"\n                  f\"bw={s['mbps']:.2f} MB/s\\t\"\n                  f\"total={s['total_events']:,}\")\n\n    stop_evt.set()\n    print(\"\\nDone.\")\n\n\ndef main(args=None):\n    if args is None:\n        args = parse_args()\n\n    if args.script is None:\n        args.script = os.path.join(\n            os.path.dirname(os.path.abspath(__file__)),\n            'genx320_event_mode_streaming_on_cam.py',\n        )\n\n    logging.basicConfig(\n        format=\"%(relativeCreated)010.3f - %(message)s\",\n        level=logging.DEBUG if args.debug else logging.INFO,\n    )\n\n    # Shared state accessed by GUI callbacks and camera thread\n    state_lock = threading.Lock()\n    state = {\n        # Camera script parameters (locked while connected)\n        'stream_mode':    'Raw (fastest)' if args.raw else 'Processed',\n        'csi_fifo_depth': 8,\n        'evt_fifo_depth': 8,\n        'evt_res':        args.evt_res,\n        # Visualization\n        'contrast':   16,\n        'color_mode': 'Grayscale',\n        'mode':       'Sliding Window',   # 'Canvas' or 'Sliding Window'\n        'window':     4,                  # Canvas: batches before auto-clear (0=manual); Sliding Window: batches to keep (min 1)\n        'clear':      False,\n        # Frequency visualization\n        'fc_enabled':       True,\n        'fc_cutoff_period': 5.0,\n        'fc_min_freq':      10.0,\n        'fc_max_freq':      1000.0,\n        'fc_n_timeout':     2,\n        'fc_log_freq':      True,\n        'fc_overlay':       False,\n        'fc_legend_show':   True,\n        'fc_legend_bins':   11,\n    }\n\n    last_canvas_u8  = [None]   # latest rendered uint8 canvas, for saving\n    last_freq_rgba  = [None]   # latest freq texture (H×W×4 float32), for saving\n    event_buf      = deque()  # raw event arrays from last result, for saving\n\n    # Frequency camera per-pixel IIR filter state (owned by processing_worker).\n    # Allocated here so they can be passed to the thread at connect time.\n    # fc_p1  : previous raw polarity (0 or 1); dp = p - p1 drives the filter\n    # fc_t_ud: time of last L+ → L− zero crossing (\"up-down\")\n    # fc_t_du: time of last L− → L+ zero crossing (\"down-up\")\n    # fc_per : estimated period; -1 = uninitialized, 0 = stale, >0 = valid\n    fc_L2        = np.zeros((SENSOR_H, SENSOR_W), dtype=np.float32)\n    fc_L1        = np.zeros((SENSOR_H, SENSOR_W), dtype=np.float32)\n    fc_p1        = np.full((SENSOR_H, SENSOR_W), -1.0, dtype=np.float32)  # ±1 convention, init -1\n    fc_t_ud      = np.zeros((SENSOR_H, SENSOR_W), dtype=np.float64)\n    fc_t_du      = np.zeros((SENSOR_H, SENSOR_W), dtype=np.float64)\n    fc_per       = np.full((SENSOR_H, SENSOR_W), -1.0, dtype=np.float64)\n    fc_coeffs = list(_freq_filter_coeffs(state['fc_cutoff_period']))\n    fc_t_now  = [0.0]   # last camera timestamp processed\n\n    # Lock-free mirrors of state, readable by fit_image() without taking the lock\n    fc_enabled_ref      = [state['fc_enabled']]\n    fc_legend_show_ref  = [state['fc_legend_show']]\n    legend_redraw_needed = [True]\n\n    raw_q    = queue.Queue(maxsize=8)   # camera → processing (larger: absorb bursts)\n    result_q = queue.Queue(maxsize=4)   # processing → render\n    reset_evt = threading.Event()       # render → processing: reset filter/canvas state\n    conn     = {'cam_thread': None, 'proc_thread': None, 'stop_evt': None}\n\n    # -----------------------------------------------------------------------\n    # Dear PyGui setup\n    # -----------------------------------------------------------------------\n    dpg.create_context()\n\n    def cb_file_selected(sender, app_data):\n        path = app_data.get('file_path_name', '')\n        if path:\n            args.script = path\n            dpg.set_value(\"script_path\", path)\n\n    with dpg.file_dialog(\n            directory_selector=False, show=False,\n            callback=cb_file_selected, tag=\"file_dialog\",\n            width=700, height=450,\n            default_path=os.path.dirname(args.script) if args.script else os.getcwd()):\n        dpg.add_file_extension(\".py\", color=(100, 255, 100, 255))\n        dpg.add_file_extension(\".*\",  color=(255, 255, 255, 255))\n\n    # Placeholder texture (mid-gray, matching canvas init value)\n    _ph = np.full(SENSOR_W * SENSOR_H * 4, 0.5, dtype=np.float32)\n    _ph[3::4] = 1.0\n    with dpg.texture_registry(tag=TEX_REG_TAG):\n        dpg.add_dynamic_texture(SENSOR_W, SENSOR_H, _ph, tag=TEXTURE_TAG)\n        _ph_freq = np.zeros(SENSOR_W * SENSOR_H * 4, dtype=np.float32)\n        _ph_freq[3::4] = 1.0\n        dpg.add_dynamic_texture(SENSOR_W, SENSOR_H, _ph_freq, tag=FREQ_TEX_TAG)\n    tex_wh = [SENSOR_W, SENSOR_H]\n\n    # ---- Connection callbacks ----------------------------------------------\n\n    def do_connect(port):\n        args.port = port\n        # Select cam script based on stream mode\n        script_dir = os.path.dirname(os.path.abspath(__file__))\n        with state_lock:\n            raw_mode = state['stream_mode'] == 'Raw (fastest)'\n        cam_script = os.path.join(\n            script_dir,\n            'genx320_raw_event_mode_streaming_on_cam.py' if raw_mode\n            else 'genx320_event_mode_streaming_on_cam.py',\n        )\n        args.script = cam_script\n        dpg.set_value(\"script_path\", cam_script)\n        last_freq_rgba[0] = None\n        reset_evt.set()   # processing_worker will reset filter/canvas on startup\n        stop_evt         = threading.Event()\n        conn['stop_evt'] = stop_evt\n\n        cam_t = threading.Thread(\n            target=camera_worker,\n            args=(args, state_lock, state, raw_q, stop_evt),\n            daemon=True,\n        )\n        proc_t = threading.Thread(\n            target=processing_worker,\n            args=(state_lock, state, raw_q, result_q, stop_evt,\n                  fc_L2, fc_L1, fc_p1, fc_t_ud, fc_t_du, fc_per,\n                  fc_coeffs, fc_t_now, reset_evt),\n            daemon=True,\n        )\n        cam_t.start()\n        proc_t.start()\n        conn['cam_thread']  = cam_t\n        conn['proc_thread'] = proc_t\n        dpg.configure_item(\"connect_btn\", label=\"Disconnect\")\n        _set_cam_settings_enabled(False)\n        logging.info(f\"Connecting to {port}...\")\n\n    def do_disconnect():\n        if conn['stop_evt']:\n            conn['stop_evt'].set()\n        conn['cam_thread']  = None\n        conn['proc_thread'] = None\n        conn['stop_evt']    = None\n        dpg.configure_item(\"connect_btn\", label=\"Connect\")\n        _set_cam_settings_enabled(True)\n\n    CAM_SETTING_TAGS = [\"stream_mode_combo\", \"csi_fifo_input\", \"evt_fifo_input\"]\n\n    def _set_cam_settings_enabled(enabled):\n        for tag in CAM_SETTING_TAGS:\n            dpg.configure_item(tag, enabled=enabled)\n        # Swap combo ↔ readonly text — DearPyGui clears combo preview on disable\n        if enabled:\n            dpg.show_item(\"evt_res_combo\")\n            dpg.hide_item(\"evt_res_display\")\n        else:\n            with state_lock:\n                val = str(state['evt_res'])\n            dpg.set_value(\"evt_res_display\", val)\n            dpg.hide_item(\"evt_res_combo\")\n            dpg.show_item(\"evt_res_display\")\n\n    def cb_refresh(s, v, u=None):\n        items = list_com_ports()\n        dpg.configure_item(\"port_combo\", items=items)\n        if items and not dpg.get_value(\"port_combo\"):\n            dpg.set_value(\"port_combo\", items[0])\n\n    def cb_connect(s, v, u=None):\n        if conn['cam_thread'] and conn['cam_thread'].is_alive():\n            do_disconnect()\n        else:\n            if not args.script:\n                return\n            port = dpg.get_value(\"port_combo\")\n            if not port:\n                return\n            do_connect(port)\n\n    # ---- Camera settings callbacks (applied at connect time) ---------------\n\n    STREAM_MODES = ['Raw (fastest)', 'Processed']\n\n    def cb_stream_mode(s, v, u=None):\n        with state_lock:\n            state['stream_mode'] = v\n        raw = v == 'Raw (fastest)'\n        # EVT FIFO only applies to the processed cam script\n        (dpg.hide_item if raw else dpg.show_item)(\"evt_fifo_row\")\n\n    def cb_csi_fifo(s, v, u=None):\n        with state_lock:\n            state['csi_fifo_depth'] = max(4, v)\n\n    def cb_evt_fifo(s, v, u=None):\n        with state_lock:\n            state['evt_fifo_depth'] = max(4, v)\n\n    def cb_evt_res(s, v, u=None):\n        with state_lock:\n            state['evt_res'] = int(v)\n\n    # ---- Visualization callbacks -------------------------------------------\n\n    # Per-mode window memory: remembered independently so switching back restores last value\n    window_by_mode = {'Sliding Window': 4, 'Canvas': 0}\n\n    def _sync_window_ui(window_val, mode):\n        \"\"\"Update window input value/min and show Clear button only for Canvas+0.\"\"\"\n        dpg.configure_item(\"window_input\", min_value=(0 if mode == 'Canvas' else 1))\n        dpg.set_value(\"window_input\", window_val)\n        show_clear = (mode == 'Canvas' and window_val == 0)\n        (dpg.show_item if show_clear else dpg.hide_item)(\"clear_btn\")\n\n    def cb_clear(s=None, v=None, u=None):\n        with state_lock:\n            state['clear'] = True\n\n    def cb_contrast(s, v, u=None):\n        with state_lock:\n            state['contrast'] = v\n\n    def cb_color_mode(s, v, u=None):\n        with state_lock:\n            state['color_mode'] = v\n\n    def cb_mode(s, v, u=None):\n        # Save current window value for the old mode, restore for the new mode\n        with state_lock:\n            old_mode = state['mode']\n            window_by_mode[old_mode] = state['window']\n            w = window_by_mode[v]\n            state['mode']   = v\n            state['window'] = w\n            state['clear']  = True\n        _sync_window_ui(w, v)\n\n    def cb_window(s, v, u=None):\n        with state_lock:\n            state['window'] = v\n            mode = state['mode']\n            window_by_mode[mode] = v\n        _sync_window_ui(v, mode)\n\n    def cb_save(s=None, v=None, u=None):\n        img      = last_canvas_u8[0]\n        freq_img = last_freq_rgba[0]\n        if img is None:\n            return\n        with state_lock:\n            color_mode   = state['color_mode']\n            legend_show  = state['fc_legend_show']\n            legend_bins  = state['fc_legend_bins']\n            fc_min       = state['fc_min_freq']\n            fc_max       = state['fc_max_freq']\n            fc_log_freq  = state['fc_log_freq']\n        ts   = int(time.time())\n        base = f\"events_{ts}\"\n\n        if not _PIL_AVAILABLE:\n            logging.warning(\"pip install Pillow to enable image saving\")\n            return\n\n        try:\n            # Save event canvas image\n            if color_mode == \"Grayscale\":\n                pil_evt = Image.fromarray(img, 'L')\n            else:\n                rgb = (EVT_DARK_RGB if color_mode == \"Evt Dark\" else EVT_LIGHT_RGB)[img]\n                pil_evt = Image.fromarray(rgb, 'RGB')\n            pil_evt.save(f\"{base}_evt.png\")\n            logging.info(f\"Saved {base}_evt.png\")\n\n            # Save frequency image, compositing legend onto the right if enabled\n            if freq_img is not None:\n                freq_u8  = (np.clip(freq_img[:, :, :3], 0.0, 1.0) * 255).astype(np.uint8)\n                pil_freq = Image.fromarray(freq_u8, 'RGB')\n                if legend_show:\n                    legend_pil = _make_freq_legend_pil(\n                        SENSOR_H, fc_min, fc_max, fc_log_freq, legend_bins)\n                    combined = Image.new('RGB', (SENSOR_W + LEGEND_DW, SENSOR_H))\n                    combined.paste(pil_freq,   (0,        0))\n                    combined.paste(legend_pil, (SENSOR_W, 0))\n                    combined.save(f\"{base}_freq.png\")\n                else:\n                    pil_freq.save(f\"{base}_freq.png\")\n                logging.info(f\"Saved {base}_freq.png\")\n\n        except Exception as e:\n            logging.warning(f\"Failed to save images: {e}\")\n\n        # Save raw events as CSV\n        batches = list(event_buf)\n        if batches:\n            all_events = np.concatenate(batches, axis=0)\n            csv_path   = f\"{base}.csv\"\n            np.savetxt(\n                csv_path, all_events,\n                delimiter=',', fmt='%d',\n                header='type,sec,ms,us,x,y', comments='',\n            )\n            logging.info(f\"Saved {csv_path}  ({len(all_events):,} events)\")\n\n    # ---- Frequency camera callbacks ----------------------------------------\n\n    def cb_fc_enabled(s, v, u=None):\n        with state_lock:\n            state['fc_enabled'] = v\n        fc_enabled_ref[0] = v\n        dpg.configure_item(\"fc_controls\", show=v)\n        for tag in (\"freq_img_h\", \"freq_img_v\", \"freq_legend_h\", \"freq_legend_v\"):\n            (dpg.show_item if v else dpg.hide_item)(tag)\n        if not v:\n            last_freq_rgba[0] = None\n        dpg.configure_item(\"save_btn\",\n                           label=\"Save Images and Events\" if v else \"Save Image and Events\")\n        fit_image()\n\n    def cb_fc_cutoff(s, v, u=None):\n        with state_lock:\n            state['fc_cutoff_period'] = v\n        fc_coeffs[:] = list(_freq_filter_coeffs(v))\n\n    def cb_fc_min_freq(s, v, u=None):\n        with state_lock:\n            state['fc_min_freq'] = max(v, 0.01)\n        legend_redraw_needed[0] = True\n\n    def cb_fc_max_freq(s, v, u=None):\n        with state_lock:\n            state['fc_max_freq'] = max(v, 1.0)\n        legend_redraw_needed[0] = True\n\n    def cb_fc_n_timeout(s, v, u=None):\n        with state_lock:\n            state['fc_n_timeout'] = max(v, 1)\n\n\n    def cb_fc_log_freq(s, v, u=None):\n        with state_lock:\n            state['fc_log_freq'] = v\n        legend_redraw_needed[0] = True\n\n    def cb_fc_overlay(s, v, u=None):\n        with state_lock:\n            state['fc_overlay'] = v\n\n    def cb_fc_legend_bins(s, v, u=None):\n        with state_lock:\n            state['fc_legend_bins'] = max(v, 2)\n        legend_redraw_needed[0] = True\n\n    def cb_fc_legend_show(s, v, u=None):\n        with state_lock:\n            state['fc_legend_show'] = v\n        fc_legend_show_ref[0] = v\n        dpg.configure_item(\"freq_legend_h\", show=v)\n        dpg.configure_item(\"freq_legend_v\", show=v)\n        legend_redraw_needed[0] = True\n        fit_image()\n\n    def cb_fc_reset(s=None, v=None, u=None):\n        reset_evt.set()   # processing_worker handles the actual reset safely\n\n    # ---- UI layout ---------------------------------------------------------\n\n    with dpg.window(tag=\"main_win\", no_scrollbar=True, no_title_bar=True):\n        with dpg.table(\n            header_row=False, resizable=True,\n            borders_innerV=True, tag=\"layout_table\",\n            scrollX=False, scrollY=False,\n        ):\n            dpg.add_table_column(init_width_or_weight=1.0)\n            dpg.add_table_column(init_width_or_weight=CTRL_WIDTH, width_fixed=True)\n\n            with dpg.table_row():\n\n                # ── Left: event canvas ─────────────────────────────────────\n                with dpg.table_cell():\n                    # Horizontal layout (side by side)\n                    with dpg.group(horizontal=True, tag=\"images_horiz\"):\n                        dpg.add_image(TEXTURE_TAG,  tag=\"evt_img_h\",\n                                      width=SENSOR_W, height=SENSOR_H)\n                        dpg.add_image(FREQ_TEX_TAG, tag=\"freq_img_h\",\n                                      width=SENSOR_W, height=SENSOR_H)\n                        dpg.add_drawlist(tag=\"freq_legend_h\",\n                                         width=LEGEND_DW, height=SENSOR_H)\n                    # Vertical layout (stacked), hidden initially\n                    with dpg.group(tag=\"images_vert\", show=False):\n                        dpg.add_image(TEXTURE_TAG,  tag=\"evt_img_v\",\n                                      width=SENSOR_W, height=SENSOR_H)\n                        with dpg.group(horizontal=True):\n                            dpg.add_image(FREQ_TEX_TAG, tag=\"freq_img_v\",\n                                          width=SENSOR_W, height=SENSOR_H)\n                            dpg.add_drawlist(tag=\"freq_legend_v\",\n                                             width=LEGEND_DW, height=SENSOR_H)\n\n                # ── Right: controls ─────────────────────────────────────────\n                with dpg.table_cell():\n                    with dpg.child_window(width=CTRL_WIDTH, border=False):\n\n                        # ── Windows performance warning ──────────────────────\n                        if sys.platform == 'win32':\n                            dpg.add_text(\n                                \"Warning: Windows reduces transfer speed.\\n\"\n                                \"Use macOS or Linux for best performance.\",\n                                color=(255, 200, 0, 255))\n                            dpg.add_separator()\n\n                        # ── Connection ──────────────────────────────────────\n                        with dpg.group():\n                            with dpg.group(horizontal=True):\n                                dpg.add_text(\"Script\")\n                                dpg.add_input_text(\n                                    tag=\"script_path\",\n                                    default_value=args.script or \"\",\n                                    hint=\"select a .py script...\",\n                                    width=CTRL_WIDTH - 112, readonly=True)\n                                dpg.add_button(\n                                    label=\"...\", width=28,\n                                    callback=lambda: dpg.show_item(\"file_dialog\"))\n\n                            init_ports = list_com_ports()\n                            init_port  = args.port or (init_ports[0] if init_ports else \"\")\n                            with dpg.group(horizontal=True):\n                                dpg.add_text(\"Port  \")\n                                dpg.add_combo(\n                                    items=init_ports, default_value=init_port,\n                                    tag=\"port_combo\", width=CTRL_WIDTH - 112)\n                                dpg.add_button(label=\"Ref\", callback=cb_refresh, width=28)\n\n                        # ── Camera script parameters ────────────────────────\n                        dpg.add_separator()\n                        dpg.add_text(\"Camera Parameters  (applied at connect)\")\n\n                        with dpg.group(horizontal=True):\n                            dpg.add_text(\"Stream   \")\n                            dpg.add_combo(\n                                tag=\"stream_mode_combo\",\n                                items=STREAM_MODES,\n                                default_value=state['stream_mode'],\n                                callback=cb_stream_mode, width=-1)\n\n                        with dpg.group(horizontal=True):\n                            dpg.add_text(\"CSI FIFO \")\n                            dpg.add_input_int(\n                                tag=\"csi_fifo_input\", label=\"##csi_fifo\",\n                                default_value=state['csi_fifo_depth'],\n                                min_value=4, min_clamped=True,\n                                step=1, step_fast=4,\n                                callback=cb_csi_fifo, width=-1)\n\n                        with dpg.group(horizontal=True, tag=\"evt_fifo_row\", show=False):\n                            dpg.add_text(\"EVT FIFO \")\n                            dpg.add_input_int(\n                                tag=\"evt_fifo_input\", label=\"##evt_fifo\",\n                                default_value=state['evt_fifo_depth'],\n                                min_value=4, min_clamped=True,\n                                step=1, step_fast=4,\n                                callback=cb_evt_fifo, width=-1)\n\n                        with dpg.group(horizontal=True):\n                            dpg.add_text(\"EVT Buffer\")\n                            dpg.add_combo(\n                                tag=\"evt_res_combo\",\n                                items=[str(v) for v in EVT_RES_OPTIONS],\n                                default_value=str(state['evt_res']),\n                                callback=cb_evt_res, width=-1)\n                            dpg.add_input_text(\n                                tag=\"evt_res_display\",\n                                default_value=str(state['evt_res']),\n                                readonly=True, show=False, width=-1)\n\n                        dpg.add_separator()\n                        dpg.add_button(label=\"Connect\", tag=\"connect_btn\",\n                                       callback=cb_connect, width=-1)\n\n                        # ── Event Visualization ─────────────────────────────\n                        dpg.add_separator()\n                        dpg.add_text(\"Event Visualization\")\n\n                        with dpg.group(horizontal=True):\n                            dpg.add_text(\"Contrast \")\n                            dpg.add_input_int(\n                                label=\"##contrast\",\n                                default_value=state['contrast'],\n                                min_value=1, max_value=128,\n                                min_clamped=True, max_clamped=True,\n                                step=1, step_fast=8,\n                                callback=cb_contrast, width=-1)\n\n                        with dpg.group(horizontal=True):\n                            dpg.add_text(\"Color    \")\n                            dpg.add_combo(\n                                items=COLOR_MODES,\n                                default_value=state['color_mode'],\n                                tag=\"color_mode_combo\",\n                                callback=cb_color_mode,\n                                width=-1)\n\n                        with dpg.group(horizontal=True):\n                            dpg.add_text(\"Mode     \")\n                            dpg.add_combo(\n                                items=[\"Sliding Window\", \"Canvas\"],\n                                default_value=state['mode'],\n                                tag=\"mode_combo\",\n                                callback=cb_mode,\n                                width=-1)\n\n                        with dpg.group(horizontal=True):\n                            dpg.add_text(\"Window   \")\n                            dpg.add_input_int(\n                                tag=\"window_input\",\n                                label=\"##window\",\n                                default_value=state['window'],\n                                min_value=1,\n                                min_clamped=True,\n                                step=1, step_fast=10,\n                                callback=cb_window, width=-60)\n                            dpg.add_button(label=\"Clear\", tag=\"clear_btn\",\n                                           callback=cb_clear, width=50, show=False)\n\n                        # ── Frequency Visualization ─────────────────────────\n                        with dpg.group(horizontal=True):\n                            dpg.add_checkbox(tag=\"fc_enabled_check\",\n                                             default_value=state['fc_enabled'],\n                                             callback=cb_fc_enabled)\n                            dpg.add_text(\"Frequency Visualization\")\n\n                        with dpg.group(tag=\"fc_controls\", show=state['fc_enabled']):\n                            with dpg.group(horizontal=True):\n                                dpg.add_text(\"Cutoff T \")\n                                dpg.add_input_float(\n                                    tag=\"fc_cutoff_input\", label=\"##fc_cutoff\",\n                                    default_value=state['fc_cutoff_period'],\n                                    min_value=1.0, min_clamped=True,\n                                    step=0.5, step_fast=5.0,\n                                    callback=cb_fc_cutoff, width=-1)\n\n                            with dpg.group(horizontal=True):\n                                dpg.add_text(\"Min Hz   \")\n                                dpg.add_input_float(\n                                    tag=\"fc_min_input\", label=\"##fc_min\",\n                                    default_value=state['fc_min_freq'],\n                                    min_value=0.01, min_clamped=True,\n                                    step=1.0, step_fast=10.0,\n                                    callback=cb_fc_min_freq, width=-1)\n\n                            with dpg.group(horizontal=True):\n                                dpg.add_text(\"Max Hz   \")\n                                dpg.add_input_float(\n                                    tag=\"fc_max_input\", label=\"##fc_max\",\n                                    default_value=state['fc_max_freq'],\n                                    min_value=1.0, min_clamped=True,\n                                    step=10.0, step_fast=100.0,\n                                    callback=cb_fc_max_freq, width=-1)\n\n                            with dpg.group(horizontal=True):\n                                dpg.add_text(\"Timeout  \")\n                                dpg.add_input_int(\n                                    tag=\"fc_timeout_input\", label=\"##fc_timeout\",\n                                    default_value=state['fc_n_timeout'],\n                                    min_value=1, min_clamped=True,\n                                    step=1,\n                                    callback=cb_fc_n_timeout, width=-60)\n                                dpg.add_button(label=\"Reset\", tag=\"fc_reset_btn\",\n                                               callback=cb_fc_reset, width=50)\n\n                            with dpg.group(horizontal=True):\n                                dpg.add_checkbox(tag=\"fc_log_check\",\n                                                 default_value=state['fc_log_freq'],\n                                                 callback=cb_fc_log_freq)\n                                dpg.add_text(\"Log frequency scale\")\n\n                            with dpg.group(horizontal=True):\n                                dpg.add_checkbox(tag=\"fc_overlay_check\",\n                                                 default_value=state['fc_overlay'],\n                                                 callback=cb_fc_overlay)\n                                dpg.add_text(\"Overlay active pixels\")\n\n                            with dpg.group(horizontal=True):\n                                dpg.add_checkbox(tag=\"fc_legend_check\",\n                                                 default_value=state['fc_legend_show'],\n                                                 callback=cb_fc_legend_show)\n                                dpg.add_text(\"Show legend\")\n\n                            with dpg.group(horizontal=True):\n                                dpg.add_text(\"Bins     \")\n                                dpg.add_input_int(\n                                    tag=\"fc_legend_bins_input\", label=\"##fc_legend_bins\",\n                                    default_value=state['fc_legend_bins'],\n                                    min_value=2, min_clamped=True,\n                                    step=1, step_fast=5,\n                                    callback=cb_fc_legend_bins, width=-1)\n\n                        # ── Save ────────────────────────────────────────────\n                        dpg.add_separator()\n                        dpg.add_button(label=\"Save Images and Events\",\n                                       tag=\"save_btn\", callback=cb_save, width=-1)\n\n                        # ── Stats ───────────────────────────────────────────\n                        dpg.add_separator()\n                        dpg.add_text(\"Statistics\")\n                        with dpg.table(header_row=False, borders_innerV=False,\n                                       policy=dpg.mvTable_SizingFixedFit):\n                            dpg.add_table_column(init_width_or_weight=95,  width_fixed=True)\n                            dpg.add_table_column(init_width_or_weight=150, width_fixed=True)\n                            for lbl, tag in [\n                                (\"Events/batch\", \"stat_ev_batch\"),\n                                (\"Rate\",         \"stat_rate\"),\n                                (\"Bandwidth\",    \"stat_bw\"),\n                                (\"Total events\", \"stat_total\"),\n                                (\"Uptime\",       \"stat_uptime\"),\n                            ]:\n                                with dpg.table_row():\n                                    dpg.add_text(lbl)\n                                    dpg.add_text(\"—\", tag=tag)\n\n\n    dpg.create_viewport(title=\"GenX320 Event Viewer\",\n                        width=1280, height=800, resizable=True)\n    dpg.setup_dearpygui()\n    dpg.show_viewport()\n    dpg.set_primary_window(\"main_win\", True)\n\n    def handle_exit(signum, frame):\n        if conn['stop_evt']:\n            conn['stop_evt'].set()\n        dpg.stop_dearpygui()\n\n    signal.signal(signal.SIGINT,  handle_exit)\n    signal.signal(signal.SIGTERM, handle_exit)\n\n    if args.port and args.script:\n        do_connect(args.port)\n\n    # Apply initial UI state (default mode is Sliding Window, so C button stays hidden)\n    _sync_window_ui(state['window'], state['mode'])\n\n    disp_wh = [0, 0, None]   # [dw, dh, layout ('h' or 'v')]\n\n    def fit_image():\n        fw, fh = tex_wh\n        if fw <= 0 or fh <= 0:\n            return\n        fc_en     = fc_enabled_ref[0]\n        legend_dw = (LEGEND_DW if fc_legend_show_ref[0] else 0) if fc_en else 0\n        n_images  = 2 if fc_en else 1\n        avail_w = max(dpg.get_viewport_width()  - CTRL_WIDTH - 30 - legend_dw, 1)\n        avail_h = max(dpg.get_viewport_height() - 60, 1)\n\n        # Scale for each arrangement; pick whichever makes images larger\n        scale_h = min(avail_w / (n_images * fw), avail_h / fh)           # side by side\n        scale_v = min(avail_w / fw,               avail_h / (n_images * fh))  # stacked\n\n        if scale_h >= scale_v:\n            layout = 'h'\n            scale  = scale_h\n        else:\n            layout = 'v'\n            scale  = scale_v\n\n        dw, dh = max(int(fw * scale), 1), max(int(fh * scale), 1)\n        if [dw, dh, layout] != disp_wh:\n            disp_wh[0], disp_wh[1], disp_wh[2] = dw, dh, layout\n            if layout == 'h':\n                dpg.show_item(\"images_horiz\")\n                dpg.hide_item(\"images_vert\")\n                dpg.configure_item(\"evt_img_h\",  width=dw, height=dh)\n                dpg.configure_item(\"freq_img_h\", width=dw, height=dh)\n            else:\n                dpg.hide_item(\"images_horiz\")\n                dpg.show_item(\"images_vert\")\n                dpg.configure_item(\"evt_img_v\",  width=dw, height=dh)\n                dpg.configure_item(\"freq_img_v\", width=dw, height=dh)\n            # Resize both drawlists so the active one is correct on next redraw\n            dpg.configure_item(\"freq_legend_h\", height=dh)\n            dpg.configure_item(\"freq_legend_v\", height=dh)\n            legend_redraw_needed[0] = True\n\n    dpg.set_viewport_resize_callback(lambda: fit_image())\n    fit_image()\n\n    # -----------------------------------------------------------------------\n    # Render loop  (drawing thread — texture uploads and GUI only)\n    # -----------------------------------------------------------------------\n    last_stat_update = 0.0\n\n    while dpg.is_dearpygui_running():\n\n        # Detect camera thread death (e.g. unplugged)\n        t = conn['cam_thread']\n        if t is not None and not t.is_alive():\n            conn['cam_thread']  = None\n            conn['proc_thread'] = None\n            conn['stop_evt']    = None\n            dpg.configure_item(\"connect_btn\", label=\"Connect\")\n            _set_cam_settings_enabled(True)\n\n        # Snapshot visualization parameters (needed for texture conversion + legend)\n        with state_lock:\n            color_mode       = state['color_mode']\n            fc_enabled       = state['fc_enabled']\n            fc_min           = state['fc_min_freq']\n            fc_max           = state['fc_max_freq']\n            fc_n_to          = state['fc_n_timeout']\n            fc_log_freq      = state['fc_log_freq']\n            fc_overlay       = state['fc_overlay']\n            fc_legend_show   = state['fc_legend_show']\n            fc_legend_bins   = state['fc_legend_bins']\n\n        # Drain all available processed results; keep the latest\n        got_result   = False\n        result_latest = None\n        try:\n            while True:\n                result_latest = result_q.get_nowait()\n                got_result = True\n        except queue.Empty:\n            pass\n\n        if got_result and result_latest is not None:\n            r = result_latest\n            canvas_u8 = r['canvas_u8']\n            last_canvas_u8[0] = canvas_u8\n            event_buf.clear()\n            event_buf.extend(r['event_buf'])\n\n            tex_data = _canvas_to_texture(canvas_u8, color_mode)\n            dpg.set_value(TEXTURE_TAG, tex_data)\n\n            if fc_enabled and r['fc_enabled']:\n                freq_tex = _freq_to_texture(\n                    r['fc_per'], r['fc_t_ud'], r['fc_t_du'], r['fc_t_now'],\n                    fc_n_to, fc_min, fc_max,\n                    use_log=fc_log_freq, overlay_events=fc_overlay)\n                last_freq_rgba[0] = freq_tex.reshape(SENSOR_H, SENSOR_W, 4)\n                dpg.set_value(FREQ_TEX_TAG, freq_tex)\n\n            now = time.perf_counter()\n            if now - last_stat_update >= 0.2:\n                last_stat_update = now\n                s = r['stats']\n                dpg.set_value(\"stat_ev_batch\", f\"{s['event_count']:,}\")\n                dpg.set_value(\"stat_rate\",     f\"{s['event_rate']:,.0f} ev/s\")\n                dpg.set_value(\"stat_bw\",       f\"{s['mbps']:.2f} MB/s\")\n                dpg.set_value(\"stat_total\",    f\"{s['total_events']:,}\")\n                dpg.set_value(\"stat_uptime\",   f\"{s['elapsed']:.1f} s\")\n\n        # Redraw legend only when parameters changed, not every frame\n        if legend_redraw_needed[0]:\n            if fc_legend_show:\n                legend_dh = max(disp_wh[1], 1)\n                _draw_freq_legend(\"freq_legend_h\", legend_dh,\n                                  fc_min, fc_max, fc_log_freq, fc_legend_bins)\n                _draw_freq_legend(\"freq_legend_v\", legend_dh,\n                                  fc_min, fc_max, fc_log_freq, fc_legend_bins)\n            legend_redraw_needed[0] = False\n\n        # Reset UI if the camera thread died unexpectedly (e.g. connection error)\n        if conn['cam_thread'] and not conn['cam_thread'].is_alive():\n            do_disconnect()\n\n        dpg.render_dearpygui_frame()\n\n    dpg.destroy_context()\n\n\nif __name__ == '__main__':\n    _args = parse_args()\n    if _args.benchmark:\n        run_benchmark(_args)\n    else:\n        main(_args)\n"
  },
  {
    "path": "tools/genx320-event-streaming/genx320_raw_event_mode_streaming_on_cam.py",
    "content": "# This work is licensed under the MIT license.\n# Copyright (c) 2013-2026 OpenMV LLC. All rights reserved.\n# https://github.com/openmv/openmv/blob/master/LICENSE\n#\n# This example shows off using the genx320 raw event camera from Prophesee\n# using event streaming mode and sending the data back to the PC.\n#\n# This script is meant to be run using https://github.com/openmv/openmv-python\n# from a PC using desktop tools. No visualization or text output is generated\n# by this script for OpenMV IDE.\n#\n# Raw EVT 2.0 format\n# ------------------\n# Each event is a 32-bit little-endian word. The firmware streams these words\n# directly from the sensor without any decoding.\n#\n# Bit layout of each 32-bit word:\n#\n#   Bits [31:28]  type  (4 bits)  — event type:\n#       0x0  TD_LOW       Pixel event — decrease in illumination (negative polarity)\n#       0x1  TD_HIGH      Pixel event — increase in illumination (positive polarity)\n#       0x8  EV_TIME_HIGH Upper 28 bits of the microsecond timestamp counter\n#       0xA  EXT_TRIGGER  External trigger event\n#       0xE  OTHERS       Reserved for future extension\n#       0xF  CONTINUED    Extra data appended to the previous event\n#\n# TD_LOW / TD_HIGH pixel event (type == 0x0 or 0x1):\n#   Bits [27:22]  ts   (6 bits)  — timestamp low, microseconds (0–63 µs)\n#   Bits [21:11]  x    (11 bits) — pixel column  (0–319 for GenX320)\n#   Bits [10:0]   y    (11 bits) — pixel row     (0–319 for GenX320)\n#\n#   Decoding:\n#       type = (word >> 28) & 0xF\n#       ts   = (word >> 22) & 0x3F\n#       x    = (word >> 11) & 0x7FF\n#       y    = (word      ) & 0x7FF\n#       t_us = time_high | ts          # full microsecond timestamp\n#       polarity = type                # 0 = negative, 1 = positive\n#\n# EV_TIME_HIGH (type == 0x8):\n#   Bits [27:0]  time_high (28 bits) — upper bits of timestamp counter\n#\n#   Decoding:\n#       time_high = (word & 0x0FFFFFFF) << 6   # units: microseconds\n#\n#   Must be tracked across the stream. Combine with ts from pixel events:\n#       t_us = time_high | ts\n#\n#   Split into seconds / milliseconds / microseconds:\n#       ts_s  = t_us // 1_000_000\n#       ts_ms = (t_us // 1_000) % 1_000\n#       ts_us = t_us % 1_000\n#\n# EXT_TRIGGER (type == 0xA):\n#   Bits [27:22]  ts         (6 bits)  — timestamp low, microseconds\n#   Bits [12:8]   trigger_id (5 bits)  — trigger channel ID\n#   Bit  [0]      polarity   (1 bit)   — 0 = falling, 1 = rising\n#\n#   Decoding:\n#       ts         = (word >> 22) & 0x3F\n#       trigger_id = (word >>  8) & 0x1F\n#       polarity   = (word      ) & 0x1\n#       t_us       = time_high | ts\n#\n# Parsing pseudocode (Python):\n#\n#   time_high = 0\n#   for word in struct.unpack_from('<' + 'I' * n, buf):\n#       event_type = (word >> 28) & 0xF\n#       if event_type == 0x8:                        # EV_TIME_HIGH\n#           time_high = (word & 0x0FFFFFFF) << 6\n#       elif event_type in (0x0, 0x1):               # TD pixel event\n#           ts   = (word >> 22) & 0x3F\n#           x    = (word >> 11) & 0x7FF\n#           y    = (word      ) & 0x7FF\n#           t_us = time_high | ts\n#           pol  = event_type                        # 0=neg, 1=pos\n\nimport csi\nimport protocol\n\n# Event buffers arrive from the camera and are stored in\n# a fifo buffer before being processed by python.\nCSI_FIFO_DEPTH = 8\n\n# Must be a power of two between 1024 and 65536.\nEVT_RES = 8192\n\n# Initialize the sensor.\ncsi0 = csi.CSI(cid=csi.GENX320)\ncsi0.reset()\ncsi0.ioctl(csi.IOCTL_GENX320_SET_MODE, csi.GENX320_MODE_EVENT, EVT_RES)\ncsi0.framebuffers(CSI_FIFO_DEPTH)\n\n# Grab pointer to the internal FIFO buffer.\nevents = csi0.ioctl(csi.IOCTL_GENX320_READ_EVENTS_RAW)\nevents_mv = memoryview(events.bytearray())\nframe_available = True\n\n\nclass RawEventChannel:\n\n    def size(self):\n        return len(events_mv)\n\n    def shape(self):\n        return (len(events_mv), 1)\n\n    def read(self, offset, size):\n        global frame_available\n        if frame_available:\n            end = offset + size\n            mv = events_mv[offset:end]\n            if end == len(events_mv):\n                frame_available = False\n            return mv\n        return bytes(size)\n\n    def poll(self):\n        return frame_available\n\n\nprotocol.register(name='raw_events', backend=RawEventChannel())\n\nwhile True:\n    if not frame_available:\n        events = csi0.ioctl(csi.IOCTL_GENX320_READ_EVENTS_RAW)\n        events_mv = memoryview(events.bytearray())\n        frame_available = True\n"
  },
  {
    "path": "tools/genx320-overlay-calibration/README.md",
    "content": "# GenX320 Overlay Calibration\n\nA PC-side GUI that streams a color frame and a 320×320 grayscale histogram frame from the GenX320 event camera simultaneously, displays them side by side, and composites them into a calibrated overlay. A homography computed from point correspondences aligns the GenX320 onto the main camera's coordinate space for a pixel-accurate overlay.\n\n![GenX320 Overlay Calibration GUI](genx320_overlay_calibration.jpeg)\n\n## Platform Notes\n\nmacOS and Linux are recommended for the best GUI performance and throughput. On Windows, DearPyGui rendering can be noticeably slower, which may reduce frame rates. The camera script and serial protocol work on all platforms, but if you experience a sluggish UI or low frame rate, consider switching to a Mac or Linux machine.\n\nOn macOS and Linux the companion script's `read` method is automatically renamed to `readp` before execution (this is handled transparently by the PC script).\n\nCRC is disabled by default on macOS and Linux for better USB throughput. It is enabled by default on Windows where it improves reliability. Override with `--crc`.\n\n## Prerequisites\n\n1. **OpenMV IDE** v4.8.4 or later.\n2. **OpenMV Cam Firmware** v5.0.0 or later.\n3. **Python dependencies:**\n\n```\npip install dearpygui numpy pyserial Pillow openmv\n```\n\nOptionally install OpenCV for automatic checkerboard detection and better warp quality:\n\n```\npip install opencv-python\n```\n\nWithout OpenCV, the composite falls back to PIL bilinear resize and automatic alignment is unavailable.\n\n## Running\n\n```\npython genx320_overlay_calibration_on_pc.py\n```\n\nThe companion camera script (`genx320_overlay_calibration_on_cam.py`) is loaded automatically from the same folder. You can override any option from the command line:\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--port PORT` | *(GUI selector)* | Serial port to connect on |\n| `--script PATH` | `genx320_overlay_calibration_on_cam.py` | MicroPython script to run on the camera |\n| `--baudrate N` | `921600` | Serial baud rate |\n| `--crc` | off (Linux/Mac), on (Windows) | Enable CRC on the serial protocol |\n| `--quiet` | off | Suppress camera stdout |\n| `--debug` | off | Enable verbose logging |\n| `--benchmark` | off | Headless throughput benchmark (no GUI) |\n\n## Benchmark Mode\n\nRun without the GUI to measure raw USB throughput:\n\n```\npython genx320_overlay_calibration_on_pc.py --benchmark\npython genx320_overlay_calibration_on_pc.py --benchmark --port /dev/ttyACM0\n```\n\nPrints at 10 Hz:\n\n```\nelapsed=3.2s    fps=9.1    bw=1.24 MB/s    frames=29\n```\n\nPress **Ctrl+C** to stop.\n\n## GUI Overview\n\nThe window has two panes: a **left image area** and a **right control panel**.\n\n### Image Area\n\n- **Top row** — main color camera (left) and GenX320 histogram (right), each scaled to occupy half the available width at the same display height.\n- **Bottom** — composite image: the GenX320 frame warped and blended onto the main frame. Without a homography the GenX320 is stretched to fill. With a homography it is perspective-warped to align. The composite is horizontally centered.\n\nAll images resize automatically when the window is resized.\n\n### Camera Parameters *(applied at connect)*\n\nThese patch the on-camera script before it is executed. They are locked while connected.\n\n| Control | Default | Description |\n|---------|---------|-------------|\n| Main Res | VGA (640×480) | Main camera resolution: QVGA, VGA, or HD |\n| Main Fmt | RGB565 | Main camera pixel format: RGB565 or GRAYSCALE |\n\nThe GenX320 always outputs 320×320 grayscale in histogram mode — no additional controls are needed.\n\n### Overlay Alpha\n\nA slider from 0% to 100% controlling how much of the GenX320 frame is blended over the main frame in the composite. Defaults to 50%.\n\n### Calibration Pattern\n\nOpens a separate window displaying a flickering checkerboard (alternating between blank and checkerboard). Since event cameras only generate output in response to brightness changes, the flicker provides continuous edge events without requiring any physical movement. Configure **Cols**, **Rows**, and **Hz** to control the pattern, then click **Show Calibration Pattern**. Point the screen at both cameras. The pattern window is available regardless of alignment mode.\n\n### Overlay Alignment\n\nComputes a homography (perspective warp) that maps GenX320 pixel coordinates to main camera pixel coordinates for a geometrically correct overlay.\n\n#### Manual Mode\n\nClick **Pick Main Points**, then click 4 landmark points on the main camera image. Click **Pick GenX320 Points**, then click the same 4 landmarks in the same order on the GenX320 image. The homography is computed automatically once all 8 points are set. Numbered circles (1-4) are drawn on each image as you click to track progress.\n\n> **Tip:** Spread the 4 points across the full frame for the most accurate warp. Avoid clustering all points in one region.\n\n#### Automatic Mode\n\nClick **Auto Detect** while a checkerboard is visible to both cameras. The detector tries up to 10 times with fresh frames, so the flickering pattern can produce different event snapshots across attempts.\n\nThe detector uses a blob-grid algorithm designed for event camera images: heavy median filtering removes event noise, Otsu thresholding binarizes the image, and contour detection finds the dark-square centroids. These are organized into a grid by clustering Y coordinates, and inner corner points are computed from 2x2 blocks of adjacent blob centers. The same algorithm runs on both the GenX320 and main camera images to ensure point correspondence, and a RANSAC homography is computed from all matched corners.\n\nThe grid size is detected automatically -- no manual corner count is needed. The status line reports the number of inliers after detection.\n\n#### Shared Controls\n\n- **Reset Homography** -- clears all points and the transform.\n- **transform =** -- read-only copyable text box showing the computed 3x3 perspective matrix, ready to paste into firmware or a processing script.\n\n### Save Images\n\nSaves the current frames and transform to disk. The button label changes to **Save Images + Transform** once a homography has been computed.\n\n- `genx320_overlay_main_<timestamp>.png` — main camera frame (RGB).\n- `genx320_overlay_genx320_<timestamp>.png` — GenX320 histogram frame.\n- `genx320_overlay_composite_<timestamp>.png` — composited overlay image.\n- `genx320_overlay_transform_<timestamp>.txt` — the 3×3 homography matrix.\n\nThese files are excluded from git via `.gitignore`.\n\n### Statistics\n\n| Field | Description |\n|-------|-------------|\n| FPS | Frame pair rate (EMA) |\n| Bandwidth | Combined USB data rate (MB/s, EMA) |\n| Total frames | Cumulative frame pairs since connect |\n| Uptime | Seconds since connect |\n"
  },
  {
    "path": "tools/genx320-overlay-calibration/genx320_overlay_calibration_on_cam.py",
    "content": "# This work is licensed under the MIT license.\n# Copyright (c) 2013-2026 OpenMV LLC. All rights reserved.\n# https://github.com/openmv/openmv/blob/master/LICENSE\n#\n# This script pulls color and event images from the camera.\n#\n# This script is meant to be run using https://github.com/openmv/openmv-python\n# from a PC using desktop tools. No visualization or text output is generated\n# by this script for OpenMV IDE.\n\nimport csi\nimport protocol\nimport json\n\nMAIN_PIXFORMAT = csi.RGB565\nMAIN_FRAME_SIZE = csi.VGA\n\n# Initialize the main camera.\ncsi0 = csi.CSI()\ncsi0.reset(hard=True)\ncsi0.pixformat(MAIN_PIXFORMAT)\ncsi0.framesize(MAIN_FRAME_SIZE)\ncsi0_img = csi0.snapshot()\ncsi0_img_mv = memoryview(csi0_img.bytearray())\ncsi0_frame_available = True\n\n# Parse image info from string representation.\ncsi0_img_info = json.loads(str(csi0_img))\ncsi0_img_width = csi0_img_info['w']\ncsi0_img_height = csi0_img_info['h']\ncsi0_img_size = csi0_img_info['size']\n\n# Initialize the GenX320 in histogram mode — outputs 320x320 grayscale.\ncsi1 = csi.CSI(cid=csi.GENX320)\ncsi1.reset(hard=False)\ncsi1.pixformat(csi.GRAYSCALE)\ncsi1.framesize((320, 320))\ncsi1.brightness(128)\ncsi1.contrast(64)\ncsi1_img = csi1.snapshot()\ncsi1_img_mv = memoryview(csi1_img.bytearray())\ncsi1_frame_available = True\n\n# Parse image info from string representation.\ncsi1_img_info = json.loads(str(csi1_img))\ncsi1_img_width = csi1_img_info['w']\ncsi1_img_height = csi1_img_info['h']\ncsi1_img_size = csi1_img_info['size']\n\n\nclass MainChannel:\n    def size(self):\n        return csi0_img_size\n\n    def shape(self):\n        return (csi0_img_height, csi0_img_width, csi0_img_size)\n\n    def read(self, offset, size):\n        global csi0_frame_available\n\n        if csi0_frame_available:\n            end = offset + size\n            mv = csi0_img_mv[offset:end]\n            if end == csi0_img_size:\n                csi0_frame_available = False\n            return mv\n        return bytes(size)\n\n    def poll(self):\n        return csi0_frame_available\n\n\nclass GenX320Channel:\n    def size(self):\n        return csi1_img_size\n\n    def shape(self):\n        return (csi1_img_height, csi1_img_width, csi1_img_size)\n\n    def read(self, offset, size):\n        global csi1_frame_available\n\n        if csi1_frame_available:\n            end = offset + size\n            mv = csi1_img_mv[offset:end]\n            if end == csi1_img_size:\n                csi1_frame_available = False\n            return mv\n        return bytes(size)\n\n    def poll(self):\n        return csi1_frame_available\n\n\nprotocol.register(name='main',    backend=MainChannel())\nprotocol.register(name='genx320', backend=GenX320Channel())\n\nwhile True:\n    if not csi0_frame_available:\n        csi0_img = csi0.snapshot()\n        csi0_img_mv = memoryview(csi0_img.bytearray())\n        csi0_frame_available = True\n\n    if not csi1_frame_available:\n        csi1_img = csi1.snapshot()\n        csi1_img_mv = memoryview(csi1_img.bytearray())\n        csi1_frame_available = True\n"
  },
  {
    "path": "tools/genx320-overlay-calibration/genx320_overlay_calibration_on_pc.py",
    "content": "#!/usr/bin/env python3\n#\n# This work is licensed under the MIT license.\n# Copyright (c) 2013-2026 OpenMV LLC. All rights reserved.\n# https://github.com/openmv/openmv/blob/master/LICENSE\n#\n# GenX320 overlay calibration GUI for OpenMV cameras on PC.\n# Requires: pip install dearpygui numpy pyserial Pillow openmv\n#\n# Streams RGB565/Grayscale frames from the main camera and 320x320 grayscale\n# histogram frames from the GenX320 event camera simultaneously, displays them\n# side by side, and composites them into a third image below. A homography\n# computed from point correspondences aligns the GenX320 onto the main camera\n# frame for a pixel-accurate overlay.\n\nimport sys\nimport os\nimport argparse\nimport time\nimport logging\nimport signal\nimport threading\nimport queue\nimport numpy as np\ntry:\n    from PIL import Image\n    _PIL_AVAILABLE = True\nexcept ImportError:\n    _PIL_AVAILABLE = False\nimport serial.tools.list_ports\nimport dearpygui.dearpygui as dpg\nfrom openmv.camera import Camera\n\n\nCOLOR_CAMERA = \"\\033[32m\"\nCOLOR_RESET  = \"\\033[0m\"\n\nEMA_ALPHA  = 0.2\nCTRL_WIDTH = 320\n\n# Main camera resolution options (GenX320 is always 320x320 grayscale).\nMAIN_RES_OPTIONS = ['QVGA (320×240)', 'VGA (640×480)', 'HD (1280×720)']\nPIXFMT_OPTIONS   = ['RGB565', 'GRAYSCALE']\n\nMAIN_RES_MAP = {\n    'QVGA (320×240)': 'csi.QVGA',\n    'VGA (640×480)':  'csi.VGA',\n    'HD (1280×720)':  'csi.HD',\n}\nPIXFMT_MAP = {\n    'RGB565':    'csi.RGB565',\n    'GRAYSCALE': 'csi.GRAYSCALE',\n}\n\n# Tags\nMAIN_TEX_TAG   = \"main_tex\"\nGENX320_TEX_TAG = \"genx320_tex\"\nCOMP_TEX_TAG   = \"comp_tex\"\nTEX_REG_TAG    = \"tex_reg\"\n\n\n# ---------------------------------------------------------------------------\n# RGB565 → RGB888 conversion (vectorized)\n# ---------------------------------------------------------------------------\n\ndef rgb565_to_rgb888(data, w, h):\n    \"\"\"Convert a bytes-like object of RGB565 pixels to (H,W,3) uint8.\"\"\"\n    words = np.frombuffer(data, dtype='<u2').reshape(h, w)\n    r = ((words >> 11) & 0x1F) * 255 // 31\n    g = ((words >>  5) & 0x3F) * 255 // 63\n    b = ( words        & 0x1F) * 255 // 31\n    return np.stack([r, g, b], axis=2).astype(np.uint8)\n\n\ndef gray_to_rgb888(data, w, h):\n    \"\"\"Convert a bytes-like object of 8-bit grayscale to (H,W,3) uint8.\"\"\"\n    gray = np.frombuffer(data, dtype=np.uint8).reshape(h, w)\n    return np.stack([gray, gray, gray], axis=2)\n\n\ndef to_dpg_rgba(rgb888):\n    \"\"\"Convert (H,W,3) uint8 RGB to flat float32 RGBA for DearPyGui texture.\"\"\"\n    h, w = rgb888.shape[:2]\n    rgba = np.empty((h, w, 4), dtype=np.float32)\n    rgba[:, :, :3] = rgb888.astype(np.float32) * (1.0 / 255.0)\n    rgba[:, :,  3] = 1.0\n    return rgba.ravel()\n\n\n# ---------------------------------------------------------------------------\n# Script patching\n# ---------------------------------------------------------------------------\n\ndef patch_script(script, main_res, main_pixfmt):\n    \"\"\"Patch cam script constants before exec.\n\n    Replaces MAIN_FRAME_SIZE and MAIN_PIXFORMAT constant assignments.\n    On macOS/Linux also renames 'def read' → 'def readp'.\n    \"\"\"\n    import re\n    main_csi = MAIN_RES_MAP[main_res]\n    main_fmt = PIXFMT_MAP[main_pixfmt]\n\n    script = re.sub(r'MAIN_FRAME_SIZE\\s*=\\s*\\S+',\n                    f'MAIN_FRAME_SIZE = {main_csi}', script)\n    script = re.sub(r'MAIN_PIXFORMAT\\s*=\\s*\\S+',\n                    f'MAIN_PIXFORMAT = {main_fmt}', script)\n\n    if sys.platform != 'win32':\n        script = script.replace('def read(self, offset, size):',\n                                'def readp(self, offset, size):')\n    return script\n\n\n# ---------------------------------------------------------------------------\n# Camera worker\n# ---------------------------------------------------------------------------\n\ndef camera_worker(args, state_lock, state, frame_q, stop_evt):\n    try:\n        with Camera(\n            args.port, baudrate=args.baudrate, crc=args.crc, seq=args.seq,\n            ack=args.ack, events=args.events, timeout=args.timeout,\n            max_retry=args.max_retry, max_payload=args.max_payload,\n            drop_rate=args.drop_rate,\n        ) as camera:\n            logging.info(f\"Connected to OpenMV on {args.port}\")\n            camera.stop()\n            time.sleep(0.5)\n\n            with open(args.script) as f:\n                script = f.read()\n            with state_lock:\n                main_res    = state['main_res']\n                main_pixfmt = state['main_pixfmt']\n            script = patch_script(script, main_res, main_pixfmt)\n            logging.debug(f\"Patched script: main={main_res}/{main_pixfmt} \"\n                          f\"readp={'yes' if sys.platform != 'win32' else 'no'}\")\n            camera.exec(script)\n            logging.info(\"Script running, streaming frames...\")\n\n            start_time  = time.perf_counter()\n            last_time   = start_time\n            total_bytes = 0\n            mbps_ema    = 0.0\n            fps_ema     = 0.0\n            frame_count = 0\n\n            while not stop_evt.is_set():\n                status = camera.read_status()\n\n                if not args.quiet and status and status.get('stdout'):\n                    if text := camera.read_stdout():\n                        print(f\"{COLOR_CAMERA}{text}{COLOR_RESET}\", end='')\n\n                has_main   = camera.has_channel('main')   and status and status.get('main')\n                has_genx320 = camera.has_channel('genx320') and status and status.get('genx320')\n\n                if not has_main and not has_genx320:\n                    time.sleep(0.005)\n                    continue\n\n                main_frame   = None  # (data, w, h)\n                genx320_frame = None\n\n                if has_main:\n                    sz = camera.channel_size('main')\n                    if sz > 0:\n                        shape = camera._channel_shape(camera.get_channel(name='main'))\n                        if shape and len(shape) >= 2:\n                            h, w = shape[0], shape[1]\n                            data = camera.channel_read('main', sz)\n                            if data:\n                                main_frame = (data, w, h)\n\n                if has_genx320:\n                    sz = camera.channel_size('genx320')\n                    if sz > 0:\n                        shape = camera._channel_shape(camera.get_channel(name='genx320'))\n                        if shape and len(shape) >= 2:\n                            h, w = shape[0], shape[1]\n                            data = camera.channel_read('genx320', sz)\n                            if data:\n                                genx320_frame = (data, w, h)\n\n                if main_frame is None and genx320_frame is None:\n                    time.sleep(0.005)\n                    continue\n\n                now       = time.perf_counter()\n                dt        = max(now - last_time, 1e-6)\n                last_time = now\n\n                batch_bytes = ((len(main_frame[0])    if main_frame    else 0) +\n                               (len(genx320_frame[0]) if genx320_frame else 0))\n                total_bytes += batch_bytes\n                frame_count += 1\n                elapsed      = now - start_time\n\n                mb_per_sec     = batch_bytes / 1048576.0 / dt\n                frames_per_sec = 1.0 / dt\n\n                mbps_ema = (mb_per_sec if mbps_ema == 0.0\n                            else mbps_ema * (1 - EMA_ALPHA) + mb_per_sec * EMA_ALPHA)\n                fps_ema  = (frames_per_sec if fps_ema == 0.0\n                            else fps_ema  * (1 - EMA_ALPHA) + frames_per_sec * EMA_ALPHA)\n\n                stats = {\n                    'fps':          fps_ema,\n                    'mbps':         mbps_ema,\n                    'total_frames': frame_count,\n                    'elapsed':      elapsed,\n                }\n\n                if frame_q.full():\n                    try:\n                        frame_q.get_nowait()\n                    except queue.Empty:\n                        pass\n                frame_q.put((main_frame, genx320_frame, stats))\n\n    except Exception as e:\n        logging.error(f\"Camera error: {e}\")\n        if args.debug:\n            import traceback\n            logging.error(traceback.format_exc())\n\n\n# ---------------------------------------------------------------------------\n# Argument parsing\n# ---------------------------------------------------------------------------\n\ndef parse_args():\n    p = argparse.ArgumentParser(description='OpenMV GenX320 overlay calibration GUI')\n    p.add_argument('--port',        default=None)\n    p.add_argument('--script',      default=None)\n    p.add_argument('--baudrate',    default=921600,  type=int)\n    p.add_argument('--crc',         default=None,    action=argparse.BooleanOptionalAction)\n    p.add_argument('--seq',         default=True,    action=argparse.BooleanOptionalAction)\n    p.add_argument('--ack',         default=False,   action=argparse.BooleanOptionalAction)\n    p.add_argument('--events',      default=True,    action=argparse.BooleanOptionalAction)\n    p.add_argument('--timeout',     default=5.0,     type=float)\n    p.add_argument('--max_retry',   default=5,       type=int)\n    p.add_argument('--max_payload', default=65536,   type=int)\n    p.add_argument('--drop_rate',   default=0,       type=int)\n    p.add_argument('--quiet',       default=False,   action='store_true')\n    p.add_argument('--debug',       default=False,   action='store_true')\n    p.add_argument('--benchmark',   default=False,   action='store_true',\n                   help='Headless throughput benchmark — no GUI')\n    args = p.parse_args()\n\n    if args.crc is None:\n        args.crc = sys.platform == 'win32'\n\n    return args\n\n\ndef list_com_ports():\n    return sorted(p.device for p in serial.tools.list_ports.comports())\n\n\n# ---------------------------------------------------------------------------\n# Benchmark (headless)\n# ---------------------------------------------------------------------------\n\ndef run_benchmark(args):\n    \"\"\"Headless throughput benchmark — no GUI, prints stats to terminal.\"\"\"\n    if not args.port:\n        ports = list_com_ports()\n        if not ports:\n            print(\"No serial ports found. Use --port to specify one.\")\n            sys.exit(1)\n        args.port = ports[0]\n        print(f\"Auto-selected port: {args.port}\")\n\n    if args.script is None:\n        args.script = os.path.join(\n            os.path.dirname(os.path.abspath(__file__)),\n            'genx320_overlay_calibration_on_cam.py',\n        )\n\n    state_lock = threading.Lock()\n    state = {\n        'main_res':    'VGA (640×480)',\n        'main_pixfmt': 'RGB565',\n    }\n\n    frame_q  = queue.Queue(maxsize=4)\n    stop_evt = threading.Event()\n\n    def handle_exit(signum, frame):\n        stop_evt.set()\n\n    signal.signal(signal.SIGINT,  handle_exit)\n    signal.signal(signal.SIGTERM, handle_exit)\n\n    t = threading.Thread(\n        target=camera_worker,\n        args=(args, state_lock, state, frame_q, stop_evt),\n        daemon=True,\n    )\n    t.start()\n    print(f\"Connecting to {args.port} ...\")\n\n    last_print = time.perf_counter()\n    while not stop_evt.is_set():\n        try:\n            _, _, stats = frame_q.get(timeout=0.1)\n        except queue.Empty:\n            if not t.is_alive():\n                print(\"Camera thread died unexpectedly.\")\n                break\n            continue\n\n        now = time.perf_counter()\n        if now - last_print >= 0.1:\n            last_print = now\n            print(f\"elapsed={stats['elapsed']:.1f}s\\t\"\n                  f\"fps={stats['fps']:.1f}\\t\"\n                  f\"bw={stats['mbps']:.2f} MB/s\\t\"\n                  f\"frames={stats['total_frames']:,}\")\n\n    stop_evt.set()\n    print(\"\\nDone.\")\n\n\n# ---------------------------------------------------------------------------\n# Main\n# ---------------------------------------------------------------------------\n\ndef main(args=None):\n    if args is None:\n        _args = parse_args()\n        if _args.benchmark:\n            run_benchmark(_args)\n            return\n        args = _args\n\n    if args.script is None:\n        args.script = os.path.join(\n            os.path.dirname(os.path.abspath(__file__)),\n            'genx320_overlay_calibration_on_cam.py',\n        )\n\n    logging.basicConfig(\n        format=\"%(relativeCreated)010.3f - %(message)s\",\n        level=logging.DEBUG if args.debug else logging.INFO,\n    )\n\n    state_lock = threading.Lock()\n    state = {\n        'main_res':    'VGA (640×480)',\n        'main_pixfmt': 'RGB565',\n    }\n\n    # Current pixel dimensions — start at 1×1, updated on first received frame\n    main_wh    = [1, 1]\n    genx320_wh = [1, 1]\n\n    # Overlay alpha: fraction of GenX320 blended onto main (0.0–1.0)\n    overlay_alpha = [0.5]\n\n    # Homography matrix (3×3 float64), None = no warp\n    homography = [None]\n\n    # Point correspondences for homography computation\n    main_pts    = []\n    genx320_pts = []\n    pick_state  = [None]\n\n    # Latest decoded frames (H,W,3 uint8)\n    last_main_rgb    = [None]\n    last_genx320_rgb = [None]\n\n    # Flickering calibration pattern window\n    pattern_stop_evt = [None]\n    pattern_thread   = [None]\n    pattern_root     = [None]\n\n    conn    = {'thread': None, 'stop_evt': None}\n    frame_q = queue.Queue(maxsize=4)\n\n    signal.signal(signal.SIGINT, lambda *_: dpg.stop_dearpygui())\n\n    # -----------------------------------------------------------------------\n    # DPG setup\n    # -----------------------------------------------------------------------\n    dpg.create_context()\n\n    def _make_placeholder(w, h):\n        buf = np.full(w * h * 4, 0.05, dtype=np.float32)\n        buf[3::4] = 1.0\n        return buf\n\n    with dpg.texture_registry(tag=TEX_REG_TAG):\n        dpg.add_dynamic_texture(1, 1, _make_placeholder(1, 1), tag=MAIN_TEX_TAG)\n        dpg.add_dynamic_texture(1, 1, _make_placeholder(1, 1), tag=GENX320_TEX_TAG)\n        dpg.add_dynamic_texture(1, 1, _make_placeholder(1, 1), tag=COMP_TEX_TAG)\n\n    # -----------------------------------------------------------------------\n    # Helpers\n    # -----------------------------------------------------------------------\n\n    def _do_connect(port):\n        args.port = port\n        # Reset size tracking; main loop will recreate textures on first frame.\n        main_wh[0], main_wh[1]       = 1, 1\n        genx320_wh[0], genx320_wh[1] = 1, 1\n        homography[0] = None\n        main_pts.clear()\n        genx320_pts.clear()\n        pick_state[0] = None\n\n        stop_evt = threading.Event()\n        conn['stop_evt'] = stop_evt\n        t = threading.Thread(\n            target=camera_worker,\n            args=(args, state_lock, state, frame_q, stop_evt),\n            daemon=True,\n        )\n        t.start()\n        conn['thread'] = t\n        dpg.configure_item(\"connect_btn\", label=\"Disconnect\")\n        _set_cam_settings_enabled(False)\n        logging.info(f\"Connecting to {port}...\")\n\n    def _do_disconnect():\n        if conn['stop_evt']:\n            conn['stop_evt'].set()\n        conn['thread']   = None\n        conn['stop_evt'] = None\n        dpg.configure_item(\"connect_btn\", label=\"Connect\")\n        _set_cam_settings_enabled(True)\n\n    CAM_SETTING_TAGS = [\"main_res_combo\", \"main_pixfmt_combo\"]\n\n    def _set_cam_settings_enabled(enabled):\n        for tag in CAM_SETTING_TAGS:\n            dpg.configure_item(tag, enabled=enabled)\n\n    def _fmt_homography(H):\n        rows = []\n        for row in H:\n            rows.append(\"  [ \" + \",  \".join(f\"{v:12.6f}\" for v in row) + \" ]\")\n        return \"transform =\\n[\\n\" + \",\\n\".join(rows) + \"\\n]\"\n\n    def _recompute_homography():\n        if len(main_pts) == 4 and len(genx320_pts) == 4:\n            try:\n                import cv2\n                src = np.float32(genx320_pts)\n                dst = np.float32(main_pts)\n                H, _ = cv2.findHomography(src, dst)\n                homography[0] = H\n                dpg.set_value(\"pick_status\", \"Homography computed.\")\n            except ImportError:\n                A = []\n                for (sx, sy), (dx, dy) in zip(genx320_pts, main_pts):\n                    A.append([-sx, -sy, -1,  0,   0,  0, sx*dx, sy*dx, dx])\n                    A.append([ 0,   0,  0, -sx, -sy, -1, sx*dy, sy*dy, dy])\n                A = np.array(A, dtype=np.float64)\n                _, _, Vt = np.linalg.svd(A)\n                H = Vt[-1].reshape(3, 3)\n                H /= H[2, 2]\n                homography[0] = H\n                dpg.set_value(\"pick_status\", \"Homography computed (no cv2).\")\n            if homography[0] is not None:\n                dpg.set_value(\"homography_text\", _fmt_homography(homography[0]))\n                dpg.configure_item(\"save_btn\", label=\"Save Images + Transform\")\n\n    def _make_composite():\n        main_rgb    = last_main_rgb[0]\n        genx320_rgb = last_genx320_rgb[0]\n        if main_rgb is None:\n            return None\n        mw, mh = main_wh\n        alpha  = overlay_alpha[0]\n        comp   = main_rgb.copy().astype(np.float32)\n        if genx320_rgb is not None:\n            gh, gw = genx320_rgb.shape[:2]\n            H = homography[0]\n            if H is not None:\n                try:\n                    import cv2\n                    warped = cv2.warpPerspective(genx320_rgb, H, (mw, mh))\n                    coverage = cv2.warpPerspective(\n                        np.ones((gh, gw), dtype=np.float32), H, (mw, mh),\n                        flags=cv2.INTER_NEAREST)\n                except ImportError:\n                    warped = np.array(Image.fromarray(genx320_rgb).resize(\n                        (mw, mh), Image.BILINEAR))\n                    coverage = np.ones((mh, mw), dtype=np.float32)\n                mask = (coverage > 0).reshape(mh, mw, 1).astype(np.float32)\n                comp = comp * (1 - mask * alpha) + warped.astype(np.float32) * alpha\n            else:\n                try:\n                    import cv2\n                    warped = cv2.resize(genx320_rgb, (mw, mh))\n                except ImportError:\n                    warped = np.array(Image.fromarray(genx320_rgb).resize(\n                        (mw, mh), Image.BILINEAR))\n                comp = comp * (1 - alpha) + warped.astype(np.float32) * alpha\n        return np.clip(comp, 0, 255).astype(np.uint8)\n\n    def _fit_images():\n        vp_w = max(dpg.get_viewport_width()  - CTRL_WIDTH - 30, 1)\n        vp_h = max(dpg.get_viewport_height() - 60, 1)\n        mw, mh = main_wh\n        gw, gh = genx320_wh\n\n        slot_w   = vp_w / 2\n        slot_h   = vp_h * 0.55\n        main_s   = min(slot_w / max(mw, 1), slot_h / max(mh, 1))\n        genx320_s = min(slot_w / max(gw, 1), slot_h / max(gh, 1))\n        target_h  = min(mh * main_s, gh * genx320_s)\n        main_s    = target_h / max(mh, 1)\n        genx320_s = target_h / max(gh, 1)\n\n        comp_scale = min(vp_w / max(mw, 1), (vp_h * 0.4) / max(mh, 1))\n\n        for tag, w, h, s in [\n            (\"main_img\",    mw, mh, main_s),\n            (\"genx320_img\", gw, gh, genx320_s),\n            (\"comp_img\",    mw, mh, comp_scale),\n        ]:\n            dpg.configure_item(tag,\n                               width=max(1, int(w * s)),\n                               height=max(1, int(h * s)))\n\n        comp_w = max(1, int(mw * comp_scale))\n        indent = max(0, (vp_w - comp_w) // 2)\n        dpg.configure_item(\"comp_row\", indent=indent)\n\n    # -----------------------------------------------------------------------\n    # Callbacks\n    # -----------------------------------------------------------------------\n\n    def cb_main_res(s, v, u=None):\n        with state_lock:\n            state['main_res'] = v\n\n    def cb_main_pixfmt(s, v, u=None):\n        with state_lock:\n            state['main_pixfmt'] = v\n\n    def cb_refresh(s=None, v=None, u=None):\n        items = list_com_ports()\n        dpg.configure_item(\"port_combo\", items=items)\n        if items and not dpg.get_value(\"port_combo\"):\n            dpg.set_value(\"port_combo\", items[0])\n\n    def cb_connect(s=None, v=None, u=None):\n        if conn['thread'] and conn['thread'].is_alive():\n            _do_disconnect()\n        else:\n            port = dpg.get_value(\"port_combo\")\n            if not port:\n                return\n            _do_connect(port)\n\n    def cb_save(s=None, v=None, u=None):\n        ts = int(time.time())\n        if _PIL_AVAILABLE:\n            if last_main_rgb[0] is not None:\n                name = f\"genx320_overlay_main_{ts}.png\"\n                Image.fromarray(last_main_rgb[0]).save(name)\n                print(f\"Saved: {name}\")\n            if last_genx320_rgb[0] is not None:\n                name = f\"genx320_overlay_genx320_{ts}.png\"\n                Image.fromarray(last_genx320_rgb[0]).save(name)\n                print(f\"Saved: {name}\")\n            comp = _make_composite()\n            if comp is not None:\n                name = f\"genx320_overlay_composite_{ts}.png\"\n                Image.fromarray(comp).save(name)\n                print(f\"Saved: {name}\")\n        else:\n            print(\"pip install Pillow  to enable image saving.\")\n        H = homography[0]\n        if H is not None:\n            name = f\"genx320_overlay_transform_{ts}.txt\"\n            with open(name, 'w') as f:\n                f.write(_fmt_homography(H) + \"\\n\")\n            print(f\"Saved: {name}\")\n\n    def cb_align_mode(s, v, u=None):\n        is_auto = (v == 'Automatic')\n        dpg.configure_item(\"manual_group\", show=not is_auto)\n        dpg.configure_item(\"auto_group\",   show=is_auto)\n\n    def _find_board_blobs(img_rgb):\n        \"\"\"Blob-grid detection for event camera images.\n\n        Returns (True, corners, grid_shape) or (False, None, None).\n        corners is an Nx1x2 array of inner corner points (like findChessboardCorners).\n        grid_shape is (inner_cols, inner_rows) for the detected grid.\n        \"\"\"\n        import cv2\n        gray = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2GRAY)\n\n        # Heavy median to denoise event speckle, then Otsu binarize\n        med = cv2.medianBlur(gray, 21)\n        _, binary = cv2.threshold(med, 0, 255,\n                                  cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)\n\n        # Find contours of the dark squares (now foreground after INV)\n        contours, _ = cv2.findContours(binary, cv2.RETR_LIST,\n                                       cv2.CHAIN_APPROX_SIMPLE)\n\n        raw_centers = []\n        raw_areas   = []\n        for cnt in contours:\n            area = cv2.contourArea(cnt)\n            if area < 100:\n                continue\n            M = cv2.moments(cnt)\n            if M['m00'] == 0:\n                continue\n            raw_centers.append([M['m10'] / M['m00'], M['m01'] / M['m00']])\n            raw_areas.append(area)\n\n        if len(raw_areas) < 6:\n            return False, None, None\n\n        raw_areas   = np.array(raw_areas)\n        raw_centers = np.array(raw_centers, dtype=np.float32)\n\n        # Keep contours whose area is within 3x of the median\n        median_area = np.median(raw_areas)\n        mask    = (raw_areas > median_area / 3) & (raw_areas < median_area * 3)\n        centers = raw_centers[mask]\n\n        if len(centers) < 6:\n            return False, None, None\n\n        # Cluster into rows by Y coordinate\n        sorted_by_y = centers[centers[:, 1].argsort()]\n        y_gaps      = np.diff(sorted_by_y[:, 1])\n        sorted_gaps = np.sort(y_gaps)\n        gap_diffs   = np.diff(sorted_gaps)\n\n        # Find threshold at the first significant jump in sorted gaps\n        threshold = sorted_gaps[-1]\n        for i, gd in enumerate(gap_diffs):\n            prev_median = np.median(gap_diffs[:max(1, i)])\n            if gd > max(prev_median * 5, 10):\n                threshold = (sorted_gaps[i] + sorted_gaps[i + 1]) / 2\n                break\n\n        rows = []\n        current_row = [sorted_by_y[0]]\n        for i in range(1, len(sorted_by_y)):\n            if sorted_by_y[i, 1] - current_row[-1][1] < threshold:\n                current_row.append(sorted_by_y[i])\n            else:\n                rows.append(np.array(current_row))\n                current_row = [sorted_by_y[i]]\n        rows.append(np.array(current_row))\n\n        # Sort each row by X\n        for i in range(len(rows)):\n            rows[i] = rows[i][rows[i][:, 0].argsort()]\n\n        # Keep rows with the most common column count\n        col_counts  = [len(r) for r in rows]\n        most_common = max(set(col_counts), key=col_counts.count)\n        grid_rows   = [r for r in rows if len(r) == most_common]\n\n        if len(grid_rows) < 2 or most_common < 2:\n            return False, None, None\n\n        # Inner corners: centroid of each 2x2 block of adjacent blob centers\n        inner_corners = []\n        for r in range(len(grid_rows) - 1):\n            row_corners = []\n            for c in range(most_common - 1):\n                tl = grid_rows[r][c]\n                tr = grid_rows[r][c + 1]\n                bl = grid_rows[r + 1][c]\n                br = grid_rows[r + 1][c + 1]\n                row_corners.append((tl + tr + bl + br) / 4.0)\n            inner_corners.append(row_corners)\n\n        n_rows = len(inner_corners)\n        n_cols = len(inner_corners[0])\n        pts    = np.array([pt for row in inner_corners for pt in row],\n                          dtype=np.float32).reshape(-1, 1, 2)\n\n        logging.debug(f\"Blob grid: {len(grid_rows)}x{most_common} blobs -> \"\n                      f\"{n_rows}x{n_cols} inner corners\")\n\n        return True, pts, (n_cols, n_rows)\n\n    def _run_pattern_window(cols, rows, hz, stop_evt):\n        import tkinter as tk\n\n        squares_x = cols + 1\n        squares_y = rows + 1\n        PHASE_MS  = max(33, int(500 / hz))  # half-period in ms\n\n        root = tk.Tk()\n        pattern_root[0] = root\n        root.title(\"Calibration Pattern\")\n        root.geometry(\"800x600\")\n        root.resizable(True, True)\n        root.configure(bg='black')\n\n        canvas = tk.Canvas(root, bg='black', highlightthickness=0)\n        canvas.pack(fill='both', expand=True)\n\n        phase = [0]\n\n        def draw():\n            w = canvas.winfo_width()\n            h = canvas.winfo_height()\n            canvas.delete('all')\n            if phase[0] == 0:\n                return  # blank — black canvas bg covers it\n            sq_w = w / squares_x\n            sq_h = h / squares_y\n            for row in range(squares_y):\n                for col in range(squares_x):\n                    if (row + col) % 2 == 0:\n                        x0 = col * sq_w\n                        y0 = row * sq_h\n                        canvas.create_rectangle(x0, y0, x0 + sq_w, y0 + sq_h,\n                                                fill='white', outline='')\n\n        def flip():\n            phase[0] ^= 1\n            draw()\n            root.after(PHASE_MS, flip)\n\n        def check_stop():\n            if stop_evt.is_set():\n                root.quit()\n                return\n            root.after(100, check_stop)\n\n        def on_close():\n            stop_evt.set()\n\n        root.protocol(\"WM_DELETE_WINDOW\", on_close)\n        root.bind('<Escape>', lambda e: on_close())\n\n        root.after(PHASE_MS, flip)\n        root.after(100, check_stop)\n        root.mainloop()\n        root.destroy()\n\n        pattern_root[0] = None\n        stop_evt.set()\n        if dpg.does_item_exist(\"pattern_btn\"):\n            dpg.configure_item(\"pattern_btn\", label=\"Show Calibration Pattern\")\n\n    def cb_show_hide_pattern(s=None, v=None, u=None):\n        if pattern_thread[0] is not None and pattern_thread[0].is_alive():\n            pattern_stop_evt[0].set()   # signals flip_thread to call root.destroy\n            pattern_thread[0]   = None\n            pattern_stop_evt[0] = None\n            dpg.configure_item(\"pattern_btn\", label=\"Show Calibration Pattern\")\n        else:\n            cols = dpg.get_value(\"board_cols\")\n            rows = dpg.get_value(\"board_rows\")\n            hz   = dpg.get_value(\"pattern_hz\")\n            stop_evt = threading.Event()\n            pattern_stop_evt[0] = stop_evt\n            t = threading.Thread(\n                target=_run_pattern_window,\n                args=(cols, rows, hz, stop_evt),\n                daemon=True,\n            )\n            pattern_thread[0] = t\n            t.start()\n            dpg.configure_item(\"pattern_btn\", label=\"Hide Calibration Pattern\")\n\n    def cb_auto_detect(s=None, v=None, u=None):\n        try:\n            import cv2\n        except ImportError:\n            dpg.set_value(\"pick_status\", \"Auto mode requires opencv-python.\")\n            return\n        main_rgb    = last_main_rgb[0]\n        genx320_rgb = last_genx320_rgb[0]\n        if main_rgb is None or genx320_rgb is None:\n            dpg.set_value(\"pick_status\", \"No frames available yet.\")\n            return\n        cols = dpg.get_value(\"board_cols\")\n        rows = dpg.get_value(\"board_rows\")\n        board_size  = (cols, rows)\n        gw, gh      = genx320_wh\n        SCALE       = 4\n        genx320_up  = cv2.resize(genx320_rgb, (gw * SCALE, gh * SCALE),\n                                 interpolation=cv2.INTER_CUBIC)\n\n        # Freeze copies for the background thread\n        main_snap    = main_rgb.copy()\n        genx320_snap = genx320_up.copy()\n\n        dpg.set_value(\"pick_status\", \"Running detection pipeline...\")\n\n        MAX_ATTEMPTS = 10\n        RETRY_SEC    = 0.1\n\n        def _detect():\n            import cv2\n\n            for attempt in range(1, MAX_ATTEMPTS + 1):\n                # Grab fresh frames each attempt\n                if attempt > 1:\n                    time.sleep(RETRY_SEC)\n                m_rgb = last_main_rgb[0]\n                g_rgb = last_genx320_rgb[0]\n                if m_rgb is None or g_rgb is None:\n                    continue\n                m_snap = m_rgb.copy()\n                g_snap = cv2.resize(g_rgb, (gw * SCALE, gh * SCALE),\n                                    interpolation=cv2.INTER_CUBIC)\n\n                dpg.set_value(\"pick_status\",\n                              f\"Detecting... attempt {attempt}/{MAX_ATTEMPTS}\")\n\n                ret_g, corners_g, grid_g = _find_board_blobs(g_snap)\n                if not ret_g:\n                    continue\n\n                ret_m, corners_m, grid_m = _find_board_blobs(m_snap)\n                if not ret_m:\n                    continue\n\n                if grid_g != grid_m:\n                    continue\n\n                corners_g_scaled = corners_g / SCALE\n                src = corners_g_scaled.reshape(-1, 2).astype(np.float32)\n                dst = corners_m.reshape(-1, 2).astype(np.float32)\n\n                H, inlier_mask = cv2.findHomography(src, dst, cv2.RANSAC, 5.0)\n                if H is None:\n                    continue\n\n                n = len(src)\n                inliers = int(inlier_mask.sum()) if inlier_mask is not None else n\n                homography[0] = H\n                dpg.set_value(\"homography_text\", _fmt_homography(H))\n                dpg.configure_item(\"save_btn\", label=\"Save Images + Transform\")\n                dpg.set_value(\"pick_status\",\n                              f\"Auto: {grid_g[0]}x{grid_g[1]} grid, \"\n                              f\"{inliers}/{n} inliers \"\n                              f\"(attempt {attempt}/{MAX_ATTEMPTS}).\")\n                return\n\n            dpg.set_value(\"pick_status\",\n                          f\"Board not found after {MAX_ATTEMPTS} attempts.\\n\"\n                          f\"Ensure the pattern is visible to both cameras.\")\n\n        threading.Thread(target=_detect, daemon=True).start()\n\n    def cb_pick_main(s=None, v=None, u=None):\n        main_pts.clear()\n        genx320_pts.clear()\n        homography[0] = None\n        pick_state[0] = 'main'\n        dpg.set_value(\"pick_status\", \"Click 4 points on the main image.\")\n\n    def cb_pick_genx320(s=None, v=None, u=None):\n        genx320_pts.clear()\n        pick_state[0] = 'genx320'\n        dpg.set_value(\"pick_status\",\n                      f\"Click 4 matching points on the GenX320 image \"\n                      f\"({len(main_pts)}/4 main points set).\")\n\n    def cb_reset_homography(s=None, v=None, u=None):\n        homography[0] = None\n        main_pts.clear()\n        genx320_pts.clear()\n        pick_state[0] = None\n        dpg.set_value(\"pick_status\", \"Homography reset.\")\n        dpg.set_value(\"homography_text\", \"\")\n        dpg.configure_item(\"save_btn\", label=\"Save Images\")\n\n    def _handle_image_click(tag, img_wh, pts_list, other_list, this_label, other_label):\n        mx, my = dpg.get_mouse_pos(local=False)\n        try:\n            imin = dpg.get_item_rect_min(tag)\n            imax = dpg.get_item_rect_max(tag)\n        except Exception:\n            return\n        if not (imin[0] <= mx <= imax[0] and imin[1] <= my <= imax[1]):\n            return\n        w, h = img_wh\n        dw = imax[0] - imin[0]\n        dh = imax[1] - imin[1]\n        px = int((mx - imin[0]) / max(dw, 1) * w)\n        py = int((my - imin[1]) / max(dh, 1) * h)\n        pts_list.append((px, py))\n        n = len(pts_list)\n        if n < 4:\n            dpg.set_value(\"pick_status\", f\"{n}/4 {this_label} points. Keep clicking.\")\n        else:\n            if len(other_list) == 4:\n                _recompute_homography()\n            else:\n                dpg.set_value(\"pick_status\",\n                              f\"4 {this_label} points set. Now click 4 {other_label} points.\")\n\n    def cb_mouse_click(s=None, v=None, u=None):\n        if pick_state[0] == 'main':\n            if len(main_pts) < 4:\n                _handle_image_click(\"main_img\", main_wh,\n                                    main_pts, genx320_pts, 'main', 'GenX320')\n        elif pick_state[0] == 'genx320':\n            if len(genx320_pts) < 4:\n                _handle_image_click(\"genx320_img\", genx320_wh,\n                                    genx320_pts, main_pts, 'GenX320', 'main')\n\n    # -----------------------------------------------------------------------\n    # UI layout\n    # -----------------------------------------------------------------------\n    with dpg.window(tag=\"main_win\", no_scrollbar=True, no_title_bar=True):\n        with dpg.table(\n            header_row=False, resizable=True,\n            borders_innerV=True, tag=\"layout_table\",\n            scrollX=False, scrollY=False,\n        ):\n            dpg.add_table_column(init_width_or_weight=1.0)\n            dpg.add_table_column(init_width_or_weight=CTRL_WIDTH, width_fixed=True)\n\n            with dpg.table_row():\n\n                # ── Left: image panels ──────────────────────────────────────\n                with dpg.table_cell():\n                    with dpg.group(horizontal=True, tag=\"top_images\"):\n                        dpg.add_image(MAIN_TEX_TAG,    tag=\"main_img\",\n                                      width=1, height=1)\n                        dpg.add_image(GENX320_TEX_TAG, tag=\"genx320_img\",\n                                      width=1, height=1)\n                    dpg.add_separator()\n                    with dpg.group(tag=\"comp_row\"):\n                        dpg.add_image(COMP_TEX_TAG, tag=\"comp_img\",\n                                      width=1, height=1)\n                # ── Right: controls ─────────────────────────────────────────\n                with dpg.table_cell():\n                    with dpg.child_window(width=CTRL_WIDTH, border=False):\n\n                        if sys.platform == 'win32':\n                            dpg.add_text(\n                                \"Warning: Windows reduces transfer speed.\\n\"\n                                \"Use macOS or Linux for best performance.\",\n                                color=(255, 200, 0, 255))\n                            dpg.add_separator()\n\n                        # ── Connection ──────────────────────────────────────\n                        init_ports = list_com_ports()\n                        init_port  = args.port or (init_ports[0] if init_ports else \"\")\n                        with dpg.group(horizontal=True):\n                            dpg.add_text(\"Port  \")\n                            dpg.add_combo(\n                                items=init_ports, default_value=init_port,\n                                tag=\"port_combo\", width=CTRL_WIDTH - 90)\n                            dpg.add_button(label=\"Ref\", callback=cb_refresh, width=28)\n\n                        # ── Camera Parameters ───────────────────────────────\n                        dpg.add_separator()\n                        dpg.add_text(\"Camera Parameters  (applied at connect)\")\n                        dpg.add_text(\"GenX320 is always 320×320 grayscale.\",\n                                     color=(150, 150, 150, 255))\n\n                        with dpg.group(horizontal=True):\n                            dpg.add_text(\"Main Res \")\n                            dpg.add_combo(\n                                tag=\"main_res_combo\",\n                                items=MAIN_RES_OPTIONS,\n                                default_value=state['main_res'],\n                                callback=cb_main_res, width=-1)\n\n                        with dpg.group(horizontal=True):\n                            dpg.add_text(\"Main Fmt \")\n                            dpg.add_combo(\n                                tag=\"main_pixfmt_combo\",\n                                items=PIXFMT_OPTIONS,\n                                default_value=state['main_pixfmt'],\n                                callback=cb_main_pixfmt, width=-1)\n\n                        dpg.add_separator()\n                        dpg.add_button(label=\"Connect\", tag=\"connect_btn\",\n                                       callback=cb_connect, width=-1)\n\n                        # ── Overlay Alpha ───────────────────────────────────\n                        dpg.add_separator()\n                        dpg.add_text(\"Overlay Alpha\")\n                        dpg.add_slider_int(\n                            tag=\"alpha_slider\",\n                            default_value=int(overlay_alpha[0] * 100),\n                            min_value=0, max_value=100,\n                            format=\"%d%%\", width=-1,\n                            callback=lambda s, v, u=None: overlay_alpha.__setitem__(0, v / 100.0))\n\n                        # ── Calibration Pattern ─────────────────────────────\n                        dpg.add_separator()\n                        dpg.add_text(\"Calibration Pattern\")\n                        with dpg.group(horizontal=True):\n                            dpg.add_text(\"Cols \")\n                            dpg.add_input_int(tag=\"board_cols\",\n                                              default_value=7,\n                                              min_value=2, max_value=20,\n                                              width=-1)\n                        with dpg.group(horizontal=True):\n                            dpg.add_text(\"Rows \")\n                            dpg.add_input_int(tag=\"board_rows\",\n                                              default_value=7,\n                                              min_value=2, max_value=20,\n                                              width=-1)\n                        with dpg.group(horizontal=True):\n                            dpg.add_text(\"Hz   \")\n                            dpg.add_input_int(tag=\"pattern_hz\",\n                                              default_value=2,\n                                              min_value=1, max_value=30,\n                                              width=-1)\n                        dpg.add_button(label=\"Show Calibration Pattern\",\n                                       tag=\"pattern_btn\",\n                                       callback=cb_show_hide_pattern, width=-1)\n\n                        # ── Overlay Alignment ───────────────────────────────\n                        dpg.add_separator()\n                        dpg.add_text(\"Overlay Alignment\")\n\n                        with dpg.group(horizontal=True):\n                            dpg.add_text(\"Mode     \")\n                            dpg.add_combo(\n                                items=[\"Manual\", \"Automatic\"],\n                                default_value=\"Manual\",\n                                tag=\"align_mode_combo\",\n                                callback=cb_align_mode, width=-1)\n\n                        with dpg.group(tag=\"manual_group\", show=True):\n                            dpg.add_text(\n                                \"Click 4 matching points on each image to \"\n                                \"compute a homography that aligns the GenX320 \"\n                                \"onto the main camera frame.\",\n                                wrap=CTRL_WIDTH - 10)\n                            dpg.add_button(label=\"Pick Main Points\",\n                                           callback=cb_pick_main, width=-1)\n                            dpg.add_button(label=\"Pick GenX320 Points\",\n                                           callback=cb_pick_genx320, width=-1)\n\n                        with dpg.group(tag=\"auto_group\", show=False):\n                            dpg.add_text(\n                                \"Click Auto Detect to find the checkerboard \"\n                                \"in both images. The grid is detected \"\n                                \"automatically.\",\n                                wrap=CTRL_WIDTH - 10)\n                            dpg.add_button(label=\"Auto Detect\",\n                                           callback=cb_auto_detect, width=-1)\n\n                        dpg.add_button(label=\"Reset Homography\",\n                                       callback=cb_reset_homography, width=-1)\n                        dpg.add_text(\"\", tag=\"pick_status\", wrap=CTRL_WIDTH - 10)\n                        dpg.add_input_text(\n                            tag=\"homography_text\",\n                            default_value=\"\",\n                            multiline=True, readonly=True,\n                            width=-1, height=90)\n\n                        # ── Save ────────────────────────────────────────────\n                        dpg.add_separator()\n                        dpg.add_button(label=\"Save Images\", tag=\"save_btn\",\n                                       callback=cb_save, width=-1)\n\n                        # ── Statistics ──────────────────────────────────────\n                        dpg.add_separator()\n                        dpg.add_text(\"Statistics\")\n\n                        stat_defs = [\n                            (\"FPS\",           \"stat_fps\"),\n                            (\"Bandwidth\",     \"stat_mbps\"),\n                            (\"Total frames\",  \"stat_frames\"),\n                            (\"Uptime\",        \"stat_uptime\"),\n                        ]\n                        for lbl, tag in stat_defs:\n                            with dpg.group(horizontal=True):\n                                dpg.add_text(f\"{lbl:<14}\")\n                                dpg.add_text(\"-\", tag=tag)\n\n    with dpg.handler_registry():\n        dpg.add_mouse_click_handler(callback=cb_mouse_click)\n\n    dpg.create_viewport(\n        title=\"GenX320 Overlay Calibration\",\n        width=1400, height=900,\n        resizable=True,\n    )\n    dpg.setup_dearpygui()\n    dpg.show_viewport()\n    dpg.set_primary_window(\"main_win\", True)\n    dpg.add_viewport_drawlist(tag=\"vp_overlay\", front=True)\n\n    if args.port:\n        _do_connect(args.port)\n\n    # -----------------------------------------------------------------------\n    # Render loop\n    # -----------------------------------------------------------------------\n    last_stat_time = time.perf_counter()\n    pending_stats  = None\n\n    _PT_COLORS = [\n        (0, 255,   0, 255),\n        (255, 255,  0, 255),\n        (255, 165,  0, 255),\n        (255,   0,  0, 255),\n    ]\n\n    while dpg.is_dearpygui_running():\n        while True:\n            try:\n                main_frame, genx320_frame, stats = frame_q.get_nowait()\n            except queue.Empty:\n                break\n\n            pending_stats = stats\n\n            # Decode and upload main frame\n            if main_frame is not None:\n                data, w, h = main_frame\n                if w != main_wh[0] or h != main_wh[1]:\n                    main_wh[0], main_wh[1] = w, h\n                    for t in (MAIN_TEX_TAG, COMP_TEX_TAG):\n                        dpg.delete_item(t)\n                        if dpg.does_alias_exist(t):\n                            dpg.remove_alias(t)\n                    dpg.add_dynamic_texture(w, h, _make_placeholder(w, h),\n                                            tag=MAIN_TEX_TAG, parent=TEX_REG_TAG)\n                    dpg.add_dynamic_texture(w, h, _make_placeholder(w, h),\n                                            tag=COMP_TEX_TAG, parent=TEX_REG_TAG)\n                    dpg.configure_item(\"main_img\", texture_tag=MAIN_TEX_TAG)\n                    dpg.configure_item(\"comp_img\", texture_tag=COMP_TEX_TAG)\n                expected_rgb565 = w * h * 2\n                expected_gray   = w * h\n                if len(data) == expected_rgb565:\n                    rgb = rgb565_to_rgb888(data, w, h)\n                elif len(data) == expected_gray:\n                    rgb = gray_to_rgb888(data, w, h)\n                else:\n                    rgb = None\n                if rgb is not None:\n                    last_main_rgb[0] = rgb\n                    dpg.set_value(MAIN_TEX_TAG, to_dpg_rgba(rgb))\n\n            # Decode and upload GenX320 frame (always grayscale)\n            if genx320_frame is not None:\n                data, w, h = genx320_frame\n                if w != genx320_wh[0] or h != genx320_wh[1]:\n                    genx320_wh[0], genx320_wh[1] = w, h\n                    dpg.delete_item(GENX320_TEX_TAG)\n                    if dpg.does_alias_exist(GENX320_TEX_TAG):\n                        dpg.remove_alias(GENX320_TEX_TAG)\n                    dpg.add_dynamic_texture(w, h, _make_placeholder(w, h),\n                                            tag=GENX320_TEX_TAG, parent=TEX_REG_TAG)\n                    dpg.configure_item(\"genx320_img\", texture_tag=GENX320_TEX_TAG)\n                expected_gray = w * h\n                if len(data) == expected_gray:\n                    rgb = gray_to_rgb888(data, w, h)\n                    last_genx320_rgb[0] = rgb\n                    dpg.set_value(GENX320_TEX_TAG, to_dpg_rgba(rgb))\n\n            # Update composite\n            comp = _make_composite()\n            if comp is not None:\n                dpg.set_value(COMP_TEX_TAG, to_dpg_rgba(comp))\n\n        # Stats update at ~5 Hz\n        now = time.perf_counter()\n        if pending_stats and (now - last_stat_time) >= 0.2:\n            s = pending_stats\n            dpg.set_value(\"stat_fps\",    f\"{s['fps']:.1f} fps\")\n            dpg.set_value(\"stat_mbps\",   f\"{s['mbps']:.2f} MB/s\")\n            dpg.set_value(\"stat_frames\", f\"{s['total_frames']:,}\")\n            dpg.set_value(\"stat_uptime\", f\"{s['elapsed']:.1f} s\")\n            last_stat_time = now\n\n        if conn['thread'] and not conn['thread'].is_alive():\n            _do_disconnect()\n\n        _fit_images()\n\n        # Draw point overlays\n        dpg.delete_item(\"vp_overlay\", children_only=True)\n        try:\n            for img_tag, pts, wh in [\n                (\"main_img\",    main_pts,    main_wh),\n                (\"genx320_img\", genx320_pts, genx320_wh),\n            ]:\n                if not pts:\n                    continue\n                imin = dpg.get_item_rect_min(img_tag)\n                imax = dpg.get_item_rect_max(img_tag)\n                fw, fh = wh\n                dw = imax[0] - imin[0]\n                dh = imax[1] - imin[1]\n                for i, (px, py) in enumerate(pts):\n                    sx = imin[0] + px / max(fw, 1) * dw\n                    sy = imin[1] + py / max(fh, 1) * dh\n                    col = _PT_COLORS[i % len(_PT_COLORS)]\n                    dpg.draw_circle([sx, sy], 8, color=col,\n                                    thickness=2, parent=\"vp_overlay\")\n                    dpg.draw_text([sx + 10, sy - 8], str(i + 1), size=14,\n                                  color=col, parent=\"vp_overlay\")\n        except Exception:\n            pass\n\n        dpg.render_dearpygui_frame()\n\n    dpg.destroy_context()\n\n    if pattern_stop_evt[0]:\n        pattern_stop_evt[0].set()\n    if conn['stop_evt']:\n        conn['stop_evt'].set()\n\n    print(\"\\nDone.\")\n\n\nif __name__ == '__main__':\n    _args = parse_args()\n    if _args.benchmark:\n        run_benchmark(_args)\n    else:\n        main(_args)\n"
  },
  {
    "path": "tools/thermal-overlay-calibration/README.md",
    "content": "# Thermal Overlay Calibration\n\nA PC-side GUI that streams a color frame and a FLIR Lepton thermal frame simultaneously from an OpenMV Cam, displays them side by side, and composites them into a calibrated overlay. A homography computed from point correspondences aligns the Lepton onto the main camera's coordinate space for a pixel-accurate overlay.\n\n![Thermal Overlay Calibration GUI](thermal-overlay-calibration.jpeg)\n\n## Platform Notes\n\nmacOS and Linux are recommended for the best GUI performance and throughput. On Windows, DearPyGui rendering can be noticeably slower, which may reduce frame rates. The camera script and serial protocol work on all platforms, but if you experience a sluggish UI or low frame rate, consider switching to a Mac or Linux machine.\n\nOn macOS and Linux the companion script's `read` method is automatically renamed to `readp` before execution (this is handled transparently by the PC script).\n\nCRC is disabled by default on macOS and Linux for better USB throughput. It is enabled by default on Windows where it improves reliability. Override with `--crc`.\n\n## Prerequisites\n\n1. **OpenMV IDE** v4.8.4 or later.\n2. **OpenMV Cam Firmware** v5.0.0 or later.\n3. **Python dependencies:**\n\n```\npip install dearpygui numpy pyserial Pillow openmv\n```\n\nOptionally install OpenCV for automatic checkerboard detection and better warp quality:\n\n```\npip install opencv-python\n```\n\nWithout OpenCV, the composite falls back to PIL bilinear resize and automatic alignment is unavailable.\n\n## Running\n\n```\npython thermal_overlay_calibration_on_pc.py\n```\n\nThe companion camera script (`thermal_overlay_calibration_on_cam.py`) is loaded automatically from the same folder. You can override any option from the command line:\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--port PORT` | *(GUI selector)* | Serial port to connect on |\n| `--script PATH` | `thermal_overlay_calibration_on_cam.py` | MicroPython script to run on the camera |\n| `--baudrate N` | `921600` | Serial baud rate |\n| `--crc` | off (Linux/Mac), on (Windows) | Enable CRC on the serial protocol |\n| `--quiet` | off | Suppress camera stdout |\n| `--debug` | off | Enable verbose logging |\n| `--benchmark` | off | Headless throughput benchmark (no GUI) |\n\n## Benchmark Mode\n\nRun without the GUI to measure raw USB throughput:\n\n```\npython thermal_overlay_calibration_on_pc.py --benchmark\npython thermal_overlay_calibration_on_pc.py --benchmark --port /dev/ttyACM0\n```\n\nPrints at 10 Hz:\n\n```\nelapsed=3.2s    fps=9.1    bw=1.24 MB/s    frames=29\n```\n\nPress **Ctrl+C** to stop.\n\n## GUI Overview\n\nThe window has two panes: a **left image area** and a **right control panel**.\n\n### Image Area\n\n- **Top row** — main color camera (left) and Lepton thermal (right), each scaled to occupy half the available width at the same display height.\n- **Bottom** — composite image: the Lepton warped and blended onto the main frame. Without a homography the Lepton is stretched to fill. With a homography it is perspective-warped to align. The composite is horizontally centered.\n\nAll images resize automatically when the window is resized.\n\n### Camera Parameters *(applied at connect)*\n\nThese patch the on-camera script before it is executed. They are locked while connected.\n\n| Control | Default | Description |\n|---------|---------|-------------|\n| Main Res | VGA (640×480) | Main camera resolution: QVGA, VGA, or HD |\n| Main Fmt | RGB565 | Main camera pixel format: RGB565 or GRAYSCALE |\n| Lepton | QQVGA (160×120) | Lepton resolution: QQVGA, QVGA, or VGA |\n| Lep Fmt | RGB565 | Lepton pixel format: RGB565 or GRAYSCALE |\n| Lep Pal | IRONBOW | Color palette applied when Lep Fmt is RGB565: IRONBOW or RAINBOW |\n\nThe palette combo is hidden when Lep Fmt is set to GRAYSCALE.\n\n### Overlay Alpha\n\nA slider from 0% to 100% controlling how much of the Lepton is blended over the main frame in the composite. Defaults to 50%.\n\n### Overlay Alignment\n\nComputes a homography (perspective warp) that maps Lepton pixel coordinates to main camera pixel coordinates for a geometrically correct overlay.\n\n#### Manual Mode\n\n![Manual Point Picking](thermal-overlay-calibration-manual.jpeg)\n\nClick **Pick Main Points**, then click 4 landmark points on the main camera image. Click **Pick Lepton Points**, then click the same 4 landmarks in the same order on the Lepton image. The homography is computed automatically once all 8 points are set. Numbered circles (1–4) are drawn on each image as you click to track progress.\n\n> **Tip:** Spread the 4 points across the full frame for the most accurate warp. Avoid clustering all points in one region.\n\n#### Automatic Mode\n\nPlace a heated checkerboard in the field of view of both cameras. Set **Cols** and **Rows** to the number of *inner* corners of the board (e.g. a 8×8 square checkerboard has 7×7 inner corners), then click **Auto Detect**.\n\nThe detector tries multiple preprocessing variants — CLAHE contrast enhancement, unsharp masking, Otsu binary thresholding, image inversion, and each individual RGB channel — to maximize robustness across different thermal palettes (IRONBOW, RAINBOW, etc.). If OpenCV 4+ is available, the saddle-point `findChessboardCornersSB` is tried first before falling back to the classic `findChessboardCorners`. All detected corners are used for the homography (RANSAC), giving much higher accuracy than 4-point manual picking.\n\nThe status line reports the number of inliers after detection.\n\n#### Shared Controls\n\n- **Reset Homography** — clears all points and the transform.\n- **transform =** — read-only copyable text box showing the computed 3×3 perspective matrix, ready to paste into firmware or a processing script.\n\n### Save Images\n\nSaves the current frames and transform to disk. The button label changes to **Save Images + Transform** once a homography has been computed.\n\n- `thermal_main_<timestamp>.png` — main camera frame (RGB).\n- `thermal_lepton_<timestamp>.png` — Lepton frame.\n- `thermal_composite_<timestamp>.png` — composited overlay image.\n- `thermal_transform_<timestamp>.txt` — the 3×3 homography matrix.\n\nThese files are excluded from git via `.gitignore`.\n\n### Statistics\n\n| Field | Description |\n|-------|-------------|\n| FPS | Frame pair rate (EMA) |\n| Bandwidth | Combined USB data rate (MB/s, EMA) |\n| Total frames | Cumulative frame pairs since connect |\n| Uptime | Seconds since connect |\n"
  },
  {
    "path": "tools/thermal-overlay-calibration/thermal_overlay_calibration_on_cam.py",
    "content": "# This work is licensed under the MIT license.\n# Copyright (c) 2013-2026 OpenMV LLC. All rights reserved.\n# https://github.com/openmv/openmv/blob/master/LICENSE\n#\n# This script pulls color and thermal images from the camera.\n#\n# This script is meant to be run using https://github.com/openmv/openmv-python\n# from a PC using desktop tools. No visualization or text output is generated\n# by this script for OpenMV IDE.\n\nimport csi\nimport protocol\nimport json\nimport image\n\nMAIN_PIXFORMAT = csi.RGB565\nMAIN_FRAME_SIZE = csi.VGA\n\nLEPTON_FRAME_SIZE = csi.QVGA\nLEPTON_PIXFORMAT = csi.RGB565\nLEPTON_PALETTE = image.PALETTE_IRONBOW\n\n# Initialize the sensor.\ncsi0 = csi.CSI()\ncsi0.reset(hard=True)\ncsi0.pixformat(MAIN_PIXFORMAT)\ncsi0.framesize(MAIN_FRAME_SIZE)\ncsi0_img = csi0.snapshot()\ncsi0_img_mv = memoryview(csi0_img.bytearray())\ncsi0_frame_available = True\n\n# Parse image info from string representation\ncsi0_img_info = json.loads(str(csi0_img))\ncsi0_img_width = csi0_img_info['w']\ncsi0_img_height = csi0_img_info['h']\ncsi0_img_size = csi0_img_info['size']\n\n# Initialize the LEPTON sensor.\ncsi1 = csi.CSI(cid=csi.LEPTON)\ncsi1.reset(hard=False)\ncsi1.pixformat(LEPTON_PIXFORMAT)\ncsi1.framesize(LEPTON_FRAME_SIZE)\ncsi1.color_palette(LEPTON_PALETTE)\ncsi1_img = csi1.snapshot()\ncsi1_img_mv = memoryview(csi1_img.bytearray())\ncsi1_frame_available = True\n\n# Parse image info from string representation\ncsi1_img_info = json.loads(str(csi1_img))\ncsi1_img_width = csi1_img_info['w']\ncsi1_img_height = csi1_img_info['h']\ncsi1_img_size = csi1_img_info['size']\n\n\nclass MainChannel:\n    def size(self):\n        return csi0_img_size\n\n    def shape(self):\n        return (csi0_img_height, csi0_img_width, csi0_img_size)\n\n    def read(self, offset, size):\n        global csi0_frame_available\n\n        if csi0_frame_available:\n            end = offset + size\n            mv = csi0_img_mv[offset:end]\n            if end == csi0_img_size:\n                csi0_frame_available = False\n            return mv\n        return bytes(size)\n\n    def poll(self):\n        return csi0_frame_available\n\n\nclass LeptonChannel:\n    def size(self):\n        return csi1_img_size\n\n    def shape(self):\n        return (csi1_img_height, csi1_img_width, csi1_img_size)\n\n    def read(self, offset, size):\n        global csi1_frame_available\n\n        if csi1_frame_available:\n            end = offset + size\n            mv = csi1_img_mv[offset:end]\n            if end == csi1_img_size:\n                csi1_frame_available = False\n            return mv\n        return bytes(size)\n\n    def poll(self):\n        return csi1_frame_available\n\n\nprotocol.register(name='main', backend=MainChannel())\nprotocol.register(name='lepton', backend=LeptonChannel())\n\nwhile True:\n    if not csi0_frame_available:\n        csi0_img = csi0.snapshot()\n        csi0_img_mv = memoryview(csi0_img.bytearray())\n        csi0_frame_available = True\n\n    if not csi1_frame_available:\n        csi1_img = csi1.snapshot()\n        csi1_img_mv = memoryview(csi1_img.bytearray())\n        csi1_frame_available = True\n"
  },
  {
    "path": "tools/thermal-overlay-calibration/thermal_overlay_calibration_on_pc.py",
    "content": "#!/usr/bin/env python3\n#\n# This work is licensed under the MIT license.\n# Copyright (c) 2013-2026 OpenMV LLC. All rights reserved.\n# https://github.com/openmv/openmv/blob/master/LICENSE\n#\n# Thermal overlay calibration GUI for OpenMV cameras on PC.\n# Requires: pip install dearpygui numpy pyserial Pillow openmv\n#\n# Streams RGB565/Grayscale frames from a main camera and a FLIR Lepton\n# simultaneously, displays them side by side, and composites them into\n# a third image below. A homography computed from 4 point correspondences\n# can be used to align the Lepton onto the main camera frame.\n\nimport sys\nimport os\nimport argparse\nimport time\nimport logging\nimport signal\nimport threading\nimport queue\nimport numpy as np\ntry:\n    from PIL import Image\n    _PIL_AVAILABLE = True\nexcept ImportError:\n    _PIL_AVAILABLE = False\nimport serial.tools.list_ports\nimport dearpygui.dearpygui as dpg\nfrom openmv.camera import Camera\n\n\nCOLOR_CAMERA = \"\\033[32m\"\nCOLOR_RESET  = \"\\033[0m\"\n\nEMA_ALPHA = 0.2\nCTRL_WIDTH = 320\n\n# Resolution options sent to the camera script as constants.\nMAIN_RES_OPTIONS   = ['QVGA (320×240)', 'VGA (640×480)', 'HD (1280×720)']\nLEPTON_RES_OPTIONS = ['QQVGA (160×120)', 'QVGA (320×240)', 'VGA (640×480)']\nPIXFMT_OPTIONS     = ['RGB565', 'GRAYSCALE']\nPALETTE_OPTIONS    = ['IRONBOW', 'RAINBOW']\n\nMAIN_RES_MAP = {\n    'QVGA (320×240)': 'csi.QVGA',\n    'VGA (640×480)':  'csi.VGA',\n    'HD (1280×720)':  'csi.HD',\n}\nLEPTON_RES_MAP = {\n    'QQVGA (160×120)': 'csi.QQVGA',\n    'QVGA (320×240)':  'csi.QVGA',\n    'VGA (640×480)':   'csi.VGA',\n}\nPIXFMT_MAP = {\n    'RGB565':    'csi.RGB565',\n    'GRAYSCALE': 'csi.GRAYSCALE',\n}\nPALETTE_MAP = {\n    'IRONBOW': 'image.PALETTE_IRONBOW',\n    'RAINBOW': 'image.PALETTE_RAINBOW',\n}\n\n# Tags\nMAIN_TEX_TAG    = \"main_tex\"\nLEPTON_TEX_TAG  = \"lepton_tex\"\nCOMP_TEX_TAG    = \"comp_tex\"\nTEX_REG_TAG     = \"tex_reg\"\n\n\n# ---------------------------------------------------------------------------\n# RGB565 → RGB888 conversion (vectorized)\n# ---------------------------------------------------------------------------\n\ndef rgb565_to_rgb888(data, w, h):\n    \"\"\"Convert a bytes-like object of RGB565 pixels to (H,W,3) uint8.\"\"\"\n    words = np.frombuffer(data, dtype='<u2').reshape(h, w)\n    r = ((words >> 11) & 0x1F) * 255 // 31\n    g = ((words >>  5) & 0x3F) * 255 // 63\n    b = ( words        & 0x1F) * 255 // 31\n    return np.stack([r, g, b], axis=2).astype(np.uint8)\n\n\ndef gray_to_rgb888(data, w, h):\n    \"\"\"Convert a bytes-like object of 8-bit grayscale to (H,W,3) uint8.\"\"\"\n    gray = np.frombuffer(data, dtype=np.uint8).reshape(h, w)\n    return np.stack([gray, gray, gray], axis=2)\n\n\ndef to_dpg_rgba(rgb888):\n    \"\"\"Convert (H,W,3) uint8 RGB to flat float32 RGBA for DearPyGui texture.\"\"\"\n    h, w = rgb888.shape[:2]\n    rgba = np.empty((h, w, 4), dtype=np.float32)\n    rgba[:, :, :3] = rgb888.astype(np.float32) * (1.0 / 255.0)\n    rgba[:, :,  3] = 1.0\n    return rgba.ravel()\n\n\n# ---------------------------------------------------------------------------\n# Script patching\n# ---------------------------------------------------------------------------\n\ndef patch_script(script, main_res, lepton_res, main_pixfmt, lepton_pixfmt, lepton_palette):\n    \"\"\"Patch cam script constants before exec.\n\n    Replaces MAIN_FRAME_SIZE, LEPTON_FRAME_SIZE, MAIN_PIXFORMAT, LEPTON_PIXFORMAT,\n    and LEPTON_PALETTE constant assignments.\n    On macOS/Linux also renames 'def read' → 'def readp'.\n    \"\"\"\n    import re\n    main_csi    = MAIN_RES_MAP[main_res]\n    lepton_csi  = LEPTON_RES_MAP[lepton_res]\n    main_fmt    = PIXFMT_MAP[main_pixfmt]\n    lepton_fmt  = PIXFMT_MAP[lepton_pixfmt]\n    palette     = PALETTE_MAP[lepton_palette]\n\n    script = re.sub(r'MAIN_FRAME_SIZE\\s*=\\s*\\S+',\n                    f'MAIN_FRAME_SIZE = {main_csi}', script)\n    script = re.sub(r'LEPTON_FRAME_SIZE\\s*=\\s*\\S+',\n                    f'LEPTON_FRAME_SIZE = {lepton_csi}', script)\n    script = re.sub(r'MAIN_PIXFORMAT\\s*=\\s*\\S+',\n                    f'MAIN_PIXFORMAT = {main_fmt}', script)\n    script = re.sub(r'LEPTON_PIXFORMAT\\s*=\\s*\\S+',\n                    f'LEPTON_PIXFORMAT = {lepton_fmt}', script)\n    script = re.sub(r'LEPTON_PALETTE\\s*=\\s*\\S+',\n                    f'LEPTON_PALETTE = {palette}', script)\n\n    if sys.platform != 'win32':\n        script = script.replace('def read(self, offset, size):',\n                                'def readp(self, offset, size):')\n    return script\n\n\n# ---------------------------------------------------------------------------\n# Camera worker\n# ---------------------------------------------------------------------------\n\ndef camera_worker(args, state_lock, state, frame_q, stop_evt):\n    try:\n        with Camera(\n            args.port, baudrate=args.baudrate, crc=args.crc, seq=args.seq,\n            ack=args.ack, events=args.events, timeout=args.timeout,\n            max_retry=args.max_retry, max_payload=args.max_payload,\n            drop_rate=args.drop_rate,\n        ) as camera:\n            logging.info(f\"Connected to OpenMV on {args.port}\")\n            camera.stop()\n            time.sleep(0.5)\n\n            with open(args.script) as f:\n                script = f.read()\n            with state_lock:\n                main_res       = state['main_res']\n                lepton_res     = state['lepton_res']\n                main_pixfmt    = state['main_pixfmt']\n                lepton_pixfmt  = state['lepton_pixfmt']\n                lepton_palette = state['lepton_palette']\n            script = patch_script(script, main_res, lepton_res,\n                                  main_pixfmt, lepton_pixfmt, lepton_palette)\n            logging.debug(f\"Patched script: main={main_res}/{main_pixfmt} \"\n                          f\"lepton={lepton_res}/{lepton_pixfmt}/{lepton_palette} \"\n                          f\"readp={'yes' if sys.platform != 'win32' else 'no'}\")\n            camera.exec(script)\n            logging.info(\"Script running, streaming frames...\")\n\n            start_time  = time.perf_counter()\n            last_time   = start_time\n            total_bytes = 0\n            mbps_ema    = 0.0\n            fps_ema     = 0.0\n            frame_count = 0\n\n            while not stop_evt.is_set():\n                status = camera.read_status()\n\n                if not args.quiet and status and status.get('stdout'):\n                    if text := camera.read_stdout():\n                        print(f\"{COLOR_CAMERA}{text}{COLOR_RESET}\", end='')\n\n                has_main   = camera.has_channel('main')   and status and status.get('main')\n                has_lepton = camera.has_channel('lepton') and status and status.get('lepton')\n\n                if not has_main and not has_lepton:\n                    time.sleep(0.005)\n                    continue\n\n                main_frame   = None  # (data, w, h)\n                lepton_frame = None\n\n                if has_main:\n                    sz = camera.channel_size('main')\n                    if sz > 0:\n                        shape = camera._channel_shape(camera.get_channel(name='main'))\n                        if shape and len(shape) >= 2:\n                            h, w = shape[0], shape[1]\n                            data = camera.channel_read('main', sz)\n                            if data:\n                                main_frame = (data, w, h)\n\n                if has_lepton:\n                    sz = camera.channel_size('lepton')\n                    if sz > 0:\n                        shape = camera._channel_shape(camera.get_channel(name='lepton'))\n                        if shape and len(shape) >= 2:\n                            h, w = shape[0], shape[1]\n                            data = camera.channel_read('lepton', sz)\n                            if data:\n                                lepton_frame = (data, w, h)\n\n                if main_frame is None and lepton_frame is None:\n                    time.sleep(0.005)\n                    continue\n\n                now       = time.perf_counter()\n                dt        = max(now - last_time, 1e-6)\n                last_time = now\n\n                batch_bytes = ((len(main_frame[0])   if main_frame   else 0) +\n                               (len(lepton_frame[0]) if lepton_frame else 0))\n                total_bytes += batch_bytes\n                frame_count += 1\n                elapsed      = now - start_time\n\n                mb_per_sec     = batch_bytes / 1048576.0 / dt\n                frames_per_sec = 1.0 / dt\n\n                mbps_ema = (mb_per_sec if mbps_ema == 0.0\n                            else mbps_ema * (1 - EMA_ALPHA) + mb_per_sec * EMA_ALPHA)\n                fps_ema  = (frames_per_sec if fps_ema == 0.0\n                            else fps_ema  * (1 - EMA_ALPHA) + frames_per_sec * EMA_ALPHA)\n\n                stats = {\n                    'fps':          fps_ema,\n                    'mbps':         mbps_ema,\n                    'total_frames': frame_count,\n                    'elapsed':      elapsed,\n                }\n\n                if frame_q.full():\n                    try:\n                        frame_q.get_nowait()\n                    except queue.Empty:\n                        pass\n                frame_q.put((main_frame, lepton_frame, stats))\n\n    except Exception as e:\n        logging.error(f\"Camera error: {e}\")\n        if args.debug:\n            import traceback\n            logging.error(traceback.format_exc())\n\n\n# ---------------------------------------------------------------------------\n# Argument parsing\n# ---------------------------------------------------------------------------\n\ndef parse_args():\n    p = argparse.ArgumentParser(description='OpenMV thermal overlay calibration GUI')\n    p.add_argument('--port',        default=None)\n    p.add_argument('--script',      default=None)\n    p.add_argument('--baudrate',    default=921600,  type=int)\n    p.add_argument('--crc',         default=None,    action=argparse.BooleanOptionalAction)\n    p.add_argument('--seq',         default=True,    action=argparse.BooleanOptionalAction)\n    p.add_argument('--ack',         default=False,   action=argparse.BooleanOptionalAction)\n    p.add_argument('--events',      default=True,    action=argparse.BooleanOptionalAction)\n    p.add_argument('--timeout',     default=5.0,     type=float)\n    p.add_argument('--max_retry',   default=5,       type=int)\n    p.add_argument('--max_payload', default=65536,   type=int)\n    p.add_argument('--drop_rate',   default=0,       type=int)\n    p.add_argument('--quiet',       default=False,   action='store_true')\n    p.add_argument('--debug',       default=False,   action='store_true')\n    p.add_argument('--benchmark',   default=False,   action='store_true',\n                   help='Headless throughput benchmark — no GUI')\n    args = p.parse_args()\n\n    # CRC default: off on Mac/Linux (faster), on on Windows (more reliable)\n    if args.crc is None:\n        args.crc = sys.platform == 'win32'\n\n    return args\n\n\ndef list_com_ports():\n    return sorted(p.device for p in serial.tools.list_ports.comports())\n\n\n# ---------------------------------------------------------------------------\n# Benchmark (headless)\n# ---------------------------------------------------------------------------\n\ndef run_benchmark(args):\n    \"\"\"Headless throughput benchmark — no GUI, prints stats to terminal.\"\"\"\n    if not args.port:\n        ports = list_com_ports()\n        if not ports:\n            print(\"No serial ports found. Use --port to specify one.\")\n            sys.exit(1)\n        args.port = ports[0]\n        print(f\"Auto-selected port: {args.port}\")\n\n    if args.script is None:\n        args.script = os.path.join(\n            os.path.dirname(os.path.abspath(__file__)),\n            'thermal_overlay_calibration_on_cam.py',\n        )\n\n    state_lock = threading.Lock()\n    state = {\n        'main_res':       'VGA (640×480)',\n        'lepton_res':     'QQVGA (160×120)',\n        'main_pixfmt':    'RGB565',\n        'lepton_pixfmt':  'RGB565',\n        'lepton_palette': 'IRONBOW',\n    }\n\n    frame_q  = queue.Queue(maxsize=4)\n    stop_evt = threading.Event()\n\n    def handle_exit(signum, frame):\n        stop_evt.set()\n\n    signal.signal(signal.SIGINT,  handle_exit)\n    signal.signal(signal.SIGTERM, handle_exit)\n\n    t = threading.Thread(\n        target=camera_worker,\n        args=(args, state_lock, state, frame_q, stop_evt),\n        daemon=True,\n    )\n    t.start()\n    print(f\"Connecting to {args.port} ...\")\n\n    last_print = time.perf_counter()\n    while not stop_evt.is_set():\n        try:\n            _, _, stats = frame_q.get(timeout=0.1)\n        except queue.Empty:\n            if not t.is_alive():\n                print(\"Camera thread died unexpectedly.\")\n                break\n            continue\n\n        now = time.perf_counter()\n        if now - last_print >= 0.1:\n            last_print = now\n            print(f\"elapsed={stats['elapsed']:.1f}s\\t\"\n                  f\"fps={stats['fps']:.1f}\\t\"\n                  f\"bw={stats['mbps']:.2f} MB/s\\t\"\n                  f\"frames={stats['total_frames']:,}\")\n\n    stop_evt.set()\n    print(\"\\nDone.\")\n\n\n# ---------------------------------------------------------------------------\n# Main\n# ---------------------------------------------------------------------------\n\ndef main(args=None):\n    if args is None:\n        _args = parse_args()\n        if _args.benchmark:\n            run_benchmark(_args)\n            return\n        args = _args\n\n    if args.script is None:\n        args.script = os.path.join(\n            os.path.dirname(os.path.abspath(__file__)),\n            'thermal_overlay_calibration_on_cam.py',\n        )\n\n    logging.basicConfig(\n        format=\"%(relativeCreated)010.3f - %(message)s\",\n        level=logging.DEBUG if args.debug else logging.INFO,\n    )\n\n    state_lock = threading.Lock()\n    state = {\n        'main_res':       'VGA (640×480)',\n        'lepton_res':     'QQVGA (160×120)',\n        'main_pixfmt':    'RGB565',\n        'lepton_pixfmt':  'RGB565',\n        'lepton_palette': 'IRONBOW',\n    }\n\n    # Current pixel dimensions — start at 1×1, updated on first received frame\n    main_wh   = [1, 1]\n    lepton_wh = [1, 1]\n\n    # Overlay alpha: fraction of Lepton blended onto main (0.0–1.0)\n    overlay_alpha = [0.5]\n\n    # Homography matrix (3×3 float64), None = identity / no warp\n    homography = [None]\n\n    # Point correspondences for homography computation:\n    # Each list holds up to 4 (x, y) points in image pixel space\n    # pick_state: None | 'main' | 'lepton'\n    main_pts   = []\n    lepton_pts = []\n    pick_state = [None]\n\n    # Latest decoded frames (H,W,3 uint8), kept for save and composite\n    last_main_rgb   = [None]\n    last_lepton_rgb = [None]\n\n    conn = {'thread': None, 'stop_evt': None}\n    frame_q = queue.Queue(maxsize=4)\n\n    signal.signal(signal.SIGINT, lambda *_: dpg.stop_dearpygui())\n\n    # -----------------------------------------------------------------------\n    # DPG setup\n    # -----------------------------------------------------------------------\n    dpg.create_context()\n\n    # Placeholder textures (dark gray)\n    def _make_placeholder(w, h):\n        buf = np.full(w * h * 4, 0.05, dtype=np.float32)\n        buf[3::4] = 1.0\n        return buf\n\n    with dpg.texture_registry(tag=TEX_REG_TAG):\n        dpg.add_dynamic_texture(1, 1, _make_placeholder(1, 1), tag=MAIN_TEX_TAG)\n        dpg.add_dynamic_texture(1, 1, _make_placeholder(1, 1), tag=LEPTON_TEX_TAG)\n        dpg.add_dynamic_texture(1, 1, _make_placeholder(1, 1), tag=COMP_TEX_TAG)\n\n    # -----------------------------------------------------------------------\n    # Helpers\n    # -----------------------------------------------------------------------\n\n    def _do_connect(port):\n        args.port = port\n        # Reset size tracking; main loop will recreate textures on first frame.\n        main_wh[0], main_wh[1]     = 1, 1\n        lepton_wh[0], lepton_wh[1] = 1, 1\n        homography[0] = None\n        main_pts.clear()\n        lepton_pts.clear()\n        pick_state[0] = None\n\n        stop_evt = threading.Event()\n        conn['stop_evt'] = stop_evt\n        t = threading.Thread(\n            target=camera_worker,\n            args=(args, state_lock, state, frame_q, stop_evt),\n            daemon=True,\n        )\n        t.start()\n        conn['thread'] = t\n        dpg.configure_item(\"connect_btn\", label=\"Disconnect\")\n        _set_cam_settings_enabled(False)\n        logging.info(f\"Connecting to {port}...\")\n\n    def _do_disconnect():\n        if conn['stop_evt']:\n            conn['stop_evt'].set()\n        conn['thread']   = None\n        conn['stop_evt'] = None\n        dpg.configure_item(\"connect_btn\", label=\"Connect\")\n        _set_cam_settings_enabled(True)\n\n    CAM_SETTING_TAGS = [\"main_res_combo\", \"lepton_res_combo\",\n                        \"main_pixfmt_combo\", \"lepton_pixfmt_combo\", \"lepton_palette_combo\"]\n\n    def _set_cam_settings_enabled(enabled):\n        for tag in CAM_SETTING_TAGS:\n            dpg.configure_item(tag, enabled=enabled)\n\n    def _fmt_homography(H):\n        rows = []\n        for row in H:\n            rows.append(\"  [ \" + \",  \".join(f\"{v:12.6f}\" for v in row) + \" ]\")\n        return \"transform =\\n[\\n\" + \",\\n\".join(rows) + \"\\n]\"\n\n    def _recompute_homography():\n        if len(main_pts) == 4 and len(lepton_pts) == 4:\n            try:\n                import cv2\n                src = np.float32(lepton_pts)\n                dst = np.float32(main_pts)\n                H, _ = cv2.findHomography(src, dst)\n                homography[0] = H\n                dpg.set_value(\"pick_status\", \"Homography computed.\")\n            except ImportError:\n                # Manual least-squares DLT without cv2\n                A = []\n                lw, lh = lepton_wh\n                for (sx, sy), (dx, dy) in zip(lepton_pts, main_pts):\n                    A.append([-sx, -sy, -1,  0,   0,  0, sx*dx, sy*dx, dx])\n                    A.append([ 0,   0,  0, -sx, -sy, -1, sx*dy, sy*dy, dy])\n                A = np.array(A, dtype=np.float64)\n                _, _, Vt = np.linalg.svd(A)\n                H = Vt[-1].reshape(3, 3)\n                H /= H[2, 2]\n                homography[0] = H\n                dpg.set_value(\"pick_status\", \"Homography computed (no cv2).\")\n            if homography[0] is not None:\n                dpg.set_value(\"homography_text\", _fmt_homography(homography[0]))\n                dpg.configure_item(\"save_btn\", label=\"Save Images + Transform\")\n\n    def _make_composite():\n        main_rgb   = last_main_rgb[0]\n        lepton_rgb = last_lepton_rgb[0]\n        if main_rgb is None:\n            return None\n        mw, mh = main_wh\n        alpha  = overlay_alpha[0]\n        comp   = main_rgb.copy().astype(np.float32)\n        if lepton_rgb is not None:\n            lh, lw = lepton_rgb.shape[:2]\n            H = homography[0]\n            if H is not None:\n                try:\n                    import cv2\n                    warped = cv2.warpPerspective(lepton_rgb, H, (mw, mh))\n                    # Warp an all-ones mask to find which output pixels are\n                    # actually covered by the lepton — avoids false positives\n                    # from palette colors that map to exactly (0,0,0).\n                    # INTER_NEAREST keeps coverage exactly 0 or 1 so the\n                    # mask has a hard edge with no dark fringe.\n                    coverage = cv2.warpPerspective(\n                        np.ones((lh, lw), dtype=np.float32), H, (mw, mh),\n                        flags=cv2.INTER_NEAREST)\n                except ImportError:\n                    warped = np.array(Image.fromarray(lepton_rgb).resize(\n                        (mw, mh), Image.BILINEAR))\n                    coverage = np.ones((mh, mw), dtype=np.float32)\n                mask = (coverage > 0).reshape(mh, mw, 1).astype(np.float32)\n                comp = comp * (1 - mask * alpha) + warped.astype(np.float32) * alpha\n            else:\n                # Stretch Lepton over main frame — full coverage, no mask needed\n                try:\n                    import cv2\n                    warped = cv2.resize(lepton_rgb, (mw, mh))\n                except ImportError:\n                    warped = np.array(Image.fromarray(lepton_rgb).resize(\n                        (mw, mh), Image.BILINEAR))\n                comp = comp * (1 - alpha) + warped.astype(np.float32) * alpha\n        return np.clip(comp, 0, 255).astype(np.uint8)\n\n    def _fit_images():\n        \"\"\"Scale all three image widgets to fill the available space.\"\"\"\n        vp_w = max(dpg.get_viewport_width()  - CTRL_WIDTH - 30, 1)\n        vp_h = max(dpg.get_viewport_height() - 60, 1)\n        mw, mh = main_wh\n        lw, lh = lepton_wh\n\n        # Top row: each image gets half the available width as its slot.\n        # Scale each to fit its slot, then clamp both to the same display height.\n        slot_w   = vp_w / 2\n        slot_h   = vp_h * 0.55\n        main_s   = min(slot_w / max(mw, 1), slot_h / max(mh, 1))\n        lepton_s = min(slot_w / max(lw, 1), slot_h / max(lh, 1))\n        target_h = min(mh * main_s, lh * lepton_s)\n        main_s   = target_h / max(mh, 1)\n        lepton_s = target_h / max(lh, 1)\n\n        # Bottom: composite fills the remaining height\n        comp_scale = min(vp_w / max(mw, 1), (vp_h * 0.4) / max(mh, 1))\n\n        for tag, w, h, s in [\n            (\"main_img\",   mw, mh, main_s),\n            (\"lepton_img\", lw, lh, lepton_s),\n            (\"comp_img\",   mw, mh, comp_scale),\n        ]:\n            dpg.configure_item(tag,\n                               width=max(1, int(w * s)),\n                               height=max(1, int(h * s)))\n\n        # Center the composite horizontally\n        comp_w = max(1, int(mw * comp_scale))\n        indent = max(0, (vp_w - comp_w) // 2)\n        dpg.configure_item(\"comp_row\", indent=indent)\n\n    # -----------------------------------------------------------------------\n    # Callbacks\n    # -----------------------------------------------------------------------\n\n    def cb_main_res(s, v, u=None):\n        with state_lock:\n            state['main_res'] = v\n\n    def cb_lepton_res(s, v, u=None):\n        with state_lock:\n            state['lepton_res'] = v\n\n    def cb_main_pixfmt(s, v, u=None):\n        with state_lock:\n            state['main_pixfmt'] = v\n\n    def cb_lepton_pixfmt(s, v, u=None):\n        with state_lock:\n            state['lepton_pixfmt'] = v\n        dpg.configure_item(\"lepton_palette_group\", show=(v == 'RGB565'))\n\n    def cb_lepton_palette(s, v, u=None):\n        with state_lock:\n            state['lepton_palette'] = v\n\n    def cb_refresh(s=None, v=None, u=None):\n        items = list_com_ports()\n        dpg.configure_item(\"port_combo\", items=items)\n        if items and not dpg.get_value(\"port_combo\"):\n            dpg.set_value(\"port_combo\", items[0])\n\n    def cb_connect(s=None, v=None, u=None):\n        if conn['thread'] and conn['thread'].is_alive():\n            _do_disconnect()\n        else:\n            port = dpg.get_value(\"port_combo\")\n            if not port:\n                return\n            _do_connect(port)\n\n    def cb_save(s=None, v=None, u=None):\n        ts = int(time.time())\n        if _PIL_AVAILABLE:\n            if last_main_rgb[0] is not None:\n                name = f\"thermal_main_{ts}.png\"\n                Image.fromarray(last_main_rgb[0]).save(name)\n                print(f\"Saved: {name}\")\n            if last_lepton_rgb[0] is not None:\n                name = f\"thermal_lepton_{ts}.png\"\n                Image.fromarray(last_lepton_rgb[0]).save(name)\n                print(f\"Saved: {name}\")\n            comp = _make_composite()\n            if comp is not None:\n                name = f\"thermal_composite_{ts}.png\"\n                Image.fromarray(comp).save(name)\n                print(f\"Saved: {name}\")\n        else:\n            print(\"pip install Pillow  to enable image saving.\")\n        H = homography[0]\n        if H is not None:\n            name = f\"thermal_transform_{ts}.txt\"\n            with open(name, 'w') as f:\n                f.write(_fmt_homography(H) + \"\\n\")\n            print(f\"Saved: {name}\")\n\n    def cb_pick_main(s=None, v=None, u=None):\n        main_pts.clear()\n        lepton_pts.clear()\n        homography[0] = None\n        pick_state[0] = 'main'\n        dpg.set_value(\"pick_status\", \"Click 4 points on the main image.\")\n\n    def cb_pick_lepton(s=None, v=None, u=None):\n        lepton_pts.clear()\n        pick_state[0] = 'lepton'\n        dpg.set_value(\"pick_status\",\n                      f\"Click 4 matching points on the Lepton image \"\n                      f\"({len(main_pts)}/4 main points set).\")\n\n    def cb_align_mode(s, v, u=None):\n        is_auto = (v == 'Automatic')\n        dpg.configure_item(\"manual_group\", show=not is_auto)\n        dpg.configure_item(\"auto_group\",   show=is_auto)\n\n    def _find_board(img_rgb, board_size):\n        \"\"\"Try multiple detection methods and preprocessing variants.\n\n        Accepts an RGB image so individual channels can be tried — important\n        because different thermal palettes (IRONBOW, RAINBOW, etc.) achieve\n        best hot/cold contrast on different channels after grayscale conversion.\n\n        Returns (True, corners) or (False, None).\n        \"\"\"\n        import cv2\n        clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(4, 4))\n\n        def _variants(g):\n            enhanced = clahe.apply(g)\n            blurred  = cv2.GaussianBlur(enhanced, (0, 0), 3)\n            sharp    = cv2.addWeighted(enhanced, 2.0, blurred, -1.0, 0)\n            _, otsu     = cv2.threshold(g,     0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)\n            _, otsu_inv = cv2.threshold(255-g, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)\n            return [enhanced, 255 - enhanced, sharp, 255 - sharp,\n                    otsu, otsu_inv, g, 255 - g]\n\n        # Build candidate list: standard grayscale + each individual channel\n        gray   = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2GRAY)\n        r, g, b = img_rgb[:, :, 0], img_rgb[:, :, 1], img_rgb[:, :, 2]\n        candidates = (_variants(gray) + _variants(r) +\n                      _variants(g)    + _variants(b))\n\n        flags_classic = cv2.CALIB_CB_ADAPTIVE_THRESH | cv2.CALIB_CB_NORMALIZE_IMAGE\n\n        # findChessboardCornersSB (OpenCV 4+, saddle-point, most robust)\n        if hasattr(cv2, 'findChessboardCornersSB'):\n            for img in candidates:\n                ret, corners = cv2.findChessboardCornersSB(img, board_size, flags=0)\n                if ret:\n                    return True, corners\n\n        # Classic detector fallback\n        for img in candidates:\n            ret, corners = cv2.findChessboardCorners(img, board_size, flags=flags_classic)\n            if ret:\n                return True, corners\n\n        return False, None\n\n    def cb_auto_detect(s=None, v=None, u=None):\n        try:\n            import cv2\n        except ImportError:\n            dpg.set_value(\"pick_status\", \"Auto mode requires opencv-python.\")\n            return\n        main_rgb   = last_main_rgb[0]\n        lepton_rgb = last_lepton_rgb[0]\n        if main_rgb is None or lepton_rgb is None:\n            dpg.set_value(\"pick_status\", \"No frames available yet.\")\n            return\n        cols = dpg.get_value(\"board_cols\")\n        rows = dpg.get_value(\"board_rows\")\n        board_size = (cols, rows)\n\n        # Lepton is very low-res; upscale 4× so corners have enough spread\n        lh, lw = lepton_rgb.shape[:2]\n        SCALE = 4\n        lepton_up = cv2.resize(lepton_rgb, (lw * SCALE, lh * SCALE),\n                               interpolation=cv2.INTER_CUBIC)\n\n        ret_m, corners_m = _find_board(main_rgb,  board_size)\n        ret_l, corners_l = _find_board(lepton_up, board_size)\n\n        if not ret_m and not ret_l:\n            dpg.set_value(\"pick_status\",\n                          f\"Board ({cols}×{rows}) not found in either image. \"\n                          f\"Ensure the full board is visible in both cameras.\")\n            return\n        if not ret_m:\n            dpg.set_value(\"pick_status\",\n                          f\"Board ({cols}×{rows}) not found in main image.\")\n            return\n        if not ret_l:\n            dpg.set_value(\"pick_status\",\n                          f\"Board ({cols}×{rows}) not found in Lepton image.\")\n            return\n\n        criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)\n        gray_m = cv2.cvtColor(main_rgb,  cv2.COLOR_RGB2GRAY)\n        gray_l = cv2.cvtColor(lepton_up, cv2.COLOR_RGB2GRAY)\n        corners_m = cv2.cornerSubPix(gray_m, corners_m, (11, 11), (-1, -1), criteria)\n        corners_l = cv2.cornerSubPix(gray_l, corners_l, (5,  5),  (-1, -1), criteria)\n\n        # Scale Lepton corners back to original pixel space\n        corners_l = corners_l / SCALE\n\n        src = corners_l.reshape(-1, 2).astype(np.float32)\n        dst = corners_m.reshape(-1, 2).astype(np.float32)\n        H, inlier_mask = cv2.findHomography(src, dst, cv2.RANSAC, 5.0)\n        if H is None:\n            dpg.set_value(\"pick_status\", \"Homography computation failed.\")\n            return\n        inliers = int(inlier_mask.sum()) if inlier_mask is not None else len(src)\n        homography[0] = H\n        dpg.set_value(\"homography_text\", _fmt_homography(H))\n        dpg.configure_item(\"save_btn\", label=\"Save Images + Transform\")\n        dpg.set_value(\"pick_status\",\n                      f\"Auto: {cols}×{rows} board, {inliers}/{len(src)} inliers.\")\n\n    def cb_reset_homography(s=None, v=None, u=None):\n        homography[0] = None\n        main_pts.clear()\n        lepton_pts.clear()\n        pick_state[0] = None\n        dpg.set_value(\"pick_status\", \"Homography reset.\")\n        dpg.set_value(\"homography_text\", \"\")\n        dpg.configure_item(\"save_btn\", label=\"Save Images\")\n\n    def _handle_image_click(tag, img_wh, pts_list, other_list, this_label):\n        \"\"\"Record a clicked point in image pixel space.\"\"\"\n        mx, my = dpg.get_mouse_pos(local=False)\n        try:\n            imin = dpg.get_item_rect_min(tag)\n            imax = dpg.get_item_rect_max(tag)\n        except Exception:\n            return\n        if not (imin[0] <= mx <= imax[0] and imin[1] <= my <= imax[1]):\n            return\n        w, h = img_wh\n        dw = imax[0] - imin[0]\n        dh = imax[1] - imin[1]\n        px = int((mx - imin[0]) / max(dw, 1) * w)\n        py = int((my - imin[1]) / max(dh, 1) * h)\n        pts_list.append((px, py))\n        n = len(pts_list)\n        if n < 4:\n            dpg.set_value(\"pick_status\",\n                          f\"{n}/4 {this_label} points. Keep clicking.\")\n        else:\n            if len(other_list) == 4:\n                _recompute_homography()\n            else:\n                other_label = 'Lepton' if this_label == 'main' else 'main'\n                dpg.set_value(\"pick_status\",\n                              f\"4 {this_label} points set. Now click 4 {other_label} points.\")\n\n    def cb_mouse_click(s=None, v=None, u=None):\n        if pick_state[0] == 'main':\n            if len(main_pts) < 4:\n                _handle_image_click(\"main_img\", main_wh,\n                                    main_pts, lepton_pts, 'main')\n        elif pick_state[0] == 'lepton':\n            if len(lepton_pts) < 4:\n                _handle_image_click(\"lepton_img\", lepton_wh,\n                                    lepton_pts, main_pts, 'Lepton')\n\n    # -----------------------------------------------------------------------\n    # UI layout\n    # -----------------------------------------------------------------------\n    with dpg.window(tag=\"main_win\", no_scrollbar=True, no_title_bar=True):\n        with dpg.table(\n            header_row=False, resizable=True,\n            borders_innerV=True, tag=\"layout_table\",\n            scrollX=False, scrollY=False,\n        ):\n            dpg.add_table_column(init_width_or_weight=1.0)\n            dpg.add_table_column(init_width_or_weight=CTRL_WIDTH, width_fixed=True)\n\n            with dpg.table_row():\n\n                # ── Left: image panels ──────────────────────────────────────\n                with dpg.table_cell():\n                    # Top row: main + lepton side by side\n                    with dpg.group(horizontal=True, tag=\"top_images\"):\n                        dpg.add_image(MAIN_TEX_TAG,   tag=\"main_img\",\n                                      width=1, height=1)\n                        dpg.add_image(LEPTON_TEX_TAG, tag=\"lepton_img\",\n                                      width=1, height=1)\n                    dpg.add_separator()\n                    # Bottom: composite (centered via indent set in _fit_images)\n                    with dpg.group(tag=\"comp_row\"):\n                        dpg.add_image(COMP_TEX_TAG, tag=\"comp_img\",\n                                      width=1, height=1)\n\n                # ── Right: controls ─────────────────────────────────────────\n                with dpg.table_cell():\n                    with dpg.child_window(width=CTRL_WIDTH, border=False):\n\n                        # Windows performance warning\n                        if sys.platform == 'win32':\n                            dpg.add_text(\n                                \"Warning: Windows reduces transfer speed.\\n\"\n                                \"Use macOS or Linux for best performance.\",\n                                color=(255, 200, 0, 255))\n                            dpg.add_separator()\n\n                        # ── Connection ──────────────────────────────────────\n                        init_ports = list_com_ports()\n                        init_port  = args.port or (init_ports[0] if init_ports else \"\")\n                        with dpg.group(horizontal=True):\n                            dpg.add_text(\"Port  \")\n                            dpg.add_combo(\n                                items=init_ports, default_value=init_port,\n                                tag=\"port_combo\", width=CTRL_WIDTH - 90)\n                            dpg.add_button(label=\"Ref\", callback=cb_refresh, width=28)\n\n                        # ── Camera Parameters ───────────────────────────────\n                        dpg.add_separator()\n                        dpg.add_text(\"Camera Parameters  (applied at connect)\")\n\n                        with dpg.group(horizontal=True):\n                            dpg.add_text(\"Main Res \")\n                            dpg.add_combo(\n                                tag=\"main_res_combo\",\n                                items=MAIN_RES_OPTIONS,\n                                default_value=state['main_res'],\n                                callback=cb_main_res, width=-1)\n\n                        with dpg.group(horizontal=True):\n                            dpg.add_text(\"Main Fmt \")\n                            dpg.add_combo(\n                                tag=\"main_pixfmt_combo\",\n                                items=PIXFMT_OPTIONS,\n                                default_value=state['main_pixfmt'],\n                                callback=cb_main_pixfmt, width=-1)\n\n                        with dpg.group(horizontal=True):\n                            dpg.add_text(\"Lepton   \")\n                            dpg.add_combo(\n                                tag=\"lepton_res_combo\",\n                                items=LEPTON_RES_OPTIONS,\n                                default_value=state['lepton_res'],\n                                callback=cb_lepton_res, width=-1)\n\n                        with dpg.group(horizontal=True):\n                            dpg.add_text(\"Lep Fmt  \")\n                            dpg.add_combo(\n                                tag=\"lepton_pixfmt_combo\",\n                                items=PIXFMT_OPTIONS,\n                                default_value=state['lepton_pixfmt'],\n                                callback=cb_lepton_pixfmt, width=-1)\n\n                        with dpg.group(horizontal=True, tag=\"lepton_palette_group\",\n                                       show=True):\n                            dpg.add_text(\"Lep Pal  \")\n                            dpg.add_combo(\n                                tag=\"lepton_palette_combo\",\n                                items=PALETTE_OPTIONS,\n                                default_value=state['lepton_palette'],\n                                callback=cb_lepton_palette, width=-1)\n\n                        dpg.add_separator()\n                        dpg.add_button(label=\"Connect\", tag=\"connect_btn\",\n                                       callback=cb_connect, width=-1)\n\n                        # ── Overlay Alpha ───────────────────────────────────\n                        dpg.add_separator()\n                        dpg.add_text(\"Overlay Alpha\")\n                        dpg.add_slider_int(\n                            tag=\"alpha_slider\",\n                            default_value=int(overlay_alpha[0] * 100),\n                            min_value=0, max_value=100,\n                            format=\"%d%%\", width=-1,\n                            callback=lambda s, v, u=None: overlay_alpha.__setitem__(0, v / 100.0))\n\n                        # ── Overlay Alignment ───────────────────────────────\n                        dpg.add_separator()\n                        dpg.add_text(\"Overlay Alignment\")\n\n                        with dpg.group(horizontal=True):\n                            dpg.add_text(\"Mode     \")\n                            dpg.add_combo(\n                                items=[\"Manual\", \"Automatic\"],\n                                default_value=\"Manual\",\n                                tag=\"align_mode_combo\",\n                                callback=cb_align_mode, width=-1)\n\n                        # Manual mode\n                        with dpg.group(tag=\"manual_group\", show=True):\n                            dpg.add_text(\n                                \"Click 4 matching points on each image to \"\n                                \"compute a homography that aligns the Lepton \"\n                                \"onto the main camera frame. Without a \"\n                                \"homography the Lepton is stretched to fill \"\n                                \"the composite.\",\n                                wrap=CTRL_WIDTH - 10)\n                            dpg.add_button(label=\"Pick Main Points\",\n                                           callback=cb_pick_main, width=-1)\n                            dpg.add_button(label=\"Pick Lepton Points\",\n                                           callback=cb_pick_lepton, width=-1)\n\n                        # Automatic mode\n                        with dpg.group(tag=\"auto_group\", show=False):\n                            dpg.add_text(\n                                \"Place a heated checkerboard in view of both \"\n                                \"cameras, then click Detect. Inner corners \"\n                                \"(cols × rows) must match the board.\",\n                                wrap=CTRL_WIDTH - 10)\n                            with dpg.group(horizontal=True):\n                                dpg.add_text(\"Cols \")\n                                dpg.add_input_int(tag=\"board_cols\",\n                                                  default_value=7,\n                                                  min_value=2, max_value=20,\n                                                  width=-1)\n                            with dpg.group(horizontal=True):\n                                dpg.add_text(\"Rows \")\n                                dpg.add_input_int(tag=\"board_rows\",\n                                                  default_value=6,\n                                                  min_value=2, max_value=20,\n                                                  width=-1)\n                            dpg.add_button(label=\"Auto Detect\",\n                                           callback=cb_auto_detect, width=-1)\n\n                        dpg.add_button(label=\"Reset Homography\",\n                                       callback=cb_reset_homography, width=-1)\n\n                        dpg.add_text(\"\", tag=\"pick_status\", wrap=CTRL_WIDTH - 10)\n                        dpg.add_input_text(\n                            tag=\"homography_text\",\n                            default_value=\"\",\n                            multiline=True, readonly=True,\n                            width=-1, height=90)\n\n                        # ── Save ────────────────────────────────────────────\n                        dpg.add_separator()\n                        dpg.add_button(label=\"Save Images\", tag=\"save_btn\",\n                                       callback=cb_save, width=-1)\n\n                        # ── Statistics ──────────────────────────────────────\n                        dpg.add_separator()\n                        dpg.add_text(\"Statistics\")\n\n                        stat_defs = [\n                            (\"FPS\",           \"stat_fps\"),\n                            (\"Bandwidth\",     \"stat_mbps\"),\n                            (\"Total frames\",  \"stat_frames\"),\n                            (\"Uptime\",        \"stat_uptime\"),\n                        ]\n                        for lbl, tag in stat_defs:\n                            with dpg.group(horizontal=True):\n                                dpg.add_text(f\"{lbl:<14}\")\n                                dpg.add_text(\"—\", tag=tag)\n\n    # Mouse handler for point picking\n    with dpg.handler_registry():\n        dpg.add_mouse_click_handler(callback=cb_mouse_click)\n\n    dpg.create_viewport(\n        title=\"Thermal Overlay Calibration\",\n        width=1280, height=800,\n        resizable=True,\n    )\n    dpg.setup_dearpygui()\n    dpg.show_viewport()\n    dpg.set_primary_window(\"main_win\", True)\n    dpg.add_viewport_drawlist(tag=\"vp_overlay\", front=True)\n\n    if args.port:\n        _do_connect(args.port)\n\n    # -----------------------------------------------------------------------\n    # Render loop\n    # -----------------------------------------------------------------------\n    last_stat_time  = time.perf_counter()\n    pending_stats   = None\n\n    while dpg.is_dearpygui_running():\n        # Drain frame queue\n        while True:\n            try:\n                main_frame, lepton_frame, stats = frame_q.get_nowait()\n            except queue.Empty:\n                break\n\n            pending_stats = stats\n\n            # Decode and upload main frame\n            if main_frame is not None:\n                data, w, h = main_frame\n                if w != main_wh[0] or h != main_wh[1]:\n                    main_wh[0], main_wh[1] = w, h\n                    for t in (MAIN_TEX_TAG, COMP_TEX_TAG):\n                        dpg.delete_item(t)\n                        if dpg.does_alias_exist(t):\n                            dpg.remove_alias(t)\n                    dpg.add_dynamic_texture(w, h, _make_placeholder(w, h),\n                                            tag=MAIN_TEX_TAG, parent=TEX_REG_TAG)\n                    dpg.add_dynamic_texture(w, h, _make_placeholder(w, h),\n                                            tag=COMP_TEX_TAG, parent=TEX_REG_TAG)\n                    dpg.configure_item(\"main_img\", texture_tag=MAIN_TEX_TAG)\n                    dpg.configure_item(\"comp_img\", texture_tag=COMP_TEX_TAG)\n                expected_rgb565 = w * h * 2\n                expected_gray   = w * h\n                if len(data) == expected_rgb565:\n                    rgb = rgb565_to_rgb888(data, w, h)\n                elif len(data) == expected_gray:\n                    rgb = gray_to_rgb888(data, w, h)\n                else:\n                    rgb = None\n                if rgb is not None:\n                    last_main_rgb[0] = rgb\n                    dpg.set_value(MAIN_TEX_TAG, to_dpg_rgba(rgb))\n\n            # Decode and upload lepton frame\n            if lepton_frame is not None:\n                data, w, h = lepton_frame\n                if w != lepton_wh[0] or h != lepton_wh[1]:\n                    lepton_wh[0], lepton_wh[1] = w, h\n                    dpg.delete_item(LEPTON_TEX_TAG)\n                    if dpg.does_alias_exist(LEPTON_TEX_TAG):\n                        dpg.remove_alias(LEPTON_TEX_TAG)\n                    dpg.add_dynamic_texture(w, h, _make_placeholder(w, h),\n                                            tag=LEPTON_TEX_TAG, parent=TEX_REG_TAG)\n                    dpg.configure_item(\"lepton_img\", texture_tag=LEPTON_TEX_TAG)\n                expected_rgb565 = w * h * 2\n                expected_gray   = w * h\n                if len(data) == expected_rgb565:\n                    rgb = rgb565_to_rgb888(data, w, h)\n                elif len(data) == expected_gray:\n                    rgb = gray_to_rgb888(data, w, h)\n                else:\n                    rgb = None\n                if rgb is not None:\n                    last_lepton_rgb[0] = rgb\n                    dpg.set_value(LEPTON_TEX_TAG, to_dpg_rgba(rgb))\n\n            # Update composite\n            comp = _make_composite()\n            if comp is not None:\n                dpg.set_value(COMP_TEX_TAG, to_dpg_rgba(comp))\n\n        # Stats update at ~5 Hz\n        now = time.perf_counter()\n        if pending_stats and (now - last_stat_time) >= 0.2:\n            s = pending_stats\n            dpg.set_value(\"stat_fps\",    f\"{s['fps']:.1f} fps\")\n            dpg.set_value(\"stat_mbps\",   f\"{s['mbps']:.2f} MB/s\")\n            dpg.set_value(\"stat_frames\", f\"{s['total_frames']:,}\")\n            dpg.set_value(\"stat_uptime\", f\"{s['elapsed']:.1f} s\")\n            last_stat_time = now\n\n        # Reset UI if the camera thread died unexpectedly (e.g. connection error)\n        if conn['thread'] and not conn['thread'].is_alive():\n            _do_disconnect()\n\n        _fit_images()\n\n        # Draw point overlays on top of the image widgets\n        _PT_COLORS = [\n            (0, 255,   0, 255),\n            (255, 255,  0, 255),\n            (255, 165,  0, 255),\n            (255,   0,  0, 255),\n        ]\n        dpg.delete_item(\"vp_overlay\", children_only=True)\n        try:\n            for img_tag, pts, wh in [\n                (\"main_img\",   main_pts,   main_wh),\n                (\"lepton_img\", lepton_pts, lepton_wh),\n            ]:\n                if not pts:\n                    continue\n                imin = dpg.get_item_rect_min(img_tag)\n                imax = dpg.get_item_rect_max(img_tag)\n                fw, fh = wh\n                dw = imax[0] - imin[0]\n                dh = imax[1] - imin[1]\n                for i, (px, py) in enumerate(pts):\n                    sx = imin[0] + px / max(fw, 1) * dw\n                    sy = imin[1] + py / max(fh, 1) * dh\n                    col = _PT_COLORS[i % len(_PT_COLORS)]\n                    dpg.draw_circle([sx, sy], 8, color=col,\n                                    thickness=2, parent=\"vp_overlay\")\n                    dpg.draw_text([sx + 10, sy - 8], str(i + 1), size=14,\n                                  color=col, parent=\"vp_overlay\")\n        except Exception:\n            pass\n\n        dpg.render_dearpygui_frame()\n\n    dpg.destroy_context()\n\n    if conn['stop_evt']:\n        conn['stop_evt'].set()\n\n    print(\"\\nDone.\")\n\n\nif __name__ == '__main__':\n    _args = parse_args()\n    if _args.benchmark:\n        run_benchmark(_args)\n    else:\n        main(_args)\n"
  }
]