Repository: openmv/openmv-projects Branch: master Commit: ff2fd706f1cd Files: 28 Total size: 710.5 KB Directory structure: gitextract_ouy8kveg/ ├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── robotics/ │ ├── README.md │ ├── autonomous-rover/ │ │ └── README.md │ └── donkey-car/ │ ├── README.md │ ├── download/ │ │ ├── Magnet_Plate_v7.stl │ │ ├── Magnet_Roll_Cage_v2.stl │ │ └── OpenMV_Donkey_Mount.stl │ ├── line_follower_main.py │ ├── pca9685.py │ ├── servo.py │ └── servo_controller/ │ └── servo_controller.ino └── tools/ ├── README.md ├── ccm-tuning/ │ ├── README.md │ ├── ccm_tuning_on_cam.py │ └── ccm_tuning_on_pc.py ├── genx320-event-streaming/ │ ├── README.md │ ├── genx320_event_mode_streaming_on_cam.py │ ├── genx320_event_mode_streaming_on_pc.py │ └── genx320_raw_event_mode_streaming_on_cam.py ├── genx320-overlay-calibration/ │ ├── README.md │ ├── genx320_overlay_calibration_on_cam.py │ └── genx320_overlay_calibration_on_pc.py └── thermal-overlay-calibration/ ├── README.md ├── thermal_overlay_calibration_on_cam.py └── thermal_overlay_calibration_on_pc.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ *.mp4 !text !filter !merge !diff ================================================ FILE: .gitignore ================================================ # Claude session folder .claude/ # Python cache __pycache__/ *.pyc # CCM tuner generated output files ccm_frame_*.bmp ccm_params_*.txt # GenX320 event streaming saved output files events_*.png events_*.csv # Thermal overlay calibration saved output files thermal_main_*.png thermal_lepton_*.png thermal_composite_*.png thermal_transform_*.txt # GenX320 overlay calibration saved output files genx320_overlay_main_*.png genx320_overlay_genx320_*.png genx320_overlay_composite_*.png genx320_overlay_transform_*.txt ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2017 OpenMV Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ [![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) [![GitHub forks](https://img.shields.io/github/forks/openmv/openmv-projects?color=green)](https://github.com/openmv/openmv-projects/network) [![GitHub stars](https://img.shields.io/github/stars/openmv/openmv-projects?color=yellow)](https://github.com/openmv/openmv-projects/stargazers) [![GitHub issues](https://img.shields.io/github/issues/openmv/openmv-projects?color=orange)](https://github.com/openmv/openmv-projects/issues) # OpenMV Projects A 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. - [PC Tools](#pc-tools) - [Robotics](#robotics) - [Contributing to the project](#contributing-to-the-project) + [Contribution guidelines](#contribution-guidelines) --- ## PC Tools Desktop 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. | Project | Description | |---------|-------------| | [GenX320 Viz](tools/genx320-event-streaming/README.md) | Real-time event camera visualization with per-pixel frequency mapping for the Prophesee GenX320 sensor. | | [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. | | [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. | | [CCM Tuning](tools/ccm-tuning/README.md) | Interactive Color Correction Matrix tuner — streams raw Bayer frames and replicates the N6 ISP pipeline in software. | [Browse all tools](tools/README.md) --- ## Robotics Complete robotics projects that use the OpenMV Cam as the primary perception system — from autonomous rovers to self-driving cars. | Project | Description | |---------|-------------| | [Donkey Car](robotics/donkey-car/README.md) | OpenMV-powered Donkey Car build with line following and autonomous driving. | | [Autonomous Rover](robotics/autonomous-rover/README.md) | Tracked rover using monocular edge detection for obstacle avoidance, controlled by a Teensy 3.5. | [Browse all robotics projects](robotics/README.md) --- ## Contributing to the project Contributions are most welcome. If you are interested in contributing to the project, start by creating a fork of the following repository: * https://github.com/openmv/openmv-projects.git Clone the forked repository, and add a remote to the main repository: ```bash git clone https://github.com//openmv-projects.git git -C openmv-projects remote add upstream https://github.com/openmv/openmv-projects.git ``` Now 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: ```bash git checkout -b git push origin -u ``` ### Contribution guidelines Please 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: * Fix one problem. Don't try to tackle multiple issues at once. * Split the changes into logical groups using git commits. * Pull request title should be less than 78 characters, and match this pattern: * `:<1 space><.>` * Commit subject line should be less than 78 characters, and match this pattern: * `:<1 space><.>` ================================================ FILE: robotics/README.md ================================================ # OpenMV Robotics Projects Complete 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. --- ## [Donkey Self-Driving Car](donkey-car/README.md) An [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. The 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. **Includes:** - 3D-printable parts: roll cage, camera mount, and magnet plate (STL files in `download/`) - Step-by-step build photo guide (40+ steps) - `line_follower_main.py` — on-camera line following script - PCA9685 servo driver and servo controller Arduino sketch --- ## [Autonomous Rover](autonomous-rover/README.md) A 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. The 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. **Hardware:** - OpenMV Cam (vision + UART) - Teensy 3.5 (motion control, odometry) - VL53L0X TOF sensor (close-range fallback distance) - BNO055 IMU (turn control) - Tracked aluminum chassis with Hall effect odometry sensors - Adafruit Motor Shield V2 ================================================ FILE: robotics/autonomous-rover/README.md ================================================ # Teensy 3.5/OpenMV Rover This 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. About 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: >      The method I am using involves capturing an image, converting it to grayscale, blurring it slightly and then using canny edge detection to highlight the edges in the image. Using the edge detected image, starting from the left and moving along 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 edge encountered. I am left with an array that contains coordinates of the first edges found in front of the robot. Using this array, I then 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 anything 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 about. This will change depending on the angle of the head. If the head is looking down towards the ground, obviously everything in the scene 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, indicated by a sharp change in values in the array of nearest edges. With 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: ![EdgeDetection Test](images/EdgeDetectionTest.png) Now 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. ![Rover Chassis](images/EbayRover.jpg) Angular 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. The 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. I 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. If 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. To 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. Source Code and this readme is found on the TeensyOpenMV github page: https://github.com/mjs513/TeensyOpenMV Here are a couple of screen shots of the rover: 1. http://forums.openmv.io/viewtopic.php?f=5&t=276 2. http://forums.openmv.io/viewtopic.php?f=6&t=393 ![Front View](images/Rover2.png) ![Side View](images/Rover1.png) ================================================ FILE: robotics/donkey-car/README.md ================================================ # Donkey Self-Driving Car This 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). ![OpenMV Cam powered Donkey Car](images/donkey-car-web.jpg "OpenMV Cam powered Donkey Car") ## Parts The 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. Part Description | Part Link | Part Count | Part Cost ---------------- | --------- | ---------- | --------- 1/16 2.4Ghz Exceed RC Magnet Car
![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 Magnet Car Base Plate
![Magnet Car Base Plate](images/parts/base.jpg "Magnet Car Base Plate") | https://www.shapeways.com/product/6YD3XR9ND/magnet-car-base-plate

You can download the STL file for this part [here](download/Magnet_Plate_v7.stl).

*Magnet Base Plate by Adam Conway*. | 1 | $55.10 Magnet Car Roll Cage
![Magnet Car Roll Cage](images/parts/cage.jpg "Magnet Car Roll Cage") | https://www.shapeways.com/product/74VXFV7AT/magnet-car-roll-cage

You can download the STL file for this part [here](download/Magnet_Roll_Cage_v2.stl).

*Magnet Car Roll Cage by Adam Conway*. | 1 | $66.92 OpenMV Cam Donkey Mount
![OpenMV Cam Donkey Mount](images/parts/camera-mount.jpg "OpenMV Cam Donkey Mount") | https://www.shapeways.com/product/G7YQBUMRC/openmv-cam-donkey-mount

You can download the STL file for these parts [here](download/OpenMV_Donkey_Mount.stl).

*OpenMV Cam Donkey Mount by Chris Anderson*. | 1 | $21.18 M2 Machine Screw Set
![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 M3 35mm Machine Screws
![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 M3 Machine Screw Nuts
![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 30 CM Servo Lead Extension Assemblies
![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 OpenMV Cam M7
![OpenMV Cam M7](images/parts/camera.jpg "OpenMV Cam M7") | https://openmv.io/products/openmv-cam-m7

Note: You will need a soldering iron and solder to attach the pin headers for this part. | 1 | $65.00 OpenMV Cam Servo Shield
![OpenMV Cam Servo Shield](images/parts/servos.jpg "OpenMV Cam Servo Shield") | https://openmv.io/products/servo-shield

Note: You will need a soldering iron and solder to attach the pin headers for this part. | 1 | $15.00 Zip Ties
![Zip Ties](images/parts/ties.jpg "Zip Ties") | https://www.amazon.com/Cable-Zip-Ties-Fastening-Organization/dp/B01LPOB2JW | 1 | $9.99 Micro USB Cable
![Micro USB Cable](images/parts/uusb.jpg "Micro USB Cable") | https://www.amazon.com/AmazonBasics-USB-Male-Micro-Cable/dp/B01EK87T9M | 1 | $5.99 **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). While 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!** Part Description | Part Link | Part Count | Part Cost ---------------- | --------- | ---------- | --------- 5V 16 MHz Arduino Pro Mini
![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 Arduino Pro Mini Programmer
![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 Servo Controller Board
![Servo Controller Board](images/parts/controller.jpg "Servo Controller Board") | https://oshpark.com/shared_projects/2bKUWmbq

You can download the Gerber files for this part [here](https://644db4de3505c40a0444-327723bce298e3ff5813fb42baeefbaa.ssl.cf1.rackcdn.com/ab7a7db45c3c6b37bcca1d8fc84e26e4.zip).

*Servo Controller Board by Chris Anderson*. | 1 | $10.50 Male Headers
![Male Headers](images/parts/male.jpg "Male Headers") | https://www.amazon.com/SamIdea-15-Pack-Straight-Connector-Prototype/dp/B01M9FCAXW

Note: You will need a soldering iron and solder to attach these pin headers to the above PCB. | 1 | $5.69 8-pin Stackable Headers
![8-pin Stackable Headers](images/parts/headers.jpg "8-pin Stackable Headers") | https://www.amazon.com/Venel-Electronic-Component-Stackable-Shields/dp/B071454KP1

Note: You will need a soldering iron and solder to attach these pin headers to the above PCB. | 1 | $5.08 RC Receiver Servo Adapters
![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 **Sub-Total $42.20** - You may have some of the above parts lying around. In 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. Part Description | Part Link | Part Count | Part Cost ---------------- | --------- | ---------- | --------- OpenMV Cam Wide Angle Lens
![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 **Sub-Total $15.00** Moving 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. Part Description | Part Link | Part Count | Part Cost ---------------- | --------- | ---------- | --------- Turnigy 1300mAh 2S 20C LiPo Pack
![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 Tamiya Mini Female to XT60 Male Adapters
![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 Turnigy E3 Compact 2S/3S Lipo Charger
![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 **Sub-Total $45.77** Finally, 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. Part Description | Part Link | Part Count | Part Cost ---------------- | --------- | ---------- | --------- OpenMV Cam WiFi Shield
![OpenMV Cam WiFi Shield](images/parts/wifi.jpg "OpenMV Cam WiFi Shield") | https://openmv.io/products/wifi-shield | 1 | $35.00 *Note, as of 8/15/2017 wireless programming has not yet been implemented for the OpenMV Cam but it is coming soon.* **Sub-Total $35.00** ## Assembly Once you've purchased and received all the parts you want for your DIY Robocar above you can now build it. ![Parts](images/build/step(1)small.jpg "Parts") Note that you're going to need an exacto knife, a philips screw driver, pliers, a soldering iron, and some solder. ![Tools](images/build/step(2)small.jpg "Tools") ### Step 1 - Clean up parts: Your 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. ![De-bur](images/build/step(3)small.jpg "De-bur") Next, 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. ![Insert](images/build/step(4)small.jpg "Insert") ### Step 2 - Assemble the body: The 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. ![Body](images/build/step(5)small.jpg "Body") To 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. ![Body](images/build/step(6)small.jpg "Body") After 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. ![Last](images/build/step(7)small.jpg "Last") Next, 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. ![Align](images/build/step(8)small.jpg "Align") Moving 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. ![Lock](images/build/step(9)small.jpg "Lock") Now, 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. ![Holder](images/build/step(10)small.jpg "Holder") Next, 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. ![Hood](images/build/step(11)small.jpg "Hood") So 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. ![Clip](images/build/step(12)small.jpg "Clip") Afterwards, 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. ![Exacto](images/build/step(13)small.jpg "Exacto") Finally, push each pin through each stand hole to firmly attach the base to the RC Car. ![Attach](images/build/step(14)small.jpg "Attach") Once you've finished this your car should look like this below. ![Done](images/build/step(15)small.jpg "Done") ### Step 3 - Assemble the head: Now 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. ![Clean-up](images/build/step(16)small.jpg "Clean-up") Then 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. ![Legs](images/build/step(17)small.jpg "Legs") Finally, if you bought the wide angle lens above replace the lens that your OpenMV Cam comes with the wide angle lens. ![Lens](images/build/step(18)small.jpg "Lens") Next, let's build up the servo shield for your OpenMV Cam so that it can control the RC car. ![Shield](images/build/step(19)small.jpg "Shield") You 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. ![Soldered](images/build/step(20)small.jpg "Soldered") If 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. ![WiFi](images/build/step(21)small.jpg "WiFi") Finally, 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. ![Stack](images/build/step(22)small.jpg "Stack") ### Step 4 - Putting it together: Attach 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. ![Mounting](images/build/step(23)small.jpg "Mounting") Next, 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. ![Controller](images/build/step(24)small.jpg "Controller") Finally, put the black tube that comes with your RC Car over the antenna to protect the antenna. ![Antenna](images/build/step(25)small.jpg "Antenna") If you bought the LiPo battery upgrade parts let's install those next. First, attach the XT60 adapters to each LiPo battery. ![Adapters](images/build/step(26)small.jpg "Adapters") Then, 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. ![Lipo](images/build/step(27)small.jpg "Lipo") After your done it should look like the picture below. ![Done](images/build/step(28)small.jpg "Done") **LAST, MAKE SURE TO MOVE THE JUMPER ON YOUR ESC TO THE LIPO POSITION TOO!** ![Danger](images/build/step(29)small.jpg "Danger") ### Step 5 - Installing the software: Because 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. ![OpenMV_Cam](images/build/step(40)small.jpg "OpenMV_Cam") Next, 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. ![Update](images/build/step(41).png "Update") Click 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. ![Firmware](images/build/step(42).png "Firmware") Now 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. ![View](images/build/step(43).png "View") After 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). ![Script](images/build/step(44).png "Script") Finally, 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. *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).* ### Optional Step 1 - Building the Arduino based Servo Controller: If 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. ![Parts](images/build/step(30)small.jpg "Parts") First, solder up the Arduino Pro Mini like the image below. ![Arduino](images/build/step(31)small.jpg "Arduino") Next, 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. ![Controller](images/build/step(32)small.jpg "Controller") It should look like this on the bottom. ![Bottom](images/build/step(33)small.jpg "Bottom") Now, 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. ![Stack-up](images/build/step(34)small.jpg "Stack-up") Finally, 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. ![Wire](images/build/step(35)small.jpg "Wire") Once 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. ![Done](images/build/step(36)small.jpg "Done") ### Optional Step 2 - Programming the Arduino based Servo Controller: Connect 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. ![Programmer](images/build/step(37)small.jpg "Programmer") Install 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)`` . ![Arduino_IDE](images/build/step(38).png "Arduino_IDE") Finally, 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. ![Arduino_IDE_Done](images/build/step(39).png "Arduino_IDE_Done") The 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. ## How does the robocar follow the line? The 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). ================================================ FILE: robotics/donkey-car/download/OpenMV_Donkey_Mount.stl ================================================ solid stl_item0 facet normal 1 0 0 outer loop vertex 61 -57 20 vertex 61 -60 20 vertex 61 -59.097 16.003 endloop endfacet facet normal 1 0 0 outer loop vertex 61 -60 16.003 vertex 61 -59.097 16.003 vertex 61 -60 20 endloop endfacet facet normal 1 0 0 outer loop vertex 61 -60 0 vertex 61 -59.097 10.097 vertex 61 -60 10.097 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 32.03106 11.64583 -14.81199 vertex 30.2 12.534 -18.127 vertex 32.059 11.6008 -14.64391 endloop endfacet facet normal 1 0 0 outer loop vertex 61 -59.097 16.003 vertex 61 -59.097 10.097 vertex 61 -57 20 endloop endfacet facet normal 1 0 0 outer loop vertex 61 -57 0 vertex 61 -57 20 vertex 61 -59.097 10.097 endloop endfacet facet normal 1 0 0 outer loop vertex 61 -60 0 vertex 61 -57 0 vertex 61 -59.097 10.097 endloop endfacet facet normal -1 0 0 outer loop vertex 20.1 -60 10.097 vertex 20.1 -59.097 10.097 vertex 20.1 -60 0 endloop endfacet facet normal -1 0 0 outer loop vertex 20.1 -60 20 vertex 20.1 -59.097 16.003 vertex 20.1 -60 16.003 endloop endfacet facet normal -1 0 0 outer loop vertex 20.1 -60 0 vertex 20.1 -59.097 10.097 vertex 20.1 -57 0 endloop endfacet facet normal -1 0 0 outer loop vertex 20.1 -57 20 vertex 20.1 -57 0 vertex 20.1 -59.097 10.097 endloop endfacet facet normal -1 0 0 outer loop vertex 20.1 -57 20 vertex 20.1 -59.097 10.097 vertex 20.1 -59.097 16.003 endloop endfacet facet normal -1 0 0 outer loop vertex 20.1 -57 20 vertex 20.1 -59.097 16.003 vertex 20.1 -60 20 endloop endfacet facet normal 0 0 1 outer loop vertex 58.2 8 20 vertex 56.103 2.403 20 vertex 58.2 -3.2 20 endloop endfacet facet normal 0 0 1 outer loop vertex 56.103 -0.802 20 vertex 58.2 -3.2 20 vertex 56.103 2.403 20 endloop endfacet facet normal 0 0 1 outer loop vertex 58.2 -3.2 20 vertex 56.103 -0.802 20 vertex 27.1 -3.2 20 endloop endfacet facet normal -1 0 0 outer loop vertex 46.1 -57 15 vertex 46.1 -55.482 14.12 vertex 46.1 -56.524 13.078 endloop endfacet facet normal -1 0 0 outer loop vertex 46.1 -57 15 vertex 46.1 -56.524 13.078 vertex 46.1 -57 12.14379 endloop endfacet facet normal -1 0 0 outer loop vertex 46.1 -56.524 7.542 vertex 46.1 -55.482 6.5 vertex 46.1 -57 5.6 endloop endfacet facet normal -1 0 0 outer loop vertex 46.1 -57 8.47621 vertex 46.1 -56.524 7.542 vertex 46.1 -57 5.6 endloop endfacet facet normal 0 0 1 outer loop vertex 27.1 8 20 vertex 29.097 2.403 20 vertex 45.937 8 20 endloop endfacet facet normal -1 0 0 outer loop vertex 46.1 -55.482 6.5 vertex 46.1 -54.168 5.831 vertex 46.1 -57 5.6 endloop endfacet facet normal 0 0 1 outer loop vertex 29.097 -0.802 20 vertex 27.1 -3.2 20 vertex 56.103 -0.802 20 endloop endfacet facet normal 0 0.45359 0.89121 outer loop vertex 45.18865 -41.208 13.396 vertex 45.13548 -41.59019 13.59052 vertex 45.182 -41.591 13.59093 endloop endfacet facet normal 0 0 1 outer loop vertex 27.1 8 20 vertex 27.1 -3.2 20 vertex 29.097 2.403 20 endloop endfacet facet normal 0 0 1 outer loop vertex 29.097 -0.802 20 vertex 29.097 2.403 20 vertex 27.1 -3.2 20 endloop endfacet facet normal 0 0 1 outer loop vertex 26.6 -36.2 20 vertex 52.2 -36.2 20 vertex 26.6 -33.2 20 endloop endfacet facet normal 0 0 1 outer loop vertex 56.103 2.403 20 vertex 45.937 8 20 vertex 29.097 2.403 20 endloop endfacet facet normal 0 0 1 outer loop vertex 26.6 -33.2 20 vertex 52.2 -36.2 20 vertex 52.2 -33.2 20 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 32.514 11.9629 -15.99543 vertex 30.2 12.534 -18.127 vertex 32.3618 11.92344 -15.84815 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 32.237 11.8912 -15.72781 vertex 32.3618 11.92344 -15.84815 vertex 30.2 12.534 -18.127 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 32.514 11.9629 -15.99543 vertex 32.67122 11.98363 -16.0728 vertex 30.2 12.534 -18.127 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 32.237 11.5105 -14.30687 vertex 31.997 11.14241 -12.933 vertex 32.38921 11.47118 -14.1601 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 32.514 11.43885 -14.03945 vertex 32.38921 11.47118 -14.1601 vertex 31.997 11.14241 -12.933 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 32.1568 11.55121 -14.4588 vertex 31.997 11.14241 -12.933 vertex 32.237 11.5105 -14.30687 endloop endfacet facet normal 0 1 0 outer loop vertex 58.2 8 20 vertex 51.9 8 19.90931 vertex 45.937 8 20 endloop endfacet facet normal 0 0 1 outer loop vertex 45.937 8 20 vertex 56.103 2.403 20 vertex 58.2 8 20 endloop endfacet facet normal 0 0 1 outer loop vertex 34.539 -57 20 vertex 61 -60 20 vertex 54.937 -57 20 endloop endfacet facet normal 0 -1 0 outer loop vertex 54.648 -60 16.327 vertex 54.265 -60 16.522 vertex 53.698 -60 16.003 endloop endfacet facet normal 0 -1 0 outer loop vertex 55.073 -60 16.259 vertex 54.648 -60 16.327 vertex 53.698 -60 16.003 endloop endfacet facet normal 0 0 1 outer loop vertex 54.937 -57 20 vertex 61 -60 20 vertex 61 -57 20 endloop endfacet facet normal 0 0 1 outer loop vertex 20.1 -57 20 vertex 26.419 -60 20 vertex 34.539 -57 20 endloop endfacet facet normal 0 0 1 outer loop vertex 61 -60 20 vertex 34.539 -57 20 vertex 26.419 -60 20 endloop endfacet facet normal 0 0 1 outer loop vertex 26.419 -60 20 vertex 20.1 -57 20 vertex 20.1 -60 20 endloop endfacet facet normal 0.99982 0.01896 0.00193 outer loop vertex 58.18832 -0.78834 0 vertex 58.008 9.368 -6.378 vertex 58.02918 7.60273 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 53.96 -60 18.444 vertex 26.419 -60 20 vertex 53.765 -60 18.06 endloop endfacet facet normal 1 0 0 outer loop vertex 55.2 7.74214 -12.60822 vertex 55.2 6.95722 -4.89569 vertex 55.2 4.36328 0 endloop endfacet facet normal 1 0 0 outer loop vertex 55.2 6.45898 0 vertex 55.2 4.36328 0 vertex 55.2 6.95722 -4.89569 endloop endfacet facet normal 1 0 0 outer loop vertex 37.8 22.7 4.662 vertex 37.8 22.60546 1.94475 vertex 37.8 26.19 1.681 endloop endfacet facet normal 1 0 0 outer loop vertex 52.2 -36.2 -10.48639 vertex 52.2 -36.2 -58 vertex 52.2 -33.2 -58 endloop endfacet facet normal 1 0 0 outer loop vertex 52.2 -36.2 -10.48639 vertex 52.2 -33.2 -58 vertex 52.2 -33.2 20 endloop endfacet facet normal 0 0.9994 -0.03477 outer loop vertex 46.9 22.7 4.662 vertex 46.1 22.603 1.874 vertex 37.8 22.7 4.662 endloop endfacet facet normal 0 0.9994 -0.03477 outer loop vertex 37.8 22.60546 1.94475 vertex 37.8 22.7 4.662 vertex 46.1 22.603 1.874 endloop endfacet facet normal 0.98801 0.1543 -0.00564 outer loop vertex 40.882 19.30637 2.33263 vertex 40.882 19.40817 5.11997 vertex 40.89557 19.21993 2.34466 endloop endfacet facet normal 0 1 0 outer loop vertex 45.937 8 20 vertex 51.9 8 19.90931 vertex 46.9 8 19.90931 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 51.54319 5.13795 -2.89068 vertex 51.502 5.0705 -2.639 vertex 33.98219 5.10296 -2.76013 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 52.752 5.39395 -3.84597 vertex 55.2 7.74214 -12.60822 vertex 53.138 5.37813 -3.78692 endloop endfacet facet normal 0 -1 0 outer loop vertex 53.96 -60 16.827 vertex 53.698 -60 16.003 vertex 54.265 -60 16.522 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.487 5.33204 -3.61494 vertex 53.138 5.37813 -3.78692 vertex 55.2 7.74214 -12.60822 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.487 5.33204 -3.61494 vertex 55.2 7.74214 -12.60822 vertex 53.67405 5.28375 -3.43474 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.764 5.26059 -3.3483 vertex 53.67405 5.28375 -3.43474 vertex 55.2 7.74214 -12.60822 endloop endfacet facet normal 0.46126 0.88667 -0.03246 outer loop vertex 41.504 18.07045 2.50458 vertex 41.504 18.1725 5.29188 vertex 41.59237 18.02471 2.51094 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.764 5.26059 -3.3483 vertex 55.2 7.74214 -12.60822 vertex 53.8835 5.19975 -3.12129 endloop endfacet facet normal 0.45961 0.88753 -0.03242 outer loop vertex 41.59237 18.02471 2.51094 vertex 41.69207 18.07515 5.30542 vertex 41.925 17.85333 2.53478 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 32.366 7.85499 -0.66298 vertex 30.2 7.67736 0 vertex 32.752 7.83917 -0.60393 endloop endfacet facet normal 1 0 0 outer loop vertex 34.539 -47.788 10.31 vertex 34.539 -50.584 9.881 vertex 34.539 -48.019 8.855 endloop endfacet facet normal 1 0 0 outer loop vertex 34.539 -51.311 8.88 vertex 34.539 -51.788 8.63766 vertex 34.539 -49.73 6.5 endloop endfacet facet normal 1 0 0 outer loop vertex 34.539 -50.868 9.323 vertex 34.539 -48.019 8.855 vertex 34.539 -50.584 9.881 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 31.563 8.06241 -1.43714 vertex 30.2 7.67736 0 vertex 31.741 7.97239 -1.10114 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 32.017 7.90082 -0.83403 vertex 30.2 7.67736 0 vertex 32.366 7.85499 -0.66298 endloop endfacet facet normal 1 0 0 outer loop vertex 34.539 -47.788 10.31 vertex 34.539 -48.019 11.765 vertex 34.539 -50.486 10.5 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 31.502 8.1623 -1.80997 vertex 30.2 7.67736 0 vertex 31.54787 8.08719 -1.52965 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 31.54787 8.08719 -1.52965 vertex 30.2 7.67736 0 vertex 31.563 8.06241 -1.43714 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 32.017 7.90082 -0.83403 vertex 31.741 7.97239 -1.10114 vertex 30.2 7.67736 0 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 31.741 8.35244 -2.51968 vertex 31.997 11.14241 -12.933 vertex 31.60713 8.28455 -2.26628 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 31.80942 8.37017 -2.58583 vertex 31.997 11.14241 -12.933 vertex 31.741 8.35244 -2.51968 endloop endfacet facet normal 1 0 0 outer loop vertex 34.539 -51.044 14.789 vertex 34.539 -51.311 12.12 vertex 34.539 -49.73 14.12 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 32.017 8.42381 -2.78603 vertex 31.997 11.14241 -12.933 vertex 31.80942 8.37017 -2.58583 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 32.366 8.46988 -2.95801 vertex 31.997 11.14241 -12.933 vertex 32.017 8.42381 -2.78603 endloop endfacet facet normal 1 0 0 outer loop vertex 34.539 -50.868 11.677 vertex 34.539 -49.73 14.12 vertex 34.539 -51.311 12.12 endloop endfacet facet normal 1 0 0 outer loop vertex 34.539 -51.788 12.36234 vertex 34.539 -51.311 12.12 vertex 34.539 -51.044 14.789 endloop endfacet facet normal 1 0 0 outer loop vertex 34.539 -51.788 12.36234 vertex 34.539 -51.044 14.789 vertex 34.539 -51.788 14.90704 endloop endfacet facet normal 1 0 0 outer loop vertex 34.539 -50.486 10.5 vertex 34.539 -50.584 9.881 vertex 34.539 -47.788 10.31 endloop endfacet facet normal 1 0 0 outer loop vertex 34.539 -50.584 11.119 vertex 34.539 -50.486 10.5 vertex 34.539 -48.019 11.765 endloop endfacet facet normal 1 0 0 outer loop vertex 34.539 -48.019 11.765 vertex 34.539 -48.688 13.078 vertex 34.539 -50.584 11.119 endloop endfacet facet normal -0.46127 0.88667 -0.03239 outer loop vertex 42.859 17.95514 5.32211 vertex 43.04729 18.0526 5.30856 vertex 42.859 17.85333 2.53478 endloop endfacet facet normal 1 0 0 outer loop vertex 34.539 -49.73 14.12 vertex 34.539 -50.868 11.677 vertex 34.539 -48.688 13.078 endloop endfacet facet normal 1 0 0 outer loop vertex 34.539 -50.868 11.677 vertex 34.539 -50.584 11.119 vertex 34.539 -48.688 13.078 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 32.752 8.4857 -3.01706 vertex 31.997 11.14241 -12.933 vertex 32.366 8.46988 -2.95801 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 31.997 11.14241 -12.933 vertex 32.059 11.6008 -14.64391 vertex 30.2 12.534 -18.127 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 32.059 11.80093 -15.39088 vertex 30.2 12.534 -18.127 vertex 32.02493 11.74602 -15.18592 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 31.997 11.70088 -15.01744 vertex 32.02493 11.74602 -15.18592 vertex 30.2 12.534 -18.127 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 32.059 11.80093 -15.39088 vertex 32.237 11.8912 -15.72781 vertex 30.2 12.534 -18.127 endloop endfacet facet normal 1 0 0 outer loop vertex 34.539 -48.019 8.855 vertex 34.539 -50.868 9.323 vertex 34.539 -48.688 7.542 endloop endfacet facet normal 1 0 0 outer loop vertex 34.539 -48.688 7.542 vertex 34.539 -51.311 8.88 vertex 34.539 -49.73 6.5 endloop endfacet facet normal 1 0 0 outer loop vertex 34.539 -51.311 8.88 vertex 34.539 -48.688 7.542 vertex 34.539 -50.868 9.323 endloop endfacet facet normal 1 0 0 outer loop vertex 34.539 -51.044 5.831 vertex 34.539 -49.73 6.5 vertex 34.539 -51.788 8.63766 endloop endfacet facet normal 1 0 0 outer loop vertex 34.539 -51.788 5.71296 vertex 34.539 -51.044 5.831 vertex 34.539 -51.788 8.63766 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 31.502 8.1623 -1.80997 vertex 31.51712 8.18705 -1.90237 vertex 30.2 7.67736 0 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 31.563 8.26222 -2.18292 vertex 30.2 7.67736 0 vertex 31.51712 8.18705 -1.90237 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 31.60713 8.28455 -2.26628 vertex 31.997 11.14241 -12.933 vertex 31.563 8.26222 -2.18292 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 31.563 8.26222 -2.18292 vertex 31.997 11.14241 -12.933 vertex 30.2 7.67736 0 endloop endfacet facet normal -0.15985 -0.98648 0.03603 outer loop vertex 42.859 20.75938 2.13049 vertex 42.859 20.86119 4.91782 vertex 42.78952 20.77058 2.12893 endloop endfacet facet normal 0.70742 0.18299 -0.6827 outer loop vertex 32.2711 8.41066 -15.10281 vertex 32.38921 11.47118 -14.1601 vertex 32.514 8.34773 -14.86798 endloop endfacet facet normal -0.15779 -0.98681 0.03613 outer loop vertex 42.78952 20.77058 2.12893 vertex 42.67964 20.8901 4.9138 vertex 42.392 20.83382 2.12013 endloop endfacet facet normal -0.71259 -0.70111 0.02561 outer loop vertex 43.614 20.30653 4.99498 vertex 43.28 20.64428 4.948 vertex 43.614 20.20472 2.20765 endloop endfacet facet normal 0.89433 0.4471 -0.01633 outer loop vertex 40.956 18.9367 5.18556 vertex 41.17 18.40899 2.45748 vertex 40.956 18.83489 2.39823 endloop endfacet facet normal 0.98801 0.15428 -0.00564 outer loop vertex 40.956 18.9367 5.18556 vertex 40.956 18.83489 2.39823 vertex 40.91319 19.20945 5.14761 endloop endfacet facet normal 0.98801 0.15428 -0.00564 outer loop vertex 40.89557 19.21993 2.34466 vertex 40.91319 19.20945 5.14761 vertex 40.956 18.83489 2.39823 endloop endfacet facet normal 0.98801 0.1543 -0.00564 outer loop vertex 40.89557 19.21993 2.34466 vertex 40.882 19.40817 5.11997 vertex 40.91319 19.20945 5.14761 endloop endfacet facet normal 0.98806 -0.15398 0.00562 outer loop vertex 40.94322 19.69723 2.27826 vertex 40.9256 19.68651 5.08124 vertex 40.882 19.30637 2.33263 endloop endfacet facet normal 0.98806 -0.15398 0.00562 outer loop vertex 40.882 19.40817 5.11997 vertex 40.882 19.30637 2.33263 vertex 40.9256 19.68651 5.08124 endloop endfacet facet normal -1 0 0 outer loop vertex 32.8 8.01 19.9 vertex 32.8 26.19 1.681 vertex 32.8 8 19.80394 endloop endfacet facet normal 0.98806 -0.15397 0.00562 outer loop vertex 40.956 19.77882 2.26691 vertex 40.956 19.88063 5.05424 vertex 40.94322 19.69723 2.27826 endloop endfacet facet normal 0.98806 -0.15397 0.00562 outer loop vertex 40.9256 19.68651 5.08124 vertex 40.94322 19.69723 2.27826 vertex 40.956 19.88063 5.05424 endloop endfacet facet normal 0.89433 -0.4471 0.01633 outer loop vertex 41.17 20.20472 2.20765 vertex 41.17 20.30653 4.99498 vertex 40.956 19.77882 2.26691 endloop endfacet facet normal 0.89073 -0.11774 0.43903 outer loop vertex 32.059 8.71 -16.21979 vertex 32.237 8.80029 -16.55671 vertex 32.237 11.8912 -15.72781 endloop endfacet facet normal 0.15779 0.98682 -0.03604 outer loop vertex 41.925 17.85333 2.53478 vertex 41.925 17.95514 5.32211 vertex 42.02497 17.83743 2.537 endloop endfacet facet normal 0.15779 0.98682 -0.03604 outer loop vertex 42.13522 17.9217 5.32677 vertex 42.02497 17.83743 2.537 vertex 41.925 17.95514 5.32211 endloop endfacet facet normal 0.70652 -0.18331 0.68354 outer loop vertex 32.47992 8.86306 -16.79096 vertex 32.3618 11.92344 -15.84815 vertex 32.237 8.80029 -16.55671 endloop endfacet facet normal 0.15771 0.98683 -0.03604 outer loop vertex 42.392 17.88087 5.33245 vertex 42.392 17.77907 2.54512 vertex 42.13522 17.9217 5.32677 endloop endfacet facet normal 0.15771 0.98683 -0.03604 outer loop vertex 42.02497 17.83743 2.537 vertex 42.13522 17.9217 5.32677 vertex 42.392 17.77907 2.54512 endloop endfacet facet normal 0.46126 0.88667 -0.03246 outer loop vertex 41.69207 18.07515 5.30542 vertex 41.59237 18.02471 2.51094 vertex 41.504 18.1725 5.29188 endloop endfacet facet normal 0 -1 0 outer loop vertex 61 -60 16.003 vertex 56.186 -60 16.827 vertex 55.882 -60 16.522 endloop endfacet facet normal 0 -1 0 outer loop vertex 61 -60 16.003 vertex 55.882 -60 16.522 vertex 55.498 -60 16.327 endloop endfacet facet normal 0.45961 0.88753 -0.03242 outer loop vertex 41.925 17.85333 2.53478 vertex 41.69207 18.07515 5.30542 vertex 41.925 17.95514 5.32211 endloop endfacet facet normal 0 -1 0 outer loop vertex 56.186 -60 16.827 vertex 61 -60 16.003 vertex 56.381 -60 17.21 endloop endfacet facet normal 0.71361 0.70007 -0.02563 outer loop vertex 41.23776 18.34046 2.46701 vertex 41.31708 18.36207 5.2655 vertex 41.504 18.07045 2.50458 endloop endfacet facet normal 0.71361 0.70007 -0.02563 outer loop vertex 41.504 18.1725 5.29188 vertex 41.504 18.07045 2.50458 vertex 41.31708 18.36207 5.2655 endloop endfacet facet normal 0 -1 0 outer loop vertex 61 -60 16.003 vertex 61 -60 20 vertex 56.449 -60 17.635 endloop endfacet facet normal 0.71259 0.70111 -0.02561 outer loop vertex 41.17 18.40899 2.45748 vertex 41.17 18.5108 5.24481 vertex 41.23776 18.34046 2.46701 endloop endfacet facet normal 0.71259 0.70111 -0.02561 outer loop vertex 41.31708 18.36207 5.2655 vertex 41.23776 18.34046 2.46701 vertex 41.17 18.5108 5.24481 endloop endfacet facet normal 0 -1 0 outer loop vertex 55.882 -60 18.748 vertex 61 -60 20 vertex 55.498 -60 18.943 endloop endfacet facet normal 0 -1 0 outer loop vertex 54.265 -60 18.748 vertex 54.648 -60 18.943 vertex 26.419 -60 20 endloop endfacet facet normal 0 -1 0 outer loop vertex 54.648 -60 18.943 vertex 55.073 -60 19.011 vertex 26.419 -60 20 endloop endfacet facet normal 0 -1 0 outer loop vertex 61 -60 20 vertex 26.419 -60 20 vertex 55.073 -60 19.011 endloop endfacet facet normal 0 -1 0 outer loop vertex 55.498 -60 18.943 vertex 61 -60 20 vertex 55.073 -60 19.011 endloop endfacet facet normal 0.89086 0.11765 -0.43877 outer loop vertex 32.237 11.5105 -14.30687 vertex 32.237 8.41947 -15.13569 vertex 32.1568 11.55121 -14.4588 endloop endfacet facet normal 0.89086 0.11765 -0.43877 outer loop vertex 32.237 8.41947 -15.13569 vertex 32.0809 8.49871 -15.43139 vertex 32.1568 11.55121 -14.4588 endloop endfacet facet normal 0.89073 0.11774 -0.43903 outer loop vertex 32.1568 11.55121 -14.4588 vertex 32.0809 8.49871 -15.43139 vertex 32.059 11.6008 -14.64391 endloop endfacet facet normal 0.89073 0.11774 -0.43903 outer loop vertex 32.059 8.50982 -15.47284 vertex 32.059 11.6008 -14.64391 vertex 32.0809 8.49871 -15.43139 endloop endfacet facet normal 0.98742 0.04094 -0.15274 outer loop vertex 31.997 8.60981 -15.84596 vertex 31.997 11.70088 -15.01744 vertex 32.00463 8.59749 -15.79996 endloop endfacet facet normal 0.98742 0.04094 -0.15274 outer loop vertex 32.03106 11.64583 -14.81199 vertex 32.00463 8.59749 -15.79996 vertex 31.997 11.70088 -15.01744 endloop endfacet facet normal 0.89433 0.4471 -0.01633 outer loop vertex 41.17 18.5108 5.24481 vertex 41.17 18.40899 2.45748 vertex 40.956 18.9367 5.18556 endloop endfacet facet normal 0.98736 0.04106 -0.15311 outer loop vertex 32.059 11.6008 -14.64391 vertex 32.059 8.50982 -15.47284 vertex 32.03106 11.64583 -14.81199 endloop endfacet facet normal 0.98736 0.04106 -0.15311 outer loop vertex 32.00463 8.59749 -15.79996 vertex 32.03106 11.64583 -14.81199 vertex 32.059 8.50982 -15.47284 endloop endfacet facet normal 0.98736 -0.04106 0.15311 outer loop vertex 32.059 8.71 -16.21979 vertex 32.059 11.80093 -15.39088 vertex 32.05137 8.69769 -16.17389 endloop endfacet facet normal 0.98736 -0.04106 0.15311 outer loop vertex 32.02493 11.74602 -15.18592 vertex 32.05137 8.69769 -16.17389 vertex 32.059 11.80093 -15.39088 endloop endfacet facet normal 0.89433 -0.4471 0.01633 outer loop vertex 40.956 19.88063 5.05424 vertex 40.956 19.77882 2.26691 vertex 41.17 20.30653 4.99498 endloop endfacet facet normal 0.98742 -0.04094 0.15274 outer loop vertex 32.05137 8.69769 -16.17389 vertex 32.02493 11.74602 -15.18592 vertex 31.997 8.60981 -15.84596 endloop endfacet facet normal 0.98742 -0.04094 0.15274 outer loop vertex 31.997 11.70088 -15.01744 vertex 31.997 8.60981 -15.84596 vertex 32.02493 11.74602 -15.18592 endloop endfacet facet normal 0.89073 -0.11774 0.43903 outer loop vertex 32.059 11.80093 -15.39088 vertex 32.059 8.71 -16.21979 vertex 32.237 11.8912 -15.72781 endloop endfacet facet normal 0.70652 -0.18331 0.68354 outer loop vertex 32.237 11.8912 -15.72781 vertex 32.237 8.80029 -16.55671 vertex 32.3618 11.92344 -15.84815 endloop endfacet facet normal 0.70775 -0.1829 0.68238 outer loop vertex 32.514 8.8719 -16.82394 vertex 32.514 11.9629 -15.99543 vertex 32.47992 8.86306 -16.79096 endloop endfacet facet normal 0.70775 -0.1829 0.68238 outer loop vertex 32.3618 11.92344 -15.84815 vertex 32.47992 8.86306 -16.79096 vertex 32.514 11.9629 -15.99543 endloop endfacet facet normal 0.45391 -0.23069 0.86067 outer loop vertex 32.82001 8.91225 -16.97451 vertex 32.67122 11.98363 -16.0728 vertex 32.514 8.8719 -16.82394 endloop endfacet facet normal 0.45391 -0.23069 0.86067 outer loop vertex 32.514 11.9629 -15.99543 vertex 32.514 8.8719 -16.82394 vertex 32.67122 11.98363 -16.0728 endloop endfacet facet normal 0.45248 -0.23096 0.86135 outer loop vertex 32.82001 8.91225 -16.97451 vertex 32.863 12.00881 -16.16679 vertex 32.67122 11.98363 -16.0728 endloop endfacet facet normal -0.89433 -0.4471 0.01633 outer loop vertex 43.828 19.77882 2.26691 vertex 43.828 19.88063 5.05424 vertex 43.614 20.30653 4.99498 endloop endfacet facet normal -0.89433 -0.4471 0.01633 outer loop vertex 43.828 19.77882 2.26691 vertex 43.614 20.30653 4.99498 vertex 43.614 20.20472 2.20765 endloop endfacet facet normal 0.45444 0.23062 -0.86041 outer loop vertex 32.514 11.43885 -14.03945 vertex 32.863 8.30164 -14.69601 vertex 32.514 8.34773 -14.86798 endloop endfacet facet normal 0.70742 0.18299 -0.6827 outer loop vertex 32.514 11.43885 -14.03945 vertex 32.514 8.34773 -14.86798 vertex 32.38921 11.47118 -14.1601 endloop endfacet facet normal 0.70652 0.18329 -0.68355 outer loop vertex 32.237 8.41947 -15.13569 vertex 32.237 11.5105 -14.30687 vertex 32.2711 8.41066 -15.10281 endloop endfacet facet normal 0.70652 0.18329 -0.68355 outer loop vertex 32.38921 11.47118 -14.1601 vertex 32.2711 8.41066 -15.10281 vertex 32.237 11.5105 -14.30687 endloop endfacet facet normal -0.98806 -0.15397 0.00562 outer loop vertex 43.902 19.40817 5.11997 vertex 43.87146 19.60318 5.09284 vertex 43.902 19.30637 2.33263 endloop endfacet facet normal -0.98806 -0.15397 0.00562 outer loop vertex 43.88871 19.39119 2.32083 vertex 43.902 19.30637 2.33263 vertex 43.87146 19.60318 5.09284 endloop endfacet facet normal -0.98806 -0.15398 0.00562 outer loop vertex 43.87146 19.60318 5.09284 vertex 43.828 19.88063 5.05424 vertex 43.88871 19.39119 2.32083 endloop endfacet facet normal -0.98806 -0.15398 0.00562 outer loop vertex 43.828 19.77882 2.26691 vertex 43.88871 19.39119 2.32083 vertex 43.828 19.88063 5.05424 endloop endfacet facet normal -0.98801 0.1543 -0.00564 outer loop vertex 43.828 18.9367 5.18556 vertex 43.85931 19.13616 5.15781 vertex 43.828 18.83489 2.39823 endloop endfacet facet normal -0.98801 0.1543 -0.00564 outer loop vertex 43.84205 18.9244 2.38577 vertex 43.828 18.83489 2.39823 vertex 43.85931 19.13616 5.15781 endloop endfacet facet normal 0.15642 0.25577 -0.954 outer loop vertex 32.752 7.83917 -0.60393 vertex 32.752 4.74728 -1.43288 vertex 32.366 7.85499 -0.66298 endloop endfacet facet normal 0.45248 0.23093 -0.86136 outer loop vertex 32.366 7.85499 -0.66298 vertex 32.366 4.7631 -1.49193 vertex 32.017 7.90082 -0.83403 endloop endfacet facet normal 0.45248 0.23093 -0.86136 outer loop vertex 32.017 4.80894 -1.66297 vertex 32.017 7.90082 -0.83403 vertex 32.366 4.7631 -1.49193 endloop endfacet facet normal -0.98801 0.15428 -0.00564 outer loop vertex 43.84205 18.9244 2.38577 vertex 43.85931 19.13616 5.15781 vertex 43.902 19.40817 5.11997 endloop endfacet facet normal -0.98801 0.15428 -0.00564 outer loop vertex 43.84205 18.9244 2.38577 vertex 43.902 19.40817 5.11997 vertex 43.902 19.30637 2.33263 endloop endfacet facet normal 0.70779 0.18293 -0.68232 outer loop vertex 31.741 4.88052 -1.93008 vertex 31.741 7.97239 -1.10114 vertex 32.017 4.80894 -1.66297 endloop endfacet facet normal -0.89433 0.4471 -0.01633 outer loop vertex 43.828 18.83489 2.39823 vertex 43.614 18.40899 2.45748 vertex 43.828 18.9367 5.18556 endloop endfacet facet normal -0.89433 0.4471 -0.01633 outer loop vertex 43.614 18.5108 5.24481 vertex 43.828 18.9367 5.18556 vertex 43.614 18.40899 2.45748 endloop endfacet facet normal 0.15642 -0.25577 0.954 outer loop vertex 32.366 8.46988 -2.95801 vertex 32.366 5.37813 -3.78692 vertex 32.752 8.4857 -3.01706 endloop endfacet facet normal -0.71258 0.70112 -0.02567 outer loop vertex 43.28 18.1725 5.29188 vertex 43.42738 18.32152 5.27114 vertex 43.28 18.07045 2.50458 endloop endfacet facet normal -0.71258 0.70112 -0.02567 outer loop vertex 43.34925 18.14048 2.49484 vertex 43.28 18.07045 2.50458 vertex 43.42738 18.32152 5.27114 endloop endfacet facet normal 0 -1 0 outer loop vertex 61 -60 20 vertex 55.882 -60 18.748 vertex 56.186 -60 18.444 endloop endfacet facet normal 0 -1 0 outer loop vertex 56.381 -60 18.06 vertex 56.449 -60 17.635 vertex 61 -60 20 endloop endfacet facet normal 0 -1 0 outer loop vertex 56.449 -60 17.635 vertex 56.381 -60 17.21 vertex 61 -60 16.003 endloop endfacet facet normal 0 -1 0 outer loop vertex 56.186 -60 18.444 vertex 56.381 -60 18.06 vertex 61 -60 20 endloop endfacet facet normal -0.71362 0.70007 -0.02557 outer loop vertex 43.34925 18.14048 2.49484 vertex 43.42738 18.32152 5.27114 vertex 43.614 18.5108 5.24481 endloop endfacet facet normal -0.71362 0.70007 -0.02557 outer loop vertex 43.34925 18.14048 2.49484 vertex 43.614 18.5108 5.24481 vertex 43.614 18.40899 2.45748 endloop endfacet facet normal 0 -1 0 outer loop vertex 20.1 -60 0 vertex 61 -60 0 vertex 61 -60 10.097 endloop endfacet facet normal 0 -1 0 outer loop vertex 55.498 -60 16.327 vertex 55.073 -60 16.259 vertex 61 -60 16.003 endloop endfacet facet normal 0 -1 0 outer loop vertex 53.698 -60 16.003 vertex 61 -60 16.003 vertex 55.073 -60 16.259 endloop endfacet facet normal -0.4596 0.88753 -0.03249 outer loop vertex 43.28 18.07045 2.50458 vertex 42.94855 17.89968 2.52834 vertex 43.28 18.1725 5.29188 endloop endfacet facet normal -0.4596 0.88753 -0.03249 outer loop vertex 43.04729 18.0526 5.30856 vertex 43.28 18.1725 5.29188 vertex 42.94855 17.89968 2.52834 endloop endfacet facet normal -0.46127 0.88667 -0.03239 outer loop vertex 42.94855 17.89968 2.52834 vertex 42.859 17.85333 2.53478 vertex 43.04729 18.0526 5.30856 endloop endfacet facet normal -0.15771 0.98683 -0.03605 outer loop vertex 42.859 17.95514 5.32211 vertex 42.859 17.85333 2.53478 vertex 42.60231 17.91433 5.32779 endloop endfacet facet normal -0.15771 0.98683 -0.03605 outer loop vertex 42.49244 17.79505 2.54289 vertex 42.60231 17.91433 5.32779 vertex 42.859 17.85333 2.53478 endloop endfacet facet normal 0 -1 0 outer loop vertex 24.557 -60 16.784 vertex 24.073 -60 16.003 vertex 24.884 -60 16.617 endloop endfacet facet normal -0.15779 0.98682 -0.03604 outer loop vertex 42.60231 17.91433 5.32779 vertex 42.49244 17.79505 2.54289 vertex 42.392 17.88087 5.33245 endloop endfacet facet normal -0.15779 0.98682 -0.03604 outer loop vertex 42.392 17.77907 2.54512 vertex 42.392 17.88087 5.33245 vertex 42.49244 17.79505 2.54289 endloop endfacet facet normal 0 -1 0 outer loop vertex 53.698 -60 16.003 vertex 25.936 -60 16.784 vertex 25.609 -60 16.617 endloop endfacet facet normal 0.71259 -0.70111 0.02561 outer loop vertex 41.17 20.30653 4.99498 vertex 41.17 20.20472 2.20765 vertex 41.504 20.64428 4.948 endloop endfacet facet normal 0.71259 -0.70111 0.02561 outer loop vertex 41.504 20.64428 4.948 vertex 41.17 20.20472 2.20765 vertex 41.504 20.54247 2.16067 endloop endfacet facet normal 0 -1 0 outer loop vertex 25.936 -60 16.784 vertex 53.698 -60 16.003 vertex 26.195 -60 17.043 endloop endfacet facet normal 0.45961 -0.88753 0.03242 outer loop vertex 41.504 20.64428 4.948 vertex 41.504 20.54247 2.16067 vertex 41.925 20.86119 4.91782 endloop endfacet facet normal 0.45961 -0.88753 0.03242 outer loop vertex 41.925 20.75938 2.13049 vertex 41.925 20.86119 4.91782 vertex 41.504 20.54247 2.16067 endloop endfacet facet normal 0.45444 -0.23067 0.86039 outer loop vertex 32.366 5.37813 -3.78692 vertex 32.366 8.46988 -2.95801 vertex 32.017 5.33204 -3.61494 endloop endfacet facet normal 0.45444 -0.23067 0.86039 outer loop vertex 32.017 8.42381 -2.78603 vertex 32.017 5.33204 -3.61494 vertex 32.366 8.46988 -2.95801 endloop endfacet facet normal 0.15779 -0.98682 0.03604 outer loop vertex 42.32306 20.8227 2.12168 vertex 42.21282 20.90698 4.91145 vertex 41.925 20.75938 2.13049 endloop endfacet facet normal 0.15779 -0.98682 0.03604 outer loop vertex 41.925 20.86119 4.91782 vertex 41.925 20.75938 2.13049 vertex 42.21282 20.90698 4.91145 endloop endfacet facet normal 0.15642 -0.25577 0.954 outer loop vertex 32.752 5.39395 -3.84597 vertex 32.752 8.4857 -3.01706 vertex 32.366 5.37813 -3.78692 endloop endfacet facet normal 0.15984 -0.98648 0.03612 outer loop vertex 42.392 20.83382 2.12013 vertex 42.392 20.93586 4.90743 vertex 42.32306 20.8227 2.12168 endloop endfacet facet normal 0.15984 -0.98648 0.03612 outer loop vertex 42.21282 20.90698 4.91145 vertex 42.32306 20.8227 2.12168 vertex 42.392 20.93586 4.90743 endloop endfacet facet normal -0.15985 -0.98648 0.03603 outer loop vertex 42.67964 20.8901 4.9138 vertex 42.78952 20.77058 2.12893 vertex 42.859 20.86119 4.91782 endloop endfacet facet normal 0.15642 0.25577 -0.954 outer loop vertex 32.366 4.7631 -1.49193 vertex 32.366 7.85499 -0.66298 vertex 32.752 4.74728 -1.43288 endloop endfacet facet normal 0 -1 0 outer loop vertex 26.419 -60 20 vertex 20.1 -60 20 vertex 24.884 -60 18.849 endloop endfacet facet normal 0 -1 0 outer loop vertex 24.297 -60 18.422 vertex 20.1 -60 20 vertex 24.13 -60 18.095 endloop endfacet facet normal 0 -1 0 outer loop vertex 24.557 -60 18.682 vertex 20.1 -60 20 vertex 24.297 -60 18.422 endloop endfacet facet normal -0.15779 -0.98681 0.03613 outer loop vertex 42.67964 20.8901 4.9138 vertex 42.392 20.93586 4.90743 vertex 42.392 20.83382 2.12013 endloop endfacet facet normal 0 -1 0 outer loop vertex 25.936 -60 18.682 vertex 26.419 -60 20 vertex 25.609 -60 18.849 endloop endfacet facet normal 0 -1 0 outer loop vertex 24.557 -60 18.682 vertex 24.884 -60 18.849 vertex 20.1 -60 20 endloop endfacet facet normal 0 -1 0 outer loop vertex 26.419 -60 20 vertex 24.884 -60 18.849 vertex 25.246 -60 18.906 endloop endfacet facet normal 0 -1 0 outer loop vertex 25.609 -60 18.849 vertex 26.419 -60 20 vertex 25.246 -60 18.906 endloop endfacet facet normal -0.45961 -0.88753 0.03242 outer loop vertex 43.28 20.54247 2.16067 vertex 43.28 20.64428 4.948 vertex 42.859 20.86119 4.91782 endloop endfacet facet normal -0.45961 -0.88753 0.03242 outer loop vertex 43.28 20.54247 2.16067 vertex 42.859 20.86119 4.91782 vertex 42.859 20.75938 2.13049 endloop endfacet facet normal 0 -1 0 outer loop vertex 26.419 -60 20 vertex 25.936 -60 18.682 vertex 26.195 -60 18.422 endloop endfacet facet normal 0 -1 0 outer loop vertex 53.765 -60 17.21 vertex 53.698 -60 17.635 vertex 26.419 -60 17.733 endloop endfacet facet normal 0 -1 0 outer loop vertex 53.96 -60 16.827 vertex 53.765 -60 17.21 vertex 26.419 -60 17.733 endloop endfacet facet normal 0 -1 0 outer loop vertex 26.362 -60 17.37 vertex 53.698 -60 16.003 vertex 26.419 -60 17.733 endloop endfacet facet normal 0 -1 0 outer loop vertex 26.362 -60 18.095 vertex 26.419 -60 17.733 vertex 53.698 -60 17.635 endloop endfacet facet normal 0 -1 0 outer loop vertex 26.195 -60 18.422 vertex 26.362 -60 18.095 vertex 53.698 -60 17.635 endloop endfacet facet normal 0 -1 0 outer loop vertex 26.419 -60 20 vertex 26.195 -60 18.422 vertex 53.698 -60 17.635 endloop endfacet facet normal 0 -1 0 outer loop vertex 53.698 -60 17.635 vertex 53.765 -60 18.06 vertex 26.419 -60 20 endloop endfacet facet normal 0 -1 0 outer loop vertex 53.96 -60 18.444 vertex 54.265 -60 18.748 vertex 26.419 -60 20 endloop endfacet facet normal 0 -1 0 outer loop vertex 61 -60 10.097 vertex 20.1 -60 10.097 vertex 20.1 -60 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 26.195 -60 17.043 vertex 53.698 -60 16.003 vertex 26.362 -60 17.37 endloop endfacet facet normal 0 -1 0 outer loop vertex 25.246 -60 16.559 vertex 24.073 -60 16.003 vertex 25.609 -60 16.617 endloop endfacet facet normal 0 -1 0 outer loop vertex 53.698 -60 16.003 vertex 25.609 -60 16.617 vertex 24.073 -60 16.003 endloop endfacet facet normal 0 -1 0 outer loop vertex 25.246 -60 16.559 vertex 24.884 -60 16.617 vertex 24.073 -60 16.003 endloop endfacet facet normal 0 -1 0 outer loop vertex 53.96 -60 16.827 vertex 26.419 -60 17.733 vertex 53.698 -60 16.003 endloop endfacet facet normal -0.71259 -0.70111 0.02561 outer loop vertex 43.28 20.54247 2.16067 vertex 43.614 20.20472 2.20765 vertex 43.28 20.64428 4.948 endloop endfacet facet normal 0 -1 0 outer loop vertex 24.073 -60 16.003 vertex 24.297 -60 17.043 vertex 20.1 -60 16.003 endloop endfacet facet normal 0 -1 0 outer loop vertex 24.557 -60 16.784 vertex 24.297 -60 17.043 vertex 24.073 -60 16.003 endloop endfacet facet normal 0 -1 0 outer loop vertex 24.13 -60 17.37 vertex 20.1 -60 16.003 vertex 24.297 -60 17.043 endloop endfacet facet normal 0 -1 0 outer loop vertex 24.13 -60 17.37 vertex 24.073 -60 17.733 vertex 20.1 -60 16.003 endloop endfacet facet normal 0 -1 0 outer loop vertex 20.1 -60 20 vertex 20.1 -60 16.003 vertex 24.073 -60 17.733 endloop endfacet facet normal 0 -1 0 outer loop vertex 24.073 -60 17.733 vertex 24.13 -60 18.095 vertex 20.1 -60 20 endloop endfacet facet normal 0 -1 0 outer loop vertex 45.265 -3.2 12.665 vertex 58.2 -3.2 20 vertex 44.867 -3.2 13.445 endloop endfacet facet normal 1 0 0 outer loop vertex 34.616 -54.491 10.5 vertex 34.616 -57 5.6 vertex 34.616 -54.393 9.881 endloop endfacet facet normal 0 -1 0 outer loop vertex 43.467 -3.2 14.463 vertex 44.248 -3.2 14.065 vertex 58.2 -3.2 20 endloop endfacet facet normal 1 0 0 outer loop vertex 34.616 -54.393 9.881 vertex 34.616 -57 5.6 vertex 34.616 -54.109 9.323 endloop endfacet facet normal 0 -1 0 outer loop vertex 44.248 -3.2 14.065 vertex 44.867 -3.2 13.445 vertex 58.2 -3.2 20 endloop endfacet facet normal 0 -1 0 outer loop vertex 43.467 -3.2 14.463 vertex 58.2 -3.2 20 vertex 42.601 -3.2 14.6 endloop endfacet facet normal 0 -1 0 outer loop vertex 45.265 -3.2 10.933 vertex 58.2 -3.2 0 vertex 45.402 -3.2 11.799 endloop endfacet facet normal 0 -1 0 outer loop vertex 45.402 -3.2 11.799 vertex 58.2 -3.2 20 vertex 45.265 -3.2 12.665 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.955 -3.2 9.533 vertex 40.335 -3.2 10.152 vertex 27.1 -3.2 0 endloop endfacet facet normal 0 1 0 outer loop vertex 41.735 8 9.135 vertex 37.8 8 5.23414 vertex 40.955 8 9.533 endloop endfacet facet normal 0 1 0 outer loop vertex 40.335 8 10.152 vertex 37.8 8 5.23414 vertex 39.937 8 10.933 endloop endfacet facet normal 0 1 0 outer loop vertex 45.265 8 10.933 vertex 45.402 8 11.799 vertex 46.9 8 5.23414 endloop endfacet facet normal 0.89035 -0.1179 0.43974 outer loop vertex 31.60713 8.28455 -2.26628 vertex 31.563 5.17042 -3.01184 vertex 31.6832 5.23127 -3.23889 endloop endfacet facet normal 0 1 0 outer loop vertex 44.867 8 10.152 vertex 45.265 8 10.933 vertex 46.9 8 5.23414 endloop endfacet facet normal 0.89073 -0.11767 0.43905 outer loop vertex 31.60713 8.28455 -2.26628 vertex 31.6832 5.23127 -3.23889 vertex 31.741 8.35244 -2.51968 endloop endfacet facet normal 0.89073 -0.11767 0.43905 outer loop vertex 31.741 5.26059 -3.3483 vertex 31.741 8.35244 -2.51968 vertex 31.6832 5.23127 -3.23889 endloop endfacet facet normal 0 1 0 outer loop vertex 44.248 8 9.533 vertex 44.867 8 10.152 vertex 46.9 8 5.23414 endloop endfacet facet normal 0 -1 0 outer loop vertex 34.17384 -36.2 15.21 vertex 26.6 -36.2 20 vertex 34.17386 -36.2 13.85081 endloop endfacet facet normal 0.70746 -0.18295 0.68266 outer loop vertex 31.741 8.35244 -2.51968 vertex 31.741 5.26059 -3.3483 vertex 31.80942 8.37017 -2.58583 endloop endfacet facet normal 0.70746 -0.18295 0.68266 outer loop vertex 31.92735 5.30887 -3.52849 vertex 31.80942 8.37017 -2.58583 vertex 31.741 5.26059 -3.3483 endloop endfacet facet normal 0 1 0 outer loop vertex 37.8 8 19.80394 vertex 40.335 8 13.445 vertex 39.937 8 12.665 endloop endfacet facet normal -0.99984 0.01785 0.00038 outer loop vertex 34.12628 -38.94719 14.16569 vertex 34.168 -36.574 12.442 vertex 34.12587 -38.969 14.123 endloop endfacet facet normal 0 1 0 outer loop vertex 40.955 8 14.065 vertex 40.335 8 13.445 vertex 37.8 8 19.80394 endloop endfacet facet normal 0.70779 0.18293 -0.68232 outer loop vertex 32.017 7.90082 -0.83403 vertex 32.017 4.80894 -1.66297 vertex 31.741 7.97239 -1.10114 endloop endfacet facet normal 0 1 0 outer loop vertex 40.955 8 14.065 vertex 37.8 8 19.80394 vertex 41.735 8 14.463 endloop endfacet facet normal 0.89021 0.11797 -0.44 outer loop vertex 31.563 4.97056 -2.26607 vertex 31.563 8.06241 -1.43714 vertex 31.741 4.88052 -1.93008 endloop endfacet facet normal 0.89021 0.11797 -0.44 outer loop vertex 31.741 7.97239 -1.10114 vertex 31.741 4.88052 -1.93008 vertex 31.563 8.06241 -1.43714 endloop endfacet facet normal -0.99984 0.01785 0.00038 outer loop vertex 34.168 -36.574 12.442 vertex 34.149 -37.616 11.4 vertex 34.12587 -38.969 14.123 endloop endfacet facet normal 0.98775 0.0404 -0.1507 outer loop vertex 31.52181 5.03807 -2.51797 vertex 31.54787 8.08719 -1.52965 vertex 31.563 4.97056 -2.26607 endloop endfacet facet normal 0.98775 0.0404 -0.1507 outer loop vertex 31.563 8.06241 -1.43714 vertex 31.563 4.97056 -2.26607 vertex 31.54787 8.08719 -1.52965 endloop endfacet facet normal 0.98774 0.04044 -0.1508 outer loop vertex 31.502 5.0705 -2.639 vertex 31.502 8.1623 -1.80997 vertex 31.52181 5.03807 -2.51797 endloop endfacet facet normal 0.98774 0.04044 -0.1508 outer loop vertex 31.54787 8.08719 -1.52965 vertex 31.52181 5.03807 -2.51797 vertex 31.502 8.1623 -1.80997 endloop endfacet facet normal 0.98774 -0.04044 0.1508 outer loop vertex 31.502 8.1623 -1.80997 vertex 31.502 5.0705 -2.639 vertex 31.51712 8.18705 -1.90237 endloop endfacet facet normal 0.98774 -0.04044 0.1508 outer loop vertex 31.54319 5.13795 -2.89068 vertex 31.51712 8.18705 -1.90237 vertex 31.502 5.0705 -2.639 endloop endfacet facet normal 0 1 0 outer loop vertex 44.248 8 14.065 vertex 43.467 8 14.463 vertex 45.937 8 20 endloop endfacet facet normal 0 1 0 outer loop vertex 45.937 8 20 vertex 46.9 8 19.90931 vertex 44.248 8 14.065 endloop endfacet facet normal 0 1 0 outer loop vertex 43.467 8 14.463 vertex 42.601 8 14.6 vertex 45.937 8 20 endloop endfacet facet normal 0 1 0 outer loop vertex 41.735 8 14.463 vertex 37.8 8 19.80394 vertex 42.601 8 14.6 endloop endfacet facet normal 0.98775 -0.0404 0.1507 outer loop vertex 31.563 5.17042 -3.01184 vertex 31.563 8.26222 -2.18292 vertex 31.54319 5.13795 -2.89068 endloop endfacet facet normal 0 1 0 outer loop vertex 46.9 8 19.90931 vertex 46.9 8 5.23414 vertex 45.402 8 11.799 endloop endfacet facet normal 0 1 0 outer loop vertex 45.402 8 11.799 vertex 45.265 8 12.665 vertex 46.9 8 19.90931 endloop endfacet facet normal 0 1 0 outer loop vertex 45.265 8 12.665 vertex 44.867 8 13.445 vertex 46.9 8 19.90931 endloop endfacet facet normal 0 1 0 outer loop vertex 44.867 8 13.445 vertex 44.248 8 14.065 vertex 46.9 8 19.90931 endloop endfacet facet normal 0.89035 -0.1179 0.43974 outer loop vertex 31.60713 8.28455 -2.26628 vertex 31.563 8.26222 -2.18292 vertex 31.563 5.17042 -3.01184 endloop endfacet facet normal 0 1 0 outer loop vertex 42.601 8 8.998 vertex 37.8 8 5.23414 vertex 41.735 8 9.135 endloop endfacet facet normal 0 1 0 outer loop vertex 43.467 8 9.135 vertex 46.9 8 5.23414 vertex 42.601 8 8.998 endloop endfacet facet normal 0 1 0 outer loop vertex 43.467 8 9.135 vertex 44.248 8 9.533 vertex 46.9 8 5.23414 endloop endfacet facet normal 0 1 0 outer loop vertex 40.335 8 10.152 vertex 40.955 8 9.533 vertex 37.8 8 5.23414 endloop endfacet facet normal 0.70656 -0.18325 0.68352 outer loop vertex 31.80942 8.37017 -2.58583 vertex 31.92735 5.30887 -3.52849 vertex 32.017 8.42381 -2.78603 endloop endfacet facet normal 0.70656 -0.18325 0.68352 outer loop vertex 32.017 5.33204 -3.61494 vertex 32.017 8.42381 -2.78603 vertex 31.92735 5.30887 -3.52849 endloop endfacet facet normal 0 1 0 outer loop vertex 39.8 8 11.799 vertex 37.8 8 19.80394 vertex 39.937 8 12.665 endloop endfacet facet normal 0 1 0 outer loop vertex 37.8 8 5.23414 vertex 37.8 8 19.80394 vertex 39.8 8 11.799 endloop endfacet facet normal 0 1 0 outer loop vertex 39.8 8 11.799 vertex 39.937 8 10.933 vertex 37.8 8 5.23414 endloop endfacet facet normal 0 1 0 outer loop vertex 45.937 8 20 vertex 42.601 8 14.6 vertex 37.8 8 19.80394 endloop endfacet facet normal 0 1 0 outer loop vertex 32.8 8 19.80394 vertex 27.1 8 20 vertex 37.8 8 19.80394 endloop endfacet facet normal 1 0 0 outer loop vertex 34.616 -54.109 9.323 vertex 34.616 -57 5.6 vertex 34.616 -53.666 8.88 endloop endfacet facet normal 0 1 0 outer loop vertex 34.616 -0.802 0 vertex 40.955 -0.802 9.533 vertex 41.735 -0.802 9.135 endloop endfacet facet normal 0 1 0 outer loop vertex 40.335 -0.802 10.152 vertex 34.616 -0.802 0 vertex 39.937 -0.802 10.933 endloop endfacet facet normal 1 0 0 outer loop vertex 34.616 -53.666 8.88 vertex 34.616 -57 5.6 vertex 34.616 -53.107 8.596 endloop endfacet facet normal -0.99985 0.0174 -0.00001 outer loop vertex 34.17386 -36.2 13.85081 vertex 34.13044 -38.69427 14.66089 vertex 34.13062 -38.684 14.681 endloop endfacet facet normal 1 0 0 outer loop vertex 34.616 -52.488 8.497 vertex 34.616 -51.788 5.6 vertex 34.616 -51.87 8.596 endloop endfacet facet normal 1 0 0 outer loop vertex 34.616 -51.788 8.63766 vertex 34.616 -51.87 8.596 vertex 34.616 -51.788 5.6 endloop endfacet facet normal 0 1 0 outer loop vertex 44.248 -0.802 9.533 vertex 55.3377 -0.802 0 vertex 43.467 -0.802 9.135 endloop endfacet facet normal 1 0 0 outer loop vertex 34.616 -51.788 12.36234 vertex 34.616 -51.788 15 vertex 34.616 -51.87 12.404 endloop endfacet facet normal 1 0 0 outer loop vertex 34.616 -52.488 12.503 vertex 34.616 -51.87 12.404 vertex 34.616 -51.788 15 endloop endfacet facet normal 0 1 0 outer loop vertex 40.955 -0.802 14.065 vertex 29.097 -0.802 20 vertex 41.735 -0.802 14.463 endloop endfacet facet normal 0.98775 -0.0404 0.1507 outer loop vertex 31.51712 8.18705 -1.90237 vertex 31.54319 5.13795 -2.89068 vertex 31.563 8.26222 -2.18292 endloop endfacet facet normal 0 1 0 outer loop vertex 44.248 -0.802 14.065 vertex 43.467 -0.802 14.463 vertex 56.103 -0.802 20 endloop endfacet facet normal 0 1 0 outer loop vertex 43.467 -0.802 14.463 vertex 42.601 -0.802 14.6 vertex 56.103 -0.802 20 endloop endfacet facet normal 0 1 0 outer loop vertex 41.735 -0.802 14.463 vertex 29.097 -0.802 20 vertex 42.601 -0.802 14.6 endloop endfacet facet normal 0 1 0 outer loop vertex 56.103 -0.802 20 vertex 42.601 -0.802 14.6 vertex 29.097 -0.802 20 endloop endfacet facet normal 0 1 0 outer loop vertex 45.402 -0.802 11.799 vertex 55.3377 -0.802 0 vertex 45.265 -0.802 10.933 endloop endfacet facet normal 0 1 0 outer loop vertex 45.265 -0.802 12.665 vertex 56.103 -0.802 20 vertex 45.402 -0.802 11.799 endloop endfacet facet normal 0 1 0 outer loop vertex 44.867 -0.802 13.445 vertex 56.103 -0.802 20 vertex 45.265 -0.802 12.665 endloop endfacet facet normal 0 1 0 outer loop vertex 40.335 -0.802 10.152 vertex 40.955 -0.802 9.533 vertex 34.616 -0.802 0 endloop endfacet facet normal 0 1 0 outer loop vertex 43.467 -0.802 9.135 vertex 55.3377 -0.802 0 vertex 42.601 -0.802 8.998 endloop endfacet facet normal 0 1 0 outer loop vertex 42.601 -0.802 8.998 vertex 34.616 -0.802 0 vertex 41.735 -0.802 9.135 endloop endfacet facet normal 0 1 0 outer loop vertex 40.335 -0.802 13.445 vertex 29.097 -0.802 20 vertex 40.955 -0.802 14.065 endloop endfacet facet normal 0 1 0 outer loop vertex 39.937 -0.802 12.665 vertex 29.097 -0.802 20 vertex 40.335 -0.802 13.445 endloop endfacet facet normal 0 1 0 outer loop vertex 34.616 -0.802 0 vertex 29.097 -0.802 20 vertex 39.937 -0.802 10.933 endloop endfacet facet normal 0 1 0 outer loop vertex 39.8 -0.802 11.799 vertex 39.937 -0.802 10.933 vertex 29.097 -0.802 20 endloop endfacet facet normal 0 1 0 outer loop vertex 39.8 -0.802 11.799 vertex 29.097 -0.802 20 vertex 39.937 -0.802 12.665 endloop endfacet facet normal 0.15626 0 0.98772 outer loop vertex 42.601 -3.2 8.998 vertex 42.601 -0.802 8.998 vertex 41.735 -0.802 9.135 endloop endfacet facet normal 0.15626 0 0.98772 outer loop vertex 42.601 -3.2 8.998 vertex 41.735 -0.802 9.135 vertex 41.735 -3.2 9.135 endloop endfacet facet normal 0 1 0 outer loop vertex 40.496 -33.2 -1.077 vertex 41.277 -33.2 -0.679 vertex 40.867 -33.2 -7.837 endloop endfacet facet normal 0.45451 0 0.89074 outer loop vertex 41.735 -3.2 9.135 vertex 41.735 -0.802 9.135 vertex 40.955 -0.802 9.533 endloop endfacet facet normal 0.45451 0 0.89074 outer loop vertex 41.735 -3.2 9.135 vertex 40.955 -0.802 9.533 vertex 40.955 -3.2 9.533 endloop endfacet facet normal -0.99986 0.01691 -0.00031 outer loop vertex 34.11926 -39.33152 13.76047 vertex 34.149 -37.616 11.4 vertex 34.11792 -39.412 13.68 endloop endfacet facet normal 0.70654 0 0.70768 outer loop vertex 40.955 -3.2 9.533 vertex 40.955 -0.802 9.533 vertex 40.335 -0.802 10.152 endloop endfacet facet normal 0.70654 0 0.70768 outer loop vertex 40.955 -3.2 9.533 vertex 40.335 -0.802 10.152 vertex 40.335 -3.2 10.152 endloop endfacet facet normal 0.89098 0 0.45405 outer loop vertex 39.937 -0.802 10.933 vertex 39.937 -3.2 10.933 vertex 40.335 -3.2 10.152 endloop endfacet facet normal 0.89098 0 0.45405 outer loop vertex 39.937 -0.802 10.933 vertex 40.335 -3.2 10.152 vertex 40.335 -0.802 10.152 endloop endfacet facet normal 0.98772 0 0.15626 outer loop vertex 39.937 -3.2 10.933 vertex 39.937 -0.802 10.933 vertex 39.8 -0.802 11.799 endloop endfacet facet normal 0.98772 0 0.15626 outer loop vertex 39.937 -3.2 10.933 vertex 39.8 -0.802 11.799 vertex 39.8 -3.2 11.799 endloop endfacet facet normal 0.98772 0 -0.15626 outer loop vertex 39.8 -0.802 11.799 vertex 39.937 -3.2 12.665 vertex 39.8 -3.2 11.799 endloop endfacet facet normal 0 1 0 outer loop vertex 42.295 -33.2 0.721 vertex 42.267 -33.2 -8.855 vertex 41.897 -33.2 -0.06 endloop endfacet facet normal 0 -0.70711 0.70711 outer loop vertex 34.11792 -39.412 13.68 vertex 45.21983 -39.412 13.68 vertex 34.11926 -39.33152 13.76047 endloop endfacet facet normal -0.98772 0 0.15626 outer loop vertex 45.402 -3.2 11.799 vertex 45.402 -0.802 11.799 vertex 45.265 -0.802 10.933 endloop endfacet facet normal -0.98772 0 0.15626 outer loop vertex 45.402 -3.2 11.799 vertex 45.265 -0.802 10.933 vertex 45.265 -3.2 10.933 endloop endfacet facet normal 0 1 0 outer loop vertex 38.765 -33.2 -1.077 vertex 39.63 -33.2 -1.214 vertex 39.135 -33.2 -7.837 endloop endfacet facet normal 0 1 0 outer loop vertex 40.001 -33.2 -7.7 vertex 39.135 -33.2 -7.837 vertex 39.63 -33.2 -1.214 endloop endfacet facet normal 0 1 0 outer loop vertex 39.63 -33.2 -1.214 vertex 40.496 -33.2 -1.077 vertex 40.001 -33.2 -7.7 endloop endfacet facet normal 0 1 0 outer loop vertex 41.277 -33.2 -0.679 vertex 41.897 -33.2 -0.06 vertex 41.648 -33.2 -8.235 endloop endfacet facet normal 0 1 0 outer loop vertex 41.648 -33.2 -8.235 vertex 40.867 -33.2 -7.837 vertex 41.277 -33.2 -0.679 endloop endfacet facet normal 0 1 0 outer loop vertex 40.001 -33.2 -7.7 vertex 40.496 -33.2 -1.077 vertex 40.867 -33.2 -7.837 endloop endfacet facet normal -0.89098 0 0.45405 outer loop vertex 44.867 -0.802 10.152 vertex 45.265 -3.2 10.933 vertex 45.265 -0.802 10.933 endloop endfacet facet normal -0.89098 0 0.45405 outer loop vertex 44.867 -3.2 10.152 vertex 45.265 -3.2 10.933 vertex 44.867 -0.802 10.152 endloop endfacet facet normal -0.70711 0 0.70711 outer loop vertex 44.867 -3.2 10.152 vertex 44.867 -0.802 10.152 vertex 44.248 -0.802 9.533 endloop endfacet facet normal -0.70711 0 0.70711 outer loop vertex 44.867 -3.2 10.152 vertex 44.248 -0.802 9.533 vertex 44.248 -3.2 9.533 endloop endfacet facet normal 0 1 0 outer loop vertex 41.648 -33.2 -8.235 vertex 41.897 -33.2 -0.06 vertex 42.267 -33.2 -8.855 endloop endfacet facet normal -0.99985 0.01727 -0.00042 outer loop vertex 34.17415 -36.2 13.17602 vertex 34.12628 -38.94719 14.16569 vertex 34.17386 -36.2 13.85081 endloop endfacet facet normal -0.45405 0 0.89098 outer loop vertex 44.248 -3.2 9.533 vertex 44.248 -0.802 9.533 vertex 43.467 -0.802 9.135 endloop endfacet facet normal -0.45405 0 0.89098 outer loop vertex 44.248 -3.2 9.533 vertex 43.467 -0.802 9.135 vertex 43.467 -3.2 9.135 endloop endfacet facet normal -0.15626 0 0.98772 outer loop vertex 43.467 -3.2 9.135 vertex 43.467 -0.802 9.135 vertex 42.601 -0.802 8.998 endloop endfacet facet normal -0.15626 0 0.98772 outer loop vertex 43.467 -3.2 9.135 vertex 42.601 -0.802 8.998 vertex 42.601 -3.2 8.998 endloop endfacet facet normal -0.99985 0.01727 -0.00042 outer loop vertex 34.168 -36.574 12.442 vertex 34.12628 -38.94719 14.16569 vertex 34.17415 -36.2 13.17602 endloop endfacet facet normal -0.99985 0.01727 -0.00042 outer loop vertex 34.13044 -38.69427 14.66089 vertex 34.17386 -36.2 13.85081 vertex 34.12628 -38.94719 14.16569 endloop endfacet facet normal 0.98772 0 -0.15626 outer loop vertex 39.937 -0.802 12.665 vertex 39.937 -3.2 12.665 vertex 39.8 -0.802 11.799 endloop endfacet facet normal 0 1 0 outer loop vertex 42.267 -33.2 -8.855 vertex 42.295 -33.2 0.721 vertex 42.665 -33.2 -9.635 endloop endfacet facet normal 0.89074 0 -0.45451 outer loop vertex 40.335 -0.802 13.445 vertex 40.335 -3.2 13.445 vertex 39.937 -3.2 12.665 endloop endfacet facet normal 0.89074 0 -0.45451 outer loop vertex 40.335 -0.802 13.445 vertex 39.937 -3.2 12.665 vertex 39.937 -0.802 12.665 endloop endfacet facet normal 0.70711 0 -0.70711 outer loop vertex 40.955 -0.802 14.065 vertex 40.955 -3.2 14.065 vertex 40.335 -3.2 13.445 endloop endfacet facet normal 0.70711 0 -0.70711 outer loop vertex 40.955 -0.802 14.065 vertex 40.335 -3.2 13.445 vertex 40.335 -0.802 13.445 endloop endfacet facet normal 0.45451 0 -0.89074 outer loop vertex 41.735 -0.802 14.463 vertex 41.735 -3.2 14.463 vertex 40.955 -3.2 14.065 endloop endfacet facet normal 0.45451 0 -0.89074 outer loop vertex 41.735 -0.802 14.463 vertex 40.955 -3.2 14.065 vertex 40.955 -0.802 14.065 endloop endfacet facet normal 0.01556 0.89085 -0.45404 outer loop vertex 34.17415 -36.2 13.17602 vertex 34.27425 -36.2 13.17945 vertex 34.26765 -36.57574 12.442 endloop endfacet facet normal 0.15626 0 -0.98772 outer loop vertex 42.601 -0.802 14.6 vertex 42.601 -3.2 14.6 vertex 41.735 -3.2 14.463 endloop endfacet facet normal 0.15626 0 -0.98772 outer loop vertex 42.601 -0.802 14.6 vertex 41.735 -3.2 14.463 vertex 41.735 -0.802 14.463 endloop endfacet facet normal -0.15626 0 -0.98772 outer loop vertex 43.467 -0.802 14.463 vertex 43.467 -3.2 14.463 vertex 42.601 -3.2 14.6 endloop endfacet facet normal -0.15626 0 -0.98772 outer loop vertex 43.467 -0.802 14.463 vertex 42.601 -3.2 14.6 vertex 42.601 -0.802 14.6 endloop endfacet facet normal -0.45405 0 -0.89098 outer loop vertex 44.248 -0.802 14.065 vertex 44.248 -3.2 14.065 vertex 43.467 -3.2 14.463 endloop endfacet facet normal -0.45405 0 -0.89098 outer loop vertex 44.248 -0.802 14.065 vertex 43.467 -3.2 14.463 vertex 43.467 -0.802 14.463 endloop endfacet facet normal 0 -0.45359 0.89121 outer loop vertex 34.11109 -39.82012 13.47229 vertex 45.21014 -39.97 13.396 vertex 34.11792 -39.412 13.68 endloop endfacet facet normal -0.70768 0 -0.70654 outer loop vertex 44.248 -3.2 14.065 vertex 44.248 -0.802 14.065 vertex 44.867 -0.802 13.445 endloop endfacet facet normal -0.70768 0 -0.70654 outer loop vertex 44.248 -3.2 14.065 vertex 44.867 -0.802 13.445 vertex 44.867 -3.2 13.445 endloop endfacet facet normal -0.89074 0 -0.45451 outer loop vertex 44.867 -3.2 13.445 vertex 44.867 -0.802 13.445 vertex 45.265 -0.802 12.665 endloop endfacet facet normal -0.89074 0 -0.45451 outer loop vertex 44.867 -3.2 13.445 vertex 45.265 -0.802 12.665 vertex 45.265 -3.2 12.665 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.001 -36.2 -7.7 vertex 39.63 -36.2 -1.214 vertex 39.135 -36.2 -7.837 endloop endfacet facet normal 0 -0.89056 0.45486 outer loop vertex 34.12628 -38.94719 14.16569 vertex 45.22752 -38.969 14.123 vertex 34.13044 -38.69427 14.66089 endloop endfacet facet normal 0 -0.89056 0.45486 outer loop vertex 34.12587 -38.969 14.123 vertex 45.22752 -38.969 14.123 vertex 34.12628 -38.94719 14.16569 endloop endfacet facet normal 0 -0.89056 0.45486 outer loop vertex 45.22752 -38.969 14.123 vertex 45.23247 -38.684 14.681 vertex 34.13044 -38.69427 14.66089 endloop endfacet facet normal -0.98772 0 -0.15626 outer loop vertex 45.402 -0.802 11.799 vertex 45.402 -3.2 11.799 vertex 45.265 -0.802 12.665 endloop endfacet facet normal -0.98772 0 -0.15626 outer loop vertex 45.265 -3.2 12.665 vertex 45.265 -0.802 12.665 vertex 45.402 -3.2 11.799 endloop endfacet facet normal 0 -1 0 outer loop vertex 39.937 2.403 10.933 vertex 30.30975 2.403 0 vertex 40.335 2.403 10.152 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.001 -36.2 -7.7 vertex 40.867 -36.2 -7.837 vertex 40.496 -36.2 -1.077 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.867 -36.2 -7.837 vertex 41.648 -36.2 -8.235 vertex 41.277 -36.2 -0.679 endloop endfacet facet normal 0 -1 0 outer loop vertex 44.867 2.403 10.152 vertex 55.27692 2.403 0 vertex 45.265 2.403 10.933 endloop endfacet facet normal 0 -1 0 outer loop vertex 44.248 2.403 9.533 vertex 55.27692 2.403 0 vertex 44.867 2.403 10.152 endloop endfacet facet normal 0 -1 0 outer loop vertex 41.277 -36.2 -0.679 vertex 40.496 -36.2 -1.077 vertex 40.867 -36.2 -7.837 endloop endfacet facet normal 0 -1 0 outer loop vertex 39.63 -36.2 -1.214 vertex 40.001 -36.2 -7.7 vertex 40.496 -36.2 -1.077 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.984 -36.2 -0.679 vertex 38.355 -36.2 -8.235 vertex 38.765 -36.2 -1.077 endloop endfacet facet normal 0 -1 0 outer loop vertex 52.2 -36.2 -10.48639 vertex 41.897 -36.2 -0.06 vertex 42.267 -36.2 -8.855 endloop endfacet facet normal 1 0 0 outer loop vertex 58.2 -3.2 0 vertex 58.2 8 0 vertex 58.2 -3.2 20 endloop endfacet facet normal 1 0 0 outer loop vertex 58.2 8 20 vertex 58.2 -3.2 20 vertex 58.2 8 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 56.103 2.403 20 vertex 29.097 2.403 20 vertex 42.601 2.403 14.6 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.295 -36.2 0.721 vertex 41.897 -36.2 -0.06 vertex 52.2 -36.2 -10.48639 endloop endfacet facet normal 0 -1 0 outer loop vertex 41.648 -36.2 -8.235 vertex 42.267 -36.2 -8.855 vertex 41.897 -36.2 -0.06 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.665 -36.2 -9.635 vertex 52.2 -36.2 -10.48639 vertex 42.267 -36.2 -8.855 endloop endfacet facet normal 0.70711 0 -0.70711 outer loop vertex 38.355 -33.2 -8.235 vertex 38.355 -36.2 -8.235 vertex 37.735 -33.2 -8.855 endloop endfacet facet normal 0.45451 0 -0.89074 outer loop vertex 38.355 -33.2 -8.235 vertex 39.135 -36.2 -7.837 vertex 38.355 -36.2 -8.235 endloop endfacet facet normal -0.45405 0 -0.89098 outer loop vertex 41.648 -33.2 -8.235 vertex 41.648 -36.2 -8.235 vertex 40.867 -36.2 -7.837 endloop endfacet facet normal -0.45405 0 -0.89098 outer loop vertex 41.648 -33.2 -8.235 vertex 40.867 -36.2 -7.837 vertex 40.867 -33.2 -7.837 endloop endfacet facet normal -0.70768 0 -0.70654 outer loop vertex 41.648 -36.2 -8.235 vertex 41.648 -33.2 -8.235 vertex 42.267 -33.2 -8.855 endloop endfacet facet normal -0.70768 0 -0.70654 outer loop vertex 41.648 -36.2 -8.235 vertex 42.267 -33.2 -8.855 vertex 42.267 -36.2 -8.855 endloop endfacet facet normal -0.89074 0 -0.45451 outer loop vertex 42.665 -33.2 -9.635 vertex 42.267 -36.2 -8.855 vertex 42.267 -33.2 -8.855 endloop endfacet facet normal 0.45451 0 -0.89074 outer loop vertex 39.135 -33.2 -7.837 vertex 39.135 -36.2 -7.837 vertex 38.355 -33.2 -8.235 endloop endfacet facet normal 0.15626 0 -0.98772 outer loop vertex 40.001 -33.2 -7.7 vertex 40.001 -36.2 -7.7 vertex 39.135 -36.2 -7.837 endloop endfacet facet normal 0.15626 0 -0.98772 outer loop vertex 40.001 -33.2 -7.7 vertex 39.135 -36.2 -7.837 vertex 39.135 -33.2 -7.837 endloop endfacet facet normal -0.15626 0 -0.98772 outer loop vertex 40.867 -33.2 -7.837 vertex 40.867 -36.2 -7.837 vertex 40.001 -36.2 -7.7 endloop endfacet facet normal -0.15626 0 -0.98772 outer loop vertex 40.867 -33.2 -7.837 vertex 40.001 -36.2 -7.7 vertex 40.001 -33.2 -7.7 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -48.231 11.765 vertex 54.937 -50.486 10.5 vertex 54.937 -48 10.31 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -50.486 10.5 vertex 54.937 -50.584 9.881 vertex 54.937 -48 10.31 endloop endfacet facet normal 0.15643 0 0.98769 outer loop vertex 38.765 -33.2 -1.077 vertex 38.765 -36.2 -1.077 vertex 39.63 -36.2 -1.214 endloop endfacet facet normal 0.15643 0 0.98769 outer loop vertex 38.765 -33.2 -1.077 vertex 39.63 -36.2 -1.214 vertex 39.63 -33.2 -1.214 endloop endfacet facet normal 0.45405 0 0.89098 outer loop vertex 37.984 -33.2 -0.679 vertex 37.984 -36.2 -0.679 vertex 38.765 -36.2 -1.077 endloop endfacet facet normal 0.45405 0 0.89098 outer loop vertex 37.984 -33.2 -0.679 vertex 38.765 -36.2 -1.077 vertex 38.765 -33.2 -1.077 endloop endfacet facet normal -0.15626 0 0.98772 outer loop vertex 40.496 -36.2 -1.077 vertex 40.496 -33.2 -1.077 vertex 39.63 -33.2 -1.214 endloop endfacet facet normal -0.15626 0 0.98772 outer loop vertex 40.496 -36.2 -1.077 vertex 39.63 -33.2 -1.214 vertex 39.63 -36.2 -1.214 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -54.109 9.323 vertex 54.937 -55.482 6.5 vertex 54.937 -53.666 8.88 endloop endfacet facet normal -0.89098 0 0.45405 outer loop vertex 41.897 -33.2 -0.06 vertex 41.897 -36.2 -0.06 vertex 42.295 -33.2 0.721 endloop endfacet facet normal 0 -1 0 outer loop vertex 45.265 2.403 12.665 vertex 56.103 2.403 20 vertex 44.867 2.403 13.445 endloop endfacet facet normal 0 -1 0 outer loop vertex 44.867 2.403 13.445 vertex 56.103 2.403 20 vertex 44.248 2.403 14.065 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -55.482 14.12 vertex 54.937 -56.524 13.078 vertex 54.937 -54.109 11.677 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -53.666 8.88 vertex 54.937 -54.168 5.831 vertex 54.937 -53.107 8.596 endloop endfacet facet normal 0 -1 0 outer loop vertex 56.103 2.403 20 vertex 42.601 2.403 14.6 vertex 43.467 2.403 14.463 endloop endfacet facet normal 0 -1 0 outer loop vertex 44.248 2.403 14.065 vertex 56.103 2.403 20 vertex 43.467 2.403 14.463 endloop endfacet facet normal 0 -1 0 outer loop vertex 45.402 2.403 11.799 vertex 56.103 2.403 20 vertex 45.265 2.403 12.665 endloop endfacet facet normal 0 -1 0 outer loop vertex 45.265 2.403 10.933 vertex 55.27692 2.403 0 vertex 45.402 2.403 11.799 endloop endfacet facet normal 0 -1 0 outer loop vertex 41.735 2.403 9.135 vertex 30.30975 2.403 0 vertex 42.601 2.403 8.998 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.955 2.403 9.533 vertex 30.30975 2.403 0 vertex 41.735 2.403 9.135 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.955 2.403 9.533 vertex 40.335 2.403 10.152 vertex 30.30975 2.403 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 39.8 2.403 11.799 vertex 39.937 2.403 12.665 vertex 29.097 2.403 20 endloop endfacet facet normal 0 -1 0 outer loop vertex 39.937 2.403 12.665 vertex 40.335 2.403 13.445 vertex 29.097 2.403 20 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.335 2.403 13.445 vertex 40.955 2.403 14.065 vertex 29.097 2.403 20 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.955 2.403 14.065 vertex 41.735 2.403 14.463 vertex 29.097 2.403 20 endloop endfacet facet normal 0 -1 0 outer loop vertex 41.735 2.403 14.463 vertex 42.601 2.403 14.6 vertex 29.097 2.403 20 endloop endfacet facet normal 0.15626 0 0.98772 outer loop vertex 42.601 8 8.998 vertex 41.735 2.403 9.135 vertex 42.601 2.403 8.998 endloop endfacet facet normal -0.99985 0.0174 0 outer loop vertex 34.06549 -42.42509 14.54757 vertex 34.023 -44.866 13.755 vertex 34.06431 -42.493 14.681 endloop endfacet facet normal -0.99985 0.0174 0 outer loop vertex 34.06285 -42.57675 15.21 vertex 34.06431 -42.493 14.681 vertex 34.019 -45.096 15.21 endloop endfacet facet normal 0.98772 0 0.15626 outer loop vertex 39.937 2.403 10.933 vertex 39.8 8 11.799 vertex 39.8 2.403 11.799 endloop endfacet facet normal 0.98772 0 -0.15626 outer loop vertex 39.8 8 11.799 vertex 39.937 2.403 12.665 vertex 39.8 2.403 11.799 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 51.6568 11.55105 -14.45823 vertex 46.1 7.67736 0 vertex 51.737 11.51035 -14.30631 endloop endfacet facet normal -0.99985 0.01748 -0.00023 outer loop vertex 34.0718 -42.07143 13.98543 vertex 34.035 -44.197 12.442 vertex 34.06937 -42.209 14.123 endloop endfacet facet normal -0.98772 0 0.15626 outer loop vertex 45.265 8 10.933 vertex 45.265 2.403 10.933 vertex 45.402 2.403 11.799 endloop endfacet facet normal -0.89098 0 0.45405 outer loop vertex 45.265 2.403 10.933 vertex 45.265 8 10.933 vertex 44.867 2.403 10.152 endloop endfacet facet normal -0.99985 0.01748 -0.00023 outer loop vertex 34.035 -44.197 12.442 vertex 34.023 -44.866 13.755 vertex 34.06937 -42.209 14.123 endloop endfacet facet normal -0.15626 0 0.98772 outer loop vertex 43.467 2.403 9.135 vertex 42.601 8 8.998 vertex 42.601 2.403 8.998 endloop endfacet facet normal 0.98772 0 -0.15626 outer loop vertex 39.937 8 12.665 vertex 39.937 2.403 12.665 vertex 39.8 8 11.799 endloop endfacet facet normal 0.89074 0 -0.45451 outer loop vertex 40.335 8 13.445 vertex 40.335 2.403 13.445 vertex 39.937 2.403 12.665 endloop endfacet facet normal 0.89074 0 -0.45451 outer loop vertex 40.335 8 13.445 vertex 39.937 2.403 12.665 vertex 39.937 8 12.665 endloop endfacet facet normal 0.70711 0 -0.70711 outer loop vertex 40.955 2.403 14.065 vertex 40.335 2.403 13.445 vertex 40.335 8 13.445 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 51.737 11.89105 -15.72725 vertex 46.9 12.534 -18.127 vertex 51.559 11.80078 -15.39032 endloop endfacet facet normal 0.45451 0 -0.89074 outer loop vertex 41.735 8 14.463 vertex 41.735 2.403 14.463 vertex 40.955 2.403 14.065 endloop endfacet facet normal 0.15626 0 -0.98772 outer loop vertex 41.735 2.403 14.463 vertex 41.735 8 14.463 vertex 42.601 2.403 14.6 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 51.498 11.70084 -15.0173 vertex 46.9 12.534 -18.127 vertex 51.559 11.60065 -14.64335 endloop endfacet facet normal -0.45405 0 -0.89098 outer loop vertex 44.248 8 14.065 vertex 44.248 2.403 14.065 vertex 43.467 2.403 14.463 endloop endfacet facet normal -0.70768 0 -0.70654 outer loop vertex 44.248 2.403 14.065 vertex 44.248 8 14.065 vertex 44.867 2.403 13.445 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 51.502 8.1623 -1.80997 vertex 51.51712 8.18705 -1.90237 vertex 46.1 7.67736 0 endloop endfacet facet normal -0.70654 0 0.70768 outer loop vertex 41.277 -33.2 -0.679 vertex 41.277 -36.2 -0.679 vertex 41.897 -36.2 -0.06 endloop endfacet facet normal -0.70654 0 0.70768 outer loop vertex 41.277 -33.2 -0.679 vertex 41.897 -36.2 -0.06 vertex 41.897 -33.2 -0.06 endloop endfacet facet normal -0.45405 0 0.89098 outer loop vertex 41.277 -36.2 -0.679 vertex 41.277 -33.2 -0.679 vertex 40.496 -36.2 -1.077 endloop endfacet facet normal -0.45405 0 0.89098 outer loop vertex 40.496 -33.2 -1.077 vertex 40.496 -36.2 -1.077 vertex 41.277 -33.2 -0.679 endloop endfacet facet normal 0 0.70711 0.70711 outer loop vertex 45.12437 -42.209 14.123 vertex 37.8 -41.766 13.68 vertex 34.06937 -42.209 14.123 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 51.559 11.80078 -15.39032 vertex 46.9 12.534 -18.127 vertex 51.498 11.70084 -15.0173 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 46.9 12.534 -18.127 vertex 46.1 7.67736 0 vertex 51.559 11.60065 -14.64335 endloop endfacet facet normal 0.15626 0 0.98772 outer loop vertex 41.735 8 9.135 vertex 41.735 2.403 9.135 vertex 42.601 8 8.998 endloop endfacet facet normal 0.45451 0 0.89074 outer loop vertex 41.735 2.403 9.135 vertex 41.735 8 9.135 vertex 40.955 2.403 9.533 endloop endfacet facet normal 0.45451 0 0.89074 outer loop vertex 40.955 8 9.533 vertex 40.955 2.403 9.533 vertex 41.735 8 9.135 endloop endfacet facet normal 0.70654 0 0.70768 outer loop vertex 40.335 8 10.152 vertex 40.335 2.403 10.152 vertex 40.955 2.403 9.533 endloop endfacet facet normal 0.70654 0 0.70768 outer loop vertex 40.335 8 10.152 vertex 40.955 2.403 9.533 vertex 40.955 8 9.533 endloop endfacet facet normal 0 0.89121 0.45359 outer loop vertex 45.11967 -42.493 14.681 vertex 45.12037 -42.45247 14.60135 vertex 34.06549 -42.42509 14.54757 endloop endfacet facet normal 0.89098 0 0.45405 outer loop vertex 40.335 2.403 10.152 vertex 40.335 8 10.152 vertex 39.937 2.403 10.933 endloop endfacet facet normal 0.89098 0 0.45405 outer loop vertex 39.937 8 10.933 vertex 39.937 2.403 10.933 vertex 40.335 8 10.152 endloop endfacet facet normal 0.98772 0 0.15626 outer loop vertex 39.8 8 11.799 vertex 39.937 2.403 10.933 vertex 39.937 8 10.933 endloop endfacet facet normal -0.98772 0 0.15626 outer loop vertex 45.265 8 10.933 vertex 45.402 2.403 11.799 vertex 45.402 8 11.799 endloop endfacet facet normal -0.89098 0 0.45405 outer loop vertex 44.867 8 10.152 vertex 44.867 2.403 10.152 vertex 45.265 8 10.933 endloop endfacet facet normal -0.70711 0 0.70711 outer loop vertex 44.867 2.403 10.152 vertex 44.867 8 10.152 vertex 44.248 2.403 9.533 endloop endfacet facet normal -0.70711 0 0.70711 outer loop vertex 44.248 8 9.533 vertex 44.248 2.403 9.533 vertex 44.867 8 10.152 endloop endfacet facet normal -0.45405 0 0.89098 outer loop vertex 43.467 8 9.135 vertex 43.467 2.403 9.135 vertex 44.248 2.403 9.533 endloop endfacet facet normal -0.45405 0 0.89098 outer loop vertex 43.467 8 9.135 vertex 44.248 2.403 9.533 vertex 44.248 8 9.533 endloop endfacet facet normal -0.15626 0 0.98772 outer loop vertex 43.467 2.403 9.135 vertex 43.467 8 9.135 vertex 42.601 8 8.998 endloop endfacet facet normal 0 0.89121 0.45359 outer loop vertex 34.06431 -42.493 14.681 vertex 45.11967 -42.493 14.681 vertex 34.06549 -42.42509 14.54757 endloop endfacet facet normal 0.70711 0 -0.70711 outer loop vertex 40.955 8 14.065 vertex 40.955 2.403 14.065 vertex 40.335 8 13.445 endloop endfacet facet normal 0.45451 0 -0.89074 outer loop vertex 40.955 2.403 14.065 vertex 40.955 8 14.065 vertex 41.735 8 14.463 endloop endfacet facet normal 0.98775 -0.0404 0.1507 outer loop vertex 51.563 8.26222 -2.18292 vertex 51.54319 5.13795 -2.89068 vertex 51.563 5.17042 -3.01184 endloop endfacet facet normal 0.15626 0 -0.98772 outer loop vertex 42.601 2.403 14.6 vertex 41.735 8 14.463 vertex 42.601 8 14.6 endloop endfacet facet normal -0.15626 0 -0.98772 outer loop vertex 42.601 2.403 14.6 vertex 42.601 8 14.6 vertex 43.467 2.403 14.463 endloop endfacet facet normal -0.15626 0 -0.98772 outer loop vertex 43.467 8 14.463 vertex 43.467 2.403 14.463 vertex 42.601 8 14.6 endloop endfacet facet normal 0.89035 -0.1179 0.43974 outer loop vertex 51.563 8.26222 -2.18292 vertex 51.563 5.17042 -3.01184 vertex 51.60713 8.28455 -2.26628 endloop endfacet facet normal 0.89035 -0.1179 0.43974 outer loop vertex 51.6832 5.23127 -3.23889 vertex 51.60713 8.28455 -2.26628 vertex 51.563 5.17042 -3.01184 endloop endfacet facet normal 0 -0.70711 0.70711 outer loop vertex 45.22752 -38.969 14.123 vertex 34.12587 -38.969 14.123 vertex 45.21983 -39.412 13.68 endloop endfacet facet normal -0.45405 0 -0.89098 outer loop vertex 44.248 8 14.065 vertex 43.467 2.403 14.463 vertex 43.467 8 14.463 endloop endfacet facet normal 0.89073 -0.11767 0.43905 outer loop vertex 51.741 5.26059 -3.3483 vertex 51.741 8.35244 -2.51968 vertex 51.6832 5.23127 -3.23889 endloop endfacet facet normal -0.70768 0 -0.70654 outer loop vertex 44.867 8 13.445 vertex 44.867 2.403 13.445 vertex 44.248 8 14.065 endloop endfacet facet normal -0.89074 0 -0.45451 outer loop vertex 44.867 2.403 13.445 vertex 44.867 8 13.445 vertex 45.265 2.403 12.665 endloop endfacet facet normal -0.89074 0 -0.45451 outer loop vertex 45.265 8 12.665 vertex 45.265 2.403 12.665 vertex 44.867 8 13.445 endloop endfacet facet normal -0.98772 0 -0.15626 outer loop vertex 45.265 8 12.665 vertex 45.402 2.403 11.799 vertex 45.265 2.403 12.665 endloop endfacet facet normal -0.98772 0 -0.15626 outer loop vertex 45.402 8 11.799 vertex 45.402 2.403 11.799 vertex 45.265 8 12.665 endloop endfacet facet normal 1 0 0 outer loop vertex 37.8 8 19.80394 vertex 37.8 22.7 4.662 vertex 37.8 8.01 19.9 endloop endfacet facet normal 1 0 0 outer loop vertex 37.8 8 5.23414 vertex 37.8 8.051 6.7 vertex 37.8 8 19.80394 endloop endfacet facet normal 1 0 0 outer loop vertex 37.8 8.051 6.7 vertex 37.8 22.7 4.662 vertex 37.8 8 19.80394 endloop endfacet facet normal 1 0 0 outer loop vertex 37.8 26.19 1.681 vertex 37.8 8.01 19.9 vertex 37.8 22.7 4.662 endloop endfacet facet normal 0.89021 0.11797 -0.44 outer loop vertex 51.741 7.97239 -1.10114 vertex 51.741 4.88052 -1.93008 vertex 51.563 8.06241 -1.43714 endloop endfacet facet normal 0.89021 0.11797 -0.44 outer loop vertex 51.563 4.97056 -2.26607 vertex 51.563 8.06241 -1.43714 vertex 51.741 4.88052 -1.93008 endloop endfacet facet normal 0.98775 0.0404 -0.1507 outer loop vertex 51.52181 5.03807 -2.51797 vertex 51.54787 8.08719 -1.52965 vertex 51.563 4.97056 -2.26607 endloop endfacet facet normal 0.98775 0.0404 -0.1507 outer loop vertex 51.563 8.06241 -1.43714 vertex 51.563 4.97056 -2.26607 vertex 51.54787 8.08719 -1.52965 endloop endfacet facet normal 0.98774 0.04044 -0.1508 outer loop vertex 51.502 5.0705 -2.639 vertex 51.502 8.1623 -1.80997 vertex 51.52181 5.03807 -2.51797 endloop endfacet facet normal 0.98774 0.04044 -0.1508 outer loop vertex 51.54787 8.08719 -1.52965 vertex 51.52181 5.03807 -2.51797 vertex 51.502 8.1623 -1.80997 endloop endfacet facet normal 0.98774 -0.04044 0.1508 outer loop vertex 51.502 8.1623 -1.80997 vertex 51.502 5.0705 -2.639 vertex 51.51712 8.18705 -1.90237 endloop endfacet facet normal 0.98774 -0.04044 0.1508 outer loop vertex 51.54319 5.13795 -2.89068 vertex 51.51712 8.18705 -1.90237 vertex 51.502 5.0705 -2.639 endloop endfacet facet normal 1 0 0 outer loop vertex 34.616 -54.109 11.677 vertex 34.616 -57 15 vertex 34.616 -54.393 11.119 endloop endfacet facet normal 1 0 0 outer loop vertex 34.616 -53.107 12.404 vertex 34.616 -57 15 vertex 34.616 -53.666 12.12 endloop endfacet facet normal 1 0 0 outer loop vertex 34.616 -57 15 vertex 34.616 -53.107 12.404 vertex 34.616 -51.788 15 endloop endfacet facet normal 1 0 0 outer loop vertex 34.616 -52.488 12.503 vertex 34.616 -51.788 15 vertex 34.616 -53.107 12.404 endloop endfacet facet normal 1 0 0 outer loop vertex 34.616 -54.109 11.677 vertex 34.616 -53.666 12.12 vertex 34.616 -57 15 endloop endfacet facet normal 1 0 0 outer loop vertex 34.616 -52.488 8.497 vertex 34.616 -53.107 8.596 vertex 34.616 -51.788 5.6 endloop endfacet facet normal 1 0 0 outer loop vertex 34.616 -51.788 5.6 vertex 34.616 -53.107 8.596 vertex 34.616 -57 5.6 endloop endfacet facet normal 0.00274 0.15665 -0.98765 outer loop vertex 34.101 -40.385 10.5 vertex 34.127 -38.929 10.731 vertex 34.201 -40.3736 10.50209 endloop endfacet facet normal 1 0 0 outer loop vertex 34.616 -54.393 11.119 vertex 34.616 -57 15 vertex 34.616 -54.491 10.5 endloop endfacet facet normal 1 0 0 outer loop vertex 34.616 -57 5.6 vertex 34.616 -54.491 10.5 vertex 34.616 -57 15 endloop endfacet facet normal 0.98775 -0.0404 0.1507 outer loop vertex 51.563 8.26222 -2.18292 vertex 51.51712 8.18705 -1.90237 vertex 51.54319 5.13795 -2.89068 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -52.712 5.6 vertex 54.937 -51.256 5.831 vertex 54.937 -52.489 8.497 endloop endfacet facet normal 0.89073 -0.11767 0.43905 outer loop vertex 51.60713 8.28455 -2.26628 vertex 51.6832 5.23127 -3.23889 vertex 51.741 8.35244 -2.51968 endloop endfacet facet normal 0.70746 -0.18295 0.68266 outer loop vertex 51.741 5.26059 -3.3483 vertex 51.80941 8.37017 -2.58583 vertex 51.741 8.35244 -2.51968 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -51.256 5.831 vertex 54.937 -49.942 6.5 vertex 54.937 -51.87 8.596 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -51.311 8.88 vertex 54.937 -51.87 8.596 vertex 54.937 -49.942 6.5 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -49.942 6.5 vertex 54.937 -48.9 7.542 vertex 54.937 -51.311 8.88 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -50.486 10.5 vertex 54.937 -48.231 11.765 vertex 54.937 -50.584 11.119 endloop endfacet facet normal -1 0 0 outer loop vertex 25.4 -53.666 8.88 vertex 25.4 -57 5.6 vertex 25.4 -54.109 9.323 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -50.868 11.677 vertex 54.937 -48.9 13.078 vertex 54.937 -51.311 12.12 endloop endfacet facet normal -1 0 0 outer loop vertex 25.4 -54.393 9.881 vertex 25.4 -54.109 9.323 vertex 25.4 -57 5.6 endloop endfacet facet normal -1 0 0 outer loop vertex 25.4 -54.393 11.119 vertex 25.4 -57 15 vertex 25.4 -54.109 11.677 endloop endfacet facet normal -1 0 0 outer loop vertex 25.4 -57 5.6 vertex 25.4 -57 15 vertex 25.4 -54.491 10.5 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -52.712 15.02 vertex 54.937 -54.168 14.789 vertex 54.937 -53.107 12.404 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -53.666 12.12 vertex 54.937 -53.107 12.404 vertex 54.937 -54.168 14.789 endloop endfacet facet normal -1 0 0 outer loop vertex 25.4 -57 5.6 vertex 25.4 -53.666 8.88 vertex 25.4 -53.107 8.596 endloop endfacet facet normal -1 0 0 outer loop vertex 25.4 -52.488 8.497 vertex 25.4 -51.788 5.6 vertex 25.4 -53.107 8.596 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -52.489 12.503 vertex 54.937 -51.87 12.404 vertex 54.937 -51.256 14.789 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -53.107 12.404 vertex 54.937 -52.489 12.503 vertex 54.937 -52.712 15.02 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -52.712 15.02 vertex 54.937 -52.489 12.503 vertex 54.937 -51.256 14.789 endloop endfacet facet normal -1 0 0 outer loop vertex 25.4 -51.788 8.63766 vertex 25.4 -51.788 5.6 vertex 25.4 -51.87 8.596 endloop endfacet facet normal -1 0 0 outer loop vertex 25.4 -52.488 8.497 vertex 25.4 -51.87 8.596 vertex 25.4 -51.788 5.6 endloop endfacet facet normal -1 0 0 outer loop vertex 25.4 -52.488 12.503 vertex 25.4 -51.788 15 vertex 25.4 -51.87 12.404 endloop endfacet facet normal -1 0 0 outer loop vertex 25.4 -51.788 12.36234 vertex 25.4 -51.87 12.404 vertex 25.4 -51.788 15 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -51.311 12.12 vertex 54.937 -49.942 14.12 vertex 54.937 -51.87 12.404 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -48.9 13.078 vertex 54.937 -50.868 11.677 vertex 54.937 -50.584 11.119 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -50.584 9.881 vertex 54.937 -50.868 9.323 vertex 54.937 -48.231 8.855 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -49.942 14.12 vertex 54.937 -51.311 12.12 vertex 54.937 -48.9 13.078 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -51.256 14.789 vertex 54.937 -51.87 12.404 vertex 54.937 -49.942 14.12 endloop endfacet facet normal -1 0 0 outer loop vertex 25.4 -53.666 12.12 vertex 25.4 -57 15 vertex 25.4 -53.107 12.404 endloop endfacet facet normal -1 0 0 outer loop vertex 25.4 -54.109 11.677 vertex 25.4 -57 15 vertex 25.4 -53.666 12.12 endloop endfacet facet normal -1 0 0 outer loop vertex 25.4 -57 15 vertex 25.4 -51.788 15 vertex 25.4 -53.107 12.404 endloop endfacet facet normal -1 0 0 outer loop vertex 25.4 -52.488 12.503 vertex 25.4 -53.107 12.404 vertex 25.4 -51.788 15 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -48.231 8.855 vertex 54.937 -48 10.31 vertex 54.937 -50.584 9.881 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -48.9 7.542 vertex 54.937 -48.231 8.855 vertex 54.937 -50.868 9.323 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -48.9 13.078 vertex 54.937 -50.584 11.119 vertex 54.937 -48.231 11.765 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -50.868 9.323 vertex 54.937 -51.311 8.88 vertex 54.937 -48.9 7.542 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -51.87 8.596 vertex 54.937 -52.489 8.497 vertex 54.937 -51.256 5.831 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -52.489 8.497 vertex 54.937 -53.107 8.596 vertex 54.937 -52.712 5.6 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -52.712 5.6 vertex 54.937 -53.107 8.596 vertex 54.937 -54.168 5.831 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -54.393 9.881 vertex 54.937 -57 8.47621 vertex 54.937 -54.109 9.323 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -56.524 13.078 vertex 54.937 -57 12.14379 vertex 54.937 -54.393 11.119 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -54.393 11.119 vertex 54.937 -54.109 11.677 vertex 54.937 -56.524 13.078 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -54.168 14.789 vertex 54.937 -55.482 14.12 vertex 54.937 -53.666 12.12 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -54.109 11.677 vertex 54.937 -53.666 12.12 vertex 54.937 -55.482 14.12 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -54.491 10.5 vertex 54.937 -54.393 11.119 vertex 54.937 -57 12.14379 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -57 12.14379 vertex 54.937 -57 8.47621 vertex 54.937 -54.491 10.5 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -54.491 10.5 vertex 54.937 -57 8.47621 vertex 54.937 -54.393 9.881 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -56.524 7.542 vertex 54.937 -54.109 9.323 vertex 54.937 -57 8.47621 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -55.482 6.5 vertex 54.937 -54.109 9.323 vertex 54.937 -56.524 7.542 endloop endfacet facet normal 1 0 0 outer loop vertex 54.937 -54.168 5.831 vertex 54.937 -53.666 8.88 vertex 54.937 -55.482 6.5 endloop endfacet facet normal 0 1 0 outer loop vertex 58.2 8 20 vertex 58.2 8 0 vertex 51.9 8 3.01932 endloop endfacet facet normal 0.00274 0.15665 -0.98765 outer loop vertex 34.201 -40.3736 10.50209 vertex 34.20077 -40.38674 10.5 vertex 34.101 -40.385 10.5 endloop endfacet facet normal -0.00274 -0.15665 -0.98765 outer loop vertex 34.20077 -40.38674 10.5 vertex 34.183 -41.399 10.6606 vertex 34.101 -40.385 10.5 endloop endfacet facet normal 0 0.45359 0.89121 outer loop vertex 45.18865 -41.208 13.396 vertex 34.0868 -41.208 13.396 vertex 37.8 -41.766 13.68 endloop endfacet facet normal 0.89086 0.11761 -0.43879 outer loop vertex 51.58089 8.49849 -15.43054 vertex 51.6568 11.55105 -14.45823 vertex 51.737 8.41924 -15.13485 endloop endfacet facet normal -0.00274 -0.15665 -0.98765 outer loop vertex 34.076 -41.841 10.731 vertex 34.101 -40.385 10.5 vertex 34.183 -41.399 10.6606 endloop endfacet facet normal 0.89073 0.1177 -0.43904 outer loop vertex 51.559 8.50959 -15.47199 vertex 51.559 11.60065 -14.64335 vertex 51.58089 8.49849 -15.43054 endloop endfacet facet normal 0.89073 0.1177 -0.43904 outer loop vertex 51.6568 11.55105 -14.45823 vertex 51.58089 8.49849 -15.43054 vertex 51.559 11.60065 -14.64335 endloop endfacet facet normal 0 0.9877 -0.15637 outer loop vertex 34.06424 -42.49669 15.89568 vertex 45.11944 -42.50613 15.83607 vertex 34.0626 -42.591 15.3 endloop endfacet facet normal 0.98781 0.0403 -0.15034 outer loop vertex 51.559 11.60065 -14.64335 vertex 51.559 8.50959 -15.47199 vertex 51.498 11.70084 -15.0173 endloop endfacet facet normal 0.98781 0.0403 -0.15034 outer loop vertex 51.498 8.60981 -15.84593 vertex 51.498 11.70084 -15.0173 vertex 51.559 8.50959 -15.47199 endloop endfacet facet normal 0.98775 -0.0404 0.1507 outer loop vertex 51.559 11.80078 -15.39032 vertex 51.498 8.60981 -15.84593 vertex 51.559 8.70977 -16.21894 endloop endfacet facet normal -0.99985 0.01755 0 outer loop vertex 34.183 -41.399 10.5 vertex 34.183 -41.399 10.6606 vertex 34.20077 -40.38674 10.5 endloop endfacet facet normal 0.89073 -0.1177 0.43904 outer loop vertex 51.559 11.80078 -15.39032 vertex 51.559 8.70977 -16.21894 vertex 51.737 11.89105 -15.72725 endloop endfacet facet normal 0.89073 -0.1177 0.43904 outer loop vertex 51.737 8.80006 -16.55586 vertex 51.737 11.89105 -15.72725 vertex 51.559 8.70977 -16.21894 endloop endfacet facet normal -1 0 0 outer loop vertex 25.4 -57 5.6 vertex 25.4 -53.107 8.596 vertex 25.4 -51.788 5.6 endloop endfacet facet normal -1 0 0 outer loop vertex 25.4 -54.393 11.119 vertex 25.4 -54.491 10.5 vertex 25.4 -57 15 endloop endfacet facet normal -1 0 0 outer loop vertex 25.4 -54.393 9.881 vertex 25.4 -57 5.6 vertex 25.4 -54.491 10.5 endloop endfacet facet normal -1 0 0 outer loop vertex 25.539 -52.62606 15 vertex 25.539 -52.5 15.02 vertex 25.539 -52.37394 15 endloop endfacet facet normal 0 0.45371 0.89115 outer loop vertex 45.937 -51.256 14.789 vertex 54.937 -51.256 14.789 vertex 54.937 -49.942 14.12 endloop endfacet facet normal 0 0.15669 0.98765 outer loop vertex 54.821 -52.58594 15 vertex 54.937 -52.712 15.02 vertex 54.821 -51.7 14.85944 endloop endfacet facet normal 0 0.15669 0.98765 outer loop vertex 54.937 -52.712 15.02 vertex 54.937 -51.256 14.789 vertex 54.821 -51.7 14.85944 endloop endfacet facet normal 0 -0.15669 0.98765 outer loop vertex 54.821 -54.168 14.789 vertex 54.937 -54.168 14.789 vertex 54.821 -52.83806 15 endloop endfacet facet normal 0 -0.15669 0.98765 outer loop vertex 54.937 -52.712 15.02 vertex 54.821 -52.83806 15 vertex 54.937 -54.168 14.789 endloop endfacet facet normal 0 -0.45371 0.89115 outer loop vertex 54.937 -54.168 14.789 vertex 54.821 -54.168 14.789 vertex 54.821 -55.482 14.12 endloop endfacet facet normal 0 -0.45371 0.89115 outer loop vertex 54.937 -54.168 14.789 vertex 54.821 -55.482 14.12 vertex 54.937 -55.482 14.12 endloop endfacet facet normal 0 -0.70711 0.70711 outer loop vertex 54.821 -55.482 14.12 vertex 54.821 -56.524 13.078 vertex 54.937 -56.524 13.078 endloop endfacet facet normal 0 -0.70711 0.70711 outer loop vertex 54.821 -55.482 14.12 vertex 54.937 -56.524 13.078 vertex 54.937 -55.482 14.12 endloop endfacet facet normal 0 -0.89101 0.45399 outer loop vertex 54.821 -56.524 13.078 vertex 54.821 -57 12.14379 vertex 54.937 -57 12.14379 endloop endfacet facet normal 0 -0.89101 0.45399 outer loop vertex 54.821 -56.524 13.078 vertex 54.937 -57 12.14379 vertex 54.937 -56.524 13.078 endloop endfacet facet normal 0 -0.89101 -0.45399 outer loop vertex 54.937 -57 8.47621 vertex 54.821 -57 8.47621 vertex 54.821 -56.524 7.542 endloop endfacet facet normal 0 -0.89101 -0.45399 outer loop vertex 54.937 -57 8.47621 vertex 54.821 -56.524 7.542 vertex 54.937 -56.524 7.542 endloop endfacet facet normal 0 -0.70711 -0.70711 outer loop vertex 54.821 -56.524 7.542 vertex 54.821 -55.482 6.5 vertex 54.937 -55.482 6.5 endloop endfacet facet normal 0 -0.70711 -0.70711 outer loop vertex 54.821 -56.524 7.542 vertex 54.937 -55.482 6.5 vertex 54.937 -56.524 7.542 endloop endfacet facet normal 0 -0.45371 -0.89115 outer loop vertex 54.937 -54.168 5.831 vertex 54.937 -55.482 6.5 vertex 54.821 -54.168 5.831 endloop endfacet facet normal 0 -0.45371 -0.89115 outer loop vertex 54.821 -55.482 6.5 vertex 54.821 -54.168 5.831 vertex 54.937 -55.482 6.5 endloop endfacet facet normal 0 -0.15669 -0.98765 outer loop vertex 54.821 -54.168 5.831 vertex 54.821 -52.712 5.6 vertex 54.937 -52.712 5.6 endloop endfacet facet normal 0 -0.15669 -0.98765 outer loop vertex 54.821 -54.168 5.831 vertex 54.937 -52.712 5.6 vertex 54.937 -54.168 5.831 endloop endfacet facet normal 0 0.15669 -0.98765 outer loop vertex 54.937 -52.712 5.6 vertex 54.821 -51.7 5.76056 vertex 54.937 -51.256 5.831 endloop endfacet facet normal 0 0.15669 -0.98765 outer loop vertex 54.821 -52.712 5.6 vertex 54.821 -51.7 5.76056 vertex 54.937 -52.712 5.6 endloop endfacet facet normal 0 -1 0 outer loop vertex 34.17415 -36.2 13.17602 vertex 34.17386 -36.2 13.85081 vertex 26.6 -36.2 20 endloop endfacet facet normal 0 0.70711 -0.70711 outer loop vertex 45.937 -48.9 7.542 vertex 54.937 -48.9 7.542 vertex 54.937 -49.942 6.5 endloop endfacet facet normal -0.99986 0.01691 -0.00031 outer loop vertex 34.127 -38.929 10.731 vertex 34.11792 -39.412 13.68 vertex 34.149 -37.616 11.4 endloop endfacet facet normal -0.99984 0.01785 0.00038 outer loop vertex 34.11926 -39.33152 13.76047 vertex 34.12587 -38.969 14.123 vertex 34.149 -37.616 11.4 endloop endfacet facet normal -0.99984 0.01785 0 outer loop vertex 34.127 -38.929 10.731 vertex 34.101 -40.385 10.5 vertex 34.10841 -39.97 13.396 endloop endfacet facet normal -0.99984 0.01785 0 outer loop vertex 34.11109 -39.82012 13.47229 vertex 34.127 -38.929 10.731 vertex 34.10841 -39.97 13.396 endloop endfacet facet normal 0 -0.99463 0.10354 outer loop vertex 32.8 8.01 19.9 vertex 32.8 8 19.80394 vertex 37.8 8.01 19.9 endloop endfacet facet normal 1 0 0 outer loop vertex 34.539 -52.37394 15 vertex 34.539 -52.5 15.02 vertex 34.539 -52.62606 15 endloop endfacet facet normal -1 0 0 outer loop vertex 26.6 -36.2 -58 vertex 26.6 -36.2 20 vertex 26.6 -33.2 -58 endloop endfacet facet normal 1 0 0 outer loop vertex 54.821 -51.7 14.85944 vertex 54.821 -51.7 15 vertex 54.821 -52.58594 15 endloop endfacet facet normal 1 0 0 outer loop vertex 54.821 -57 15 vertex 54.821 -54.168 14.789 vertex 54.821 -52.83806 15 endloop endfacet facet normal -1 0 0 outer loop vertex 27.1 8 20 vertex 27.1 8 0 vertex 27.1 -3.2 20 endloop endfacet facet normal 1 0 0 outer loop vertex 54.821 -52.712 5.6 vertex 54.821 -51.7 5.6 vertex 54.821 -51.7 5.76056 endloop endfacet facet normal -0.99986 0.01691 -0.00031 outer loop vertex 34.127 -38.929 10.731 vertex 34.11109 -39.82012 13.47229 vertex 34.11792 -39.412 13.68 endloop endfacet facet normal 1 0 0 outer loop vertex 54.821 -54.168 14.789 vertex 54.821 -57 15 vertex 54.821 -55.482 14.12 endloop endfacet facet normal 1 0 0 outer loop vertex 54.821 -55.482 14.12 vertex 54.821 -57 15 vertex 54.821 -56.524 13.078 endloop endfacet facet normal 0 1 0 outer loop vertex 32.8 8 19.80394 vertex 32.8 8 3.01941 vertex 27.1 8 20 endloop endfacet facet normal 1 0 0 outer loop vertex 54.821 -57 12.14379 vertex 54.821 -56.524 13.078 vertex 54.821 -57 15 endloop endfacet facet normal 1 0 0 outer loop vertex 54.821 -57 8.47621 vertex 54.821 -57 5.6 vertex 54.821 -56.524 7.542 endloop endfacet facet normal 1 0 0 outer loop vertex 54.821 -54.168 5.831 vertex 54.821 -55.482 6.5 vertex 54.821 -57 5.6 endloop endfacet facet normal 1 0 0 outer loop vertex 54.821 -56.524 7.542 vertex 54.821 -57 5.6 vertex 54.821 -55.482 6.5 endloop endfacet facet normal 1 0 0 outer loop vertex 54.821 -52.712 5.6 vertex 54.821 -54.168 5.831 vertex 54.821 -57 5.6 endloop endfacet facet normal 0 1 0 outer loop vertex 45.937 8 20 vertex 37.8 8 19.80394 vertex 27.1 8 20 endloop endfacet facet normal 0 -1 0 outer loop vertex 34.27425 -36.2 13.17945 vertex 34.17415 -36.2 13.17602 vertex 34.27425 -36.2 10.5 endloop endfacet facet normal 0.01556 0.89085 -0.45404 outer loop vertex 34.17415 -36.2 13.17602 vertex 34.26765 -36.57574 12.442 vertex 34.168 -36.574 12.442 endloop endfacet facet normal 0.99985 -0.01736 0 outer loop vertex 45.23247 -38.684 14.681 vertex 45.22752 -38.969 14.123 vertex 45.274 -36.292 10.5 endloop endfacet facet normal 0.99985 -0.01736 0 outer loop vertex 45.22752 -38.969 14.123 vertex 45.21983 -39.412 13.68 vertex 45.274 -36.292 10.5 endloop endfacet facet normal 0.99985 -0.01736 0 outer loop vertex 45.274 -36.292 19.9 vertex 45.23417 -38.586 15.3 vertex 45.274 -36.292 10.5 endloop endfacet facet normal 0 -1 0 outer loop vertex 34.17386 -36.2 16.56919 vertex 34.17415 -36.2 17.24398 vertex 26.6 -36.2 20 endloop endfacet facet normal 0.99985 -0.01736 0 outer loop vertex 45.23417 -38.586 15.3 vertex 45.274 -36.292 19.9 vertex 45.23247 -38.684 15.919 endloop endfacet facet normal -0.99985 0.01717 0 outer loop vertex 34.101 -40.385 17.27037 vertex 34.0975 -40.589 17.303 vertex 34.101 -40.385 19.92 endloop endfacet facet normal 0.99985 -0.01736 0 outer loop vertex 45.22752 -38.969 16.477 vertex 45.274 -36.292 19.9 vertex 45.21983 -39.412 16.92 endloop endfacet facet normal 0.99985 -0.01736 0 outer loop vertex 45.182 -41.591 17.00907 vertex 45.18865 -41.208 17.204 vertex 45.182 -41.591 19.9 endloop endfacet facet normal 0.99985 -0.01736 0 outer loop vertex 45.1994 -40.589 17.303 vertex 45.21014 -39.97 17.204 vertex 45.182 -41.591 19.9 endloop endfacet facet normal 0.99985 -0.01736 0 outer loop vertex 45.274 -36.292 19.9 vertex 45.182 -41.591 19.9 vertex 45.21014 -39.97 17.204 endloop endfacet facet normal 0.99985 -0.01736 0 outer loop vertex 45.18865 -41.208 17.204 vertex 45.1994 -40.589 17.303 vertex 45.182 -41.591 19.9 endloop endfacet facet normal -0.89074 0 -0.45451 outer loop vertex 42.665 -36.2 -9.635 vertex 42.267 -36.2 -8.855 vertex 42.665 -33.2 -9.635 endloop endfacet facet normal -0.99984 0.01785 0 outer loop vertex 34.101 -40.385 13.3303 vertex 34.10841 -39.97 13.396 vertex 34.101 -40.385 10.5 endloop endfacet facet normal 0.99985 -0.01736 0 outer loop vertex 45.21014 -39.97 17.204 vertex 45.21983 -39.412 16.92 vertex 45.274 -36.292 19.9 endloop endfacet facet normal 0.99985 -0.01736 0 outer loop vertex 45.23247 -38.684 15.919 vertex 45.274 -36.292 19.9 vertex 45.22752 -38.969 16.477 endloop endfacet facet normal 0.99985 -0.01736 0 outer loop vertex 45.23247 -38.684 14.681 vertex 45.274 -36.292 10.5 vertex 45.23417 -38.586 15.3 endloop endfacet facet normal -0.99985 0.01717 0 outer loop vertex 34.0975 -40.589 13.298 vertex 34.101 -40.385 13.3303 vertex 34.101 -40.385 10.5 endloop endfacet facet normal 0 1 0 outer loop vertex 52.2 -33.2 -58 vertex 26.6 -33.2 -58 vertex 39.701 -33.2 -52.403 endloop endfacet facet normal 0 -1 0 outer loop vertex 26.6 -36.2 20 vertex 34.27425 -36.2 10.5 vertex 34.17415 -36.2 13.17602 endloop endfacet facet normal 0.99985 -0.01717 0 outer loop vertex 45.15516 -40.45194 19.9 vertex 45.153 -40.578 19.92 vertex 45.15084 -40.70406 19.9 endloop endfacet facet normal 0.01235 0.70694 -0.70717 outer loop vertex 34.149 -37.616 11.4 vertex 34.168 -36.574 12.442 vertex 34.24936 -37.61775 11.4 endloop endfacet facet normal 0.01235 0.70694 -0.70717 outer loop vertex 34.26765 -36.57574 12.442 vertex 34.24936 -37.61775 11.4 vertex 34.168 -36.574 12.442 endloop endfacet facet normal 0.00793 0.45386 -0.89104 outer loop vertex 34.22632 -38.93073 10.731 vertex 34.127 -38.929 10.731 vertex 34.22653 -38.91893 10.73701 endloop endfacet facet normal 0 1 0 outer loop vertex 42.365 -33.2 -50.467 vertex 52.2 -33.2 -58 vertex 41.967 -33.2 -51.248 endloop endfacet facet normal 0.00274 0.15665 0.98765 outer loop vertex 45.15516 -40.45194 19.9 vertex 44.19837 -40.43523 19.9 vertex 45.153 -40.578 19.92 endloop endfacet facet normal 0 1 0 outer loop vertex 41.348 -33.2 -51.867 vertex 52.2 -33.2 -58 vertex 40.567 -33.2 -52.265 endloop endfacet facet normal -0.00274 -0.15665 0.98765 outer loop vertex 34.19855 -40.5128 19.9 vertex 45.15084 -40.70406 19.9 vertex 45.153 -40.578 19.92 endloop endfacet facet normal 0.00793 0.45387 -0.89103 outer loop vertex 34.24936 -37.61775 11.4 vertex 34.22653 -38.91893 10.73701 vertex 34.149 -37.616 11.4 endloop endfacet facet normal 0.00793 0.45387 -0.89103 outer loop vertex 34.127 -38.929 10.731 vertex 34.149 -37.616 11.4 vertex 34.22653 -38.91893 10.73701 endloop endfacet facet normal 0 -1 0 outer loop vertex 52.2 -36.2 20 vertex 26.6 -36.2 20 vertex 40.00412 -36.2 19.9 endloop endfacet facet normal 0.00274 0.15665 0.98765 outer loop vertex 34.20298 -40.26068 19.9 vertex 34.101 -40.385 19.92 vertex 44.19837 -40.43523 19.9 endloop endfacet facet normal 0.00274 0.15665 -0.98765 outer loop vertex 34.127 -38.929 10.731 vertex 34.22632 -38.93073 10.731 vertex 34.201 -40.3736 10.50209 endloop endfacet facet normal -0.99985 0.01748 -0.00023 outer loop vertex 34.06549 -42.42509 14.54757 vertex 34.06937 -42.209 14.123 vertex 34.023 -44.866 13.755 endloop endfacet facet normal 0 0 1 outer loop vertex 45.15084 -40.70406 19.9 vertex 45.182 -41.591 19.9 vertex 45.15516 -40.45194 19.9 endloop endfacet facet normal -0.99985 0.0174 0 outer loop vertex 34.019 -45.096 15.21 vertex 34.06431 -42.493 14.681 vertex 34.023 -44.866 13.755 endloop endfacet facet normal 0 0 1 outer loop vertex 44.19837 -40.43523 19.9 vertex 45.15516 -40.45194 19.9 vertex 45.274 -36.292 19.9 endloop endfacet facet normal 0 1 0 outer loop vertex 38.835 -33.2 -46.937 vertex 38.055 -33.2 -47.335 vertex 38.452 -33.2 -38.767 endloop endfacet facet normal 0 0 1 outer loop vertex 45.274 -36.292 19.9 vertex 45.15516 -40.45194 19.9 vertex 45.182 -41.591 19.9 endloop endfacet facet normal -0.99985 0.01747 -0.0001 outer loop vertex 34.09068 -40.9861 13.36087 vertex 34.076 -41.841 10.731 vertex 34.0868 -41.208 13.396 endloop endfacet facet normal 0 1 0 outer loop vertex 41.745 -33.2 -38.767 vertex 42.365 -33.2 -38.148 vertex 41.967 -33.2 -47.955 endloop endfacet facet normal 0 1 0 outer loop vertex 41.967 -33.2 -47.955 vertex 41.348 -33.2 -47.335 vertex 41.745 -33.2 -38.767 endloop endfacet facet normal 0 0 1 outer loop vertex 34.27425 -36.2 19.9 vertex 34.20298 -40.26068 19.9 vertex 40.00412 -36.2 19.9 endloop endfacet facet normal -0.99985 0.01747 -0.0001 outer loop vertex 34.08046 -41.56961 13.58004 vertex 34.0868 -41.208 13.396 vertex 34.053 -43.154 11.4 endloop endfacet facet normal -0.99985 0.01747 -0.0001 outer loop vertex 34.076 -41.841 10.731 vertex 34.053 -43.154 11.4 vertex 34.0868 -41.208 13.396 endloop endfacet facet normal 0 0 1 outer loop vertex 40.00412 -36.2 19.9 vertex 44.19837 -40.43523 19.9 vertex 45.274 -36.292 19.9 endloop endfacet facet normal 0 1 0 outer loop vertex 40.965 -33.2 -39.165 vertex 41.745 -33.2 -38.767 vertex 41.348 -33.2 -47.335 endloop endfacet facet normal 0 1 0 outer loop vertex 41.348 -33.2 -47.335 vertex 40.567 -33.2 -46.937 vertex 40.965 -33.2 -39.165 endloop endfacet facet normal 0 1 0 outer loop vertex 40.567 -33.2 -46.937 vertex 39.701 -33.2 -46.8 vertex 40.099 -33.2 -39.302 endloop endfacet facet normal 0 1 0 outer loop vertex 40.099 -33.2 -39.302 vertex 40.965 -33.2 -39.165 vertex 40.567 -33.2 -46.937 endloop endfacet facet normal 0 1 0 outer loop vertex 39.233 -33.2 -39.165 vertex 40.099 -33.2 -39.302 vertex 39.701 -33.2 -46.8 endloop endfacet facet normal 0 1 0 outer loop vertex 39.701 -33.2 -46.8 vertex 38.835 -33.2 -46.937 vertex 39.233 -33.2 -39.165 endloop endfacet facet normal 0 1 0 outer loop vertex 38.452 -33.2 -38.767 vertex 39.233 -33.2 -39.165 vertex 38.835 -33.2 -46.937 endloop endfacet facet normal -0.99985 0.01729 0.00003 outer loop vertex 34.08046 -41.56961 13.58004 vertex 34.053 -43.154 11.4 vertex 34.07707 -41.766 13.68 endloop endfacet facet normal 0 -1 0 outer loop vertex 45.22923 -36.2 16.63187 vertex 52.2 -36.2 20 vertex 45.22932 -36.2 16.86519 endloop endfacet facet normal -0.99985 0.01729 0.00003 outer loop vertex 34.07707 -41.766 13.68 vertex 34.053 -43.154 11.4 vertex 34.035 -44.197 12.442 endloop endfacet facet normal -0.99985 0.01729 0.00003 outer loop vertex 34.0718 -42.07143 13.98543 vertex 34.07707 -41.766 13.68 vertex 34.035 -44.197 12.442 endloop endfacet facet normal 0 0.15669 0.98765 outer loop vertex 45.937 -52.712 15.02 vertex 54.937 -52.712 15.02 vertex 46.1 -52.58594 15 endloop endfacet facet normal 0 0.15669 0.98765 outer loop vertex 54.821 -52.58594 15 vertex 46.1 -52.58594 15 vertex 54.937 -52.712 15.02 endloop endfacet facet normal 0 -0.15669 0.98765 outer loop vertex 54.821 -52.83806 15 vertex 54.937 -52.712 15.02 vertex 46.1 -52.83806 15 endloop endfacet facet normal 0 -0.15669 0.98765 outer loop vertex 45.937 -52.712 15.02 vertex 46.1 -52.83806 15 vertex 54.937 -52.712 15.02 endloop endfacet facet normal 0 0 1 outer loop vertex 54.821 -51.7 15 vertex 46.1 -51.7 15 vertex 46.1 -52.58594 15 endloop endfacet facet normal 0 0 1 outer loop vertex 54.821 -51.7 15 vertex 46.1 -52.58594 15 vertex 54.821 -52.58594 15 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 55.2 4.36328 0 vertex 54.002 5.0705 -2.639 vertex 55.2 7.74214 -12.60822 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.941 5.17042 -3.01184 vertex 53.8835 5.19975 -3.12129 vertex 55.2 7.74214 -12.60822 endloop endfacet facet normal -0.99986 0.01691 0.00031 outer loop vertex 34.12057 -39.25577 16.76377 vertex 34.11798 -39.412 16.92 vertex 34.149 -37.616 19.02 endloop endfacet facet normal -0.99986 0.01691 0.00031 outer loop vertex 34.11198 -39.76991 17.10216 vertex 34.127 -38.929 19.689 vertex 34.11798 -39.412 16.92 endloop endfacet facet normal 0.99985 -0.01727 -0.00042 outer loop vertex 45.22923 -36.2 16.63187 vertex 45.22932 -36.2 16.86519 vertex 45.22764 -36.29119 16.60226 endloop endfacet facet normal 0.99985 -0.01727 -0.00042 outer loop vertex 45.22783 -36.29119 17.04417 vertex 45.22764 -36.29119 16.60226 vertex 45.22932 -36.2 16.86519 endloop endfacet facet normal 0 0 1 outer loop vertex 54.821 -52.83806 15 vertex 46.1 -52.83806 15 vertex 54.821 -57 15 endloop endfacet facet normal 0 0 1 outer loop vertex 46.1 -52.83806 15 vertex 46.1 -57 15 vertex 54.821 -57 15 endloop endfacet facet normal 0.89086 0.11761 -0.43879 outer loop vertex 51.737 11.51035 -14.30631 vertex 51.737 8.41924 -15.13485 vertex 51.6568 11.55105 -14.45823 endloop endfacet facet normal 0.98775 -0.0404 0.1507 outer loop vertex 51.559 11.80078 -15.39032 vertex 51.498 11.70084 -15.0173 vertex 51.498 8.60981 -15.84593 endloop endfacet facet normal 0 1 0 outer loop vertex 42.763 -33.2 -35.635 vertex 42.365 -33.2 -34.855 vertex 51.8 -33.2 -30.37797 endloop endfacet facet normal 0 1 0 outer loop vertex 51.8 -33.2 -30.37797 vertex 42.365 -33.2 -34.855 vertex 41.745 -33.2 -34.235 endloop endfacet facet normal 0 1 0 outer loop vertex 40.965 -33.2 -33.837 vertex 41.394 -33.2 -25.767 vertex 41.745 -33.2 -34.235 endloop endfacet facet normal 0 1 0 outer loop vertex 51.8 -33.2 -30.37797 vertex 42.365 -33.2 -48.735 vertex 42.763 -33.2 -37.367 endloop endfacet facet normal 0 1 0 outer loop vertex 42.365 -33.2 -38.148 vertex 42.763 -33.2 -37.367 vertex 42.365 -33.2 -48.735 endloop endfacet facet normal 0 1 0 outer loop vertex 51.8 -33.2 -30.37797 vertex 42.763 -33.2 -37.367 vertex 42.9 -33.2 -36.501 endloop endfacet facet normal 0 1 0 outer loop vertex 42.763 -33.2 -35.635 vertex 51.8 -33.2 -30.37797 vertex 42.9 -33.2 -36.501 endloop endfacet facet normal -0.99984 0.01785 -0.00038 outer loop vertex 34.149 -37.616 19.02 vertex 34.1258 -38.969 16.477 vertex 34.12057 -39.25577 16.76377 endloop endfacet facet normal 0 1 0 outer loop vertex 42.365 -33.2 -50.467 vertex 42.503 -33.2 -49.601 vertex 52.2 -33.2 -58 endloop endfacet facet normal 0 1 0 outer loop vertex 42.503 -33.2 -49.601 vertex 42.365 -33.2 -48.735 vertex 52.2 -33.2 -58 endloop endfacet facet normal 0 1 0 outer loop vertex 51.8 -33.2 -30.37797 vertex 52.2 -33.2 -58 vertex 42.365 -33.2 -48.735 endloop endfacet facet normal 0 1 0 outer loop vertex 42.365 -33.2 -48.735 vertex 41.967 -33.2 -47.955 vertex 42.365 -33.2 -38.148 endloop endfacet facet normal 0 1 0 outer loop vertex 38.835 -33.2 -52.265 vertex 39.701 -33.2 -52.403 vertex 26.6 -33.2 -58 endloop endfacet facet normal 0 1 0 outer loop vertex 39.701 -33.2 -52.403 vertex 40.567 -33.2 -52.265 vertex 52.2 -33.2 -58 endloop endfacet facet normal 0 1 0 outer loop vertex 41.348 -33.2 -51.867 vertex 41.967 -33.2 -51.248 vertex 52.2 -33.2 -58 endloop endfacet facet normal 0 1 0 outer loop vertex 37.735 -33.2 -8.855 vertex 27.1 -33.2 0 vertex 38.355 -33.2 -8.235 endloop endfacet facet normal 0 1 0 outer loop vertex 37.984 -33.2 -0.679 vertex 38.765 -33.2 -1.077 vertex 38.355 -33.2 -8.235 endloop endfacet facet normal 0 1 0 outer loop vertex 38.355 -33.2 -8.235 vertex 38.765 -33.2 -1.077 vertex 39.135 -33.2 -7.837 endloop endfacet facet normal 0.01235 0.70694 0.70717 outer loop vertex 34.26765 -36.57574 17.978 vertex 34.168 -36.574 17.978 vertex 34.24936 -37.61775 19.02 endloop endfacet facet normal 0.01556 0.89085 0.45404 outer loop vertex 45.22932 -36.2 16.86519 vertex 40.00412 -36.2 17.04422 vertex 45.22783 -36.29119 17.04417 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.00412 -36.2 17.04422 vertex 45.22932 -36.2 16.86519 vertex 40.00412 -36.2 19.9 endloop endfacet facet normal -0.99984 0.01785 0 outer loop vertex 34.101 -40.385 17.27037 vertex 34.101 -40.385 19.92 vertex 34.10841 -39.97 17.204 endloop endfacet facet normal -0.00274 -0.15665 0.98765 outer loop vertex 34.076 -41.841 19.689 vertex 34.183 -41.399 19.7594 vertex 34.101 -40.385 19.92 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.138 4.7631 -1.49193 vertex 55.2 4.36328 0 vertex 52.752 4.74728 -1.43288 endloop endfacet facet normal 0.99985 -0.01727 0.00042 outer loop vertex 45.22923 -36.2 13.78813 vertex 45.22764 -36.29119 13.81774 vertex 45.22932 -36.2 13.55481 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.764 4.88052 -1.93008 vertex 55.2 4.36328 0 vertex 53.487 4.80894 -1.66297 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.138 4.7631 -1.49193 vertex 53.487 4.80894 -1.66297 vertex 55.2 4.36328 0 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 55.2 4.36328 0 vertex 53.764 4.88052 -1.93008 vertex 53.941 4.97056 -2.26607 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 55.2 4.36328 0 vertex 53.941 4.97056 -2.26607 vertex 53.96081 5.003 -2.38713 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 55.2 4.36328 0 vertex 53.96081 5.003 -2.38713 vertex 54.002 5.0705 -2.639 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.98219 5.10296 -2.76013 vertex 55.2 7.74214 -12.60822 vertex 54.002 5.0705 -2.639 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.941 5.17042 -3.01184 vertex 55.2 7.74214 -12.60822 vertex 53.98219 5.10296 -2.76013 endloop endfacet facet normal 0.99985 -0.01727 0.00042 outer loop vertex 45.22783 -36.29119 13.37583 vertex 45.22932 -36.2 13.55481 vertex 45.22764 -36.29119 13.81774 endloop endfacet facet normal 0.99985 -0.0174 0.00001 outer loop vertex 45.22764 -36.29119 13.81774 vertex 45.22923 -36.2 13.78813 vertex 45.2292 -36.2 15.21 endloop endfacet facet normal 0.99985 -0.0174 0.00001 outer loop vertex 45.22764 -36.29119 13.81774 vertex 45.2292 -36.2 15.21 vertex 45.22762 -36.29119 15.21 endloop endfacet facet normal -0.99986 0.01691 0.00031 outer loop vertex 34.149 -37.616 19.02 vertex 34.11798 -39.412 16.92 vertex 34.127 -38.929 19.689 endloop endfacet facet normal 0 -1 0 outer loop vertex 26.6 -36.2 20 vertex 34.17415 -36.2 17.24398 vertex 34.27425 -36.2 19.9 endloop endfacet facet normal -0.99985 0.01727 0.00042 outer loop vertex 34.168 -36.574 17.978 vertex 34.17415 -36.2 17.24398 vertex 34.12746 -38.88013 16.30301 endloop endfacet facet normal -0.99985 0.01727 0.00042 outer loop vertex 34.17386 -36.2 16.56919 vertex 34.12746 -38.88013 16.30301 vertex 34.17415 -36.2 17.24398 endloop endfacet facet normal 0 -0.07378 -0.99727 outer loop vertex 51.8 22.60526 1.93881 vertex 51.9 26.09 1.681 vertex 51.8 21.60559 2.01276 endloop endfacet facet normal 0 -0.07378 -0.99727 outer loop vertex 46.9 26.09 1.681 vertex 51.9 26.09 1.681 vertex 51.8 22.60526 1.93881 endloop endfacet facet normal 0 -0.07378 -0.99727 outer loop vertex 51.9 8 3.01932 vertex 51.8 21.60559 2.01276 vertex 51.9 26.09 1.681 endloop endfacet facet normal 0.99985 -0.0174 -0.00001 outer loop vertex 45.22923 -36.2 16.63187 vertex 45.22764 -36.29119 16.60226 vertex 45.2292 -36.2 15.21 endloop endfacet facet normal 0.99985 -0.0174 -0.00001 outer loop vertex 45.22762 -36.29119 15.21 vertex 45.2292 -36.2 15.21 vertex 45.22764 -36.29119 16.60226 endloop endfacet facet normal 0 -1 0 outer loop vertex 52.2 -36.2 20 vertex 40.00412 -36.2 19.9 vertex 45.22932 -36.2 16.86519 endloop endfacet facet normal 0.01556 0.89085 -0.45404 outer loop vertex 40.00412 -36.2 13.37578 vertex 45.22932 -36.2 13.55481 vertex 45.22783 -36.29119 13.37583 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 52.70234 8.93177 -17.04733 vertex 55.2 9.443 -18.955 vertex 52.75 8.93371 -17.0546 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.137 8.91767 -16.99473 vertex 55.2 9.443 -18.955 vertex 53.44302 8.87748 -16.84475 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.08934 8.91962 -17.002 vertex 55.2 9.443 -18.955 vertex 53.137 8.91767 -16.99473 endloop endfacet facet normal 0.01556 0.89085 0.45404 outer loop vertex 34.26765 -36.57574 17.978 vertex 34.17415 -36.2 17.24398 vertex 34.168 -36.574 17.978 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 55.2 9.443 -18.955 vertex 53.486 8.8718 -16.82357 vertex 53.44302 8.87748 -16.84475 endloop endfacet facet normal 1 0 0 outer loop vertex 51.8 22.603 1.874 vertex 51.8 22.60526 1.93881 vertex 51.8 21.60559 2.01276 endloop endfacet facet normal -1 0 0 outer loop vertex 46.9 8 19.90931 vertex 46.9 26.09 1.681 vertex 46.9 22.7 4.662 endloop endfacet facet normal 0.01746 0.99985 0 outer loop vertex 45.22783 -36.29119 17.04417 vertex 45.274 -36.292 19.9 vertex 45.22764 -36.29119 16.60226 endloop endfacet facet normal 0.01746 0.99985 0 outer loop vertex 40.00412 -36.2 19.9 vertex 45.274 -36.292 19.9 vertex 45.22783 -36.29119 17.04417 endloop endfacet facet normal -0.99984 0.01785 -0.00038 outer loop vertex 34.149 -37.616 19.02 vertex 34.168 -36.574 17.978 vertex 34.1258 -38.969 16.477 endloop endfacet facet normal -1 0 0 outer loop vertex 46.9 21.60559 2.01276 vertex 46.9 8 3.01932 vertex 46.9 8 3.9056 endloop endfacet facet normal -0.99984 0.01785 -0.00038 outer loop vertex 34.12746 -38.88013 16.30301 vertex 34.1258 -38.969 16.477 vertex 34.168 -36.574 17.978 endloop endfacet facet normal 0 1 0 outer loop vertex 51.9 8 3.01932 vertex 58.2 8 0 vertex 46.9 8 3.01932 endloop endfacet facet normal -0.99985 0.01717 0 outer loop vertex 34.101 -40.385 10.5 vertex 34.076 -41.841 10.731 vertex 34.0975 -40.589 13.298 endloop endfacet facet normal -0.99985 0.01717 0 outer loop vertex 34.09068 -40.9861 13.36087 vertex 34.0975 -40.589 13.298 vertex 34.076 -41.841 10.731 endloop endfacet facet normal 0.01746 0.99985 0 outer loop vertex 45.22764 -36.29119 16.60226 vertex 45.274 -36.292 19.9 vertex 45.22762 -36.29119 15.21 endloop endfacet facet normal 0.01746 0.99985 0 outer loop vertex 45.22762 -36.29119 15.21 vertex 45.274 -36.292 10.5 vertex 45.22764 -36.29119 13.81774 endloop endfacet facet normal 0 -0.07378 -0.99727 outer loop vertex 46.9 21.60559 2.01276 vertex 51.8 21.60559 2.01276 vertex 46.9 8 3.01932 endloop endfacet facet normal 0 -0.07378 -0.99727 outer loop vertex 51.9 8 3.01932 vertex 46.9 8 3.01932 vertex 51.8 21.60559 2.01276 endloop endfacet facet normal 0.01746 0.99985 0 outer loop vertex 45.274 -36.292 10.5 vertex 45.22762 -36.29119 15.21 vertex 45.274 -36.292 19.9 endloop endfacet facet normal 0 -1 0 outer loop vertex 56.103 2.403 20 vertex 45.402 2.403 11.799 vertex 55.27692 2.403 0 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 46.1 22.603 1.874 vertex 51.8 22.603 1.874 vertex 46.9 21.60559 2.01276 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 51.8 21.60559 2.01276 vertex 46.9 21.60559 2.01276 vertex 51.8 22.603 1.874 endloop endfacet facet normal 0.01746 0.99985 0 outer loop vertex 40.00412 -36.2 19.9 vertex 45.22783 -36.29119 17.04417 vertex 40.00412 -36.2 17.04422 endloop endfacet facet normal 0.01746 0.99985 0 outer loop vertex 45.22783 -36.29119 13.37583 vertex 45.22764 -36.29119 13.81774 vertex 45.274 -36.292 10.5 endloop endfacet facet normal -1 0 0 outer loop vertex 46.9 26.09 1.681 vertex 46.9 22.60526 1.93881 vertex 46.9 22.7 4.662 endloop endfacet facet normal 0 -0.07378 -0.99727 outer loop vertex 51.8 22.60526 1.93881 vertex 46.9 22.60526 1.93881 vertex 46.9 26.09 1.681 endloop endfacet facet normal 0 0.15637 0.9877 outer loop vertex 45.18865 -41.208 13.396 vertex 34.09068 -40.9861 13.36087 vertex 34.0868 -41.208 13.396 endloop endfacet facet normal 0 0.15637 0.9877 outer loop vertex 45.18865 -41.208 13.396 vertex 34.0975 -40.589 13.298 vertex 34.09068 -40.9861 13.36087 endloop endfacet facet normal 0 0.9994 -0.03477 outer loop vertex 51.8 22.603 1.874 vertex 46.1 22.603 1.874 vertex 46.9 22.60526 1.93881 endloop endfacet facet normal 0 0.9994 -0.03477 outer loop vertex 46.1 22.603 1.874 vertex 46.9 22.7 4.662 vertex 46.9 22.60526 1.93881 endloop endfacet facet normal -0.99985 0.01755 0 outer loop vertex 34.27425 -36.2 13.17945 vertex 34.27425 -36.2 10.5 vertex 34.26765 -36.57574 12.442 endloop endfacet facet normal 0 0.9994 -0.03477 outer loop vertex 46.9 22.60526 1.93881 vertex 51.8 22.60526 1.93881 vertex 51.8 22.603 1.874 endloop endfacet facet normal -0.99985 0.01755 0 outer loop vertex 34.22653 -38.91893 10.73701 vertex 34.24936 -37.61775 11.4 vertex 34.27425 -36.2 10.5 endloop endfacet facet normal -0.99985 0.01755 0 outer loop vertex 34.27425 -36.2 10.5 vertex 34.24936 -37.61775 11.4 vertex 34.26765 -36.57574 12.442 endloop endfacet facet normal -0.99985 0.01755 0 outer loop vertex 34.20077 -40.38674 10.5 vertex 34.201 -40.3736 10.50209 vertex 34.27425 -36.2 10.5 endloop endfacet facet normal -0.99985 0.01755 0 outer loop vertex 34.27425 -36.2 10.5 vertex 34.22632 -38.93073 10.731 vertex 34.22653 -38.91893 10.73701 endloop endfacet facet normal 0 0 -1 outer loop vertex 46.1 -51.7 5.6 vertex 54.821 -52.712 5.6 vertex 46.1 -52.712 5.6 endloop endfacet facet normal -0.99985 0.01755 0 outer loop vertex 34.22632 -38.93073 10.731 vertex 34.27425 -36.2 10.5 vertex 34.201 -40.3736 10.50209 endloop endfacet facet normal 0 0 -1 outer loop vertex 46.1 -57 5.6 vertex 46.1 -52.712 5.6 vertex 54.821 -57 5.6 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.821 -51.7 5.6 vertex 54.821 -52.712 5.6 vertex 46.1 -51.7 5.6 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.821 -52.712 5.6 vertex 54.821 -57 5.6 vertex 46.1 -52.712 5.6 endloop endfacet facet normal 1 0 0 outer loop vertex 52.2 -36.2 -10.48639 vertex 52.2 -33.2 20 vertex 52.2 -36.2 20 endloop endfacet facet normal 0.99985 -0.01747 -0.0001 outer loop vertex 45.105 -43.347 19.02 vertex 45.13241 -41.766 16.92 vertex 45.13549 -41.59019 17.00948 endloop endfacet facet normal 0.99985 -0.01747 -0.0001 outer loop vertex 45.13186 -41.79772 16.88828 vertex 45.13241 -41.766 16.92 vertex 45.105 -43.347 19.02 endloop endfacet facet normal 0.99985 -0.01747 -0.0001 outer loop vertex 45.13549 -41.59019 17.00948 vertex 45.13562 -41.59019 18.32374 vertex 45.105 -43.347 19.02 endloop endfacet facet normal 0 1 0 outer loop vertex 51.9 8 19.90931 vertex 58.2 8 20 vertex 51.9 8 3.01932 endloop endfacet facet normal 0.99985 -0.01747 -0.0001 outer loop vertex 45.128 -42.034 19.689 vertex 45.105 -43.347 19.02 vertex 45.13562 -41.59019 18.32374 endloop endfacet facet normal 0.99985 -0.01717 0 outer loop vertex 45.13562 -41.59019 18.32374 vertex 45.13562 -41.59019 19.75941 vertex 45.128 -42.034 19.689 endloop endfacet facet normal 1 0 0 outer loop vertex 51.9 8 3.01932 vertex 51.9 26.09 1.681 vertex 51.9 8 19.90931 endloop endfacet facet normal 0 0.70979 0.70441 outer loop vertex 46.9 26.09 1.681 vertex 46.9 8 19.90931 vertex 51.9 26.09 1.681 endloop endfacet facet normal 0 0.70979 0.70441 outer loop vertex 51.9 8 19.90931 vertex 51.9 26.09 1.681 vertex 46.9 8 19.90931 endloop endfacet facet normal 0 1 0 outer loop vertex 55.3377 -0.802 0 vertex 45.402 -0.802 11.799 vertex 56.103 -0.802 20 endloop endfacet facet normal 0.99985 -0.0174 0 outer loop vertex 45.11821 -42.57675 15.21 vertex 45.11796 -42.591 15.3 vertex 45.071 -45.289 15.21 endloop endfacet facet normal 0.99985 -0.0174 0 outer loop vertex 45.11944 -42.50613 15.83607 vertex 45.075 -45.059 16.665 vertex 45.11796 -42.591 15.3 endloop endfacet facet normal 0.99985 -0.0174 0 outer loop vertex 45.071 -45.289 15.21 vertex 45.11796 -42.591 15.3 vertex 45.075 -45.059 16.665 endloop endfacet facet normal 0.99984 -0.01784 -0.00037 outer loop vertex 45.105 -43.347 19.02 vertex 45.12436 -42.209 16.477 vertex 45.13186 -41.79772 16.88828 endloop endfacet facet normal 0 -0.15637 0.9877 outer loop vertex 34.10841 -39.97 13.396 vertex 34.101 -40.385 13.3303 vertex 45.1994 -40.589 13.298 endloop endfacet facet normal 0 -1 0 outer loop vertex 45.22923 -36.2 13.78813 vertex 45.22932 -36.2 13.55481 vertex 52.2 -36.2 20 endloop endfacet facet normal 0.99984 -0.01784 -0.00037 outer loop vertex 45.12436 -42.209 16.477 vertex 45.105 -43.347 19.02 vertex 45.086 -44.39 17.978 endloop endfacet facet normal 0.99984 -0.01784 -0.00037 outer loop vertex 45.12379 -42.23973 16.41663 vertex 45.12436 -42.209 16.477 vertex 45.086 -44.39 17.978 endloop endfacet facet normal -1 0 0 outer loop vertex 46.9 22.7 4.662 vertex 46.9 8.051 6.7 vertex 46.9 8 19.90931 endloop endfacet facet normal -1 0 0 outer loop vertex 46.9 8 5.23414 vertex 46.9 8 19.90931 vertex 46.9 8.051 6.7 endloop endfacet facet normal 0 -1 0 outer loop vertex 45.2292 -36.2 15.21 vertex 45.22923 -36.2 13.78813 vertex 52.2 -36.2 20 endloop endfacet facet normal 0 1 0 outer loop vertex 37.337 -33.2 -9.635 vertex 27.1 -33.2 0 vertex 37.735 -33.2 -8.855 endloop endfacet facet normal 0 1 0 outer loop vertex 37.984 -33.2 -0.679 vertex 38.355 -33.2 -8.235 vertex 27.1 -33.2 0 endloop endfacet facet normal 0.99985 -0.01727 0.00042 outer loop vertex 45.12379 -42.23973 16.41663 vertex 45.086 -44.39 17.978 vertex 45.11963 -42.493 15.919 endloop endfacet facet normal 0 1 0 outer loop vertex 37.364 -33.2 -0.06 vertex 37.984 -33.2 -0.679 vertex 27.1 -33.2 0 endloop endfacet facet normal 0 -0.15793 -0.98745 outer loop vertex 34.0975 -40.589 17.303 vertex 34.101 -40.385 17.27037 vertex 45.1994 -40.589 17.303 endloop endfacet facet normal 0.99985 -0.01727 0.00042 outer loop vertex 45.075 -45.059 16.665 vertex 45.11963 -42.493 15.919 vertex 45.086 -44.39 17.978 endloop endfacet facet normal 0.99985 -0.01727 0.00042 outer loop vertex 45.11944 -42.50613 15.83607 vertex 45.11963 -42.493 15.919 vertex 45.075 -45.059 16.665 endloop endfacet facet normal 0.99985 -0.01727 -0.00042 outer loop vertex 45.12037 -42.45247 14.60135 vertex 45.075 -45.059 13.755 vertex 45.12437 -42.209 14.123 endloop endfacet facet normal 0.99985 -0.01727 -0.00042 outer loop vertex 45.12532 -42.15262 14.06662 vertex 45.12437 -42.209 14.123 vertex 45.086 -44.39 12.442 endloop endfacet facet normal 0 -1 0 outer loop vertex 39.63 -36.2 -1.214 vertex 38.765 -36.2 -1.077 vertex 39.135 -36.2 -7.837 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.364 -36.2 -0.06 vertex 31.06376 -36.2 -10.48639 vertex 37.984 -36.2 -0.679 endloop endfacet facet normal 0 -1 0 outer loop vertex 39.937 -3.2 12.665 vertex 40.335 -3.2 13.445 vertex 27.1 -3.2 20 endloop endfacet facet normal 0 -1 0 outer loop vertex 39.937 -3.2 12.665 vertex 27.1 -3.2 20 vertex 39.8 -3.2 11.799 endloop endfacet facet normal 0.99985 -0.01727 -0.00042 outer loop vertex 45.086 -44.39 12.442 vertex 45.12437 -42.209 14.123 vertex 45.075 -45.059 13.755 endloop endfacet facet normal 0 -1 0 outer loop vertex 38.355 -36.2 -8.235 vertex 39.135 -36.2 -7.837 vertex 38.765 -36.2 -1.077 endloop endfacet facet normal 0.99985 -0.0174 0 outer loop vertex 45.11821 -42.57675 15.21 vertex 45.071 -45.289 15.21 vertex 45.11967 -42.493 14.681 endloop endfacet facet normal 0 -1 0 outer loop vertex 39.937 2.403 10.933 vertex 39.8 2.403 11.799 vertex 30.30975 2.403 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 29.097 2.403 20 vertex 30.30975 2.403 0 vertex 39.8 2.403 11.799 endloop endfacet facet normal 0 -0.99463 0.10354 outer loop vertex 37.8 8.01 19.9 vertex 32.8 8 19.80394 vertex 37.8 8 19.80394 endloop endfacet facet normal 0.99985 -0.0174 0 outer loop vertex 45.12037 -42.45247 14.60135 vertex 45.11967 -42.493 14.681 vertex 45.075 -45.059 13.755 endloop endfacet facet normal 0.99985 -0.0174 0 outer loop vertex 45.075 -45.059 13.755 vertex 45.11967 -42.493 14.681 vertex 45.071 -45.289 15.21 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 40.91319 19.20945 5.14761 vertex 37.8 22.7 4.662 vertex 40.956 18.9367 5.18556 endloop endfacet facet normal 0 -1 0 outer loop vertex 38.355 -36.2 -8.235 vertex 37.984 -36.2 -0.679 vertex 37.735 -36.2 -8.855 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 40.956 19.88063 5.05424 vertex 41.17 20.30653 4.99498 vertex 37.8 22.7 4.662 endloop endfacet facet normal 0.89074 0 -0.45451 outer loop vertex 37.735 -33.2 -8.855 vertex 37.735 -36.2 -8.855 vertex 37.337 -36.2 -9.635 endloop endfacet facet normal 0.89074 0 -0.45451 outer loop vertex 37.735 -33.2 -8.855 vertex 37.337 -36.2 -9.635 vertex 37.337 -33.2 -9.635 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 41.504 18.1725 5.29188 vertex 37.8 8.051 6.7 vertex 41.69207 18.07515 5.30542 endloop endfacet facet normal 0.70711 0 -0.70711 outer loop vertex 37.735 -33.2 -8.855 vertex 38.355 -36.2 -8.235 vertex 37.735 -36.2 -8.855 endloop endfacet facet normal -0.00274 -0.15665 0.98765 outer loop vertex 34.076 -41.841 19.689 vertex 45.128 -42.034 19.689 vertex 34.183 -41.399 19.7594 endloop endfacet facet normal 0.70654 0 0.70768 outer loop vertex 37.364 -33.2 -0.06 vertex 37.364 -36.2 -0.06 vertex 37.984 -36.2 -0.679 endloop endfacet facet normal 0.70654 0 0.70768 outer loop vertex 37.364 -33.2 -0.06 vertex 37.984 -36.2 -0.679 vertex 37.984 -33.2 -0.679 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 41.17 18.5108 5.24481 vertex 37.8 8.051 6.7 vertex 41.31708 18.36207 5.2655 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 41.504 18.1725 5.29188 vertex 41.31708 18.36207 5.2655 vertex 37.8 8.051 6.7 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 41.925 17.95514 5.32211 vertex 41.69207 18.07515 5.30542 vertex 37.8 8.051 6.7 endloop endfacet facet normal 0.98772 0 -0.15626 outer loop vertex 37.337 -36.2 -9.635 vertex 37.2 -36.2 -10.501 vertex 37.337 -33.2 -9.635 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 40.956 18.9367 5.18556 vertex 37.8 8.051 6.7 vertex 41.17 18.5108 5.24481 endloop endfacet facet normal 0 0 -1 outer loop vertex 26.6 -36.2 -58 vertex 26.6 -33.2 -58 vertex 52.2 -33.2 -58 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 43.87146 19.60318 5.09284 vertex 46.9 22.7 4.662 vertex 43.828 19.88063 5.05424 endloop endfacet facet normal 0 1 0 outer loop vertex 37.435 -33.2 -51.248 vertex 26.6 -33.2 -58 vertex 37.037 -33.2 -50.467 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 43.614 18.5108 5.24481 vertex 46.9 8.051 6.7 vertex 43.828 18.9367 5.18556 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 43.42738 18.32152 5.27114 vertex 46.9 8.051 6.7 vertex 43.614 18.5108 5.24481 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 43.28 18.1725 5.29188 vertex 46.9 8.051 6.7 vertex 43.42738 18.32152 5.27114 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 42.859 17.95514 5.32211 vertex 46.9 8.051 6.7 vertex 43.04729 18.0526 5.30856 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 43.28 18.1725 5.29188 vertex 43.04729 18.0526 5.30856 vertex 46.9 8.051 6.7 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 37.8 8.051 6.7 vertex 42.13522 17.9217 5.32677 vertex 41.925 17.95514 5.32211 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 37.8 8.051 6.7 vertex 46.9 8.051 6.7 vertex 42.392 17.88087 5.33245 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 41.504 20.64428 4.948 vertex 37.8 22.7 4.662 vertex 41.17 20.30653 4.99498 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 41.925 20.86119 4.91782 vertex 37.8 22.7 4.662 vertex 41.504 20.64428 4.948 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 46.9 22.7 4.662 vertex 37.8 22.7 4.662 vertex 42.392 20.93586 4.90743 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 42.67964 20.8901 4.9138 vertex 46.9 22.7 4.662 vertex 42.392 20.93586 4.90743 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 42.859 20.86119 4.91782 vertex 46.9 22.7 4.662 vertex 42.67964 20.8901 4.9138 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 42.21282 20.90698 4.91145 vertex 42.392 20.93586 4.90743 vertex 37.8 22.7 4.662 endloop endfacet facet normal 0 1 0 outer loop vertex 37.833 -33.2 -38.148 vertex 38.452 -33.2 -38.767 vertex 38.055 -33.2 -47.335 endloop endfacet facet normal 0 1 0 outer loop vertex 38.055 -33.2 -47.335 vertex 37.435 -33.2 -47.955 vertex 37.833 -33.2 -38.148 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 43.28 20.64428 4.948 vertex 46.9 22.7 4.662 vertex 42.859 20.86119 4.91782 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 46.9 22.7 4.662 vertex 43.28 20.64428 4.948 vertex 43.614 20.30653 4.99498 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.763 8.80006 -16.55586 vertex 53.72891 8.80887 -16.58874 vertex 55.2 9.443 -18.955 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.486 8.8718 -16.82357 vertex 55.2 9.443 -18.955 vertex 53.72891 8.80887 -16.58874 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 43.614 20.30653 4.99498 vertex 43.828 19.88063 5.05424 vertex 46.9 22.7 4.662 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 46.9 22.7 4.662 vertex 43.87146 19.60318 5.09284 vertex 43.902 19.40817 5.11997 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 43.85931 19.13616 5.15781 vertex 43.828 18.9367 5.18556 vertex 46.9 22.7 4.662 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 46.9 8.051 6.7 vertex 46.9 22.7 4.662 vertex 43.828 18.9367 5.18556 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 43.902 19.40817 5.11997 vertex 43.85931 19.13616 5.15781 vertex 46.9 22.7 4.662 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 42.13522 17.9217 5.32677 vertex 37.8 8.051 6.7 vertex 42.392 17.88087 5.33245 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 42.859 17.95514 5.32211 vertex 42.60231 17.91433 5.32779 vertex 46.9 8.051 6.7 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 40.882 19.40817 5.11997 vertex 37.8 22.7 4.662 vertex 40.91319 19.20945 5.14761 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 40.9256 19.68651 5.08124 vertex 37.8 22.7 4.662 vertex 40.882 19.40817 5.11997 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 40.956 19.88063 5.05424 vertex 37.8 22.7 4.662 vertex 40.9256 19.68651 5.08124 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 41.925 20.86119 4.91782 vertex 42.21282 20.90698 4.91145 vertex 37.8 22.7 4.662 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 37.8 8.051 6.7 vertex 40.956 18.9367 5.18556 vertex 37.8 22.7 4.662 endloop endfacet facet normal -0.01556 -0.89084 -0.45404 outer loop vertex 45.086 -44.39 12.442 vertex 34.023 -44.866 13.755 vertex 34.035 -44.197 12.442 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 55.2 7.74214 -12.60822 vertex 52.366 5.37813 -3.78692 vertex 53.137 8.30163 -14.69598 endloop endfacet facet normal -0.01725 -0.98758 -0.15616 outer loop vertex 34.023 -44.866 13.755 vertex 45.075 -45.059 13.755 vertex 34.019 -45.096 15.21 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.137 8.30163 -14.69598 vertex 52.366 5.37813 -3.78692 vertex 52.79762 8.28775 -14.64419 endloop endfacet facet normal 0 0.45359 0.89121 outer loop vertex 34.07707 -41.766 13.68 vertex 37.8 -41.766 13.68 vertex 34.08046 -41.56961 13.58004 endloop endfacet facet normal 0 1 0 outer loop vertex 41.897 -33.2 3.234 vertex 41.277 -33.2 3.853 vertex 52.2 -33.2 20 endloop endfacet facet normal 0 1 0 outer loop vertex 42.295 -33.2 2.453 vertex 41.897 -33.2 3.234 vertex 52.2 -33.2 20 endloop endfacet facet normal 0 0.45359 0.89121 outer loop vertex 34.08046 -41.56961 13.58004 vertex 37.8 -41.766 13.68 vertex 34.0868 -41.208 13.396 endloop endfacet facet normal 0 1 0 outer loop vertex 52.2 -33.2 20 vertex 42.665 -33.2 -9.635 vertex 42.295 -33.2 0.721 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.78491 8.43036 -15.17632 vertex 55.2 7.74214 -12.60822 vertex 53.763 8.41924 -15.13485 endloop endfacet facet normal 0 1 0 outer loop vertex 40.496 -33.2 4.251 vertex 39.63 -33.2 4.388 vertex 52.2 -33.2 20 endloop endfacet facet normal 0 -0.15637 0.9877 outer loop vertex 34.0975 -40.589 13.298 vertex 45.1994 -40.589 13.298 vertex 34.101 -40.385 13.3303 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.486 8.34772 -14.86795 vertex 55.2 7.74214 -12.60822 vertex 53.137 8.30163 -14.69598 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.52008 8.35653 -14.90081 vertex 55.2 7.74214 -12.60822 vertex 53.486 8.34772 -14.86795 endloop endfacet facet normal 0 1 0 outer loop vertex 42.295 -33.2 2.453 vertex 52.2 -33.2 20 vertex 42.432 -33.2 1.587 endloop endfacet facet normal 0 1 0 outer loop vertex 42.432 -33.2 1.587 vertex 52.2 -33.2 20 vertex 42.295 -33.2 0.721 endloop endfacet facet normal 0 -1 0 outer loop vertex 39.937 -3.2 10.933 vertex 39.8 -3.2 11.799 vertex 27.1 -3.2 0 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.52008 8.35653 -14.90081 vertex 53.763 8.41924 -15.13485 vertex 55.2 7.74214 -12.60822 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.941 8.50959 -15.47199 vertex 54.002 8.60981 -15.84593 vertex 55.2 7.74214 -12.60822 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 55.2 9.443 -18.955 vertex 55.2 7.74214 -12.60822 vertex 54.002 8.60981 -15.84593 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 54.002 8.60981 -15.84593 vertex 53.941 8.70977 -16.21894 vertex 55.2 9.443 -18.955 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.941 8.70977 -16.21894 vertex 53.763 8.80006 -16.55586 vertex 55.2 9.443 -18.955 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.78491 8.43036 -15.17632 vertex 53.941 8.50959 -15.47199 vertex 55.2 7.74214 -12.60822 endloop endfacet facet normal 0 0.98763 0.1568 outer loop vertex 25.539 -47.788 10.31 vertex 25.539 -48.019 11.765 vertex 34.539 -47.788 10.31 endloop endfacet facet normal 0 0.98763 0.1568 outer loop vertex 34.539 -48.019 11.765 vertex 34.539 -47.788 10.31 vertex 25.539 -48.019 11.765 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 53.08934 8.91962 -17.002 vertex 52.75 8.93371 -17.0546 vertex 55.2 9.443 -18.955 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 35.0753 9.443 -18.955 vertex 55.2 9.443 -18.955 vertex 52.363 8.91767 -16.99473 endloop endfacet facet normal 0 0.89101 0.45399 outer loop vertex 25.539 -48.688 13.078 vertex 34.539 -48.688 13.078 vertex 34.539 -48.019 11.765 endloop endfacet facet normal 0 0.89101 0.45399 outer loop vertex 25.539 -48.688 13.078 vertex 34.539 -48.019 11.765 vertex 25.539 -48.019 11.765 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 52.32002 8.91199 -16.97355 vertex 35.0753 9.443 -18.955 vertex 52.363 8.91767 -16.99473 endloop endfacet facet normal 0 0.70711 0.70711 outer loop vertex 34.539 -48.688 13.078 vertex 25.539 -48.688 13.078 vertex 25.539 -49.73 14.12 endloop endfacet facet normal 0 1 0 outer loop vertex 44.867 -0.802 13.445 vertex 44.248 -0.802 14.065 vertex 56.103 -0.802 20 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.432 -36.2 1.587 vertex 52.2 -36.2 -10.48639 vertex 42.295 -36.2 2.453 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.496 -36.2 4.251 vertex 40.00412 -36.2 10.5 vertex 39.63 -36.2 4.388 endloop endfacet facet normal 0 1 0 outer loop vertex 27.1 -33.2 0 vertex 37.083 -33.2 -24.367 vertex 37.435 -33.2 -35.635 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.432 -36.2 1.587 vertex 42.295 -36.2 0.721 vertex 52.2 -36.2 -10.48639 endloop endfacet facet normal 0 -1 0 outer loop vertex 41.897 -36.2 -0.06 vertex 41.277 -36.2 -0.679 vertex 41.648 -36.2 -8.235 endloop endfacet facet normal 0 1 0 outer loop vertex 37.083 -33.2 -24.367 vertex 37.481 -33.2 -25.148 vertex 37.435 -33.2 -35.635 endloop endfacet facet normal 0 1 0 outer loop vertex 37.833 -33.2 -34.855 vertex 37.435 -33.2 -35.635 vertex 37.481 -33.2 -25.148 endloop endfacet facet normal 0 0.89101 -0.45399 outer loop vertex 25.539 -48.019 8.855 vertex 34.539 -48.019 8.855 vertex 34.539 -48.688 7.542 endloop endfacet facet normal 0 0.89101 -0.45399 outer loop vertex 25.539 -48.019 8.855 vertex 34.539 -48.688 7.542 vertex 25.539 -48.688 7.542 endloop endfacet facet normal 0 0.98763 -0.1568 outer loop vertex 25.539 -48.019 8.855 vertex 25.539 -47.788 10.31 vertex 34.539 -48.019 8.855 endloop endfacet facet normal 0 0.98763 -0.1568 outer loop vertex 25.539 -47.788 10.31 vertex 34.539 -47.788 10.31 vertex 34.539 -48.019 8.855 endloop endfacet facet normal 0.45405 0 -0.89098 outer loop vertex 38.765 -33.2 4.251 vertex 38.765 -36.2 4.251 vertex 37.984 -36.2 3.853 endloop endfacet facet normal 0.45405 0 -0.89098 outer loop vertex 38.765 -33.2 4.251 vertex 37.984 -36.2 3.853 vertex 37.984 -33.2 3.853 endloop endfacet facet normal 0 0.70711 0.70711 outer loop vertex 34.539 -48.688 13.078 vertex 25.539 -49.73 14.12 vertex 34.539 -49.73 14.12 endloop endfacet facet normal 0.15643 0 -0.98769 outer loop vertex 39.63 -33.2 4.388 vertex 39.63 -36.2 4.388 vertex 38.765 -36.2 4.251 endloop endfacet facet normal 0.15643 0 -0.98769 outer loop vertex 39.63 -33.2 4.388 vertex 38.765 -36.2 4.251 vertex 38.765 -33.2 4.251 endloop endfacet facet normal 0 0.45371 0.89115 outer loop vertex 34.539 -49.73 14.12 vertex 25.539 -51.044 14.789 vertex 34.539 -51.044 14.789 endloop endfacet facet normal -0.15626 0 -0.98772 outer loop vertex 40.496 -33.2 4.251 vertex 40.496 -36.2 4.251 vertex 39.63 -36.2 4.388 endloop endfacet facet normal -0.15626 0 -0.98772 outer loop vertex 40.496 -33.2 4.251 vertex 39.63 -36.2 4.388 vertex 39.63 -33.2 4.388 endloop endfacet facet normal 0 0.45371 0.89115 outer loop vertex 25.539 -49.73 14.12 vertex 25.539 -51.044 14.789 vertex 34.539 -49.73 14.12 endloop endfacet facet normal 0 0.15669 0.98765 outer loop vertex 25.539 -51.044 14.789 vertex 25.539 -51.788 14.90704 vertex 34.539 -51.788 14.90704 endloop endfacet facet normal 0 0.15669 0.98765 outer loop vertex 25.539 -51.044 14.789 vertex 34.539 -51.788 14.90704 vertex 34.539 -51.044 14.789 endloop endfacet facet normal -0.45405 0 -0.89098 outer loop vertex 41.277 -33.2 3.853 vertex 41.277 -36.2 3.853 vertex 40.496 -36.2 4.251 endloop endfacet facet normal -0.45405 0 -0.89098 outer loop vertex 41.277 -33.2 3.853 vertex 40.496 -36.2 4.251 vertex 40.496 -33.2 4.251 endloop endfacet facet normal 0 0.15669 -0.98765 outer loop vertex 25.539 -51.044 5.831 vertex 34.539 -51.044 5.831 vertex 34.539 -51.788 5.71296 endloop endfacet facet normal 0 0.15669 -0.98765 outer loop vertex 25.539 -51.044 5.831 vertex 34.539 -51.788 5.71296 vertex 25.539 -51.788 5.71296 endloop endfacet facet normal -0.70654 0 -0.70768 outer loop vertex 41.897 -33.2 3.234 vertex 41.897 -36.2 3.234 vertex 41.277 -36.2 3.853 endloop endfacet facet normal -0.70654 0 -0.70768 outer loop vertex 41.897 -33.2 3.234 vertex 41.277 -36.2 3.853 vertex 41.277 -33.2 3.853 endloop endfacet facet normal 0 0.45371 -0.89115 outer loop vertex 25.539 -49.73 6.5 vertex 34.539 -49.73 6.5 vertex 34.539 -51.044 5.831 endloop endfacet facet normal 0 0.45371 -0.89115 outer loop vertex 25.539 -49.73 6.5 vertex 34.539 -51.044 5.831 vertex 25.539 -51.044 5.831 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.503 -36.2 -49.601 vertex 52.2 -36.2 -58 vertex 42.365 -36.2 -48.735 endloop endfacet facet normal -0.89098 0 -0.45405 outer loop vertex 42.295 -33.2 2.453 vertex 42.295 -36.2 2.453 vertex 41.897 -36.2 3.234 endloop endfacet facet normal -0.89098 0 -0.45405 outer loop vertex 42.295 -33.2 2.453 vertex 41.897 -36.2 3.234 vertex 41.897 -33.2 3.234 endloop endfacet facet normal 0 0.70711 -0.70711 outer loop vertex 25.539 -49.73 6.5 vertex 25.539 -48.688 7.542 vertex 34.539 -49.73 6.5 endloop endfacet facet normal 0 0.70711 -0.70711 outer loop vertex 34.539 -48.688 7.542 vertex 34.539 -49.73 6.5 vertex 25.539 -48.688 7.542 endloop endfacet facet normal -0.98772 0 -0.15626 outer loop vertex 42.432 -33.2 1.587 vertex 42.432 -36.2 1.587 vertex 42.295 -36.2 2.453 endloop endfacet facet normal -0.98772 0 -0.15626 outer loop vertex 42.432 -33.2 1.587 vertex 42.295 -36.2 2.453 vertex 42.295 -33.2 2.453 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.833 -36.2 -38.148 vertex 38.055 -36.2 -47.335 vertex 38.452 -36.2 -38.767 endloop endfacet facet normal 0 -0.45295 0.89154 outer loop vertex 25.539 -51.788 8.63766 vertex 30.72 -51.87 8.596 vertex 25.539 -51.311 8.88 endloop endfacet facet normal -0.98772 0 0.15626 outer loop vertex 42.295 -33.2 0.721 vertex 42.295 -36.2 0.721 vertex 42.432 -36.2 1.587 endloop endfacet facet normal -0.98772 0 0.15626 outer loop vertex 42.295 -33.2 0.721 vertex 42.432 -36.2 1.587 vertex 42.432 -33.2 1.587 endloop endfacet facet normal -0.89098 0 0.45405 outer loop vertex 42.295 -33.2 0.721 vertex 41.897 -36.2 -0.06 vertex 42.295 -36.2 0.721 endloop endfacet facet normal 0.99985 -0.01717 0 outer loop vertex 45.13562 -41.59019 12.09626 vertex 45.128 -42.034 10.731 vertex 45.13562 -41.59019 10.66059 endloop endfacet facet normal 0 1 0 outer loop vertex 37.298 -33.2 -36.501 vertex 27.1 -33.2 0 vertex 37.435 -33.2 -35.635 endloop endfacet facet normal 0 1 0 outer loop vertex 37.037 -33.2 -48.735 vertex 26.6 -33.2 -58 vertex 37.435 -33.2 -37.367 endloop endfacet facet normal 0 1 0 outer loop vertex 37.435 -33.2 -37.367 vertex 37.833 -33.2 -38.148 vertex 37.435 -33.2 -47.955 endloop endfacet facet normal 0 1 0 outer loop vertex 37.435 -33.2 -51.248 vertex 38.055 -33.2 -51.867 vertex 26.6 -33.2 -58 endloop endfacet facet normal 0 1 0 outer loop vertex 38.055 -33.2 -51.867 vertex 38.835 -33.2 -52.265 vertex 26.6 -33.2 -58 endloop endfacet facet normal 0 1 0 outer loop vertex 37.298 -33.2 -36.501 vertex 37.435 -33.2 -37.367 vertex 26.6 -33.2 -58 endloop endfacet facet normal 0 1 0 outer loop vertex 37.435 -33.2 -47.955 vertex 37.037 -33.2 -48.735 vertex 37.435 -33.2 -37.367 endloop endfacet facet normal 0 1 0 outer loop vertex 36.9 -33.2 -49.601 vertex 26.6 -33.2 -58 vertex 37.037 -33.2 -48.735 endloop endfacet facet normal 0 1 0 outer loop vertex 36.9 -33.2 -49.601 vertex 37.037 -33.2 -50.467 vertex 26.6 -33.2 -58 endloop endfacet facet normal -0.00793 -0.45386 -0.89104 outer loop vertex 45.128 -42.034 10.731 vertex 45.105 -43.347 11.4 vertex 34.076 -41.841 10.731 endloop endfacet facet normal 0 -1 0 outer loop vertex 38.835 -36.2 -46.937 vertex 38.452 -36.2 -38.767 vertex 38.055 -36.2 -47.335 endloop endfacet facet normal 0 -1 0 outer loop vertex 27.1 -3.2 0 vertex 58.2 -3.2 0 vertex 42.601 -3.2 8.998 endloop endfacet facet normal 0 1 0 outer loop vertex 37.8 8 3.9056 vertex 46.9 8 3.9056 vertex 37.8 8 3.01941 endloop endfacet facet normal 1 0 0 outer loop vertex 37.8 8 3.9056 vertex 37.8 8 3.01941 vertex 37.8 21.5208 2.02456 endloop endfacet facet normal 0 -1 0 outer loop vertex 39.701 -36.2 -46.8 vertex 40.567 -36.2 -46.937 vertex 40.099 -36.2 -39.302 endloop endfacet facet normal 0 -0.70711 0.70711 outer loop vertex 34.539 -50.868 9.323 vertex 25.539 -50.868 9.323 vertex 25.539 -51.311 8.88 endloop endfacet facet normal 0 -0.89121 0.45359 outer loop vertex 25.539 -50.584 9.881 vertex 25.539 -50.868 9.323 vertex 34.539 -50.868 9.323 endloop endfacet facet normal 0 -0.9877 0.15637 outer loop vertex 25.539 -50.486 10.5 vertex 25.539 -50.584 9.881 vertex 34.539 -50.486 10.5 endloop endfacet facet normal 0 -0.9877 -0.15637 outer loop vertex 25.539 -50.584 11.119 vertex 25.539 -50.486 10.5 vertex 34.539 -50.584 11.119 endloop endfacet facet normal 0 -0.9877 -0.15637 outer loop vertex 34.539 -50.486 10.5 vertex 34.539 -50.584 11.119 vertex 25.539 -50.486 10.5 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.965 -36.2 -33.837 vertex 40.613 -36.2 -26.165 vertex 40.099 -36.2 -33.7 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.099 -36.2 -33.7 vertex 39.747 -36.2 -26.303 vertex 39.233 -36.2 -33.837 endloop endfacet facet normal 0 -0.89121 -0.45359 outer loop vertex 25.539 -50.868 11.677 vertex 25.539 -50.584 11.119 vertex 34.539 -50.868 11.677 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.365 -36.2 -48.735 vertex 52.2 -36.2 -58 vertex 42.365 -36.2 -38.148 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.567 -36.2 -46.937 vertex 41.348 -36.2 -47.335 vertex 40.965 -36.2 -39.165 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.965 -36.2 -39.165 vertex 40.099 -36.2 -39.302 vertex 40.567 -36.2 -46.937 endloop endfacet facet normal 0 -1 0 outer loop vertex 39.701 -36.2 -46.8 vertex 40.099 -36.2 -39.302 vertex 39.233 -36.2 -39.165 endloop endfacet facet normal 0 -1 0 outer loop vertex 38.452 -36.2 -38.767 vertex 38.835 -36.2 -46.937 vertex 39.233 -36.2 -39.165 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.365 -36.2 -38.148 vertex 41.745 -36.2 -38.767 vertex 41.967 -36.2 -47.955 endloop endfacet facet normal 0 -1 0 outer loop vertex 41.348 -36.2 -47.335 vertex 41.967 -36.2 -47.955 vertex 41.745 -36.2 -38.767 endloop endfacet facet normal 0 -0.70711 0.70711 outer loop vertex 25.539 -51.311 8.88 vertex 34.539 -51.311 8.88 vertex 34.539 -50.868 9.323 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.9 -36.2 -36.501 vertex 46.9 -36.2 -31.18159 vertex 42.763 -36.2 -35.635 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.365 -36.2 -34.855 vertex 46.9 -36.2 -31.18159 vertex 41.745 -36.2 -34.235 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.013 -36.2 -25.148 vertex 41.394 -36.2 -25.767 vertex 46.9 -36.2 -31.18159 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.365 -36.2 -34.855 vertex 42.763 -36.2 -35.635 vertex 46.9 -36.2 -31.18159 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.763 -36.2 -37.367 vertex 52.2 -36.2 -58 vertex 42.9 -36.2 -36.501 endloop endfacet facet normal 0 -1 0 outer loop vertex 41.967 -36.2 -47.955 vertex 42.365 -36.2 -48.735 vertex 42.365 -36.2 -38.148 endloop endfacet facet normal 0 -1 0 outer loop vertex 41.745 -36.2 -38.767 vertex 40.965 -36.2 -39.165 vertex 41.348 -36.2 -47.335 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.763 -36.2 -37.367 vertex 42.365 -36.2 -38.148 vertex 52.2 -36.2 -58 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.365 -36.2 -50.467 vertex 52.2 -36.2 -58 vertex 42.503 -36.2 -49.601 endloop endfacet facet normal 0 -1 0 outer loop vertex 41.967 -36.2 -51.248 vertex 52.2 -36.2 -58 vertex 42.365 -36.2 -50.467 endloop endfacet facet normal 0 -1 0 outer loop vertex 41.348 -36.2 -51.867 vertex 52.2 -36.2 -58 vertex 41.967 -36.2 -51.248 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.567 -36.2 -52.265 vertex 52.2 -36.2 -58 vertex 41.348 -36.2 -51.867 endloop endfacet facet normal 0 -1 0 outer loop vertex 46.9 -36.2 -31.18159 vertex 42.9 -36.2 -36.501 vertex 52.2 -36.2 -58 endloop endfacet facet normal 0 -1 0 outer loop vertex 41.735 -3.2 9.135 vertex 27.1 -3.2 0 vertex 42.601 -3.2 8.998 endloop endfacet facet normal 0 -1 0 outer loop vertex 26.6 -36.2 -58 vertex 52.2 -36.2 -58 vertex 39.701 -36.2 -52.403 endloop endfacet facet normal 0 -1 0 outer loop vertex 38.835 -36.2 -52.265 vertex 26.6 -36.2 -58 vertex 39.701 -36.2 -52.403 endloop endfacet facet normal 0 -1 0 outer loop vertex 38.055 -36.2 -51.867 vertex 26.6 -36.2 -58 vertex 38.835 -36.2 -52.265 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.567 -36.2 -52.265 vertex 39.701 -36.2 -52.403 vertex 52.2 -36.2 -58 endloop endfacet facet normal 0.15737 0 0.98754 outer loop vertex 38.835 -33.2 -52.265 vertex 38.835 -36.2 -52.265 vertex 39.701 -36.2 -52.403 endloop endfacet facet normal 0.15737 0 0.98754 outer loop vertex 38.835 -33.2 -52.265 vertex 39.701 -36.2 -52.403 vertex 39.701 -33.2 -52.403 endloop endfacet facet normal 0.45451 0 0.89074 outer loop vertex 38.055 -33.2 -51.867 vertex 38.055 -36.2 -51.867 vertex 38.835 -36.2 -52.265 endloop endfacet facet normal 0.45451 0 0.89074 outer loop vertex 38.055 -33.2 -51.867 vertex 38.835 -36.2 -52.265 vertex 38.835 -33.2 -52.265 endloop endfacet facet normal 0.70654 0 0.70768 outer loop vertex 37.435 -33.2 -51.248 vertex 38.055 -36.2 -51.867 vertex 38.055 -33.2 -51.867 endloop endfacet facet normal 0 1 0 outer loop vertex 36.966 -33.2 0.721 vertex 27.1 -33.2 0 vertex 36.829 -33.2 1.587 endloop endfacet facet normal 0 -1 0 outer loop vertex 38.452 -36.2 -34.235 vertex 34.019 -36.2 -31.18159 vertex 37.833 -36.2 -34.855 endloop endfacet facet normal 0 1 0 outer loop vertex 37.984 -33.2 3.853 vertex 37.364 -33.2 3.234 vertex 26.6 -33.2 20 endloop endfacet facet normal 0 -1 0 outer loop vertex 39.233 -36.2 -33.837 vertex 38.881 -36.2 -26.165 vertex 38.452 -36.2 -34.235 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.435 -36.2 -35.635 vertex 37.833 -36.2 -34.855 vertex 34.019 -36.2 -31.18159 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.435 -36.2 -37.367 vertex 37.435 -36.2 -47.955 vertex 37.833 -36.2 -38.148 endloop endfacet facet normal 0 -1 0 outer loop vertex 39.701 -36.2 -46.8 vertex 39.233 -36.2 -39.165 vertex 38.835 -36.2 -46.937 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.298 -36.2 -36.501 vertex 34.019 -36.2 -31.18159 vertex 37.435 -36.2 -37.367 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.298 -36.2 -36.501 vertex 37.435 -36.2 -35.635 vertex 34.019 -36.2 -31.18159 endloop endfacet facet normal 0 1 0 outer loop vertex 36.829 -33.2 1.587 vertex 27.1 -33.2 0 vertex 36.966 -33.2 2.453 endloop endfacet facet normal 0 -1 0 outer loop vertex 26.6 -36.2 -58 vertex 38.055 -36.2 -51.867 vertex 37.435 -36.2 -51.248 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.037 -36.2 -50.467 vertex 26.6 -36.2 -58 vertex 37.435 -36.2 -51.248 endloop endfacet facet normal 0 0.89101 0.45399 outer loop vertex 45.937 -48.9 13.078 vertex 54.937 -48.9 13.078 vertex 54.937 -48.231 11.765 endloop endfacet facet normal 0 -1 0 outer loop vertex 36.9 -36.2 -49.601 vertex 26.6 -36.2 -58 vertex 37.037 -36.2 -50.467 endloop endfacet facet normal 0 -1 0 outer loop vertex 34.019 -36.2 -31.18159 vertex 26.6 -36.2 -58 vertex 37.037 -36.2 -48.735 endloop endfacet facet normal 0 -1 0 outer loop vertex 34.019 -36.2 -31.18159 vertex 37.037 -36.2 -48.735 vertex 37.435 -36.2 -47.955 endloop endfacet facet normal 0 -1 0 outer loop vertex 38.055 -36.2 -47.335 vertex 37.833 -36.2 -38.148 vertex 37.435 -36.2 -47.955 endloop endfacet facet normal 0 -1 0 outer loop vertex 34.019 -36.2 -31.18159 vertex 37.435 -36.2 -47.955 vertex 37.435 -36.2 -37.367 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.037 -36.2 -48.735 vertex 26.6 -36.2 -58 vertex 36.9 -36.2 -49.601 endloop endfacet facet normal 0.70654 0 0.70768 outer loop vertex 37.435 -33.2 -51.248 vertex 37.435 -36.2 -51.248 vertex 38.055 -36.2 -51.867 endloop endfacet facet normal 0 0.70711 0.70711 outer loop vertex 54.937 -49.942 14.12 vertex 54.937 -48.9 13.078 vertex 45.937 -48.9 13.078 endloop endfacet facet normal 0.89098 0 0.45405 outer loop vertex 37.037 -33.2 -50.467 vertex 37.037 -36.2 -50.467 vertex 37.435 -36.2 -51.248 endloop endfacet facet normal 0.89098 0 0.45405 outer loop vertex 37.037 -33.2 -50.467 vertex 37.435 -36.2 -51.248 vertex 37.435 -33.2 -51.248 endloop endfacet facet normal 0.98772 0 0.15626 outer loop vertex 37.037 -36.2 -50.467 vertex 37.037 -33.2 -50.467 vertex 36.9 -33.2 -49.601 endloop endfacet facet normal 0.98772 0 0.15626 outer loop vertex 37.037 -36.2 -50.467 vertex 36.9 -33.2 -49.601 vertex 36.9 -36.2 -49.601 endloop endfacet facet normal 0 0.89101 -0.45399 outer loop vertex 45.937 -48.9 7.542 vertex 45.937 -48.231 8.855 vertex 54.937 -48.9 7.542 endloop endfacet facet normal 0 0.89101 -0.45399 outer loop vertex 54.937 -48.231 8.855 vertex 54.937 -48.9 7.542 vertex 45.937 -48.231 8.855 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.984 -36.2 3.853 vertex 38.765 -36.2 4.251 vertex 34.27425 -36.2 10.5 endloop endfacet facet normal 0 -1 0 outer loop vertex 38.765 -36.2 4.251 vertex 39.63 -36.2 4.388 vertex 40.00412 -36.2 10.5 endloop endfacet facet normal 0.98772 0 -0.15626 outer loop vertex 37.037 -33.2 -48.735 vertex 37.037 -36.2 -48.735 vertex 36.9 -36.2 -49.601 endloop endfacet facet normal 0.98772 0 -0.15626 outer loop vertex 37.037 -33.2 -48.735 vertex 36.9 -36.2 -49.601 vertex 36.9 -33.2 -49.601 endloop endfacet facet normal 0 0.98763 -0.1568 outer loop vertex 54.937 -48.231 8.855 vertex 45.937 -48.231 8.855 vertex 54.937 -48 10.31 endloop endfacet facet normal 0.89074 0 -0.45451 outer loop vertex 37.435 -33.2 -47.955 vertex 37.435 -36.2 -47.955 vertex 37.037 -36.2 -48.735 endloop endfacet facet normal 0.89074 0 -0.45451 outer loop vertex 37.435 -33.2 -47.955 vertex 37.037 -36.2 -48.735 vertex 37.037 -33.2 -48.735 endloop endfacet facet normal 0 -1 0 outer loop vertex 36.966 -36.2 0.721 vertex 31.06376 -36.2 -10.48639 vertex 37.364 -36.2 -0.06 endloop endfacet facet normal 0.70711 0 -0.70711 outer loop vertex 38.055 -33.2 -47.335 vertex 38.055 -36.2 -47.335 vertex 37.435 -36.2 -47.955 endloop endfacet facet normal 0.70711 0 -0.70711 outer loop vertex 38.055 -33.2 -47.335 vertex 37.435 -36.2 -47.955 vertex 37.435 -33.2 -47.955 endloop endfacet facet normal 0.89098 0 0.45405 outer loop vertex 37.435 -33.2 -37.367 vertex 37.435 -36.2 -37.367 vertex 37.833 -33.2 -38.148 endloop endfacet facet normal 0.98772 0 0.15626 outer loop vertex 37.435 -36.2 -37.367 vertex 37.435 -33.2 -37.367 vertex 37.298 -36.2 -36.501 endloop endfacet facet normal 0.98772 0 0.15626 outer loop vertex 37.298 -33.2 -36.501 vertex 37.298 -36.2 -36.501 vertex 37.435 -33.2 -37.367 endloop endfacet facet normal 0 0.15669 0.98765 outer loop vertex 54.821 -51.7 14.85944 vertex 54.937 -51.256 14.789 vertex 46.1 -51.7 14.85944 endloop endfacet facet normal 0 0.15669 0.98765 outer loop vertex 45.937 -51.256 14.789 vertex 46.1 -51.7 14.85944 vertex 54.937 -51.256 14.789 endloop endfacet facet normal 0.98772 0 -0.15626 outer loop vertex 37.435 -33.2 -35.635 vertex 37.435 -36.2 -35.635 vertex 37.298 -36.2 -36.501 endloop endfacet facet normal 0.98772 0 -0.15626 outer loop vertex 37.435 -33.2 -35.635 vertex 37.298 -36.2 -36.501 vertex 37.298 -33.2 -36.501 endloop endfacet facet normal 0 0.15669 -0.98765 outer loop vertex 54.821 -51.7 5.76056 vertex 46.1 -51.7 5.76056 vertex 54.937 -51.256 5.831 endloop endfacet facet normal 0 0.15669 -0.98765 outer loop vertex 45.937 -51.256 5.831 vertex 54.937 -51.256 5.831 vertex 46.1 -51.7 5.76056 endloop endfacet facet normal 0 0.45371 -0.89115 outer loop vertex 54.937 -49.942 6.5 vertex 54.937 -51.256 5.831 vertex 45.937 -51.256 5.831 endloop endfacet facet normal 0 1 0 outer loop vertex 37.364 -33.2 -0.06 vertex 27.1 -33.2 0 vertex 36.966 -33.2 0.721 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.2 -36.2 -10.501 vertex 37.337 -36.2 -9.635 vertex 31.06376 -36.2 -10.48639 endloop endfacet facet normal 0 -1 0 outer loop vertex 34.27425 -36.2 10.5 vertex 31.06376 -36.2 -10.48639 vertex 36.829 -36.2 1.587 endloop endfacet facet normal 0 1 0 outer loop vertex 38.452 -33.2 -34.235 vertex 37.833 -33.2 -34.855 vertex 38.1 -33.2 -25.767 endloop endfacet facet normal 0 -1 0 outer loop vertex 36.966 -36.2 2.453 vertex 34.27425 -36.2 10.5 vertex 36.829 -36.2 1.587 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.364 -36.2 3.234 vertex 34.27425 -36.2 10.5 vertex 36.966 -36.2 2.453 endloop endfacet facet normal 0 -1 0 outer loop vertex 34.27425 -36.2 10.5 vertex 37.364 -36.2 3.234 vertex 37.984 -36.2 3.853 endloop endfacet facet normal 0.89098 0 0.45405 outer loop vertex 36.966 -36.2 0.721 vertex 37.364 -36.2 -0.06 vertex 36.966 -33.2 0.721 endloop endfacet facet normal 0 1 0 outer loop vertex 37.083 -33.2 -22.635 vertex 27.1 -33.2 0 vertex 37.481 -33.2 -21.855 endloop endfacet facet normal 0.70654 0 -0.70768 outer loop vertex 37.364 -36.2 3.234 vertex 37.364 -33.2 3.234 vertex 37.984 -36.2 3.853 endloop endfacet facet normal 0.70654 0 -0.70768 outer loop vertex 37.984 -33.2 3.853 vertex 37.984 -36.2 3.853 vertex 37.364 -33.2 3.234 endloop endfacet facet normal 0.89098 0 0.45405 outer loop vertex 37.364 -33.2 -0.06 vertex 36.966 -33.2 0.721 vertex 37.364 -36.2 -0.06 endloop endfacet facet normal 0 -0.89121 -0.45359 outer loop vertex 34.539 -50.584 11.119 vertex 34.539 -50.868 11.677 vertex 25.539 -50.584 11.119 endloop endfacet facet normal 0.89098 0 -0.45405 outer loop vertex 37.364 -36.2 3.234 vertex 36.966 -36.2 2.453 vertex 36.966 -33.2 2.453 endloop endfacet facet normal 0.89098 0 -0.45405 outer loop vertex 37.364 -36.2 3.234 vertex 36.966 -33.2 2.453 vertex 37.364 -33.2 3.234 endloop endfacet facet normal 0 1 0 outer loop vertex 37.2 -33.2 -10.501 vertex 27.1 -33.2 0 vertex 37.337 -33.2 -9.635 endloop endfacet facet normal 0 -0.70711 -0.70711 outer loop vertex 25.539 -50.868 11.677 vertex 34.539 -50.868 11.677 vertex 25.539 -51.311 12.12 endloop endfacet facet normal 0.98772 0 0.15626 outer loop vertex 36.829 -33.2 1.587 vertex 36.829 -36.2 1.587 vertex 36.966 -33.2 0.721 endloop endfacet facet normal 0 -0.45295 -0.89154 outer loop vertex 25.539 -51.311 12.12 vertex 34.539 -51.311 12.12 vertex 30.72 -51.87 12.404 endloop endfacet facet normal 0.98772 0 -0.15626 outer loop vertex 36.966 -33.2 2.453 vertex 36.966 -36.2 2.453 vertex 36.829 -36.2 1.587 endloop endfacet facet normal 0 1 0 outer loop vertex 38.1 -33.2 -21.235 vertex 37.481 -33.2 -21.855 vertex 37.735 -33.2 -12.148 endloop endfacet facet normal 0 1 0 outer loop vertex 37.2 -33.2 -10.501 vertex 37.337 -33.2 -11.367 vertex 27.1 -33.2 0 endloop endfacet facet normal 0 1 0 outer loop vertex 37.481 -33.2 -25.148 vertex 38.1 -33.2 -25.767 vertex 37.833 -33.2 -34.855 endloop endfacet facet normal 0.98772 0 0.15626 outer loop vertex 36.966 -36.2 0.721 vertex 36.966 -33.2 0.721 vertex 36.829 -36.2 1.587 endloop endfacet facet normal 0 -0.45295 0.89154 outer loop vertex 25.539 -51.311 8.88 vertex 30.72 -51.87 8.596 vertex 34.539 -51.311 8.88 endloop endfacet facet normal 0 -0.45295 0.89154 outer loop vertex 34.539 -51.311 8.88 vertex 30.72 -51.87 8.596 vertex 34.539 -51.788 8.63766 endloop endfacet facet normal 0 1 0 outer loop vertex 36.946 -33.2 -23.501 vertex 27.1 -33.2 0 vertex 37.083 -33.2 -22.635 endloop endfacet facet normal 0 1 0 outer loop vertex 37.337 -33.2 -11.367 vertex 37.735 -33.2 -12.148 vertex 37.481 -33.2 -21.855 endloop endfacet facet normal 0 1 0 outer loop vertex 27.1 -33.2 0 vertex 36.946 -33.2 -23.501 vertex 37.083 -33.2 -24.367 endloop endfacet facet normal 0 -0.89121 0.45359 outer loop vertex 25.539 -50.584 9.881 vertex 34.539 -50.868 9.323 vertex 34.539 -50.584 9.881 endloop endfacet facet normal 0.98772 0 -0.15626 outer loop vertex 36.966 -33.2 2.453 vertex 36.829 -36.2 1.587 vertex 36.829 -33.2 1.587 endloop endfacet facet normal 0 -0.9877 0.15637 outer loop vertex 25.539 -50.584 9.881 vertex 34.539 -50.584 9.881 vertex 34.539 -50.486 10.5 endloop endfacet facet normal 0 -0.70711 -0.70711 outer loop vertex 34.539 -51.311 12.12 vertex 25.539 -51.311 12.12 vertex 34.539 -50.868 11.677 endloop endfacet facet normal 0 -0.07338 -0.9973 outer loop vertex 32.8 21.5208 2.02456 vertex 37.8 21.5208 2.02456 vertex 37.8 8 3.01941 endloop endfacet facet normal 0 -0.45295 -0.89154 outer loop vertex 34.539 -51.788 12.36234 vertex 30.72 -51.87 12.404 vertex 34.539 -51.311 12.12 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.337 -36.2 -11.367 vertex 31.06376 -36.2 -10.48639 vertex 37.735 -36.2 -12.148 endloop endfacet facet normal 0 1 0 outer loop vertex 37.364 -33.2 3.234 vertex 36.966 -33.2 2.453 vertex 26.6 -33.2 20 endloop endfacet facet normal 0 1 0 outer loop vertex 38.765 -33.2 4.251 vertex 26.6 -33.2 20 vertex 39.63 -33.2 4.388 endloop endfacet facet normal 0 -1 0 outer loop vertex 34.019 -36.2 -31.18159 vertex 38.452 -36.2 -34.235 vertex 38.881 -36.2 -26.165 endloop endfacet facet normal 0 1 0 outer loop vertex 25.4 -51.788 5.6 vertex 25.4 -51.788 8.63766 vertex 25.539 -51.788 5.71296 endloop endfacet facet normal 0 1 0 outer loop vertex 25.539 -51.788 8.63766 vertex 25.539 -51.788 5.71296 vertex 25.4 -51.788 8.63766 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.00412 -36.2 10.5 vertex 34.27425 -36.2 10.5 vertex 38.765 -36.2 4.251 endloop endfacet facet normal 0 1 0 outer loop vertex 25.4 -51.788 12.36234 vertex 25.539 -51.788 14.90704 vertex 25.539 -51.788 12.36234 endloop endfacet facet normal 0 1 0 outer loop vertex 25.4 -51.788 15 vertex 25.539 -51.788 14.90704 vertex 25.4 -51.788 12.36234 endloop endfacet facet normal 0 1 0 outer loop vertex 34.616 -51.788 5.6 vertex 34.539 -51.788 5.71296 vertex 34.616 -51.788 8.63766 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.98688 8.13752 -1.71749 vertex 53.941 8.06241 -1.43714 vertex 55.2 7.67736 0 endloop endfacet facet normal -0.01745 -0.99985 0 outer loop vertex 34.183 -41.399 10.6606 vertex 34.183 -41.399 10.5 vertex 45.13562 -41.59019 10.66059 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.764 7.97239 -1.10114 vertex 55.2 7.67736 0 vertex 53.941 8.06241 -1.43714 endloop endfacet facet normal 0 1 0 outer loop vertex 34.539 -51.788 12.36234 vertex 34.539 -51.788 14.90704 vertex 34.616 -51.788 12.36234 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.487 7.90082 -0.83403 vertex 55.2 7.67736 0 vertex 53.764 7.97239 -1.10114 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.138 7.85499 -0.66298 vertex 55.2 7.67736 0 vertex 53.487 7.90082 -0.83403 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 46.1 7.67736 0 vertex 55.2 7.67736 0 vertex 52.752 7.83917 -0.60393 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 46.1 7.67736 0 vertex 52.752 7.83917 -0.60393 vertex 52.366 7.85499 -0.66298 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 37.8 8 3.9056 vertex 37.8 21.5208 2.02456 vertex 40.956 18.83489 2.39823 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 40.956 18.83489 2.39823 vertex 37.8 21.5208 2.02456 vertex 40.89557 19.21993 2.34466 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 40.882 19.30637 2.33263 vertex 37.8 21.5208 2.02456 vertex 40.94322 19.69723 2.27826 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 40.94322 19.69723 2.27826 vertex 37.8 21.5208 2.02456 vertex 40.956 19.77882 2.26691 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.487 8.42381 -2.78603 vertex 53.486 11.43882 -14.03931 vertex 53.138 8.46988 -2.95801 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.764 8.35244 -2.51968 vertex 53.6382 11.47814 -14.18608 vertex 53.55569 8.40608 -2.71986 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.55569 8.40608 -2.71986 vertex 53.486 11.43882 -14.03931 vertex 53.487 8.42381 -2.78603 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.80787 8.33011 -2.43633 vertex 53.763 11.51035 -14.30631 vertex 53.764 8.35244 -2.51968 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 37.8 8 3.9056 vertex 41.59237 18.02471 2.51094 vertex 41.925 17.85333 2.53478 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 37.8 8 3.9056 vertex 41.925 17.85333 2.53478 vertex 42.02497 17.83743 2.537 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.941 8.26222 -2.18292 vertex 53.763 11.51035 -14.30631 vertex 53.80787 8.33011 -2.43633 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 41.23776 18.34046 2.46701 vertex 41.504 18.07045 2.50458 vertex 37.8 8 3.9056 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 41.504 18.07045 2.50458 vertex 41.59237 18.02471 2.51094 vertex 37.8 8 3.9056 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 37.8 8 3.9056 vertex 40.956 18.83489 2.39823 vertex 41.17 18.40899 2.45748 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 41.17 18.40899 2.45748 vertex 41.23776 18.34046 2.46701 vertex 37.8 8 3.9056 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.138 7.85499 -0.66298 vertex 52.752 7.83917 -0.60393 vertex 55.2 7.67736 0 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.95612 8.23746 -2.0905 vertex 54.002 8.1623 -1.80997 vertex 55.2 7.67736 0 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 54.002 8.1623 -1.80997 vertex 53.98688 8.13752 -1.71749 vertex 55.2 7.67736 0 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.941 8.26222 -2.18292 vertex 53.95612 8.23746 -2.0905 vertex 55.2 7.67736 0 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 43.614 20.20472 2.20765 vertex 46.9 21.60559 2.01276 vertex 43.828 19.77882 2.26691 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 43.88871 19.39119 2.32083 vertex 43.828 19.77882 2.26691 vertex 46.9 21.60559 2.01276 endloop endfacet facet normal 0 0.9877 0.15637 outer loop vertex 45.11967 -42.493 14.681 vertex 34.06431 -42.493 14.681 vertex 45.11821 -42.57675 15.21 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 43.902 19.30637 2.33263 vertex 46.9 21.60559 2.01276 vertex 43.84205 18.9244 2.38577 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 43.84205 18.9244 2.38577 vertex 46.9 21.60559 2.01276 vertex 43.828 18.83489 2.39823 endloop endfacet facet normal 0 0.70711 0.70711 outer loop vertex 45.12437 -42.209 14.123 vertex 45.12532 -42.15262 14.06662 vertex 37.8 -41.766 13.68 endloop endfacet facet normal 0 -1 0 outer loop vertex 34.019 -36.2 -31.18159 vertex 37.481 -36.2 -25.148 vertex 37.083 -36.2 -24.367 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 43.614 18.40899 2.45748 vertex 46.9 8 3.9056 vertex 43.34925 18.14048 2.49484 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 43.614 18.40899 2.45748 vertex 43.828 18.83489 2.39823 vertex 46.9 8 3.9056 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 43.28 18.07045 2.50458 vertex 46.9 8 3.9056 vertex 42.94855 17.89968 2.52834 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 43.34925 18.14048 2.49484 vertex 46.9 8 3.9056 vertex 43.28 18.07045 2.50458 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 42.859 17.85333 2.53478 vertex 42.94855 17.89968 2.52834 vertex 46.9 8 3.9056 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.083 -36.2 -22.635 vertex 31.06376 -36.2 -10.48639 vertex 36.946 -36.2 -23.501 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 42.392 17.77907 2.54512 vertex 37.8 8 3.9056 vertex 42.02497 17.83743 2.537 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.481 -36.2 -21.855 vertex 38.1 -36.2 -21.235 vertex 31.06376 -36.2 -10.48639 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 42.859 17.85333 2.53478 vertex 46.9 8 3.9056 vertex 42.49244 17.79505 2.54289 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 37.8 8 3.9056 vertex 42.392 17.77907 2.54512 vertex 46.9 8 3.9056 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 42.49244 17.79505 2.54289 vertex 46.9 8 3.9056 vertex 42.392 17.77907 2.54512 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 41.504 20.54247 2.16067 vertex 41.17 20.20472 2.20765 vertex 37.8 22.603 1.874 endloop endfacet facet normal 0 0.89121 -0.45359 outer loop vertex 45.12379 -42.23973 16.41663 vertex 45.11963 -42.493 15.919 vertex 34.16879 -42.209 16.477 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 41.925 20.75938 2.13049 vertex 41.504 20.54247 2.16067 vertex 37.8 22.603 1.874 endloop endfacet facet normal 0.00793 0.45387 0.89103 outer loop vertex 34.22632 -38.93073 19.689 vertex 34.24915 -37.62968 19.02608 vertex 34.127 -38.929 19.689 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.083 -36.2 -24.367 vertex 36.946 -36.2 -23.501 vertex 34.019 -36.2 -31.18159 endloop endfacet facet normal 0 -1 0 outer loop vertex 34.019 -36.2 -31.18159 vertex 36.946 -36.2 -23.501 vertex 31.06376 -36.2 -10.48639 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.083 -36.2 -22.635 vertex 37.481 -36.2 -21.855 vertex 31.06376 -36.2 -10.48639 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.2 -36.2 -10.501 vertex 31.06376 -36.2 -10.48639 vertex 37.337 -36.2 -11.367 endloop endfacet facet normal 0 0.70711 0.70711 outer loop vertex 45.13237 -41.766 13.68 vertex 37.8 -41.766 13.68 vertex 45.12532 -42.15262 14.06662 endloop endfacet facet normal 0.89098 0 0.45405 outer loop vertex 37.083 -36.2 -24.367 vertex 37.481 -36.2 -25.148 vertex 37.481 -33.2 -25.148 endloop endfacet facet normal 0.89074 0 -0.45451 outer loop vertex 37.481 -33.2 -21.855 vertex 37.481 -36.2 -21.855 vertex 37.083 -36.2 -22.635 endloop endfacet facet normal 0.01235 0.70694 0.70717 outer loop vertex 34.149 -37.616 19.02 vertex 34.24936 -37.61775 19.02 vertex 34.168 -36.574 17.978 endloop endfacet facet normal 0 -1 0 outer loop vertex 34.27425 -36.2 17.24055 vertex 34.27425 -36.2 19.9 vertex 34.17415 -36.2 17.24398 endloop endfacet facet normal 0.89098 0 0.45405 outer loop vertex 37.337 -33.2 -11.367 vertex 37.337 -36.2 -11.367 vertex 37.735 -36.2 -12.148 endloop endfacet facet normal 0.89098 0 0.45405 outer loop vertex 37.337 -33.2 -11.367 vertex 37.735 -36.2 -12.148 vertex 37.735 -33.2 -12.148 endloop endfacet facet normal 0.01556 0.89085 0.45404 outer loop vertex 34.27425 -36.2 17.24055 vertex 34.17415 -36.2 17.24398 vertex 34.26765 -36.57574 17.978 endloop endfacet facet normal 0.98772 0 0.15626 outer loop vertex 37.337 -36.2 -11.367 vertex 37.337 -33.2 -11.367 vertex 37.2 -36.2 -10.501 endloop endfacet facet normal 0 0.45359 -0.89121 outer loop vertex 43.008 -41.208 17.204 vertex 45.13549 -41.59019 17.00948 vertex 45.13241 -41.766 16.92 endloop endfacet facet normal 0.89098 0 0.45405 outer loop vertex 37.083 -33.2 -24.367 vertex 37.083 -36.2 -24.367 vertex 37.481 -33.2 -25.148 endloop endfacet facet normal 0 0.70711 -0.70711 outer loop vertex 45.12436 -42.209 16.477 vertex 34.16879 -42.209 16.477 vertex 45.13186 -41.79772 16.88828 endloop endfacet facet normal 0 0.70711 -0.70711 outer loop vertex 45.13186 -41.79772 16.88828 vertex 34.16879 -42.209 16.477 vertex 45.13241 -41.766 16.92 endloop endfacet facet normal 0 0.89121 -0.45359 outer loop vertex 45.12436 -42.209 16.477 vertex 45.12379 -42.23973 16.41663 vertex 34.16879 -42.209 16.477 endloop endfacet facet normal 0.98772 0 0.15626 outer loop vertex 37.083 -36.2 -24.367 vertex 37.083 -33.2 -24.367 vertex 36.946 -33.2 -23.501 endloop endfacet facet normal 0.98772 0 0.15626 outer loop vertex 37.083 -36.2 -24.367 vertex 36.946 -33.2 -23.501 vertex 36.946 -36.2 -23.501 endloop endfacet facet normal 0.98772 0 -0.15626 outer loop vertex 37.083 -33.2 -22.635 vertex 37.083 -36.2 -22.635 vertex 36.946 -36.2 -23.501 endloop endfacet facet normal 0.98772 0 -0.15626 outer loop vertex 37.083 -33.2 -22.635 vertex 36.946 -36.2 -23.501 vertex 36.946 -33.2 -23.501 endloop endfacet facet normal 0.89074 0 -0.45451 outer loop vertex 37.083 -36.2 -22.635 vertex 37.083 -33.2 -22.635 vertex 37.481 -33.2 -21.855 endloop endfacet facet normal 0.98772 0 0.15626 outer loop vertex 37.337 -33.2 -11.367 vertex 37.2 -33.2 -10.501 vertex 37.2 -36.2 -10.501 endloop endfacet facet normal -0.99984 0.01785 0 outer loop vertex 34.101 -40.385 19.92 vertex 34.127 -38.929 19.689 vertex 34.10841 -39.97 17.204 endloop endfacet facet normal 0.98772 0 -0.15626 outer loop vertex 37.2 -33.2 -10.501 vertex 37.337 -33.2 -9.635 vertex 37.2 -36.2 -10.501 endloop endfacet facet normal -0.99984 0.01785 0 outer loop vertex 34.11198 -39.76991 17.10216 vertex 34.10841 -39.97 17.204 vertex 34.127 -38.929 19.689 endloop endfacet facet normal -0.00793 -0.45386 0.89104 outer loop vertex 34.076 -41.841 19.689 vertex 45.105 -43.347 19.02 vertex 45.128 -42.034 19.689 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 35.0753 9.443 -18.955 vertex 33.25 8.93375 -17.05474 vertex 30.2 9.443 -18.955 endloop endfacet facet normal -0.00274 -0.15665 0.98765 outer loop vertex 34.183 -41.399 19.7594 vertex 34.19855 -40.5128 19.9 vertex 34.101 -40.385 19.92 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 32.863 8.9179 -16.99558 vertex 30.2 9.443 -18.955 vertex 33.20235 8.93177 -17.04736 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 32.82001 8.91225 -16.97451 vertex 30.2 9.443 -18.955 vertex 32.863 8.9179 -16.99558 endloop endfacet facet normal -0.00274 -0.15665 0.98765 outer loop vertex 45.13562 -41.59019 19.75941 vertex 34.183 -41.399 19.7594 vertex 45.128 -42.034 19.689 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.58934 8.91988 -17.00297 vertex 33.25 8.93375 -17.05474 vertex 35.0753 9.443 -18.955 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.20235 8.93177 -17.04736 vertex 30.2 9.443 -18.955 vertex 33.25 8.93375 -17.05474 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 52.363 12.00867 -16.16623 vertex 52.53732 12.0159 -16.19325 vertex 46.9 12.534 -18.127 endloop endfacet facet normal -0.98754 0 0.15737 outer loop vertex 42.365 -33.2 -50.467 vertex 42.365 -36.2 -50.467 vertex 42.503 -36.2 -49.601 endloop endfacet facet normal -0.98754 0 0.15737 outer loop vertex 42.365 -33.2 -50.467 vertex 42.503 -36.2 -49.601 vertex 42.503 -33.2 -49.601 endloop endfacet facet normal 0 1 0 outer loop vertex 34.616 -51.788 15 vertex 34.616 -51.788 12.36234 vertex 34.539 -51.788 14.90704 endloop endfacet facet normal 0.00274 0.15665 0.98765 outer loop vertex 34.22632 -38.93073 19.689 vertex 34.127 -38.929 19.689 vertex 34.22609 -38.94382 19.69108 endloop endfacet facet normal -0.89098 0 0.45405 outer loop vertex 41.967 -33.2 -51.248 vertex 41.967 -36.2 -51.248 vertex 42.365 -36.2 -50.467 endloop endfacet facet normal -0.89098 0 0.45405 outer loop vertex 41.967 -33.2 -51.248 vertex 42.365 -36.2 -50.467 vertex 42.365 -33.2 -50.467 endloop endfacet facet normal 0 1 0 outer loop vertex 25.4 -51.788 15 vertex 34.616 -51.788 15 vertex 25.539 -51.788 14.90704 endloop endfacet facet normal 0 1 0 outer loop vertex 34.539 -51.788 14.90704 vertex 25.539 -51.788 14.90704 vertex 34.616 -51.788 15 endloop endfacet facet normal -0.70711 0 0.70711 outer loop vertex 41.348 -33.2 -51.867 vertex 41.348 -36.2 -51.867 vertex 41.967 -36.2 -51.248 endloop endfacet facet normal -0.70711 0 0.70711 outer loop vertex 41.348 -33.2 -51.867 vertex 41.967 -36.2 -51.248 vertex 41.967 -33.2 -51.248 endloop endfacet facet normal -0.45405 0 0.89098 outer loop vertex 40.567 -33.2 -52.265 vertex 40.567 -36.2 -52.265 vertex 41.348 -36.2 -51.867 endloop endfacet facet normal -0.45405 0 0.89098 outer loop vertex 40.567 -33.2 -52.265 vertex 41.348 -36.2 -51.867 vertex 41.348 -33.2 -51.867 endloop endfacet facet normal 0.00274 0.15665 0.98765 outer loop vertex 34.101 -40.385 19.92 vertex 34.20298 -40.26068 19.9 vertex 34.127 -38.929 19.689 endloop endfacet facet normal 0.00274 0.15665 0.98765 outer loop vertex 34.127 -38.929 19.689 vertex 34.20298 -40.26068 19.9 vertex 34.22609 -38.94382 19.69108 endloop endfacet facet normal 0 1 0 outer loop vertex 34.539 -51.788 8.63766 vertex 34.616 -51.788 8.63766 vertex 34.539 -51.788 5.71296 endloop endfacet facet normal -0.15737 0 0.98754 outer loop vertex 39.701 -33.2 -52.403 vertex 39.701 -36.2 -52.403 vertex 40.567 -36.2 -52.265 endloop endfacet facet normal -0.15737 0 0.98754 outer loop vertex 39.701 -33.2 -52.403 vertex 40.567 -36.2 -52.265 vertex 40.567 -33.2 -52.265 endloop endfacet facet normal 0.45451 0 -0.89074 outer loop vertex 38.835 -33.2 -46.937 vertex 38.835 -36.2 -46.937 vertex 38.055 -36.2 -47.335 endloop endfacet facet normal 0.45451 0 -0.89074 outer loop vertex 38.835 -33.2 -46.937 vertex 38.055 -36.2 -47.335 vertex 38.055 -33.2 -47.335 endloop endfacet facet normal 0.00793 0.45387 0.89103 outer loop vertex 34.24915 -37.62968 19.02608 vertex 34.149 -37.616 19.02 vertex 34.127 -38.929 19.689 endloop endfacet facet normal 0.15626 0 -0.98772 outer loop vertex 38.835 -36.2 -46.937 vertex 38.835 -33.2 -46.937 vertex 39.701 -33.2 -46.8 endloop endfacet facet normal 0.15626 0 -0.98772 outer loop vertex 38.835 -36.2 -46.937 vertex 39.701 -33.2 -46.8 vertex 39.701 -36.2 -46.8 endloop endfacet facet normal 0.00793 0.45386 0.89104 outer loop vertex 34.149 -37.616 19.02 vertex 34.24915 -37.62968 19.02608 vertex 34.24936 -37.61775 19.02 endloop endfacet facet normal -0.15626 0 -0.98772 outer loop vertex 40.567 -33.2 -46.937 vertex 40.567 -36.2 -46.937 vertex 39.701 -36.2 -46.8 endloop endfacet facet normal -0.15626 0 -0.98772 outer loop vertex 40.567 -33.2 -46.937 vertex 39.701 -36.2 -46.8 vertex 39.701 -33.2 -46.8 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.137 12.00867 -16.16623 vertex 55.2 12.534 -18.127 vertex 52.92433 12.01736 -16.19868 endloop endfacet facet normal -0.45405 0 -0.89098 outer loop vertex 41.348 -33.2 -47.335 vertex 41.348 -36.2 -47.335 vertex 40.567 -36.2 -46.937 endloop endfacet facet normal -0.45405 0 -0.89098 outer loop vertex 41.348 -33.2 -47.335 vertex 40.567 -36.2 -46.937 vertex 40.567 -33.2 -46.937 endloop endfacet facet normal -0.70768 0 -0.70654 outer loop vertex 41.967 -33.2 -47.955 vertex 41.967 -36.2 -47.955 vertex 41.348 -36.2 -47.335 endloop endfacet facet normal -0.70768 0 -0.70654 outer loop vertex 41.967 -33.2 -47.955 vertex 41.348 -36.2 -47.335 vertex 41.348 -33.2 -47.335 endloop endfacet facet normal -0.89074 0 -0.45451 outer loop vertex 42.365 -33.2 -48.735 vertex 42.365 -36.2 -48.735 vertex 41.967 -36.2 -47.955 endloop endfacet facet normal -0.89074 0 -0.45451 outer loop vertex 42.365 -33.2 -48.735 vertex 41.967 -36.2 -47.955 vertex 41.967 -33.2 -47.955 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.486 11.9627 -15.99467 vertex 55.2 12.534 -18.127 vertex 53.2942 11.98802 -16.08918 endloop endfacet facet normal -0.98754 0 -0.15737 outer loop vertex 42.365 -36.2 -48.735 vertex 42.365 -33.2 -48.735 vertex 42.503 -36.2 -49.601 endloop endfacet facet normal -0.98754 0 -0.15737 outer loop vertex 42.503 -33.2 -49.601 vertex 42.503 -36.2 -49.601 vertex 42.365 -33.2 -48.735 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.2942 11.98802 -16.08918 vertex 55.2 12.534 -18.127 vertex 53.137 12.00867 -16.16623 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.61079 11.93038 -15.87403 vertex 55.2 12.534 -18.127 vertex 53.486 11.9627 -15.99467 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.763 11.89105 -15.72725 vertex 55.2 12.534 -18.127 vertex 53.61079 11.93038 -15.87403 endloop endfacet facet normal 0.15626 0 0.98772 outer loop vertex 39.233 -33.2 -39.165 vertex 39.233 -36.2 -39.165 vertex 40.099 -36.2 -39.302 endloop endfacet facet normal 0.15626 0 0.98772 outer loop vertex 39.233 -33.2 -39.165 vertex 40.099 -36.2 -39.302 vertex 40.099 -33.2 -39.302 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.941 11.80078 -15.39032 vertex 55.2 12.534 -18.127 vertex 53.763 11.89105 -15.72725 endloop endfacet facet normal 0.45405 0 0.89098 outer loop vertex 38.452 -33.2 -38.767 vertex 38.452 -36.2 -38.767 vertex 39.233 -36.2 -39.165 endloop endfacet facet normal 0.45405 0 0.89098 outer loop vertex 38.452 -33.2 -38.767 vertex 39.233 -36.2 -39.165 vertex 39.233 -33.2 -39.165 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 54.002 11.70084 -15.0173 vertex 55.2 12.534 -18.127 vertex 53.941 11.80078 -15.39032 endloop endfacet facet normal 0.70711 0 0.70711 outer loop vertex 37.833 -33.2 -38.148 vertex 37.833 -36.2 -38.148 vertex 38.452 -36.2 -38.767 endloop endfacet facet normal 0.70711 0 0.70711 outer loop vertex 37.833 -33.2 -38.148 vertex 38.452 -36.2 -38.767 vertex 38.452 -33.2 -38.767 endloop endfacet facet normal 0.89098 0 0.45405 outer loop vertex 37.833 -33.2 -38.148 vertex 37.435 -36.2 -37.367 vertex 37.833 -36.2 -38.148 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.941 11.60065 -14.64335 vertex 53.86082 11.55996 -14.49146 vertex 55.2 7.67736 0 endloop endfacet facet normal -0.70654 0 0.70768 outer loop vertex 41.745 -33.2 -38.767 vertex 41.745 -36.2 -38.767 vertex 42.365 -36.2 -38.148 endloop endfacet facet normal -0.70654 0 0.70768 outer loop vertex 41.745 -33.2 -38.767 vertex 42.365 -36.2 -38.148 vertex 42.365 -33.2 -38.148 endloop endfacet facet normal -0.45451 0 0.89074 outer loop vertex 40.965 -33.2 -39.165 vertex 40.965 -36.2 -39.165 vertex 41.745 -36.2 -38.767 endloop endfacet facet normal -0.45451 0 0.89074 outer loop vertex 40.965 -33.2 -39.165 vertex 41.745 -36.2 -38.767 vertex 41.745 -33.2 -38.767 endloop endfacet facet normal -0.15626 0 0.98772 outer loop vertex 40.099 -33.2 -39.302 vertex 40.099 -36.2 -39.302 vertex 40.965 -36.2 -39.165 endloop endfacet facet normal -0.15626 0 0.98772 outer loop vertex 40.099 -33.2 -39.302 vertex 40.965 -36.2 -39.165 vertex 40.965 -33.2 -39.165 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 51.741 8.35244 -2.51968 vertex 51.80941 8.37017 -2.58583 vertex 52.014 11.43882 -14.03931 endloop endfacet facet normal 0.89074 0 -0.45451 outer loop vertex 37.833 -33.2 -34.855 vertex 37.833 -36.2 -34.855 vertex 37.435 -36.2 -35.635 endloop endfacet facet normal 0.89074 0 -0.45451 outer loop vertex 37.833 -33.2 -34.855 vertex 37.435 -36.2 -35.635 vertex 37.435 -33.2 -35.635 endloop endfacet facet normal 0.70768 0 -0.70654 outer loop vertex 38.452 -33.2 -34.235 vertex 38.452 -36.2 -34.235 vertex 37.833 -36.2 -34.855 endloop endfacet facet normal 0.70768 0 -0.70654 outer loop vertex 38.452 -33.2 -34.235 vertex 37.833 -36.2 -34.855 vertex 37.833 -33.2 -34.855 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 46.1 7.67736 0 vertex 51.741 8.35244 -2.51968 vertex 52.014 11.43882 -14.03931 endloop endfacet facet normal 0.45405 0 -0.89098 outer loop vertex 39.233 -33.2 -33.837 vertex 39.233 -36.2 -33.837 vertex 38.452 -36.2 -34.235 endloop endfacet facet normal 0.45405 0 -0.89098 outer loop vertex 39.233 -33.2 -33.837 vertex 38.452 -36.2 -34.235 vertex 38.452 -33.2 -34.235 endloop endfacet facet normal 0.15626 0 -0.98772 outer loop vertex 39.233 -36.2 -33.837 vertex 39.233 -33.2 -33.837 vertex 40.099 -33.2 -33.7 endloop endfacet facet normal 0.15626 0 -0.98772 outer loop vertex 39.233 -36.2 -33.837 vertex 40.099 -33.2 -33.7 vertex 40.099 -36.2 -33.7 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.86082 11.55996 -14.49146 vertex 53.763 11.51035 -14.30631 vertex 55.2 7.67736 0 endloop endfacet facet normal -0.15626 0 -0.98772 outer loop vertex 40.965 -33.2 -33.837 vertex 40.965 -36.2 -33.837 vertex 40.099 -36.2 -33.7 endloop endfacet facet normal -0.15626 0 -0.98772 outer loop vertex 40.965 -33.2 -33.837 vertex 40.099 -36.2 -33.7 vertex 40.099 -33.2 -33.7 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.486 11.43882 -14.03931 vertex 53.55569 8.40608 -2.71986 vertex 53.6382 11.47814 -14.18608 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.637 8.9179 -16.99558 vertex 33.58934 8.91988 -17.00297 vertex 35.0753 9.443 -18.955 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.637 8.9179 -16.99558 vertex 35.0753 9.443 -18.955 vertex 33.94306 8.87754 -16.84498 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.6382 11.47814 -14.18608 vertex 53.764 8.35244 -2.51968 vertex 53.763 11.51035 -14.30631 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 51.80941 8.37017 -2.58583 vertex 52.017 8.42381 -2.78603 vertex 52.014 11.43882 -14.03931 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 52.017 8.42381 -2.78603 vertex 52.366 8.46988 -2.95801 vertex 52.363 11.39274 -13.86733 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 52.363 11.39274 -13.86733 vertex 52.014 11.43882 -14.03931 vertex 52.017 8.42381 -2.78603 endloop endfacet facet normal -0.99985 0.01727 0.00042 outer loop vertex 34.13103 -38.66043 15.7701 vertex 34.13068 -38.684 15.919 vertex 34.17386 -36.2 16.56919 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.986 8.8719 -16.82394 vertex 35.0753 9.443 -18.955 vertex 34.2289 8.80913 -16.5897 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 55.2 12.534 -18.127 vertex 54.002 11.70084 -15.0173 vertex 55.2 7.67736 0 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.941 11.60065 -14.64335 vertex 55.2 7.67736 0 vertex 54.002 11.70084 -15.0173 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 55.2 7.67736 0 vertex 53.763 11.51035 -14.30631 vertex 53.941 8.26222 -2.18292 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 34.503 8.60981 -15.84596 vertex 34.49537 8.62211 -15.89185 vertex 51.559 8.70977 -16.21894 endloop endfacet facet normal -0.99985 0.0174 0.00001 outer loop vertex 34.13206 -38.60025 15.21 vertex 34.13232 -38.586 15.3 vertex 34.17384 -36.2 15.21 endloop endfacet facet normal -0.99985 0.0174 0.00001 outer loop vertex 34.17386 -36.2 16.56919 vertex 34.17384 -36.2 15.21 vertex 34.13232 -38.586 15.3 endloop endfacet facet normal -0.99985 0.0174 0.00001 outer loop vertex 34.17386 -36.2 16.56919 vertex 34.13232 -38.586 15.3 vertex 34.13103 -38.66043 15.7701 endloop endfacet facet normal 0.45444 -0.23067 0.86039 outer loop vertex 52.366 8.46988 -2.95801 vertex 52.017 5.33204 -3.61494 vertex 52.366 5.37813 -3.78692 endloop endfacet facet normal 0 -1 0 outer loop vertex 34.17384 -36.2 15.21 vertex 34.17386 -36.2 16.56919 vertex 26.6 -36.2 20 endloop endfacet facet normal 0.15642 -0.25577 0.954 outer loop vertex 52.752 5.39395 -3.84597 vertex 52.752 8.4857 -3.01706 vertex 52.366 5.37813 -3.78692 endloop endfacet facet normal 0.15642 -0.25577 0.954 outer loop vertex 52.366 8.46988 -2.95801 vertex 52.366 5.37813 -3.78692 vertex 52.752 8.4857 -3.01706 endloop endfacet facet normal -0.15642 -0.25577 0.954 outer loop vertex 52.752 5.39395 -3.84597 vertex 53.138 5.37813 -3.78692 vertex 52.752 8.4857 -3.01706 endloop endfacet facet normal -0.15642 -0.25577 0.954 outer loop vertex 53.138 8.46988 -2.95801 vertex 52.752 8.4857 -3.01706 vertex 53.138 5.37813 -3.78692 endloop endfacet facet normal -0.99985 0.0174 -0.00001 outer loop vertex 34.13206 -38.60025 15.21 vertex 34.17384 -36.2 15.21 vertex 34.13062 -38.684 14.681 endloop endfacet facet normal -0.45444 -0.23067 0.86039 outer loop vertex 53.138 5.37813 -3.78692 vertex 53.487 5.33204 -3.61494 vertex 53.138 8.46988 -2.95801 endloop endfacet facet normal -0.99985 0.0174 -0.00001 outer loop vertex 34.17386 -36.2 13.85081 vertex 34.13062 -38.684 14.681 vertex 34.17384 -36.2 15.21 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 34.263 8.41947 -15.13569 vertex 34.503 7.394 -11.30915 vertex 34.02007 8.35653 -14.90084 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 34.28491 8.43059 -15.17717 vertex 34.441 8.50982 -15.47284 vertex 51.498 8.60981 -15.84593 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 34.441 8.50982 -15.47284 vertex 34.44863 8.52215 -15.51884 vertex 51.498 8.60981 -15.84593 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 34.02007 8.35653 -14.90084 vertex 34.503 7.394 -11.30915 vertex 33.986 8.34773 -14.86798 endloop endfacet facet normal 0 1 0 outer loop vertex 25.539 -51.788 5.71296 vertex 34.539 -51.788 5.71296 vertex 34.616 -51.788 5.6 endloop endfacet facet normal 0 1 0 outer loop vertex 25.539 -51.788 5.71296 vertex 34.616 -51.788 5.6 vertex 25.4 -51.788 5.6 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.637 8.30164 -14.69601 vertex 34.503 7.394 -11.30915 vertex 33.25 8.28582 -14.63696 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.637 8.30164 -14.69601 vertex 33.986 8.34773 -14.86798 vertex 34.503 7.394 -11.30915 endloop endfacet facet normal -0.99985 0.01727 0.00042 outer loop vertex 34.12746 -38.88013 16.30301 vertex 34.17386 -36.2 16.56919 vertex 34.13068 -38.684 15.919 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 34.49537 8.62211 -15.89185 vertex 34.441 8.71 -16.21979 vertex 51.559 8.70977 -16.21894 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 51.559 8.70977 -16.21894 vertex 51.498 8.60981 -15.84593 vertex 34.503 8.60981 -15.84596 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 35.0753 9.443 -18.955 vertex 51.559 8.70977 -16.21894 vertex 34.263 8.80029 -16.55671 endloop endfacet facet normal 0 -0.9877 -0.15637 outer loop vertex 45.23247 -38.684 15.919 vertex 34.13103 -38.66043 15.7701 vertex 45.23417 -38.586 15.3 endloop endfacet facet normal -0.45451 0 -0.89074 outer loop vertex 41.745 -33.2 -34.235 vertex 41.745 -36.2 -34.235 vertex 40.965 -36.2 -33.837 endloop endfacet facet normal -0.45451 0 -0.89074 outer loop vertex 41.745 -33.2 -34.235 vertex 40.965 -36.2 -33.837 vertex 40.965 -33.2 -33.837 endloop endfacet facet normal -0.70711 0 -0.70711 outer loop vertex 42.365 -33.2 -34.855 vertex 42.365 -36.2 -34.855 vertex 41.745 -36.2 -34.235 endloop endfacet facet normal -0.70711 0 -0.70711 outer loop vertex 42.365 -33.2 -34.855 vertex 41.745 -36.2 -34.235 vertex 41.745 -33.2 -34.235 endloop endfacet facet normal 0 -0.15818 0.98741 outer loop vertex 30.72 -51.87 8.596 vertex 25.4 -51.87 8.596 vertex 25.4 -52.488 8.497 endloop endfacet facet normal -0.89074 0 -0.45451 outer loop vertex 42.763 -36.2 -35.635 vertex 42.365 -36.2 -34.855 vertex 42.365 -33.2 -34.855 endloop endfacet facet normal 0 -0.45295 0.89154 outer loop vertex 30.72 -51.87 8.596 vertex 25.539 -51.788 8.63766 vertex 25.4 -51.87 8.596 endloop endfacet facet normal 0 -0.45295 0.89154 outer loop vertex 25.4 -51.788 8.63766 vertex 25.4 -51.87 8.596 vertex 25.539 -51.788 8.63766 endloop endfacet facet normal -0.98772 0 0.15626 outer loop vertex 42.763 -36.2 -37.367 vertex 42.9 -33.2 -36.501 vertex 42.763 -33.2 -37.367 endloop endfacet facet normal 0 -0.45295 -0.89154 outer loop vertex 25.4 -51.788 12.36234 vertex 25.539 -51.788 12.36234 vertex 25.4 -51.87 12.404 endloop endfacet facet normal -0.89098 0 0.45405 outer loop vertex 42.763 -33.2 -37.367 vertex 42.365 -33.2 -38.148 vertex 42.763 -36.2 -37.367 endloop endfacet facet normal -0.89098 0 0.45405 outer loop vertex 42.365 -36.2 -38.148 vertex 42.763 -36.2 -37.367 vertex 42.365 -33.2 -38.148 endloop endfacet facet normal -0.89074 0 -0.45451 outer loop vertex 42.763 -33.2 -35.635 vertex 42.763 -36.2 -35.635 vertex 42.365 -33.2 -34.855 endloop endfacet facet normal -0.98772 0 -0.15626 outer loop vertex 42.9 -33.2 -36.501 vertex 42.9 -36.2 -36.501 vertex 42.763 -36.2 -35.635 endloop endfacet facet normal -0.98772 0 -0.15626 outer loop vertex 42.9 -33.2 -36.501 vertex 42.763 -36.2 -35.635 vertex 42.763 -33.2 -35.635 endloop endfacet facet normal 0 -0.9877 0.15637 outer loop vertex 34.13062 -38.684 14.681 vertex 45.23247 -38.684 14.681 vertex 34.13206 -38.60025 15.21 endloop endfacet facet normal -0.98772 0 0.15626 outer loop vertex 42.9 -33.2 -36.501 vertex 42.763 -36.2 -37.367 vertex 42.9 -36.2 -36.501 endloop endfacet facet normal 0 0.9877 0.15637 outer loop vertex 34.616 -54.491 10.5 vertex 34.616 -54.393 9.881 vertex 25.4 -54.491 10.5 endloop endfacet facet normal 0 -0.9877 -0.15637 outer loop vertex 34.13232 -38.586 15.3 vertex 45.23417 -38.586 15.3 vertex 34.13103 -38.66043 15.7701 endloop endfacet facet normal 0 0.89121 0.45359 outer loop vertex 25.4 -54.393 9.881 vertex 34.616 -54.393 9.881 vertex 25.4 -54.109 9.323 endloop endfacet facet normal 0 1 0 outer loop vertex 42.411 -33.2 -24.367 vertex 42.548 -33.2 -23.501 vertex 51.8 -33.2 -30.37797 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.013 -36.2 -21.855 vertex 42.411 -36.2 -22.635 vertex 52.2 -36.2 -10.48639 endloop endfacet facet normal 0 0.70711 0.70711 outer loop vertex 34.616 -54.109 9.323 vertex 25.4 -53.666 8.88 vertex 25.4 -54.109 9.323 endloop endfacet facet normal 0 1 0 outer loop vertex 39.747 -33.2 -26.303 vertex 40.613 -33.2 -26.165 vertex 40.099 -33.2 -33.7 endloop endfacet facet normal 0 1 0 outer loop vertex 39.233 -33.2 -33.837 vertex 38.452 -33.2 -34.235 vertex 38.881 -33.2 -26.165 endloop endfacet facet normal 0 1 0 outer loop vertex 38.1 -33.2 -25.767 vertex 38.881 -33.2 -26.165 vertex 38.452 -33.2 -34.235 endloop endfacet facet normal 0 1 0 outer loop vertex 40.613 -33.2 -26.165 vertex 41.394 -33.2 -25.767 vertex 40.965 -33.2 -33.837 endloop endfacet facet normal 0 1 0 outer loop vertex 27.1 -33.2 0 vertex 37.337 -33.2 -11.367 vertex 37.481 -33.2 -21.855 endloop endfacet facet normal 0 1 0 outer loop vertex 37.735 -33.2 -12.148 vertex 38.355 -33.2 -12.767 vertex 38.1 -33.2 -21.235 endloop endfacet facet normal -0.99985 0.0174 0 outer loop vertex 34.06285 -42.57675 15.21 vertex 34.019 -45.096 15.21 vertex 34.0626 -42.591 15.3 endloop endfacet facet normal -0.99985 0.0174 0 outer loop vertex 34.019 -45.096 15.21 vertex 34.023 -44.866 16.665 vertex 34.0626 -42.591 15.3 endloop endfacet facet normal -0.99985 0.0174 0 outer loop vertex 34.06424 -42.49669 15.89568 vertex 34.0626 -42.591 15.3 vertex 34.023 -44.866 16.665 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 34.441 8.71 -16.21979 vertex 34.263 8.80029 -16.55671 vertex 51.559 8.70977 -16.21894 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.986 8.8719 -16.82394 vertex 33.94306 8.87754 -16.84498 vertex 35.0753 9.443 -18.955 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 34.263 8.80029 -16.55671 vertex 34.2289 8.80913 -16.5897 vertex 35.0753 9.443 -18.955 endloop endfacet facet normal -0.99985 0.01729 -0.00003 outer loop vertex 34.07881 -41.6651 16.97135 vertex 34.07707 -41.766 16.92 vertex 34.053 -43.154 19.02 endloop endfacet facet normal -0.99985 0.01729 -0.00003 outer loop vertex 34.07 -42.17571 16.51029 vertex 34.035 -44.197 17.978 vertex 34.07707 -41.766 16.92 endloop endfacet facet normal 0 1 0 outer loop vertex 41.394 -33.2 -21.235 vertex 40.613 -33.2 -20.837 vertex 40.867 -33.2 -13.165 endloop endfacet facet normal -0.99985 0.01729 -0.00003 outer loop vertex 34.053 -43.154 19.02 vertex 34.07707 -41.766 16.92 vertex 34.035 -44.197 17.978 endloop endfacet facet normal 0 1 0 outer loop vertex 38.355 -33.2 -12.767 vertex 39.135 -33.2 -13.165 vertex 38.881 -33.2 -20.837 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.487 5.33204 -3.61494 vertex 33.138 5.37813 -3.78692 vertex 34.503 7.394 -11.30915 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.138 5.37813 -3.78692 vertex 32.752 5.39395 -3.84597 vertex 34.503 7.394 -11.30915 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 34.503 7.394 -11.30915 vertex 34.263 8.41947 -15.13569 vertex 51.498 8.60981 -15.84593 endloop endfacet facet normal 0 1 0 outer loop vertex 38.881 -33.2 -20.837 vertex 38.1 -33.2 -21.235 vertex 38.355 -33.2 -12.767 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 51.498 8.60981 -15.84593 vertex 51.559 8.50959 -15.47199 vertex 34.503 7.394 -11.30915 endloop endfacet facet normal -0.99985 0.01717 0 outer loop vertex 34.08972 -41.04183 17.23058 vertex 34.076 -41.841 19.689 vertex 34.0975 -40.589 17.303 endloop endfacet facet normal -0.99985 0.01717 0 outer loop vertex 34.101 -40.385 19.92 vertex 34.0975 -40.589 17.303 vertex 34.076 -41.841 19.689 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.67405 5.28375 -3.43474 vertex 33.487 5.33204 -3.61494 vertex 51.559 8.50959 -15.47199 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.487 5.33204 -3.61494 vertex 34.503 7.394 -11.30915 vertex 51.559 8.50959 -15.47199 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.764 5.26059 -3.3483 vertex 33.67405 5.28375 -3.43474 vertex 51.559 8.50959 -15.47199 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.941 5.17042 -3.01184 vertex 33.8835 5.19975 -3.12129 vertex 51.737 8.41924 -15.13485 endloop endfacet facet normal 0 1 0 outer loop vertex 40.001 -33.2 -13.303 vertex 40.867 -33.2 -13.165 vertex 40.613 -33.2 -20.837 endloop endfacet facet normal 0 1 0 outer loop vertex 42.013 -33.2 -21.855 vertex 41.394 -33.2 -21.235 vertex 41.648 -33.2 -12.767 endloop endfacet facet normal 0 1 0 outer loop vertex 40.867 -33.2 -13.165 vertex 41.648 -33.2 -12.767 vertex 41.394 -33.2 -21.235 endloop endfacet facet normal 0 1 0 outer loop vertex 40.613 -33.2 -20.837 vertex 39.747 -33.2 -20.7 vertex 40.001 -33.2 -13.303 endloop endfacet facet normal 0 1 0 outer loop vertex 39.135 -33.2 -13.165 vertex 40.001 -33.2 -13.303 vertex 39.747 -33.2 -20.7 endloop endfacet facet normal 0 1 0 outer loop vertex 39.747 -33.2 -20.7 vertex 38.881 -33.2 -20.837 vertex 39.135 -33.2 -13.165 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.98219 5.10296 -2.76013 vertex 33.941 5.17042 -3.01184 vertex 51.54319 5.13795 -2.89068 endloop endfacet facet normal -0.99985 0.01747 0.0001 outer loop vertex 34.07881 -41.6651 16.97135 vertex 34.053 -43.154 19.02 vertex 34.08682 -41.208 17.204 endloop endfacet facet normal 0 1 0 outer loop vertex 40.965 -33.2 -33.837 vertex 40.099 -33.2 -33.7 vertex 40.613 -33.2 -26.165 endloop endfacet facet normal 0 1 0 outer loop vertex 40.099 -33.2 -33.7 vertex 39.233 -33.2 -33.837 vertex 39.747 -33.2 -26.303 endloop endfacet facet normal 0 1 0 outer loop vertex 38.881 -33.2 -26.165 vertex 39.747 -33.2 -26.303 vertex 39.233 -33.2 -33.837 endloop endfacet facet normal 0 1 0 outer loop vertex 42.411 -33.2 -24.367 vertex 51.8 -33.2 -30.37797 vertex 42.013 -33.2 -25.148 endloop endfacet facet normal -0.99985 0.01747 0.0001 outer loop vertex 34.08972 -41.04183 17.23058 vertex 34.08682 -41.208 17.204 vertex 34.076 -41.841 19.689 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.487 4.80894 -1.66297 vertex 33.764 4.88052 -1.93008 vertex 34.002 4.36328 0 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.487 4.80894 -1.66297 vertex 34.002 4.36328 0 vertex 33.138 4.7631 -1.49193 endloop endfacet facet normal -0.99985 0.01747 0.0001 outer loop vertex 34.053 -43.154 19.02 vertex 34.076 -41.841 19.689 vertex 34.08682 -41.208 17.204 endloop endfacet facet normal 0 1 0 outer loop vertex 41.648 -33.2 -12.767 vertex 42.267 -33.2 -12.148 vertex 42.013 -33.2 -21.855 endloop endfacet facet normal 0 1 0 outer loop vertex 52.2 -33.2 20 vertex 51.8 -33.2 -30.37797 vertex 42.802 -33.2 -10.501 endloop endfacet facet normal 0 1 0 outer loop vertex 42.665 -33.2 -11.367 vertex 51.8 -33.2 -30.37797 vertex 42.267 -33.2 -12.148 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 34.263 8.41947 -15.13569 vertex 34.28491 8.43059 -15.17717 vertex 51.498 8.60981 -15.84593 endloop endfacet facet normal 0 1 0 outer loop vertex 42.665 -33.2 -11.367 vertex 42.802 -33.2 -10.501 vertex 51.8 -33.2 -30.37797 endloop endfacet facet normal 0 1 0 outer loop vertex 42.802 -33.2 -10.501 vertex 42.665 -33.2 -9.635 vertex 52.2 -33.2 20 endloop endfacet facet normal 0 0.15793 -0.98745 outer loop vertex 34.0975 -40.589 17.303 vertex 43.008 -41.208 17.204 vertex 34.08972 -41.04183 17.23058 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.8835 5.19975 -3.12129 vertex 33.764 5.26059 -3.3483 vertex 51.737 8.41924 -15.13485 endloop endfacet facet normal 0 1 0 outer loop vertex 42.548 -33.2 -23.501 vertex 42.411 -33.2 -22.635 vertex 51.8 -33.2 -30.37797 endloop endfacet facet normal 0 1 0 outer loop vertex 42.013 -33.2 -21.855 vertex 42.267 -33.2 -12.148 vertex 42.411 -33.2 -22.635 endloop endfacet facet normal 0 1 0 outer loop vertex 41.745 -33.2 -34.235 vertex 41.394 -33.2 -25.767 vertex 51.8 -33.2 -30.37797 endloop endfacet facet normal 0 1 0 outer loop vertex 42.013 -33.2 -25.148 vertex 51.8 -33.2 -30.37797 vertex 41.394 -33.2 -25.767 endloop endfacet facet normal 0 1 0 outer loop vertex 42.411 -33.2 -22.635 vertex 42.267 -33.2 -12.148 vertex 51.8 -33.2 -30.37797 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 32.863 12.00881 -16.16679 vertex 30.2 12.534 -18.127 vertex 32.67122 11.98363 -16.0728 endloop endfacet facet normal -0.99985 0.01748 0.00023 outer loop vertex 34.06424 -42.49669 15.89568 vertex 34.023 -44.866 16.665 vertex 34.06431 -42.493 15.919 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.03735 12.01594 -16.19339 vertex 30.2 12.534 -18.127 vertex 32.863 12.00881 -16.16679 endloop endfacet facet normal 0 -1 0 outer loop vertex 39.747 -36.2 -26.303 vertex 40.099 -36.2 -33.7 vertex 40.613 -36.2 -26.165 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.42434 12.01764 -16.19975 vertex 30.2 12.534 -18.127 vertex 33.25 12.02477 -16.22635 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.637 12.00881 -16.16679 vertex 30.2 12.534 -18.127 vertex 33.42434 12.01764 -16.19975 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.25 12.02477 -16.22635 vertex 30.2 12.534 -18.127 vertex 33.03735 12.01594 -16.19339 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.986 11.9629 -15.99543 vertex 46.9 12.534 -18.127 vertex 33.79425 11.98808 -16.08941 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.79425 11.98808 -16.08941 vertex 46.9 12.534 -18.127 vertex 33.637 12.00881 -16.16679 endloop endfacet facet normal -0.99985 0.01748 0.00023 outer loop vertex 34.07 -42.17571 16.51029 vertex 34.0694 -42.209 16.477 vertex 34.035 -44.197 17.978 endloop endfacet facet normal -0.99985 0.01748 0.00023 outer loop vertex 34.023 -44.866 16.665 vertex 34.035 -44.197 17.978 vertex 34.0694 -42.209 16.477 endloop endfacet facet normal -0.99985 0.01748 0.00023 outer loop vertex 34.0694 -42.209 16.477 vertex 34.06431 -42.493 15.919 vertex 34.023 -44.866 16.665 endloop endfacet facet normal 0 -1 0 outer loop vertex 38.881 -36.2 -20.837 vertex 39.747 -36.2 -20.7 vertex 39.135 -36.2 -13.165 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.735 -36.2 -12.148 vertex 31.06376 -36.2 -10.48639 vertex 38.1 -36.2 -21.235 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.867 -36.2 -13.165 vertex 40.001 -36.2 -13.303 vertex 40.613 -36.2 -20.837 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 34.1108 11.93066 -15.87509 vertex 46.9 12.534 -18.127 vertex 33.986 11.9629 -15.99543 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 34.263 11.8912 -15.72781 vertex 46.9 12.534 -18.127 vertex 34.1108 11.93066 -15.87509 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 34.441 11.80093 -15.39088 vertex 46.9 12.534 -18.127 vertex 34.263 11.8912 -15.72781 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 34.46894 11.75579 -15.22239 vertex 46.9 12.534 -18.127 vertex 34.441 11.80093 -15.39088 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 34.503 11.70088 -15.01744 vertex 46.9 12.534 -18.127 vertex 34.46894 11.75579 -15.22239 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 46.1 7.67736 0 vertex 46.9 12.534 -18.127 vertex 34.441 11.6008 -14.64391 endloop endfacet facet normal 0 -1 0 outer loop vertex 46.9 -36.2 -31.18159 vertex 52.2 -36.2 -10.48639 vertex 42.548 -36.2 -23.501 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 34.36081 11.5601 -14.492 vertex 46.1 7.67736 0 vertex 34.441 11.6008 -14.64391 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 34.47507 11.65585 -14.84938 vertex 34.441 11.6008 -14.64391 vertex 46.9 12.534 -18.127 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.735 -36.2 -12.148 vertex 38.1 -36.2 -21.235 vertex 38.355 -36.2 -12.767 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 31.997 11.14241 -12.933 vertex 32.863 11.39277 -13.86747 vertex 32.514 11.43885 -14.03945 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 34.263 11.5105 -14.30687 vertex 46.1 7.67736 0 vertex 34.36081 11.5601 -14.492 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 34.13818 11.47817 -14.1862 vertex 46.1 7.67736 0 vertex 34.263 11.5105 -14.30687 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.613 -36.2 -20.837 vertex 41.394 -36.2 -21.235 vertex 40.867 -36.2 -13.165 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.013 -36.2 -21.855 vertex 41.648 -36.2 -12.767 vertex 41.394 -36.2 -21.235 endloop endfacet facet normal 0 -1 0 outer loop vertex 39.747 -36.2 -20.7 vertex 40.613 -36.2 -20.837 vertex 40.001 -36.2 -13.303 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.001 -36.2 -13.303 vertex 39.135 -36.2 -13.165 vertex 39.747 -36.2 -20.7 endloop endfacet facet normal 0 -1 0 outer loop vertex 39.135 -36.2 -13.165 vertex 38.355 -36.2 -12.767 vertex 38.881 -36.2 -20.837 endloop endfacet facet normal 0 -1 0 outer loop vertex 38.1 -36.2 -21.235 vertex 38.881 -36.2 -20.837 vertex 38.355 -36.2 -12.767 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 31.997 11.14241 -12.933 vertex 33.25 11.37695 -13.80842 vertex 32.863 11.39277 -13.86747 endloop endfacet facet normal 0 -1 0 outer loop vertex 41.394 -36.2 -25.767 vertex 40.613 -36.2 -26.165 vertex 40.965 -36.2 -33.837 endloop endfacet facet normal 0 -1 0 outer loop vertex 38.881 -36.2 -26.165 vertex 39.233 -36.2 -33.837 vertex 39.747 -36.2 -26.303 endloop endfacet facet normal 0 -1 0 outer loop vertex 38.1 -36.2 -25.767 vertex 34.019 -36.2 -31.18159 vertex 38.881 -36.2 -26.165 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.481 -36.2 -25.148 vertex 34.019 -36.2 -31.18159 vertex 38.1 -36.2 -25.767 endloop endfacet facet normal 0 -1 0 outer loop vertex 41.745 -36.2 -34.235 vertex 46.9 -36.2 -31.18159 vertex 41.394 -36.2 -25.767 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.98688 8.13752 -1.71749 vertex 33.941 8.06241 -1.43714 vertex 46.1 7.67736 0 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.764 7.97239 -1.10114 vertex 46.1 7.67736 0 vertex 33.941 8.06241 -1.43714 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.487 7.90082 -0.83403 vertex 46.1 7.67736 0 vertex 33.764 7.97239 -1.10114 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.138 7.85499 -0.66298 vertex 32.752 7.83917 -0.60393 vertex 46.1 7.67736 0 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 30.2 7.67736 0 vertex 46.1 7.67736 0 vertex 32.752 7.83917 -0.60393 endloop endfacet facet normal 0 -1 0 outer loop vertex 41.648 -36.2 -12.767 vertex 42.013 -36.2 -21.855 vertex 42.267 -36.2 -12.148 endloop endfacet facet normal 0 -1 0 outer loop vertex 41.648 -36.2 -12.767 vertex 40.867 -36.2 -13.165 vertex 41.394 -36.2 -21.235 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.138 8.46988 -2.95801 vertex 31.997 11.14241 -12.933 vertex 32.752 8.4857 -3.01706 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.802 -36.2 -10.501 vertex 52.2 -36.2 -10.48639 vertex 42.665 -36.2 -9.635 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.487 8.42381 -2.78603 vertex 33.637 11.39277 -13.86747 vertex 33.138 8.46988 -2.95801 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.764 8.35244 -2.51968 vertex 33.637 11.39277 -13.86747 vertex 33.55569 8.40608 -2.71986 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.55569 8.40608 -2.71986 vertex 33.637 11.39277 -13.86747 vertex 33.487 8.42381 -2.78603 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.941 8.26222 -2.18292 vertex 46.1 7.67736 0 vertex 33.80787 8.33011 -2.43633 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 46.1 7.67736 0 vertex 33.637 11.39277 -13.86747 vertex 33.764 8.35244 -2.51968 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.665 -36.2 -11.367 vertex 42.267 -36.2 -12.148 vertex 52.2 -36.2 -10.48639 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.013 -36.2 -21.855 vertex 52.2 -36.2 -10.48639 vertex 42.267 -36.2 -12.148 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.665 -36.2 -11.367 vertex 52.2 -36.2 -10.48639 vertex 42.802 -36.2 -10.501 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.95612 8.23746 -2.0905 vertex 46.1 7.67736 0 vertex 33.941 8.26222 -2.18292 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.80787 8.33011 -2.43633 vertex 46.1 7.67736 0 vertex 33.764 8.35244 -2.51968 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.411 -36.2 -22.635 vertex 42.548 -36.2 -23.501 vertex 52.2 -36.2 -10.48639 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.411 -36.2 -24.367 vertex 42.013 -36.2 -25.148 vertex 46.9 -36.2 -31.18159 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.965 -36.2 -33.837 vertex 41.745 -36.2 -34.235 vertex 41.394 -36.2 -25.767 endloop endfacet facet normal 0 -1 0 outer loop vertex 42.548 -36.2 -23.501 vertex 42.411 -36.2 -24.367 vertex 46.9 -36.2 -31.18159 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.487 7.90082 -0.83403 vertex 33.138 7.85499 -0.66298 vertex 46.1 7.67736 0 endloop endfacet facet normal 0.15737 0 0.98754 outer loop vertex 38.881 -33.2 -26.165 vertex 38.881 -36.2 -26.165 vertex 39.747 -36.2 -26.303 endloop endfacet facet normal 0.15737 0 0.98754 outer loop vertex 38.881 -33.2 -26.165 vertex 39.747 -36.2 -26.303 vertex 39.747 -33.2 -26.303 endloop endfacet facet normal 0.45405 0 0.89098 outer loop vertex 38.1 -33.2 -25.767 vertex 38.1 -36.2 -25.767 vertex 38.881 -36.2 -26.165 endloop endfacet facet normal 0.45405 0 0.89098 outer loop vertex 38.1 -33.2 -25.767 vertex 38.881 -36.2 -26.165 vertex 38.881 -33.2 -26.165 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 34.002 8.1623 -1.80997 vertex 33.98688 8.13752 -1.71749 vertex 46.1 7.67736 0 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.95612 8.23746 -2.0905 vertex 34.002 8.1623 -1.80997 vertex 46.1 7.67736 0 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.637 11.39277 -13.86747 vertex 33.25 11.37695 -13.80842 vertex 33.138 8.46988 -2.95801 endloop endfacet facet normal 0.70711 0 0.70711 outer loop vertex 38.1 -36.2 -25.767 vertex 38.1 -33.2 -25.767 vertex 37.481 -36.2 -25.148 endloop endfacet facet normal 0.70711 0 0.70711 outer loop vertex 37.481 -33.2 -25.148 vertex 37.481 -36.2 -25.148 vertex 38.1 -33.2 -25.767 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 31.997 11.14241 -12.933 vertex 33.138 8.46988 -2.95801 vertex 33.25 11.37695 -13.80842 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 30.2 12.534 -18.127 vertex 30.2 7.67736 0 vertex 31.997 11.14241 -12.933 endloop endfacet facet normal -0.70711 0 0.70711 outer loop vertex 41.394 -33.2 -25.767 vertex 41.394 -36.2 -25.767 vertex 42.013 -36.2 -25.148 endloop endfacet facet normal -0.70711 0 0.70711 outer loop vertex 41.394 -33.2 -25.767 vertex 42.013 -36.2 -25.148 vertex 42.013 -33.2 -25.148 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 30.2 12.534 -18.127 vertex 33.637 12.00881 -16.16679 vertex 46.9 12.534 -18.127 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.986 11.43885 -14.03945 vertex 46.1 7.67736 0 vertex 34.13818 11.47817 -14.1862 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 34.503 11.70088 -15.01744 vertex 34.47507 11.65585 -14.84938 vertex 46.9 12.534 -18.127 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 33.986 11.43885 -14.03945 vertex 33.637 11.39277 -13.86747 vertex 46.1 7.67736 0 endloop endfacet facet normal -0.45405 0 0.89098 outer loop vertex 40.613 -33.2 -26.165 vertex 40.613 -36.2 -26.165 vertex 41.394 -36.2 -25.767 endloop endfacet facet normal -0.45405 0 0.89098 outer loop vertex 40.613 -33.2 -26.165 vertex 41.394 -36.2 -25.767 vertex 41.394 -33.2 -25.767 endloop endfacet facet normal -0.15737 0 0.98754 outer loop vertex 39.747 -33.2 -26.303 vertex 39.747 -36.2 -26.303 vertex 40.613 -36.2 -26.165 endloop endfacet facet normal -0.15737 0 0.98754 outer loop vertex 39.747 -33.2 -26.303 vertex 40.613 -36.2 -26.165 vertex 40.613 -33.2 -26.165 endloop endfacet facet normal 0.45248 -0.23096 0.86135 outer loop vertex 32.863 12.00881 -16.16679 vertex 32.82001 8.91225 -16.97451 vertex 32.863 8.9179 -16.99558 endloop endfacet facet normal 0.70768 0 -0.70654 outer loop vertex 37.481 -36.2 -21.855 vertex 37.481 -33.2 -21.855 vertex 38.1 -36.2 -21.235 endloop endfacet facet normal 0.70768 0 -0.70654 outer loop vertex 38.1 -33.2 -21.235 vertex 38.1 -36.2 -21.235 vertex 37.481 -33.2 -21.855 endloop endfacet facet normal 0.45405 0 -0.89098 outer loop vertex 38.881 -33.2 -20.837 vertex 38.881 -36.2 -20.837 vertex 38.1 -36.2 -21.235 endloop endfacet facet normal 0.45405 0 -0.89098 outer loop vertex 38.881 -33.2 -20.837 vertex 38.1 -36.2 -21.235 vertex 38.1 -33.2 -21.235 endloop endfacet facet normal 0.15603 -0.25582 0.95405 outer loop vertex 32.863 12.00881 -16.16679 vertex 32.863 8.9179 -16.99558 vertex 33.03735 12.01594 -16.19339 endloop endfacet facet normal 0.15603 -0.25582 0.95405 outer loop vertex 33.20235 8.93177 -17.04736 vertex 33.03735 12.01594 -16.19339 vertex 32.863 8.9179 -16.99558 endloop endfacet facet normal 0.15626 0 -0.98772 outer loop vertex 38.881 -36.2 -20.837 vertex 38.881 -33.2 -20.837 vertex 39.747 -33.2 -20.7 endloop endfacet facet normal 0.15626 0 -0.98772 outer loop vertex 38.881 -36.2 -20.837 vertex 39.747 -33.2 -20.7 vertex 39.747 -36.2 -20.7 endloop endfacet facet normal -0.01725 -0.98758 0.15616 outer loop vertex 45.075 -45.059 16.665 vertex 34.023 -44.866 16.665 vertex 34.019 -45.096 15.21 endloop endfacet facet normal -0.15626 0 -0.98772 outer loop vertex 40.613 -33.2 -20.837 vertex 40.613 -36.2 -20.837 vertex 39.747 -36.2 -20.7 endloop endfacet facet normal -0.15626 0 -0.98772 outer loop vertex 40.613 -33.2 -20.837 vertex 39.747 -36.2 -20.7 vertex 39.747 -33.2 -20.7 endloop endfacet facet normal 0.15843 -0.2556 0.95371 outer loop vertex 33.25 8.93375 -17.05474 vertex 33.25 12.02477 -16.22635 vertex 33.20235 8.93177 -17.04736 endloop endfacet facet normal -0.45405 0 -0.89098 outer loop vertex 41.394 -33.2 -21.235 vertex 41.394 -36.2 -21.235 vertex 40.613 -36.2 -20.837 endloop endfacet facet normal -0.45405 0 -0.89098 outer loop vertex 41.394 -33.2 -21.235 vertex 40.613 -36.2 -20.837 vertex 40.613 -33.2 -20.837 endloop endfacet facet normal -0.15843 -0.25572 0.95368 outer loop vertex 33.637 12.00881 -16.16679 vertex 33.58934 8.91988 -17.00297 vertex 33.637 8.9179 -16.99558 endloop endfacet facet normal -0.70768 0 -0.70654 outer loop vertex 42.013 -33.2 -21.855 vertex 42.013 -36.2 -21.855 vertex 41.394 -36.2 -21.235 endloop endfacet facet normal -0.70768 0 -0.70654 outer loop vertex 42.013 -33.2 -21.855 vertex 41.394 -36.2 -21.235 vertex 41.394 -33.2 -21.235 endloop endfacet facet normal -0.89074 0 -0.45451 outer loop vertex 42.411 -33.2 -22.635 vertex 42.411 -36.2 -22.635 vertex 42.013 -36.2 -21.855 endloop endfacet facet normal -0.89074 0 -0.45451 outer loop vertex 42.411 -33.2 -22.635 vertex 42.013 -36.2 -21.855 vertex 42.013 -33.2 -21.855 endloop endfacet facet normal -0.98772 0 -0.15626 outer loop vertex 42.548 -36.2 -23.501 vertex 42.411 -36.2 -22.635 vertex 42.411 -33.2 -22.635 endloop endfacet facet normal -0.98772 0 -0.15626 outer loop vertex 42.548 -36.2 -23.501 vertex 42.411 -33.2 -22.635 vertex 42.548 -33.2 -23.501 endloop endfacet facet normal -0.45391 -0.23077 0.86064 outer loop vertex 33.94306 8.87754 -16.84498 vertex 33.79425 11.98808 -16.08941 vertex 33.637 8.9179 -16.99558 endloop endfacet facet normal -0.01234 -0.70661 0.7075 outer loop vertex 34.035 -44.197 17.978 vertex 45.086 -44.39 17.978 vertex 34.053 -43.154 19.02 endloop endfacet facet normal -0.45248 -0.23088 0.86137 outer loop vertex 33.986 11.9629 -15.99543 vertex 33.94306 8.87754 -16.84498 vertex 33.986 8.8719 -16.82394 endloop endfacet facet normal -0.89098 0 0.45405 outer loop vertex 42.013 -33.2 -25.148 vertex 42.013 -36.2 -25.148 vertex 42.411 -36.2 -24.367 endloop endfacet facet normal -0.89098 0 0.45405 outer loop vertex 42.013 -33.2 -25.148 vertex 42.411 -36.2 -24.367 vertex 42.411 -33.2 -24.367 endloop endfacet facet normal -0.70775 -0.18299 0.68235 outer loop vertex 34.1108 11.93066 -15.87509 vertex 34.2289 8.80913 -16.5897 vertex 34.263 11.8912 -15.72781 endloop endfacet facet normal -0.70775 -0.18299 0.68235 outer loop vertex 34.263 8.80029 -16.55671 vertex 34.263 11.8912 -15.72781 vertex 34.2289 8.80913 -16.5897 endloop endfacet facet normal 0.15737 0 0.98754 outer loop vertex 40.001 -36.2 -13.303 vertex 40.001 -33.2 -13.303 vertex 39.135 -33.2 -13.165 endloop endfacet facet normal 0.15737 0 0.98754 outer loop vertex 40.001 -36.2 -13.303 vertex 39.135 -33.2 -13.165 vertex 39.135 -36.2 -13.165 endloop endfacet facet normal 0.45451 0 0.89074 outer loop vertex 39.135 -36.2 -13.165 vertex 39.135 -33.2 -13.165 vertex 38.355 -33.2 -12.767 endloop endfacet facet normal 0.45451 0 0.89074 outer loop vertex 39.135 -36.2 -13.165 vertex 38.355 -33.2 -12.767 vertex 38.355 -36.2 -12.767 endloop endfacet facet normal -0.00793 -0.45386 0.89104 outer loop vertex 34.053 -43.154 19.02 vertex 45.105 -43.347 19.02 vertex 34.076 -41.841 19.689 endloop endfacet facet normal 0.70654 0 0.70768 outer loop vertex 37.735 -33.2 -12.148 vertex 37.735 -36.2 -12.148 vertex 38.355 -33.2 -12.767 endloop endfacet facet normal 0.70654 0 0.70768 outer loop vertex 38.355 -36.2 -12.767 vertex 38.355 -33.2 -12.767 vertex 37.735 -36.2 -12.148 endloop endfacet facet normal -0.70652 -0.18322 0.68357 outer loop vertex 34.2289 8.80913 -16.5897 vertex 34.1108 11.93066 -15.87509 vertex 33.986 8.8719 -16.82394 endloop endfacet facet normal -0.45405 0 0.89098 outer loop vertex 40.867 -36.2 -13.165 vertex 41.648 -33.2 -12.767 vertex 40.867 -33.2 -13.165 endloop endfacet facet normal -0.15737 0 0.98754 outer loop vertex 40.867 -36.2 -13.165 vertex 40.867 -33.2 -13.165 vertex 40.001 -33.2 -13.303 endloop endfacet facet normal -0.15737 0 0.98754 outer loop vertex 40.867 -36.2 -13.165 vertex 40.001 -33.2 -13.303 vertex 40.001 -36.2 -13.303 endloop endfacet facet normal -0.89098 0 0.45405 outer loop vertex 42.665 -36.2 -11.367 vertex 42.665 -33.2 -11.367 vertex 42.267 -36.2 -12.148 endloop endfacet facet normal -0.89098 0 0.45405 outer loop vertex 42.267 -33.2 -12.148 vertex 42.267 -36.2 -12.148 vertex 42.665 -33.2 -11.367 endloop endfacet facet normal -0.70711 0 0.70711 outer loop vertex 42.267 -36.2 -12.148 vertex 42.267 -33.2 -12.148 vertex 41.648 -33.2 -12.767 endloop endfacet facet normal -0.70711 0 0.70711 outer loop vertex 42.267 -36.2 -12.148 vertex 41.648 -33.2 -12.767 vertex 41.648 -36.2 -12.767 endloop endfacet facet normal -0.45405 0 0.89098 outer loop vertex 41.648 -36.2 -12.767 vertex 41.648 -33.2 -12.767 vertex 40.867 -36.2 -13.165 endloop endfacet facet normal -0.98772 0 0.15626 outer loop vertex 42.411 -36.2 -24.367 vertex 42.548 -36.2 -23.501 vertex 42.548 -33.2 -23.501 endloop endfacet facet normal -0.98772 0 0.15626 outer loop vertex 42.411 -36.2 -24.367 vertex 42.548 -33.2 -23.501 vertex 42.411 -33.2 -24.367 endloop endfacet facet normal -0.89073 -0.11774 0.43903 outer loop vertex 34.263 11.8912 -15.72781 vertex 34.263 8.80029 -16.55671 vertex 34.441 8.71 -16.21979 endloop endfacet facet normal -0.98772 0 -0.15626 outer loop vertex 42.802 -33.2 -10.501 vertex 42.802 -36.2 -10.501 vertex 42.665 -33.2 -9.635 endloop endfacet facet normal -0.98772 0 -0.15626 outer loop vertex 42.665 -36.2 -9.635 vertex 42.665 -33.2 -9.635 vertex 42.802 -36.2 -10.501 endloop endfacet facet normal -0.98772 0 0.15626 outer loop vertex 42.802 -36.2 -10.501 vertex 42.802 -33.2 -10.501 vertex 42.665 -33.2 -11.367 endloop endfacet facet normal -0.98772 0 0.15626 outer loop vertex 42.802 -36.2 -10.501 vertex 42.665 -33.2 -11.367 vertex 42.665 -36.2 -11.367 endloop endfacet facet normal -0.98742 -0.04096 0.15274 outer loop vertex 34.49537 8.62211 -15.89185 vertex 34.46894 11.75579 -15.22239 vertex 34.441 8.71 -16.21979 endloop endfacet facet normal -0.98736 -0.04104 0.15312 outer loop vertex 34.503 8.60981 -15.84596 vertex 34.503 11.70088 -15.01744 vertex 34.49537 8.62211 -15.89185 endloop endfacet facet normal -0.98736 0.04104 -0.15312 outer loop vertex 34.47507 11.65585 -14.84938 vertex 34.503 8.60981 -15.84596 vertex 34.44863 8.52215 -15.51884 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 51.559 8.50959 -15.47199 vertex 51.58089 8.49849 -15.43054 vertex 33.764 5.26059 -3.3483 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 34.44863 8.52215 -15.51884 vertex 34.503 8.60981 -15.84596 vertex 51.498 8.60981 -15.84593 endloop endfacet facet normal 0 0.70711 -0.70711 outer loop vertex 34.0694 -42.209 16.477 vertex 34.07 -42.17571 16.51029 vertex 34.16879 -42.209 16.477 endloop endfacet facet normal -0.98742 0.04096 -0.15274 outer loop vertex 34.441 8.50982 -15.47284 vertex 34.441 11.6008 -14.64391 vertex 34.44863 8.52215 -15.51884 endloop endfacet facet normal 0 0 -1 outer loop vertex 52.2 -36.2 -58 vertex 26.6 -36.2 -58 vertex 52.2 -33.2 -58 endloop endfacet facet normal -0.99985 0.01755 0 outer loop vertex 34.27425 -36.2 19.9 vertex 34.22632 -38.93073 19.689 vertex 34.22609 -38.94382 19.69108 endloop endfacet facet normal 0 0.25875 -0.96594 outer loop vertex 35.0753 9.443 -18.955 vertex 46.9 12.534 -18.127 vertex 55.2 9.443 -18.955 endloop endfacet facet normal -0.99985 0.01755 0 outer loop vertex 34.22609 -38.94382 19.69108 vertex 34.20298 -40.26068 19.9 vertex 34.27425 -36.2 19.9 endloop endfacet facet normal -0.70652 0.18322 -0.68357 outer loop vertex 33.986 8.34773 -14.86798 vertex 33.986 11.43885 -14.03945 vertex 34.02007 8.35653 -14.90084 endloop endfacet facet normal 0 0.25875 -0.96594 outer loop vertex 55.2 12.534 -18.127 vertex 55.2 9.443 -18.955 vertex 46.9 12.534 -18.127 endloop endfacet facet normal -0.70742 0.18305 -0.68268 outer loop vertex 34.02007 8.35653 -14.90084 vertex 34.13818 11.47817 -14.1862 vertex 34.263 8.41947 -15.13569 endloop endfacet facet normal -0.99985 0.01755 0 outer loop vertex 34.183 -41.399 19.7594 vertex 34.183 -41.399 19.9 vertex 34.19855 -40.5128 19.9 endloop endfacet facet normal 0 -1 0 outer loop vertex 52.2 -36.2 -58 vertex 52.2 -36.2 -10.48639 vertex 46.9 -36.2 -31.18159 endloop endfacet facet normal 0.15603 0.25573 -0.95408 outer loop vertex 32.863 8.30164 -14.69601 vertex 32.863 11.39277 -13.86747 vertex 33.25 8.28582 -14.63696 endloop endfacet facet normal -0.99985 0.01755 0 outer loop vertex 34.27425 -36.2 19.9 vertex 34.24936 -37.61775 19.02 vertex 34.24915 -37.62968 19.02608 endloop endfacet facet normal -0.99985 0.01755 0 outer loop vertex 34.22632 -38.93073 19.689 vertex 34.27425 -36.2 19.9 vertex 34.24915 -37.62968 19.02608 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 51.563 4.97056 -2.26607 vertex 51.741 4.88052 -1.93008 vertex 34.002 4.36328 0 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 51.52181 5.03807 -2.51797 vertex 51.563 4.97056 -2.26607 vertex 34.002 4.36328 0 endloop endfacet facet normal -0.99985 0.01755 0 outer loop vertex 34.27425 -36.2 19.9 vertex 34.27425 -36.2 17.24055 vertex 34.26765 -36.57574 17.978 endloop endfacet facet normal -0.99985 0.01755 0 outer loop vertex 34.27425 -36.2 19.9 vertex 34.26765 -36.57574 17.978 vertex 34.24936 -37.61775 19.02 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 34.002 4.36328 0 vertex 33.764 4.88052 -1.93008 vertex 51.502 5.0705 -2.639 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.941 4.97056 -2.26607 vertex 33.96081 5.003 -2.38713 vertex 51.502 5.0705 -2.639 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.764 4.88052 -1.93008 vertex 33.941 4.97056 -2.26607 vertex 51.502 5.0705 -2.639 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.96081 5.003 -2.38713 vertex 34.002 5.0705 -2.639 vertex 51.502 5.0705 -2.639 endloop endfacet facet normal -0.15603 0.25573 -0.95408 outer loop vertex 33.25 11.37695 -13.80842 vertex 33.637 11.39277 -13.86747 vertex 33.25 8.28582 -14.63696 endloop endfacet facet normal 0 -1 0 outer loop vertex 34.27425 -36.2 19.9 vertex 40.00412 -36.2 19.9 vertex 26.6 -36.2 20 endloop endfacet facet normal -0.00274 -0.15665 0.98765 outer loop vertex 34.19855 -40.5128 19.9 vertex 45.153 -40.578 19.92 vertex 34.101 -40.385 19.92 endloop endfacet facet normal 0.15843 -0.2556 0.95371 outer loop vertex 33.03735 12.01594 -16.19339 vertex 33.20235 8.93177 -17.04736 vertex 33.25 12.02477 -16.22635 endloop endfacet facet normal 0.00274 0.15665 0.98765 outer loop vertex 45.153 -40.578 19.92 vertex 44.19837 -40.43523 19.9 vertex 34.101 -40.385 19.92 endloop endfacet facet normal -0.15843 -0.25572 0.95368 outer loop vertex 33.42434 12.01764 -16.19975 vertex 33.58934 8.91988 -17.00297 vertex 33.637 12.00881 -16.16679 endloop endfacet facet normal 0 0.9877 0.15637 outer loop vertex 25.4 -54.393 9.881 vertex 25.4 -54.491 10.5 vertex 34.616 -54.393 9.881 endloop endfacet facet normal 0 0 1 outer loop vertex 44.19837 -40.43523 19.9 vertex 40.00412 -36.2 19.9 vertex 34.20298 -40.26068 19.9 endloop endfacet facet normal 0 0.89121 0.45359 outer loop vertex 34.616 -54.109 9.323 vertex 25.4 -54.109 9.323 vertex 34.616 -54.393 9.881 endloop endfacet facet normal 0 0 1 outer loop vertex 34.183 -41.399 19.9 vertex 45.15084 -40.70406 19.9 vertex 34.19855 -40.5128 19.9 endloop endfacet facet normal 0 0 1 outer loop vertex 45.182 -41.591 19.9 vertex 45.15084 -40.70406 19.9 vertex 34.183 -41.399 19.9 endloop endfacet facet normal 0 0.70711 -0.70711 outer loop vertex 34.616 -54.109 11.677 vertex 25.4 -54.109 11.677 vertex 34.616 -53.666 12.12 endloop endfacet facet normal 0 0.70711 -0.70711 outer loop vertex 25.4 -53.666 12.12 vertex 34.616 -53.666 12.12 vertex 25.4 -54.109 11.677 endloop endfacet facet normal 0 0.89121 -0.45359 outer loop vertex 25.4 -54.109 11.677 vertex 34.616 -54.109 11.677 vertex 25.4 -54.393 11.119 endloop endfacet facet normal -0.01725 -0.98758 0.15616 outer loop vertex 34.019 -45.096 15.21 vertex 45.071 -45.289 15.21 vertex 45.075 -45.059 16.665 endloop endfacet facet normal 0 0.9877 -0.15637 outer loop vertex 34.616 -54.491 10.5 vertex 25.4 -54.491 10.5 vertex 25.4 -54.393 11.119 endloop endfacet facet normal -0.01556 -0.89084 0.45404 outer loop vertex 34.035 -44.197 17.978 vertex 34.023 -44.866 16.665 vertex 45.075 -45.059 16.665 endloop endfacet facet normal -0.01556 -0.89085 0.45404 outer loop vertex 34.035 -44.197 17.978 vertex 45.075 -45.059 16.665 vertex 45.086 -44.39 17.978 endloop endfacet facet normal -0.01234 -0.7066 0.7075 outer loop vertex 45.086 -44.39 17.978 vertex 45.105 -43.347 19.02 vertex 34.053 -43.154 19.02 endloop endfacet facet normal 0 -0.45295 -0.89154 outer loop vertex 25.4 -51.87 12.404 vertex 25.539 -51.788 12.36234 vertex 30.72 -51.87 12.404 endloop endfacet facet normal 0 -0.15818 -0.98741 outer loop vertex 25.4 -51.87 12.404 vertex 30.72 -51.87 12.404 vertex 25.4 -52.488 12.503 endloop endfacet facet normal -0.98774 0.04043 -0.1508 outer loop vertex 53.941 4.97056 -2.26607 vertex 53.941 8.06241 -1.43714 vertex 53.96081 5.003 -2.38713 endloop endfacet facet normal -0.98775 0.04041 -0.1507 outer loop vertex 53.96081 5.003 -2.38713 vertex 53.98688 8.13752 -1.71749 vertex 54.002 5.0705 -2.639 endloop endfacet facet normal 0.15642 0.25577 -0.954 outer loop vertex 52.366 4.7631 -1.49193 vertex 52.366 7.85499 -0.66298 vertex 52.752 4.74728 -1.43288 endloop endfacet facet normal -0.15603 -0.25569 0.95408 outer loop vertex 33.58934 8.91988 -17.00297 vertex 33.42434 12.01764 -16.19975 vertex 33.25 8.93375 -17.05474 endloop endfacet facet normal -0.15603 -0.25569 0.95408 outer loop vertex 33.25 12.02477 -16.22635 vertex 33.25 8.93375 -17.05474 vertex 33.42434 12.01764 -16.19975 endloop endfacet facet normal 0.45248 0.23093 -0.86136 outer loop vertex 52.017 4.80894 -1.66297 vertex 52.017 7.90082 -0.83403 vertex 52.366 4.7631 -1.49193 endloop endfacet facet normal 0.45248 0.23093 -0.86136 outer loop vertex 52.366 7.85499 -0.66298 vertex 52.366 4.7631 -1.49193 vertex 52.017 7.90082 -0.83403 endloop endfacet facet normal 0.70779 0.18293 -0.68232 outer loop vertex 51.741 4.88052 -1.93008 vertex 51.741 7.97239 -1.10114 vertex 52.017 4.80894 -1.66297 endloop endfacet facet normal 0 0.9877 0.15637 outer loop vertex 34.0626 -42.591 15.3 vertex 45.11796 -42.591 15.3 vertex 34.06285 -42.57675 15.21 endloop endfacet facet normal -0.45391 -0.23077 0.86064 outer loop vertex 33.637 12.00881 -16.16679 vertex 33.637 8.9179 -16.99558 vertex 33.79425 11.98808 -16.08941 endloop endfacet facet normal -0.45248 -0.23088 0.86137 outer loop vertex 33.79425 11.98808 -16.08941 vertex 33.94306 8.87754 -16.84498 vertex 33.986 11.9629 -15.99543 endloop endfacet facet normal 0 0.9877 -0.15637 outer loop vertex 45.11963 -42.493 15.919 vertex 45.11944 -42.50613 15.83607 vertex 34.06431 -42.493 15.919 endloop endfacet facet normal -0.45248 0.23093 -0.86136 outer loop vertex 53.138 7.85499 -0.66298 vertex 53.487 7.90082 -0.83403 vertex 53.138 4.7631 -1.49193 endloop endfacet facet normal -0.70652 -0.18322 0.68357 outer loop vertex 33.986 11.9629 -15.99543 vertex 33.986 8.8719 -16.82394 vertex 34.1108 11.93066 -15.87509 endloop endfacet facet normal -0.15642 0.25577 -0.954 outer loop vertex 52.752 4.74728 -1.43288 vertex 53.138 7.85499 -0.66298 vertex 53.138 4.7631 -1.49193 endloop endfacet facet normal -0.89073 -0.11774 0.43903 outer loop vertex 34.441 8.71 -16.21979 vertex 34.441 11.80093 -15.39088 vertex 34.263 11.8912 -15.72781 endloop endfacet facet normal 0 0.70711 -0.70711 outer loop vertex 34.07 -42.17571 16.51029 vertex 34.07707 -41.766 16.92 vertex 34.16879 -42.209 16.477 endloop endfacet facet normal -0.98742 -0.04096 0.15274 outer loop vertex 34.46894 11.75579 -15.22239 vertex 34.441 11.80093 -15.39088 vertex 34.441 8.71 -16.21979 endloop endfacet facet normal 0 0.89121 -0.45359 outer loop vertex 34.0694 -42.209 16.477 vertex 34.16879 -42.209 16.477 vertex 34.06431 -42.493 15.919 endloop endfacet facet normal -0.98736 -0.04104 0.15312 outer loop vertex 34.46894 11.75579 -15.22239 vertex 34.49537 8.62211 -15.89185 vertex 34.503 11.70088 -15.01744 endloop endfacet facet normal 0 -0.9877 0.15637 outer loop vertex 34.13232 -38.586 15.3 vertex 34.13206 -38.60025 15.21 vertex 45.23417 -38.586 15.3 endloop endfacet facet normal -0.98736 0.04104 -0.15312 outer loop vertex 34.47507 11.65585 -14.84938 vertex 34.503 11.70088 -15.01744 vertex 34.503 8.60981 -15.84596 endloop endfacet facet normal -0.45444 -0.23067 0.86039 outer loop vertex 53.487 5.33204 -3.61494 vertex 53.487 8.42381 -2.78603 vertex 53.138 8.46988 -2.95801 endloop endfacet facet normal -0.98742 0.04096 -0.15274 outer loop vertex 34.47507 11.65585 -14.84938 vertex 34.44863 8.52215 -15.51884 vertex 34.441 11.6008 -14.64391 endloop endfacet facet normal -0.70618 -0.18335 0.68388 outer loop vertex 53.67405 5.28375 -3.43474 vertex 53.55569 8.40608 -2.71986 vertex 53.487 5.33204 -3.61494 endloop endfacet facet normal -0.89073 0.11772 -0.43903 outer loop vertex 34.263 8.41947 -15.13569 vertex 34.263 11.5105 -14.30687 vertex 34.28491 8.43059 -15.17717 endloop endfacet facet normal -0.70528 -0.18352 0.68477 outer loop vertex 53.764 5.26059 -3.3483 vertex 53.764 8.35244 -2.51968 vertex 53.67405 5.28375 -3.43474 endloop endfacet facet normal -0.89086 0.11767 -0.43877 outer loop vertex 34.441 11.6008 -14.64391 vertex 34.441 8.50982 -15.47284 vertex 34.36081 11.5601 -14.492 endloop endfacet facet normal -0.89086 0.11767 -0.43877 outer loop vertex 34.28491 8.43059 -15.17717 vertex 34.36081 11.5601 -14.492 vertex 34.441 8.50982 -15.47284 endloop endfacet facet normal 0 -0.89056 -0.45486 outer loop vertex 34.13068 -38.684 15.919 vertex 45.23247 -38.684 15.919 vertex 34.12746 -38.88013 16.30301 endloop endfacet facet normal -0.89176 -0.11718 0.43708 outer loop vertex 53.941 5.17042 -3.01184 vertex 53.941 8.26222 -2.18292 vertex 53.8835 5.19975 -3.12129 endloop endfacet facet normal 0 -0.70711 -0.70711 outer loop vertex 34.1258 -38.969 16.477 vertex 45.21983 -39.412 16.92 vertex 34.12057 -39.25577 16.76377 endloop endfacet facet normal -0.89139 -0.11733 0.43779 outer loop vertex 53.764 8.35244 -2.51968 vertex 53.764 5.26059 -3.3483 vertex 53.80787 8.33011 -2.43633 endloop endfacet facet normal -0.89139 -0.11733 0.43779 outer loop vertex 53.8835 5.19975 -3.12129 vertex 53.80787 8.33011 -2.43633 vertex 53.764 5.26059 -3.3483 endloop endfacet facet normal 0 -0.45359 -0.89121 outer loop vertex 34.11798 -39.412 16.92 vertex 45.21014 -39.97 17.204 vertex 34.11198 -39.76991 17.10216 endloop endfacet facet normal 0 -0.15793 -0.98745 outer loop vertex 45.21014 -39.97 17.204 vertex 45.1994 -40.589 17.303 vertex 34.10841 -39.97 17.204 endloop endfacet facet normal 0 -0.15793 -0.98745 outer loop vertex 34.101 -40.385 17.27037 vertex 34.10841 -39.97 17.204 vertex 45.1994 -40.589 17.303 endloop endfacet facet normal 0.15603 0.25573 -0.95408 outer loop vertex 33.25 11.37695 -13.80842 vertex 33.25 8.28582 -14.63696 vertex 32.863 11.39277 -13.86747 endloop endfacet facet normal 0 0.15793 -0.98745 outer loop vertex 34.08682 -41.208 17.204 vertex 34.08972 -41.04183 17.23058 vertex 43.008 -41.208 17.204 endloop endfacet facet normal 0 0.15793 -0.98745 outer loop vertex 45.1994 -40.589 17.303 vertex 43.008 -41.208 17.204 vertex 34.0975 -40.589 17.303 endloop endfacet facet normal 0.45444 0.23062 -0.86041 outer loop vertex 32.863 8.30164 -14.69601 vertex 32.514 11.43885 -14.03945 vertex 32.863 11.39277 -13.86747 endloop endfacet facet normal -0.89073 0.11772 -0.43903 outer loop vertex 34.36081 11.5601 -14.492 vertex 34.28491 8.43059 -15.17717 vertex 34.263 11.5105 -14.30687 endloop endfacet facet normal 0 0.45359 -0.89121 outer loop vertex 34.08682 -41.208 17.204 vertex 43.008 -41.208 17.204 vertex 34.07881 -41.6651 16.97135 endloop endfacet facet normal -0.70652 0.18322 -0.68357 outer loop vertex 34.13818 11.47817 -14.1862 vertex 34.02007 8.35653 -14.90084 vertex 33.986 11.43885 -14.03945 endloop endfacet facet normal 0.15642 0.25577 -0.954 outer loop vertex 52.752 4.74728 -1.43288 vertex 52.366 7.85499 -0.66298 vertex 52.752 7.83917 -0.60393 endloop endfacet facet normal -0.70742 0.18305 -0.68268 outer loop vertex 34.263 8.41947 -15.13569 vertex 34.13818 11.47817 -14.1862 vertex 34.263 11.5105 -14.30687 endloop endfacet facet normal -0.45444 0.23062 -0.86041 outer loop vertex 33.637 11.39277 -13.86747 vertex 33.986 11.43885 -14.03945 vertex 33.637 8.30164 -14.69601 endloop endfacet facet normal -0.45444 0.23062 -0.86041 outer loop vertex 33.986 8.34773 -14.86798 vertex 33.637 8.30164 -14.69601 vertex 33.986 11.43885 -14.03945 endloop endfacet facet normal -0.15603 0.25573 -0.95408 outer loop vertex 33.637 8.30164 -14.69601 vertex 33.25 8.28582 -14.63696 vertex 33.637 11.39277 -13.86747 endloop endfacet facet normal -0.98775 -0.04041 0.1507 outer loop vertex 54.002 8.1623 -1.80997 vertex 53.98219 5.10296 -2.76013 vertex 54.002 5.0705 -2.639 endloop endfacet facet normal -0.98774 0.04043 -0.1508 outer loop vertex 53.98688 8.13752 -1.71749 vertex 53.96081 5.003 -2.38713 vertex 53.941 8.06241 -1.43714 endloop endfacet facet normal 0 0.15669 0.98765 outer loop vertex 34.539 -52.37394 15 vertex 25.539 -52.37394 15 vertex 25.539 -52.5 15.02 endloop endfacet facet normal 0 0.15669 0.98765 outer loop vertex 34.539 -52.37394 15 vertex 25.539 -52.5 15.02 vertex 34.539 -52.5 15.02 endloop endfacet facet normal -0.98775 0.04041 -0.1507 outer loop vertex 54.002 5.0705 -2.639 vertex 53.98688 8.13752 -1.71749 vertex 54.002 8.1623 -1.80997 endloop endfacet facet normal 0 -0.15669 0.98765 outer loop vertex 25.539 -52.5 15.02 vertex 25.539 -52.62606 15 vertex 34.539 -52.62606 15 endloop endfacet facet normal 0 -0.15669 0.98765 outer loop vertex 25.539 -52.5 15.02 vertex 34.539 -52.62606 15 vertex 34.539 -52.5 15.02 endloop endfacet facet normal -0.89125 0.11744 -0.43804 outer loop vertex 53.764 4.88052 -1.93008 vertex 53.764 7.97239 -1.10114 vertex 53.941 8.06241 -1.43714 endloop endfacet facet normal -0.89125 0.11744 -0.43804 outer loop vertex 53.764 4.88052 -1.93008 vertex 53.941 8.06241 -1.43714 vertex 53.941 4.97056 -2.26607 endloop endfacet facet normal 0 0 1 outer loop vertex 25.4 -57 15 vertex 25.539 -52.62606 15 vertex 25.4 -51.788 15 endloop endfacet facet normal 0 0 1 outer loop vertex 34.539 -52.62606 15 vertex 25.539 -52.62606 15 vertex 34.616 -57 15 endloop endfacet facet normal 0 0 1 outer loop vertex 25.539 -52.62606 15 vertex 25.539 -52.37394 15 vertex 25.4 -51.788 15 endloop endfacet facet normal -0.70652 0.18326 -0.68356 outer loop vertex 53.764 4.88052 -1.93008 vertex 53.487 4.80894 -1.66297 vertex 53.764 7.97239 -1.10114 endloop endfacet facet normal -0.70652 0.18326 -0.68356 outer loop vertex 53.487 7.90082 -0.83403 vertex 53.764 7.97239 -1.10114 vertex 53.487 4.80894 -1.66297 endloop endfacet facet normal 0 0 1 outer loop vertex 34.616 -51.788 15 vertex 34.539 -52.37394 15 vertex 34.539 -52.62606 15 endloop endfacet facet normal 0 0 1 outer loop vertex 34.616 -51.788 15 vertex 34.539 -52.62606 15 vertex 34.616 -57 15 endloop endfacet facet normal -0.45248 0.23093 -0.86136 outer loop vertex 53.487 4.80894 -1.66297 vertex 53.138 4.7631 -1.49193 vertex 53.487 7.90082 -0.83403 endloop endfacet facet normal 0 0 1 outer loop vertex 34.539 -52.37394 15 vertex 34.616 -51.788 15 vertex 25.539 -52.37394 15 endloop endfacet facet normal 0 0 1 outer loop vertex 25.4 -51.788 15 vertex 25.539 -52.37394 15 vertex 34.616 -51.788 15 endloop endfacet facet normal -0.15642 0.25577 -0.954 outer loop vertex 52.752 4.74728 -1.43288 vertex 52.752 7.83917 -0.60393 vertex 53.138 7.85499 -0.66298 endloop endfacet facet normal 0.70656 -0.18325 0.68352 outer loop vertex 51.80941 8.37017 -2.58583 vertex 51.92736 5.30887 -3.52849 vertex 52.017 8.42381 -2.78603 endloop endfacet facet normal 0.45444 -0.23067 0.86039 outer loop vertex 52.017 5.33204 -3.61494 vertex 52.366 8.46988 -2.95801 vertex 52.017 8.42381 -2.78603 endloop endfacet facet normal 0 0 1 outer loop vertex 25.4 -57 15 vertex 34.616 -57 15 vertex 25.539 -52.62606 15 endloop endfacet facet normal -1 0 0 outer loop vertex 26.6 -33.2 20 vertex 26.6 -33.2 -58 vertex 26.6 -36.2 20 endloop endfacet facet normal 0 1 0 outer loop vertex 26.6 -33.2 -58 vertex 26.6 -33.2 20 vertex 27.1 -33.2 0 endloop endfacet facet normal -1 0 0 outer loop vertex 27.1 8 0 vertex 27.1 -3.2 0 vertex 27.1 -3.2 20 endloop endfacet facet normal -0.70618 -0.18335 0.68388 outer loop vertex 53.487 8.42381 -2.78603 vertex 53.487 5.33204 -3.61494 vertex 53.55569 8.40608 -2.71986 endloop endfacet facet normal -0.70528 -0.18352 0.68477 outer loop vertex 53.55569 8.40608 -2.71986 vertex 53.67405 5.28375 -3.43474 vertex 53.764 8.35244 -2.51968 endloop endfacet facet normal -0.89176 -0.11718 0.43708 outer loop vertex 53.80787 8.33011 -2.43633 vertex 53.8835 5.19975 -3.12129 vertex 53.941 8.26222 -2.18292 endloop endfacet facet normal 0 -1 0 outer loop vertex 26.6 -36.2 20 vertex 31.06376 -36.2 -10.48639 vertex 34.27425 -36.2 10.5 endloop endfacet facet normal 0 -1 0 outer loop vertex 31.06376 -36.2 -10.48639 vertex 37.337 -36.2 -9.635 vertex 37.735 -36.2 -8.855 endloop endfacet facet normal -0.70652 0.18326 -0.68356 outer loop vertex 33.487 4.80894 -1.66297 vertex 33.487 7.90082 -0.83403 vertex 33.764 7.97239 -1.10114 endloop endfacet facet normal -0.45248 0.23093 -0.86136 outer loop vertex 33.138 4.7631 -1.49193 vertex 33.138 7.85499 -0.66298 vertex 33.487 7.90082 -0.83403 endloop endfacet facet normal -0.45248 0.23093 -0.86136 outer loop vertex 33.487 4.80894 -1.66297 vertex 33.138 4.7631 -1.49193 vertex 33.487 7.90082 -0.83403 endloop endfacet facet normal -0.15642 0.25577 -0.954 outer loop vertex 33.138 7.85499 -0.66298 vertex 33.138 4.7631 -1.49193 vertex 32.752 4.74728 -1.43288 endloop endfacet facet normal -0.15642 0.25577 -0.954 outer loop vertex 33.138 7.85499 -0.66298 vertex 32.752 4.74728 -1.43288 vertex 32.752 7.83917 -0.60393 endloop endfacet facet normal -0.98774 -0.04043 0.1508 outer loop vertex 53.98219 5.10296 -2.76013 vertex 53.95612 8.23746 -2.0905 vertex 53.941 5.17042 -3.01184 endloop endfacet facet normal -0.98774 -0.04043 0.1508 outer loop vertex 53.941 8.26222 -2.18292 vertex 53.941 5.17042 -3.01184 vertex 53.95612 8.23746 -2.0905 endloop endfacet facet normal -0.15642 -0.25577 0.954 outer loop vertex 32.752 5.39395 -3.84597 vertex 33.138 5.37813 -3.78692 vertex 32.752 8.4857 -3.01706 endloop endfacet facet normal -0.15642 -0.25577 0.954 outer loop vertex 33.138 8.46988 -2.95801 vertex 32.752 8.4857 -3.01706 vertex 33.138 5.37813 -3.78692 endloop endfacet facet normal -0.98775 -0.04041 0.1507 outer loop vertex 53.95612 8.23746 -2.0905 vertex 53.98219 5.10296 -2.76013 vertex 54.002 8.1623 -1.80997 endloop endfacet facet normal -0.45444 -0.23067 0.86039 outer loop vertex 33.138 5.37813 -3.78692 vertex 33.487 5.33204 -3.61494 vertex 33.138 8.46988 -2.95801 endloop endfacet facet normal 0 1 0 outer loop vertex 32.8 8 3.01941 vertex 27.1 8 0 vertex 27.1 8 20 endloop endfacet facet normal -0.70618 -0.18335 0.68388 outer loop vertex 33.487 8.42381 -2.78603 vertex 33.487 5.33204 -3.61494 vertex 33.55569 8.40608 -2.71986 endloop endfacet facet normal 0.70652 -0.18331 0.68354 outer loop vertex 51.86177 11.92337 -15.84787 vertex 51.97988 8.86299 -16.79067 vertex 52.014 11.9627 -15.99467 endloop endfacet facet normal -0.70528 -0.18352 0.68477 outer loop vertex 33.55569 8.40608 -2.71986 vertex 33.67405 5.28375 -3.43474 vertex 33.764 8.35244 -2.51968 endloop endfacet facet normal 0 1 0 outer loop vertex 30.25132 -0.802 -0.16196 vertex 29.097 -0.802 -0.17512 vertex 30.37071 -0.802 0 endloop endfacet facet normal 0.70742 -0.18301 0.68269 outer loop vertex 51.97988 8.86299 -16.79067 vertex 51.86177 11.92337 -15.84787 vertex 51.737 8.80006 -16.55586 endloop endfacet facet normal -0.89176 -0.11718 0.43708 outer loop vertex 33.80787 8.33011 -2.43633 vertex 33.8835 5.19975 -3.12129 vertex 33.941 8.26222 -2.18292 endloop endfacet facet normal 0.45248 -0.23099 0.86134 outer loop vertex 52.32002 8.91199 -16.97355 vertex 52.17121 11.98334 -16.07172 vertex 52.014 8.8718 -16.82357 endloop endfacet facet normal -1 0 0 outer loop vertex 32.8 21.5208 2.02456 vertex 32.8 8 19.80394 vertex 32.8 22.60546 1.94475 endloop endfacet facet normal -1 0 0 outer loop vertex 32.8 22.60546 1.94475 vertex 32.8 8 19.80394 vertex 32.8 26.19 1.681 endloop endfacet facet normal 0.15603 -0.25585 0.95404 outer loop vertex 52.70234 8.93177 -17.04733 vertex 52.75 8.93371 -17.0546 vertex 52.75 12.0246 -16.2257 endloop endfacet facet normal 0.15843 -0.25563 0.95371 outer loop vertex 52.363 12.00867 -16.16623 vertex 52.363 8.91767 -16.99473 vertex 52.53732 12.0159 -16.19325 endloop endfacet facet normal -0.98774 -0.04043 0.1508 outer loop vertex 33.98219 5.10296 -2.76013 vertex 33.95612 8.23746 -2.0905 vertex 33.941 5.17042 -3.01184 endloop endfacet facet normal -0.98774 -0.04043 0.1508 outer loop vertex 33.941 8.26222 -2.18292 vertex 33.941 5.17042 -3.01184 vertex 33.95612 8.23746 -2.0905 endloop endfacet facet normal -0.98775 -0.04041 0.1507 outer loop vertex 33.98219 5.10296 -2.76013 vertex 34.002 8.1623 -1.80997 vertex 33.95612 8.23746 -2.0905 endloop endfacet facet normal -1 0 0 outer loop vertex 32.8 22.603 1.874 vertex 32.8 21.5208 2.02456 vertex 32.8 22.60546 1.94475 endloop endfacet facet normal -1 0 0 outer loop vertex 32.8 8 3.01941 vertex 32.8 8 19.80394 vertex 32.8 21.5208 2.02456 endloop endfacet facet normal -0.15843 -0.25575 0.95367 outer loop vertex 53.08934 8.91962 -17.002 vertex 52.92433 12.01736 -16.19868 vertex 52.75 8.93371 -17.0546 endloop endfacet facet normal 0 0.70786 0.70635 outer loop vertex 37.8 8.01 19.9 vertex 37.8 26.19 1.681 vertex 32.8 8.01 19.9 endloop endfacet facet normal -0.15603 -0.25573 0.95408 outer loop vertex 53.137 8.91767 -16.99473 vertex 53.137 12.00867 -16.16623 vertex 53.08934 8.91962 -17.002 endloop endfacet facet normal -0.45444 -0.23073 0.86038 outer loop vertex 53.486 11.9627 -15.99467 vertex 53.44302 8.87748 -16.84475 vertex 53.486 8.8718 -16.82357 endloop endfacet facet normal -0.45248 -0.23088 0.86137 outer loop vertex 53.137 12.00867 -16.16623 vertex 53.137 8.91767 -16.99473 vertex 53.2942 11.98802 -16.08918 endloop endfacet facet normal -0.70742 -0.18308 0.68267 outer loop vertex 53.72891 8.80887 -16.58874 vertex 53.61079 11.93038 -15.87403 vertex 53.486 8.8718 -16.82357 endloop endfacet facet normal 0 1 0 outer loop vertex 27.1 -33.2 0 vertex 26.6 -33.2 20 vertex 36.966 -33.2 2.453 endloop endfacet facet normal 0 -1 0 outer loop vertex 36.966 -36.2 0.721 vertex 36.829 -36.2 1.587 vertex 31.06376 -36.2 -10.48639 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 42.78952 20.77058 2.12893 vertex 42.392 20.83382 2.12013 vertex 46.1 22.603 1.874 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 42.32306 20.8227 2.12168 vertex 37.8 22.603 1.874 vertex 42.392 20.83382 2.12013 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 41.925 20.75938 2.13049 vertex 37.8 22.603 1.874 vertex 42.32306 20.8227 2.12168 endloop endfacet facet normal 0 1 0 outer loop vertex 37.8 8 3.01941 vertex 46.9 8 3.01932 vertex 27.1 8 0 endloop endfacet facet normal 0 1 0 outer loop vertex 32.8 8 3.01941 vertex 37.8 8 3.01941 vertex 27.1 8 0 endloop endfacet facet normal -0.89125 0.11744 -0.43804 outer loop vertex 33.941 4.97056 -2.26607 vertex 33.764 4.88052 -1.93008 vertex 33.941 8.06241 -1.43714 endloop endfacet facet normal -0.89125 0.11744 -0.43804 outer loop vertex 33.764 7.97239 -1.10114 vertex 33.941 8.06241 -1.43714 vertex 33.764 4.88052 -1.93008 endloop endfacet facet normal 0 -0.07338 -0.9973 outer loop vertex 32.8 21.5208 2.02456 vertex 37.8 8 3.01941 vertex 32.8 8 3.01941 endloop endfacet facet normal -0.70652 0.18326 -0.68356 outer loop vertex 33.764 4.88052 -1.93008 vertex 33.487 4.80894 -1.66297 vertex 33.764 7.97239 -1.10114 endloop endfacet facet normal 0 1 0 outer loop vertex 30.37071 -0.802 0 vertex 29.097 -0.802 20 vertex 34.616 -0.802 0 endloop endfacet facet normal 0 0.9877 -0.15637 outer loop vertex 34.06424 -42.49669 15.89568 vertex 34.06431 -42.493 15.919 vertex 45.11944 -42.50613 15.83607 endloop endfacet facet normal -0.45444 -0.23067 0.86039 outer loop vertex 33.487 8.42381 -2.78603 vertex 33.138 8.46988 -2.95801 vertex 33.487 5.33204 -3.61494 endloop endfacet facet normal 0 0.45359 -0.89121 outer loop vertex 34.07707 -41.766 16.92 vertex 34.07881 -41.6651 16.97135 vertex 43.008 -41.208 17.204 endloop endfacet facet normal -0.70618 -0.18335 0.68388 outer loop vertex 33.67405 5.28375 -3.43474 vertex 33.55569 8.40608 -2.71986 vertex 33.487 5.33204 -3.61494 endloop endfacet facet normal -0.70528 -0.18352 0.68477 outer loop vertex 33.764 8.35244 -2.51968 vertex 33.67405 5.28375 -3.43474 vertex 33.764 5.26059 -3.3483 endloop endfacet facet normal 0 0.70711 -0.70711 outer loop vertex 45.13241 -41.766 16.92 vertex 34.16879 -42.209 16.477 vertex 34.07707 -41.766 16.92 endloop endfacet facet normal -0.89176 -0.11718 0.43708 outer loop vertex 33.941 5.17042 -3.01184 vertex 33.941 8.26222 -2.18292 vertex 33.8835 5.19975 -3.12129 endloop endfacet facet normal -0.89139 -0.11733 0.43779 outer loop vertex 33.764 8.35244 -2.51968 vertex 33.764 5.26059 -3.3483 vertex 33.80787 8.33011 -2.43633 endloop endfacet facet normal 0 0.9877 0.15637 outer loop vertex 34.06431 -42.493 14.681 vertex 34.06285 -42.57675 15.21 vertex 45.11821 -42.57675 15.21 endloop endfacet facet normal -0.89139 -0.11733 0.43779 outer loop vertex 33.8835 5.19975 -3.12129 vertex 33.80787 8.33011 -2.43633 vertex 33.764 5.26059 -3.3483 endloop endfacet facet normal 0 0.89121 0.45359 outer loop vertex 45.12437 -42.209 14.123 vertex 34.06937 -42.209 14.123 vertex 45.12037 -42.45247 14.60135 endloop endfacet facet normal 0 0.89121 0.45359 outer loop vertex 34.06937 -42.209 14.123 vertex 34.06549 -42.42509 14.54757 vertex 45.12037 -42.45247 14.60135 endloop endfacet facet normal -0.98775 -0.04041 0.1507 outer loop vertex 33.98219 5.10296 -2.76013 vertex 34.002 5.0705 -2.639 vertex 34.002 8.1623 -1.80997 endloop endfacet facet normal -0.98774 0.04043 -0.1508 outer loop vertex 33.941 4.97056 -2.26607 vertex 33.941 8.06241 -1.43714 vertex 33.96081 5.003 -2.38713 endloop endfacet facet normal 0 0.9877 -0.15637 outer loop vertex 45.11796 -42.591 15.3 vertex 34.0626 -42.591 15.3 vertex 45.11944 -42.50613 15.83607 endloop endfacet facet normal -0.98774 0.04043 -0.1508 outer loop vertex 33.96081 5.003 -2.38713 vertex 33.941 8.06241 -1.43714 vertex 33.98688 8.13752 -1.71749 endloop endfacet facet normal -0.98775 0.04041 -0.1507 outer loop vertex 33.96081 5.003 -2.38713 vertex 33.98688 8.13752 -1.71749 vertex 34.002 5.0705 -2.639 endloop endfacet facet normal -0.98775 0.04041 -0.1507 outer loop vertex 34.002 8.1623 -1.80997 vertex 34.002 5.0705 -2.639 vertex 33.98688 8.13752 -1.71749 endloop endfacet facet normal 0 0.89121 -0.45359 outer loop vertex 34.06431 -42.493 15.919 vertex 34.16879 -42.209 16.477 vertex 45.11963 -42.493 15.919 endloop endfacet facet normal 0 0 -1 outer loop vertex 58.2 -3.2 0 vertex 58.18832 -0.78834 0 vertex 58.2 8 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 58.18832 -0.78834 0 vertex 58.02918 7.60273 0 vertex 58.2 8 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 58.02918 7.60273 0 vertex 56.1422 7.57173 0 vertex 58.2 8 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 58.01508 -0.79136 0 vertex 58.2 -3.2 0 vertex 55.33844 -0.84055 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 27.1 -3.2 0 vertex 34.616 -0.802 0 vertex 58.2 -3.2 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 55.2 6.45898 0 vertex 55.27692 2.403 0 vertex 55.2 4.36328 0 endloop endfacet facet normal -0.01745 -0.99985 0 outer loop vertex 45.182 -41.591 17.00907 vertex 45.182 -41.591 19.9 vertex 45.13562 -41.59019 18.32374 endloop endfacet facet normal -0.01745 -0.99985 0 outer loop vertex 45.13549 -41.59019 17.00948 vertex 45.182 -41.591 17.00907 vertex 45.13562 -41.59019 18.32374 endloop endfacet facet normal -0.01745 -0.99985 0 outer loop vertex 45.13562 -41.59019 18.32374 vertex 45.182 -41.591 19.9 vertex 45.13562 -41.59019 19.75941 endloop endfacet facet normal 0 0 -1 outer loop vertex 55.2 7.55657 0 vertex 55.2 7.67736 0 vertex 56.1422 7.57173 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 58.2 8 0 vertex 56.1422 7.57173 0 vertex 55.2 7.67736 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 58.18832 -0.78834 0 vertex 58.2 -3.2 0 vertex 58.01508 -0.79136 0 endloop endfacet facet normal -0.01745 -0.99985 0 outer loop vertex 45.182 -41.591 19.9 vertex 34.183 -41.399 19.9 vertex 45.13562 -41.59019 19.75941 endloop endfacet facet normal 0 0 -1 outer loop vertex 55.3377 -0.802 0 vertex 55.33844 -0.84055 0 vertex 34.616 -0.802 0 endloop endfacet facet normal -0.01745 -0.99985 0 outer loop vertex 34.183 -41.399 19.7594 vertex 45.13562 -41.59019 19.75941 vertex 34.183 -41.399 19.9 endloop endfacet facet normal 0 -0.15637 0.9877 outer loop vertex 45.21014 -39.97 13.396 vertex 34.10841 -39.97 13.396 vertex 45.1994 -40.589 13.298 endloop endfacet facet normal 0 -0.89056 0.45486 outer loop vertex 34.13062 -38.684 14.681 vertex 34.13044 -38.69427 14.66089 vertex 45.23247 -38.684 14.681 endloop endfacet facet normal 0 0 -1 outer loop vertex 27.52565 -1.10702 0 vertex 30.32389 -1.05663 0 vertex 27.1 -3.2 0 endloop endfacet facet normal 0 -0.45359 -0.89121 outer loop vertex 34.10841 -39.97 17.204 vertex 34.11198 -39.76991 17.10216 vertex 45.21014 -39.97 17.204 endloop endfacet facet normal 0 0 -1 outer loop vertex 30.32389 -1.05663 0 vertex 30.37554 -1.05573 0 vertex 27.1 -3.2 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 30.2 7.67736 0 vertex 27.36013 7.59525 0 vertex 27.1 8 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 30.2 7.64091 0 vertex 27.36013 7.59525 0 vertex 30.2 7.67736 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 58.2 8 0 vertex 46.1 7.67736 0 vertex 27.1 8 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 27.36013 7.59525 0 vertex 27.52565 -1.10702 0 vertex 27.1 8 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 27.1 -3.2 0 vertex 27.1 8 0 vertex 27.52565 -1.10702 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 30.37071 -0.802 0 vertex 34.616 -0.802 0 vertex 30.37554 -1.05573 0 endloop endfacet facet normal 0 -0.9877 -0.15637 outer loop vertex 34.13068 -38.684 15.919 vertex 34.13103 -38.66043 15.7701 vertex 45.23247 -38.684 15.919 endloop endfacet facet normal 0 0 -1 outer loop vertex 27.1 -3.2 0 vertex 30.37554 -1.05573 0 vertex 34.616 -0.802 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 30.27247 4.36328 0 vertex 34.002 4.36328 0 vertex 30.30975 2.403 0 endloop endfacet facet normal 0 -0.89056 -0.45486 outer loop vertex 45.23247 -38.684 15.919 vertex 45.22752 -38.969 16.477 vertex 34.12746 -38.88013 16.30301 endloop endfacet facet normal 0 -0.70711 -0.70711 outer loop vertex 34.11798 -39.412 16.92 vertex 34.12057 -39.25577 16.76377 vertex 45.21983 -39.412 16.92 endloop endfacet facet normal 0 -0.45359 -0.89121 outer loop vertex 34.11798 -39.412 16.92 vertex 45.21983 -39.412 16.92 vertex 45.21014 -39.97 17.204 endloop endfacet facet normal 0 0 -1 outer loop vertex 30.2 7.67736 0 vertex 27.1 8 0 vertex 46.1 7.67736 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 55.33844 -0.84055 0 vertex 58.2 -3.2 0 vertex 34.616 -0.802 0 endloop endfacet facet normal 0 0.45359 -0.89121 outer loop vertex 45.13241 -41.766 16.92 vertex 34.07707 -41.766 16.92 vertex 43.008 -41.208 17.204 endloop endfacet facet normal 0 -0.9877 0.15637 outer loop vertex 45.937 -50.486 10.5 vertex 54.937 -50.584 9.881 vertex 54.937 -50.486 10.5 endloop endfacet facet normal 0 -0.9877 -0.15637 outer loop vertex 54.937 -50.486 10.5 vertex 45.937 -50.584 11.119 vertex 45.937 -50.486 10.5 endloop endfacet facet normal 0 0 -1 outer loop vertex 30.30975 2.403 0 vertex 34.002 4.36328 0 vertex 55.27692 2.403 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 58.2 8 0 vertex 55.2 7.67736 0 vertex 46.1 7.67736 0 endloop endfacet facet normal 0 -0.89121 0.45359 outer loop vertex 45.937 -50.868 9.323 vertex 54.937 -50.868 9.323 vertex 54.937 -50.584 9.881 endloop endfacet facet normal 0 -0.70711 -0.70711 outer loop vertex 54.937 -51.311 12.12 vertex 45.937 -51.311 12.12 vertex 54.937 -50.868 11.677 endloop endfacet facet normal 0 -0.70711 0.70711 outer loop vertex 54.937 -50.868 9.323 vertex 45.937 -50.868 9.323 vertex 54.937 -51.311 8.88 endloop endfacet facet normal 0 0 -1 outer loop vertex 55.2 4.36328 0 vertex 55.27692 2.403 0 vertex 34.002 4.36328 0 endloop endfacet facet normal 0 -0.70711 -0.70711 outer loop vertex 34.1258 -38.969 16.477 vertex 45.22752 -38.969 16.477 vertex 45.21983 -39.412 16.92 endloop endfacet facet normal 0 0 -1 outer loop vertex 20.1 -60 0 vertex 20.1 -57 0 vertex 61 -60 0 endloop endfacet facet normal 0 -0.9877 -0.15637 outer loop vertex 54.937 -50.584 11.119 vertex 45.937 -50.584 11.119 vertex 54.937 -50.486 10.5 endloop endfacet facet normal 0 -0.89121 -0.45359 outer loop vertex 54.937 -50.868 11.677 vertex 45.937 -50.584 11.119 vertex 54.937 -50.584 11.119 endloop endfacet facet normal 0 0 -1 outer loop vertex 61 -57 0 vertex 61 -60 0 vertex 20.1 -57 0 endloop endfacet facet normal 0 0.15793 -0.98745 outer loop vertex 45.18865 -41.208 17.204 vertex 43.008 -41.208 17.204 vertex 45.1994 -40.589 17.303 endloop endfacet facet normal 0 0.45359 -0.89121 outer loop vertex 45.18865 -41.208 17.204 vertex 45.13549 -41.59019 17.00948 vertex 43.008 -41.208 17.204 endloop endfacet facet normal 0 -0.45359 0.89121 outer loop vertex 45.21983 -39.412 13.68 vertex 34.11792 -39.412 13.68 vertex 45.21014 -39.97 13.396 endloop endfacet facet normal 0.15538 0.25579 -0.95416 outer loop vertex 52.57563 11.38408 -13.83503 vertex 52.4106 8.29969 -14.68874 vertex 52.363 11.39274 -13.86733 endloop endfacet facet normal 0 1 0 outer loop vertex 54.821 -51.7 15 vertex 54.821 -51.7 14.85944 vertex 46.1 -51.7 14.85944 endloop endfacet facet normal 0 1 0 outer loop vertex 54.821 -51.7 15 vertex 46.1 -51.7 14.85944 vertex 46.1 -51.7 15 endloop endfacet facet normal 0.45444 0.23065 -0.8604 outer loop vertex 52.014 8.34772 -14.86795 vertex 52.014 11.43882 -14.03931 vertex 52.363 8.30163 -14.69598 endloop endfacet facet normal 0 1 0 outer loop vertex 54.821 -51.7 5.6 vertex 46.1 -51.7 5.6 vertex 54.821 -51.7 5.76056 endloop endfacet facet normal 0 1 0 outer loop vertex 46.1 -51.7 5.76056 vertex 54.821 -51.7 5.76056 vertex 46.1 -51.7 5.6 endloop endfacet facet normal 0 -0.89056 -0.45486 outer loop vertex 34.1258 -38.969 16.477 vertex 34.12746 -38.88013 16.30301 vertex 45.22752 -38.969 16.477 endloop endfacet facet normal 0.70742 -0.18301 0.68269 outer loop vertex 51.737 11.89105 -15.72725 vertex 51.737 8.80006 -16.55586 vertex 51.86177 11.92337 -15.84787 endloop endfacet facet normal -0.70652 -0.18325 0.68356 outer loop vertex 53.61079 11.93038 -15.87403 vertex 53.72891 8.80887 -16.58874 vertex 53.763 11.89105 -15.72725 endloop endfacet facet normal 0 0.45359 -0.89121 outer loop vertex 45.182 -41.591 17.00907 vertex 45.13549 -41.59019 17.00948 vertex 45.18865 -41.208 17.204 endloop endfacet facet normal -0.89073 -0.1177 0.43904 outer loop vertex 53.941 11.80078 -15.39032 vertex 53.763 11.89105 -15.72725 vertex 53.941 8.70977 -16.21894 endloop endfacet facet normal 0 0.45295 -0.89154 outer loop vertex 34.616 -53.666 12.12 vertex 25.4 -53.666 12.12 vertex 25.4 -53.107 12.404 endloop endfacet facet normal 0 -1 0 outer loop vertex 41.735 -3.2 9.135 vertex 40.955 -3.2 9.533 vertex 27.1 -3.2 0 endloop endfacet facet normal -0.98775 -0.0404 0.1507 outer loop vertex 53.941 8.70977 -16.21894 vertex 54.002 8.60981 -15.84593 vertex 53.941 11.80078 -15.39032 endloop endfacet facet normal -0.98775 -0.0404 0.1507 outer loop vertex 54.002 11.70084 -15.0173 vertex 53.941 11.80078 -15.39032 vertex 54.002 8.60981 -15.84593 endloop endfacet facet normal -0.98781 0.0403 -0.15034 outer loop vertex 53.941 8.50959 -15.47199 vertex 53.941 11.60065 -14.64335 vertex 54.002 11.70084 -15.0173 endloop endfacet facet normal -0.98781 0.0403 -0.15034 outer loop vertex 53.941 8.50959 -15.47199 vertex 54.002 11.70084 -15.0173 vertex 54.002 8.60981 -15.84593 endloop endfacet facet normal 0 -1 0 outer loop vertex 27.1 -3.2 20 vertex 27.1 -3.2 0 vertex 39.8 -3.2 11.799 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.335 -3.2 10.152 vertex 39.937 -3.2 10.933 vertex 27.1 -3.2 0 endloop endfacet facet normal 0 0.15793 0.98745 outer loop vertex 25.4 -52.488 8.497 vertex 25.4 -53.107 8.596 vertex 34.616 -52.488 8.497 endloop endfacet facet normal -0.89086 0.11763 -0.43878 outer loop vertex 53.78491 8.43036 -15.17632 vertex 53.86082 11.55996 -14.49146 vertex 53.941 8.50959 -15.47199 endloop endfacet facet normal 0 -0.15818 0.98741 outer loop vertex 25.4 -52.488 8.497 vertex 34.616 -52.488 8.497 vertex 30.72 -51.87 8.596 endloop endfacet facet normal -0.70618 0.18331 -0.68389 outer loop vertex 53.6382 11.47814 -14.18608 vertex 53.763 8.41924 -15.13485 vertex 53.52008 8.35653 -14.90081 endloop endfacet facet normal -0.70652 0.18325 -0.68356 outer loop vertex 53.486 8.34772 -14.86795 vertex 53.486 11.43882 -14.03931 vertex 53.52008 8.35653 -14.90081 endloop endfacet facet normal 0 -0.45295 -0.89154 outer loop vertex 25.539 -51.788 12.36234 vertex 25.539 -51.311 12.12 vertex 30.72 -51.87 12.404 endloop endfacet facet normal 0 -1 0 outer loop vertex 58.2 -3.2 20 vertex 45.402 -3.2 11.799 vertex 58.2 -3.2 0 endloop endfacet facet normal -0.45444 0.23065 -0.8604 outer loop vertex 53.137 11.39274 -13.86733 vertex 53.486 11.43882 -14.03931 vertex 53.137 8.30163 -14.69598 endloop endfacet facet normal 0 -1 0 outer loop vertex 45.265 -3.2 10.933 vertex 44.867 -3.2 10.152 vertex 58.2 -3.2 0 endloop endfacet facet normal 0 0.45295 -0.89154 outer loop vertex 25.4 -53.107 12.404 vertex 34.616 -53.107 12.404 vertex 34.616 -53.666 12.12 endloop endfacet facet normal 0.15603 0.25573 -0.95408 outer loop vertex 52.4106 8.29969 -14.68874 vertex 52.57563 11.38408 -13.83503 vertex 52.75 8.28582 -14.63696 endloop endfacet facet normal 0.15603 0.25573 -0.95408 outer loop vertex 52.75 11.37695 -13.80842 vertex 52.75 8.28582 -14.63696 vertex 52.57563 11.38408 -13.83503 endloop endfacet facet normal 0.15538 0.25579 -0.95416 outer loop vertex 52.363 8.30163 -14.69598 vertex 52.363 11.39274 -13.86733 vertex 52.4106 8.29969 -14.68874 endloop endfacet facet normal 0 -1 0 outer loop vertex 43.467 -3.2 9.135 vertex 42.601 -3.2 8.998 vertex 58.2 -3.2 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 44.867 -3.2 10.152 vertex 44.248 -3.2 9.533 vertex 58.2 -3.2 0 endloop endfacet facet normal 0 0.70711 0.70711 outer loop vertex 34.616 -53.666 8.88 vertex 25.4 -53.666 8.88 vertex 34.616 -54.109 9.323 endloop endfacet facet normal 0 0.45295 0.89154 outer loop vertex 34.616 -53.107 8.596 vertex 25.4 -53.107 8.596 vertex 34.616 -53.666 8.88 endloop endfacet facet normal -0.15538 0.25575 -0.95417 outer loop vertex 52.75 8.28582 -14.63696 vertex 52.75 11.37695 -13.80842 vertex 52.79762 8.28775 -14.64419 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 42.78952 20.77058 2.12893 vertex 46.1 22.603 1.874 vertex 42.859 20.75938 2.13049 endloop endfacet facet normal -0.15603 0.25576 -0.95407 outer loop vertex 52.79762 8.28775 -14.64419 vertex 52.96266 11.38561 -13.84073 vertex 53.137 8.30163 -14.69598 endloop endfacet facet normal 0 0.89121 -0.45359 outer loop vertex 25.4 -54.393 11.119 vertex 34.616 -54.109 11.677 vertex 34.616 -54.393 11.119 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 46.1 22.603 1.874 vertex 42.392 20.83382 2.12013 vertex 37.8 22.603 1.874 endloop endfacet facet normal 0 0.9877 -0.15637 outer loop vertex 25.4 -54.393 11.119 vertex 34.616 -54.393 11.119 vertex 34.616 -54.491 10.5 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 46.9 21.60559 2.01276 vertex 46.9 8 3.9056 vertex 43.828 18.83489 2.39823 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 46.9 21.60559 2.01276 vertex 43.902 19.30637 2.33263 vertex 43.88871 19.39119 2.32083 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 43.28 20.54247 2.16067 vertex 42.859 20.75938 2.13049 vertex 46.1 22.603 1.874 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 43.28 20.54247 2.16067 vertex 46.1 22.603 1.874 vertex 43.614 20.20472 2.20765 endloop endfacet facet normal 0 0.45295 0.89154 outer loop vertex 25.4 -53.666 8.88 vertex 34.616 -53.666 8.88 vertex 25.4 -53.107 8.596 endloop endfacet facet normal 0 0.15793 0.98745 outer loop vertex 34.616 -52.488 8.497 vertex 25.4 -53.107 8.596 vertex 34.616 -53.107 8.596 endloop endfacet facet normal 0.70652 -0.18331 0.68354 outer loop vertex 52.014 8.8718 -16.82357 vertex 52.014 11.9627 -15.99467 vertex 51.97988 8.86299 -16.79067 endloop endfacet facet normal 0 -0.15818 0.98741 outer loop vertex 34.616 -51.87 8.596 vertex 30.72 -51.87 8.596 vertex 34.616 -52.488 8.497 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 40.956 19.77882 2.26691 vertex 37.8 21.5208 2.02456 vertex 41.17 20.20472 2.20765 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 40.89557 19.21993 2.34466 vertex 37.8 21.5208 2.02456 vertex 40.882 19.30637 2.33263 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 37.8 22.603 1.874 vertex 41.17 20.20472 2.20765 vertex 37.8 21.5208 2.02456 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 37.8 22.603 1.874 vertex 37.8 21.5208 2.02456 vertex 32.8 21.5208 2.02456 endloop endfacet facet normal 0 -0.45295 0.89154 outer loop vertex 34.539 -51.788 8.63766 vertex 30.72 -51.87 8.596 vertex 34.616 -51.87 8.596 endloop endfacet facet normal 0 -0.45295 0.89154 outer loop vertex 34.616 -51.788 8.63766 vertex 34.539 -51.788 8.63766 vertex 34.616 -51.87 8.596 endloop endfacet facet normal 0.45248 -0.23099 0.86134 outer loop vertex 52.014 11.9627 -15.99467 vertex 52.014 8.8718 -16.82357 vertex 52.17121 11.98334 -16.07172 endloop endfacet facet normal 0.45444 -0.23062 0.86041 outer loop vertex 52.363 8.91767 -16.99473 vertex 52.363 12.00867 -16.16623 vertex 52.32002 8.91199 -16.97355 endloop endfacet facet normal 0.45444 -0.23062 0.86041 outer loop vertex 52.17121 11.98334 -16.07172 vertex 52.32002 8.91199 -16.97355 vertex 52.363 12.00867 -16.16623 endloop endfacet facet normal 0 -0.45295 -0.89154 outer loop vertex 30.72 -51.87 12.404 vertex 34.539 -51.788 12.36234 vertex 34.616 -51.87 12.404 endloop endfacet facet normal 0 -0.45295 -0.89154 outer loop vertex 34.616 -51.788 12.36234 vertex 34.616 -51.87 12.404 vertex 34.539 -51.788 12.36234 endloop endfacet facet normal 0.15603 -0.25585 0.95404 outer loop vertex 52.53732 12.0159 -16.19325 vertex 52.70234 8.93177 -17.04733 vertex 52.75 12.0246 -16.2257 endloop endfacet facet normal 0 -0.15818 -0.98741 outer loop vertex 30.72 -51.87 12.404 vertex 34.616 -51.87 12.404 vertex 34.616 -52.488 12.503 endloop endfacet facet normal 0 -0.15818 -0.98741 outer loop vertex 25.4 -52.488 12.503 vertex 30.72 -51.87 12.404 vertex 34.616 -52.488 12.503 endloop endfacet facet normal 0.99985 -0.01736 0 outer loop vertex 45.182 -41.591 13.59093 vertex 45.182 -41.591 10.5 vertex 45.18865 -41.208 13.396 endloop endfacet facet normal 0 0.15793 -0.98745 outer loop vertex 34.616 -52.488 12.503 vertex 34.616 -53.107 12.404 vertex 25.4 -52.488 12.503 endloop endfacet facet normal 0 0.15793 -0.98745 outer loop vertex 25.4 -53.107 12.404 vertex 25.4 -52.488 12.503 vertex 34.616 -53.107 12.404 endloop endfacet facet normal 0.99985 -0.01736 0 outer loop vertex 45.1994 -40.589 13.298 vertex 45.182 -41.591 10.5 vertex 45.21014 -39.97 13.396 endloop endfacet facet normal 0.15843 -0.25563 0.95371 outer loop vertex 52.70234 8.93177 -17.04733 vertex 52.53732 12.0159 -16.19325 vertex 52.363 8.91767 -16.99473 endloop endfacet facet normal -0.15843 -0.25575 0.95367 outer loop vertex 52.75 12.0246 -16.2257 vertex 52.75 8.93371 -17.0546 vertex 52.92433 12.01736 -16.19868 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -48.9 7.542 vertex 45.937 -50.868 9.323 vertex 45.937 -48.231 8.855 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -48.231 8.855 vertex 45.937 -50.584 9.881 vertex 45.937 -48 10.31 endloop endfacet facet normal -0.15603 -0.25573 0.95408 outer loop vertex 53.08934 8.91962 -17.002 vertex 53.137 12.00867 -16.16623 vertex 52.92433 12.01736 -16.19868 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -50.486 10.5 vertex 45.937 -50.584 11.119 vertex 45.937 -48.231 11.765 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -48.231 11.765 vertex 45.937 -48 10.31 vertex 45.937 -50.486 10.5 endloop endfacet facet normal 0.99985 -0.01736 0 outer loop vertex 45.21014 -39.97 13.396 vertex 45.274 -36.292 10.5 vertex 45.21983 -39.412 13.68 endloop endfacet facet normal 0.99985 -0.01736 0 outer loop vertex 45.18865 -41.208 13.396 vertex 45.182 -41.591 10.5 vertex 45.1994 -40.589 13.298 endloop endfacet facet normal 0.99985 -0.01736 0 outer loop vertex 45.274 -36.292 10.5 vertex 45.21014 -39.97 13.396 vertex 45.182 -41.591 10.5 endloop endfacet facet normal -0.45248 -0.23088 0.86137 outer loop vertex 53.44302 8.87748 -16.84475 vertex 53.2942 11.98802 -16.08918 vertex 53.137 8.91767 -16.99473 endloop endfacet facet normal -0.45444 -0.23073 0.86038 outer loop vertex 53.2942 11.98802 -16.08918 vertex 53.44302 8.87748 -16.84475 vertex 53.486 11.9627 -15.99467 endloop endfacet facet normal 0 -1 0 outer loop vertex 41.897 -36.2 3.234 vertex 42.295 -36.2 2.453 vertex 45.22932 -36.2 13.55481 endloop endfacet facet normal 0 0 -1 outer loop vertex 45.274 -36.292 10.5 vertex 45.182 -41.591 10.5 vertex 40.00412 -36.2 10.5 endloop endfacet facet normal 0 0 -1 outer loop vertex 34.20077 -40.38674 10.5 vertex 40.00412 -36.2 10.5 vertex 45.182 -41.591 10.5 endloop endfacet facet normal -0.70742 -0.18308 0.68267 outer loop vertex 53.486 11.9627 -15.99467 vertex 53.486 8.8718 -16.82357 vertex 53.61079 11.93038 -15.87403 endloop endfacet facet normal -0.70652 -0.18325 0.68356 outer loop vertex 53.763 8.80006 -16.55586 vertex 53.763 11.89105 -15.72725 vertex 53.72891 8.80887 -16.58874 endloop endfacet facet normal 0 -1 0 outer loop vertex 52.2 -36.2 -10.48639 vertex 45.22932 -36.2 13.55481 vertex 42.295 -36.2 2.453 endloop endfacet facet normal 0 1 0 outer loop vertex 41.277 -33.2 3.853 vertex 40.496 -33.2 4.251 vertex 52.2 -33.2 20 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -54.109 11.677 vertex 45.937 -54.393 11.119 vertex 45.937 -56.524 13.078 endloop endfacet facet normal -0.89073 -0.1177 0.43904 outer loop vertex 53.763 8.80006 -16.55586 vertex 53.941 8.70977 -16.21894 vertex 53.763 11.89105 -15.72725 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 51.97988 8.86299 -16.79067 vertex 51.737 8.80006 -16.55586 vertex 35.0753 9.443 -18.955 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -54.491 10.5 vertex 45.937 -57 12.14379 vertex 45.937 -54.393 11.119 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -57 12.14379 vertex 45.937 -56.524 13.078 vertex 45.937 -54.393 11.119 endloop endfacet facet normal -0.89073 0.11768 -0.43904 outer loop vertex 53.763 8.41924 -15.13485 vertex 53.763 11.51035 -14.30631 vertex 53.78491 8.43036 -15.17632 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -52.489 8.497 vertex 45.937 -52.712 5.6 vertex 45.937 -53.107 8.596 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -53.107 8.596 vertex 45.937 -54.168 5.831 vertex 45.937 -53.666 8.88 endloop endfacet facet normal -0.89086 0.11763 -0.43878 outer loop vertex 53.941 11.60065 -14.64335 vertex 53.941 8.50959 -15.47199 vertex 53.86082 11.55996 -14.49146 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 51.6832 5.23127 -3.23889 vertex 51.563 5.17042 -3.01184 vertex 33.941 5.17042 -3.01184 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 52.363 8.30163 -14.69598 vertex 52.017 5.33204 -3.61494 vertex 52.014 8.34772 -14.86795 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 51.741 5.26059 -3.3483 vertex 51.6832 5.23127 -3.23889 vertex 33.941 5.17042 -3.01184 endloop endfacet facet normal -0.70652 0.18325 -0.68356 outer loop vertex 53.6382 11.47814 -14.18608 vertex 53.52008 8.35653 -14.90081 vertex 53.486 11.43882 -14.03931 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -50.486 10.5 vertex 45.937 -48 10.31 vertex 45.937 -50.584 9.881 endloop endfacet facet normal 0.45444 0.23065 -0.8604 outer loop vertex 52.363 11.39274 -13.86733 vertex 52.363 8.30163 -14.69598 vertex 52.014 11.43882 -14.03931 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -50.584 11.119 vertex 45.937 -50.868 11.677 vertex 45.937 -48.9 13.078 endloop endfacet facet normal 0.70618 0.18333 -0.68388 outer loop vertex 52.014 8.34772 -14.86795 vertex 51.88922 11.47102 -14.15952 vertex 52.014 11.43882 -14.03931 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -50.868 11.677 vertex 45.937 -51.311 12.12 vertex 45.937 -48.9 13.078 endloop endfacet facet normal -0.89073 0.11768 -0.43904 outer loop vertex 53.86082 11.55996 -14.49146 vertex 53.78491 8.43036 -15.17632 vertex 53.763 11.51035 -14.30631 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -51.256 14.789 vertex 45.937 -49.942 14.12 vertex 45.937 -51.87 12.404 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 35.0753 9.443 -18.955 vertex 52.014 8.8718 -16.82357 vertex 51.97988 8.86299 -16.79067 endloop endfacet facet normal -0.70618 0.18331 -0.68389 outer loop vertex 53.763 11.51035 -14.30631 vertex 53.763 8.41924 -15.13485 vertex 53.6382 11.47814 -14.18608 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -52.489 12.503 vertex 45.937 -51.256 14.789 vertex 45.937 -51.87 12.404 endloop endfacet facet normal -0.45444 0.23065 -0.8604 outer loop vertex 53.486 8.34772 -14.86795 vertex 53.137 8.30163 -14.69598 vertex 53.486 11.43882 -14.03931 endloop endfacet facet normal -0.15538 0.25575 -0.95417 outer loop vertex 52.96266 11.38561 -13.84073 vertex 52.79762 8.28775 -14.64419 vertex 52.75 11.37695 -13.80842 endloop endfacet facet normal -0.15603 0.25576 -0.95407 outer loop vertex 53.137 11.39274 -13.86733 vertex 53.137 8.30163 -14.69598 vertex 52.96266 11.38561 -13.84073 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -56.524 13.078 vertex 45.937 -55.482 14.12 vertex 45.937 -54.109 11.677 endloop endfacet facet normal -0.99982 -0.01896 -0.00193 outer loop vertex 55.3377 -0.802 0 vertex 55.33775 -0.802 -0.0242 vertex 55.33844 -0.84055 0 endloop endfacet facet normal -0.99982 -0.01896 -0.00193 outer loop vertex 55.27692 2.403 0 vertex 55.2 6.45898 0 vertex 55.28085 2.403 -2.0364 endloop endfacet facet normal -0.99982 -0.01896 -0.00193 outer loop vertex 55.2 6.95722 -4.89569 vertex 55.28085 2.403 -2.0364 vertex 55.2 6.45898 0 endloop endfacet facet normal 1 0 0 outer loop vertex 55.2 7.55657 0 vertex 55.2 9.32366 -6.38096 vertex 55.2 7.67736 0 endloop endfacet facet normal 1 0 0 outer loop vertex 55.2 12.534 -18.127 vertex 55.2 7.67736 0 vertex 55.2 9.32366 -6.38096 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 51.92736 5.30887 -3.52849 vertex 52.014 8.34772 -14.86795 vertex 52.017 5.33204 -3.61494 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 51.502 5.0705 -2.639 vertex 51.52181 5.03807 -2.51797 vertex 34.002 4.36328 0 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 52.752 4.74728 -1.43288 vertex 55.2 4.36328 0 vertex 52.366 4.7631 -1.49193 endloop endfacet facet normal -0.0155 0.96361 0.26685 outer loop vertex 55.2 7.55657 0 vertex 56.1422 7.57173 0 vertex 55.2 9.32366 -6.38096 endloop endfacet facet normal -0.0155 0.96361 0.26685 outer loop vertex 58.008 9.368 -6.378 vertex 55.2 9.32366 -6.38096 vertex 56.1422 7.57173 0 endloop endfacet facet normal 1 0 0 outer loop vertex 55.2 9.17432 -6.2872 vertex 55.2 7.74214 -12.60822 vertex 55.2 9.32366 -6.38096 endloop endfacet facet normal 1 0 0 outer loop vertex 55.2 12.534 -18.127 vertex 55.2 9.32366 -6.38096 vertex 55.2 7.74214 -12.60822 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -51.256 14.789 vertex 45.937 -52.489 12.503 vertex 45.937 -52.712 15.02 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -54.168 14.789 vertex 45.937 -52.712 15.02 vertex 45.937 -53.107 12.404 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -53.107 12.404 vertex 45.937 -52.712 15.02 vertex 45.937 -52.489 12.503 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -53.107 12.404 vertex 45.937 -53.666 12.12 vertex 45.937 -54.168 14.789 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 51.58089 8.49849 -15.43054 vertex 51.737 8.41924 -15.13485 vertex 33.764 5.26059 -3.3483 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 51.92736 5.30887 -3.52849 vertex 51.741 5.26059 -3.3483 vertex 52.014 8.34772 -14.86795 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.941 5.17042 -3.01184 vertex 52.014 8.34772 -14.86795 vertex 51.741 5.26059 -3.3483 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 51.7711 8.41043 -15.10197 vertex 52.014 8.34772 -14.86795 vertex 33.941 5.17042 -3.01184 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 51.737 8.41924 -15.13485 vertex 51.7711 8.41043 -15.10197 vertex 33.941 5.17042 -3.01184 endloop endfacet facet normal 0.00929 -0.53167 -0.8469 outer loop vertex 58.008 9.368 -6.378 vertex 55.2 9.17432 -6.2872 vertex 55.2 9.32366 -6.38096 endloop endfacet facet normal -0.01583 0.96363 0.26676 outer loop vertex 58.008 9.368 -6.378 vertex 56.1422 7.57173 0 vertex 58.02918 7.60273 0 endloop endfacet facet normal 1 0 0 outer loop vertex 55.2 7.74214 -12.60822 vertex 55.2 9.443 -18.955 vertex 55.2 12.534 -18.127 endloop endfacet facet normal 1 0 0 outer loop vertex 55.2 6.95722 -4.89569 vertex 55.2 7.74214 -12.60822 vertex 55.2 9.17432 -6.2872 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -50.584 9.881 vertex 45.937 -48.231 8.855 vertex 45.937 -50.868 9.323 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -48.9 13.078 vertex 45.937 -48.231 11.765 vertex 45.937 -50.584 11.119 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -51.311 12.12 vertex 45.937 -51.87 12.404 vertex 45.937 -49.942 14.12 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -48.9 13.078 vertex 45.937 -51.311 12.12 vertex 45.937 -49.942 14.12 endloop endfacet facet normal 0.00977 -0.53157 -0.84696 outer loop vertex 55.33775 -0.802 -0.0242 vertex 56.103 -0.802 -0.01538 vertex 55.33844 -0.84055 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 41.897 -36.2 3.234 vertex 45.22932 -36.2 13.55481 vertex 41.277 -36.2 3.853 endloop endfacet facet normal 0.00977 -0.53157 -0.84696 outer loop vertex 55.28085 2.403 -2.0364 vertex 55.2 6.95722 -4.89569 vertex 56.103 2.403 -2.02692 endloop endfacet facet normal 0.00977 -0.53157 -0.84696 outer loop vertex 55.2 9.17432 -6.2872 vertex 58.01508 -0.79136 0 vertex 55.2 6.95722 -4.89569 endloop endfacet facet normal 0.00977 -0.53157 -0.84696 outer loop vertex 58.01508 -0.79136 0 vertex 55.33844 -0.84055 0 vertex 56.103 -0.802 -0.01538 endloop endfacet facet normal 0.00977 -0.53157 -0.84696 outer loop vertex 58.01508 -0.79136 0 vertex 56.103 -0.802 -0.01538 vertex 56.103 2.403 -2.02692 endloop endfacet facet normal 0.00977 -0.53157 -0.84696 outer loop vertex 56.103 2.403 -2.02692 vertex 55.2 6.95722 -4.89569 vertex 58.01508 -0.79136 0 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -54.168 5.831 vertex 45.937 -55.482 6.5 vertex 45.937 -53.666 8.88 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -49.942 6.5 vertex 45.937 -51.256 5.831 vertex 45.937 -51.87 8.596 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -51.311 8.88 vertex 45.937 -49.942 6.5 vertex 45.937 -51.87 8.596 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -49.942 6.5 vertex 45.937 -51.311 8.88 vertex 45.937 -48.9 7.542 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -50.868 9.323 vertex 45.937 -48.9 7.542 vertex 45.937 -51.311 8.88 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -52.489 8.497 vertex 45.937 -51.87 8.596 vertex 45.937 -51.256 5.831 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -51.256 5.831 vertex 45.937 -52.712 5.6 vertex 45.937 -52.489 8.497 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -54.168 5.831 vertex 45.937 -53.107 8.596 vertex 45.937 -52.712 5.6 endloop endfacet facet normal 0 -1 0 outer loop vertex 41.277 -36.2 3.853 vertex 45.22932 -36.2 13.55481 vertex 40.496 -36.2 4.251 endloop endfacet facet normal 0.00929 -0.53167 -0.8469 outer loop vertex 55.2 9.17432 -6.2872 vertex 58.008 9.368 -6.378 vertex 58.01508 -0.79136 0 endloop endfacet facet normal 0.00929 -0.53167 -0.8469 outer loop vertex 58.18832 -0.78834 0 vertex 58.01508 -0.79136 0 vertex 58.008 9.368 -6.378 endloop endfacet facet normal 0 1 0 outer loop vertex 55.3377 -0.802 0 vertex 56.103 -0.802 20 vertex 56.103 -0.802 -0.01538 endloop endfacet facet normal 0 1 0 outer loop vertex 55.3377 -0.802 0 vertex 56.103 -0.802 -0.01538 vertex 55.33775 -0.802 -0.0242 endloop endfacet facet normal 0 -1 0 outer loop vertex 55.28085 2.403 -2.0364 vertex 56.103 2.403 -2.02692 vertex 55.27692 2.403 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 56.103 2.403 20 vertex 55.27692 2.403 0 vertex 56.103 2.403 -2.02692 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -54.393 9.881 vertex 45.937 -54.109 9.323 vertex 45.937 -57 8.47621 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -56.524 7.542 vertex 45.937 -57 8.47621 vertex 45.937 -54.109 9.323 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -54.109 9.323 vertex 45.937 -53.666 8.88 vertex 45.937 -55.482 6.5 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -55.482 6.5 vertex 45.937 -56.524 7.542 vertex 45.937 -54.109 9.323 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -54.491 10.5 vertex 45.937 -54.393 9.881 vertex 45.937 -57 8.47621 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -57 12.14379 vertex 45.937 -54.491 10.5 vertex 45.937 -57 8.47621 endloop endfacet facet normal -1 0 0 outer loop vertex 56.103 -0.802 -0.01538 vertex 56.103 -0.802 20 vertex 56.103 2.403 20 endloop endfacet facet normal -1 0 0 outer loop vertex 56.103 2.403 -2.02692 vertex 56.103 -0.802 -0.01538 vertex 56.103 2.403 20 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.00412 -36.2 13.37578 vertex 40.00412 -36.2 10.5 vertex 45.22932 -36.2 13.55481 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.00412 -36.2 10.5 vertex 40.496 -36.2 4.251 vertex 45.22932 -36.2 13.55481 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -54.168 14.789 vertex 45.937 -53.666 12.12 vertex 45.937 -55.482 14.12 endloop endfacet facet normal -1 0 0 outer loop vertex 45.937 -53.666 12.12 vertex 45.937 -54.109 11.677 vertex 45.937 -55.482 14.12 endloop endfacet facet normal 0 0.1378 0.99046 outer loop vertex 42.60231 17.91433 5.32779 vertex 42.392 17.88087 5.33245 vertex 46.9 8.051 6.7 endloop endfacet facet normal 0 -1 0 outer loop vertex 44.248 -3.2 9.533 vertex 43.467 -3.2 9.135 vertex 58.2 -3.2 0 endloop endfacet facet normal 0 1 0 outer loop vertex 52.2 -33.2 -58 vertex 51.8 -33.2 -30.37797 vertex 52.2 -33.2 20 endloop endfacet facet normal 0 1 0 outer loop vertex 46.9 8 3.01932 vertex 37.8 8 3.01941 vertex 46.9 8 3.9056 endloop endfacet facet normal 0 1 0 outer loop vertex 58.2 8 0 vertex 27.1 8 0 vertex 46.9 8 3.01932 endloop endfacet facet normal 0 -1 0 outer loop vertex 30.30975 2.403 0 vertex 55.27692 2.403 0 vertex 42.601 2.403 8.998 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 46.9 21.60559 2.01276 vertex 43.614 20.20472 2.20765 vertex 46.1 22.603 1.874 endloop endfacet facet normal 0.01746 0.99985 0 outer loop vertex 45.274 -36.292 10.5 vertex 40.00412 -36.2 10.5 vertex 45.22783 -36.29119 13.37583 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 34.002 5.0705 -2.639 vertex 33.98219 5.10296 -2.76013 vertex 51.502 5.0705 -2.639 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 52.017 5.33204 -3.61494 vertex 52.363 8.30163 -14.69598 vertex 52.366 5.37813 -3.78692 endloop endfacet facet normal 0 -0.9994 0.03477 outer loop vertex 46.9 8.051 6.7 vertex 37.8 8.051 6.7 vertex 46.9 8 5.23414 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 34.002 4.36328 0 vertex 52.366 4.7631 -1.49193 vertex 55.2 4.36328 0 endloop endfacet facet normal 0 0.9994 -0.03477 outer loop vertex 37.8 22.603 1.874 vertex 37.8 22.60546 1.94475 vertex 46.1 22.603 1.874 endloop endfacet facet normal 0.01746 0.99985 0 outer loop vertex 40.00412 -36.2 13.37578 vertex 45.22783 -36.29119 13.37583 vertex 40.00412 -36.2 10.5 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 51.741 4.88052 -1.93008 vertex 52.017 4.80894 -1.66297 vertex 34.002 4.36328 0 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 52.017 4.80894 -1.66297 vertex 52.366 4.7631 -1.49193 vertex 34.002 4.36328 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 45.2292 -36.2 15.21 vertex 52.2 -36.2 20 vertex 45.22923 -36.2 16.63187 endloop endfacet facet normal 0 1 0 outer loop vertex 37.8 8 5.23414 vertex 42.601 8 8.998 vertex 46.9 8 5.23414 endloop endfacet facet normal 0 1 0 outer loop vertex 44.867 -0.802 10.152 vertex 55.3377 -0.802 0 vertex 44.248 -0.802 9.533 endloop endfacet facet normal 0 1 0 outer loop vertex 45.265 -0.802 10.933 vertex 55.3377 -0.802 0 vertex 44.867 -0.802 10.152 endloop endfacet facet normal 0.99985 -0.01747 0.0001 outer loop vertex 45.13562 -41.59019 12.09626 vertex 45.13548 -41.59019 13.59052 vertex 45.105 -43.347 11.4 endloop endfacet facet normal 0.99985 -0.01747 0.0001 outer loop vertex 45.13337 -41.71049 13.65175 vertex 45.105 -43.347 11.4 vertex 45.13548 -41.59019 13.59052 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 51.559 8.70977 -16.21894 vertex 35.0753 9.443 -18.955 vertex 51.737 8.80006 -16.55586 endloop endfacet facet normal 0.99985 -0.01747 0.0001 outer loop vertex 45.128 -42.034 10.731 vertex 45.13562 -41.59019 12.09626 vertex 45.105 -43.347 11.4 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 52.014 8.8718 -16.82357 vertex 35.0753 9.443 -18.955 vertex 52.32002 8.91199 -16.97355 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 51.563 5.17042 -3.01184 vertex 51.54319 5.13795 -2.89068 vertex 33.941 5.17042 -3.01184 endloop endfacet facet normal 0 -1 0 outer loop vertex 52.2 -36.2 -10.48639 vertex 52.2 -36.2 20 vertex 45.22932 -36.2 13.55481 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 52.79762 8.28775 -14.64419 vertex 52.366 5.37813 -3.78692 vertex 52.75 8.28582 -14.63696 endloop endfacet facet normal 0 1 0 outer loop vertex 34.616 -0.802 0 vertex 42.601 -0.802 8.998 vertex 55.3377 -0.802 0 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 52.75 8.28582 -14.63696 vertex 52.366 5.37813 -3.78692 vertex 52.4106 8.29969 -14.68874 endloop endfacet facet normal 0 -1 0 outer loop vertex 43.467 2.403 9.135 vertex 55.27692 2.403 0 vertex 44.248 2.403 9.533 endloop endfacet facet normal 0 -1 0 outer loop vertex 43.467 2.403 9.135 vertex 42.601 2.403 8.998 vertex 55.27692 2.403 0 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 52.4106 8.29969 -14.68874 vertex 52.366 5.37813 -3.78692 vertex 52.363 8.30163 -14.69598 endloop endfacet facet normal 0 -0.9994 0.03477 outer loop vertex 46.9 8 5.23414 vertex 37.8 8.051 6.7 vertex 37.8 8 5.23414 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 52.70234 8.93177 -17.04733 vertex 52.363 8.91767 -16.99473 vertex 55.2 9.443 -18.955 endloop endfacet facet normal 0 0.98763 0.1568 outer loop vertex 54.937 -48 10.31 vertex 45.937 -48 10.31 vertex 54.937 -48.231 11.765 endloop endfacet facet normal 0 0.98763 0.1568 outer loop vertex 45.937 -48.231 11.765 vertex 54.937 -48.231 11.765 vertex 45.937 -48 10.31 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 52.752 5.39395 -3.84597 vertex 52.366 5.37813 -3.78692 vertex 55.2 7.74214 -12.60822 endloop endfacet facet normal 0 0.89101 0.45399 outer loop vertex 45.937 -48.9 13.078 vertex 54.937 -48.231 11.765 vertex 45.937 -48.231 11.765 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 51.741 7.97239 -1.10114 vertex 46.1 7.67736 0 vertex 52.017 7.90082 -0.83403 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.137 11.39274 -13.86733 vertex 52.96266 11.38561 -13.84073 vertex 53.138 8.46988 -2.95801 endloop endfacet facet normal 0 0.98763 -0.1568 outer loop vertex 54.937 -48 10.31 vertex 45.937 -48.231 8.855 vertex 45.937 -48 10.31 endloop endfacet facet normal 0.99984 -0.01784 0.00037 outer loop vertex 45.12532 -42.15262 14.06662 vertex 45.086 -44.39 12.442 vertex 45.13237 -41.766 13.68 endloop endfacet facet normal 0 0.70711 0.70711 outer loop vertex 54.937 -49.942 14.12 vertex 45.937 -48.9 13.078 vertex 45.937 -49.942 14.12 endloop endfacet facet normal 0.99984 -0.01784 0.00037 outer loop vertex 45.086 -44.39 12.442 vertex 45.105 -43.347 11.4 vertex 45.13237 -41.766 13.68 endloop endfacet facet normal 0.99984 -0.01784 0.00037 outer loop vertex 45.13337 -41.71049 13.65175 vertex 45.13237 -41.766 13.68 vertex 45.105 -43.347 11.4 endloop endfacet facet normal 0 0.45371 0.89115 outer loop vertex 54.937 -49.942 14.12 vertex 45.937 -49.942 14.12 vertex 45.937 -51.256 14.789 endloop endfacet facet normal 0 0.15669 0.98765 outer loop vertex 46.1 -52.58594 15 vertex 46.1 -51.7 14.85944 vertex 45.937 -52.712 15.02 endloop endfacet facet normal 0 0.15669 0.98765 outer loop vertex 45.937 -51.256 14.789 vertex 45.937 -52.712 15.02 vertex 46.1 -51.7 14.85944 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 52.366 7.85499 -0.66298 vertex 52.017 7.90082 -0.83403 vertex 46.1 7.67736 0 endloop endfacet facet normal 0 -0.15669 0.98765 outer loop vertex 46.1 -54.168 14.789 vertex 46.1 -52.83806 15 vertex 45.937 -54.168 14.789 endloop endfacet facet normal 0 -0.15669 0.98765 outer loop vertex 45.937 -52.712 15.02 vertex 45.937 -54.168 14.789 vertex 46.1 -52.83806 15 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 52.17121 11.98334 -16.07172 vertex 52.363 12.00867 -16.16623 vertex 46.9 12.534 -18.127 endloop endfacet facet normal 0 -0.45371 0.89115 outer loop vertex 46.1 -54.168 14.789 vertex 45.937 -54.168 14.789 vertex 45.937 -55.482 14.12 endloop endfacet facet normal 0 -0.45371 0.89115 outer loop vertex 46.1 -54.168 14.789 vertex 45.937 -55.482 14.12 vertex 46.1 -55.482 14.12 endloop endfacet facet normal 0 -0.70711 0.70711 outer loop vertex 45.937 -55.482 14.12 vertex 45.937 -56.524 13.078 vertex 46.1 -56.524 13.078 endloop endfacet facet normal 0 -0.70711 0.70711 outer loop vertex 45.937 -55.482 14.12 vertex 46.1 -56.524 13.078 vertex 46.1 -55.482 14.12 endloop endfacet facet normal -0.01556 -0.89085 -0.45404 outer loop vertex 45.075 -45.059 13.755 vertex 34.023 -44.866 13.755 vertex 45.086 -44.39 12.442 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 46.9 12.534 -18.127 vertex 51.86177 11.92337 -15.84787 vertex 52.014 11.9627 -15.99467 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 51.737 11.89105 -15.72725 vertex 51.86177 11.92337 -15.84787 vertex 46.9 12.534 -18.127 endloop endfacet facet normal 0 -0.89101 0.45399 outer loop vertex 46.1 -57 12.14379 vertex 46.1 -56.524 13.078 vertex 45.937 -57 12.14379 endloop endfacet facet normal 0 -0.89101 0.45399 outer loop vertex 45.937 -56.524 13.078 vertex 45.937 -57 12.14379 vertex 46.1 -56.524 13.078 endloop endfacet facet normal -0.01725 -0.98758 -0.15616 outer loop vertex 45.071 -45.289 15.21 vertex 34.019 -45.096 15.21 vertex 45.075 -45.059 13.755 endloop endfacet facet normal 0 -0.89101 -0.45399 outer loop vertex 45.937 -56.524 7.542 vertex 46.1 -56.524 7.542 vertex 46.1 -57 8.47621 endloop endfacet facet normal 0 -0.89101 -0.45399 outer loop vertex 45.937 -56.524 7.542 vertex 46.1 -57 8.47621 vertex 45.937 -57 8.47621 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 55.2 12.534 -18.127 vertex 46.9 12.534 -18.127 vertex 52.53732 12.0159 -16.19325 endloop endfacet facet normal 0 -0.70711 -0.70711 outer loop vertex 45.937 -56.524 7.542 vertex 45.937 -55.482 6.5 vertex 46.1 -55.482 6.5 endloop endfacet facet normal 0 -0.70711 -0.70711 outer loop vertex 45.937 -56.524 7.542 vertex 46.1 -55.482 6.5 vertex 46.1 -56.524 7.542 endloop endfacet facet normal 0 0.45359 0.89121 outer loop vertex 45.13237 -41.766 13.68 vertex 45.13337 -41.71049 13.65175 vertex 37.8 -41.766 13.68 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 52.75 12.0246 -16.2257 vertex 55.2 12.534 -18.127 vertex 52.53732 12.0159 -16.19325 endloop endfacet facet normal 0 -0.45371 -0.89115 outer loop vertex 46.1 -55.482 6.5 vertex 45.937 -54.168 5.831 vertex 46.1 -54.168 5.831 endloop endfacet facet normal 0 0.45359 0.89121 outer loop vertex 45.13337 -41.71049 13.65175 vertex 45.13548 -41.59019 13.59052 vertex 37.8 -41.766 13.68 endloop endfacet facet normal 0 -0.45371 -0.89115 outer loop vertex 45.937 -55.482 6.5 vertex 45.937 -54.168 5.831 vertex 46.1 -55.482 6.5 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 51.88922 11.47102 -14.15952 vertex 46.1 7.67736 0 vertex 52.014 11.43882 -14.03931 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 51.737 11.51035 -14.30631 vertex 46.1 7.67736 0 vertex 51.88922 11.47102 -14.15952 endloop endfacet facet normal 0 -0.15669 -0.98765 outer loop vertex 45.937 -54.168 5.831 vertex 45.937 -52.712 5.6 vertex 46.1 -52.712 5.6 endloop endfacet facet normal 0 -0.15669 -0.98765 outer loop vertex 45.937 -54.168 5.831 vertex 46.1 -52.712 5.6 vertex 46.1 -54.168 5.831 endloop endfacet facet normal 0 0.45359 0.89121 outer loop vertex 45.18865 -41.208 13.396 vertex 37.8 -41.766 13.68 vertex 45.13548 -41.59019 13.59052 endloop endfacet facet normal -0.00793 -0.45386 -0.89104 outer loop vertex 34.053 -43.154 11.4 vertex 34.076 -41.841 10.731 vertex 45.105 -43.347 11.4 endloop endfacet facet normal 0 0.15669 -0.98765 outer loop vertex 46.1 -52.712 5.6 vertex 45.937 -52.712 5.6 vertex 46.1 -51.7 5.76056 endloop endfacet facet normal 0 0.15669 -0.98765 outer loop vertex 45.937 -51.256 5.831 vertex 46.1 -51.7 5.76056 vertex 45.937 -52.712 5.6 endloop endfacet facet normal 0 0.45371 -0.89115 outer loop vertex 45.937 -49.942 6.5 vertex 54.937 -49.942 6.5 vertex 45.937 -51.256 5.831 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 51.559 11.60065 -14.64335 vertex 46.1 7.67736 0 vertex 51.6568 11.55105 -14.45823 endloop endfacet facet normal 0 0.70711 -0.70711 outer loop vertex 54.937 -49.942 6.5 vertex 45.937 -49.942 6.5 vertex 45.937 -48.9 7.542 endloop endfacet facet normal -0.01234 -0.70661 -0.7075 outer loop vertex 34.035 -44.197 12.442 vertex 34.053 -43.154 11.4 vertex 45.105 -43.347 11.4 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 53.486 11.43882 -14.03931 vertex 53.137 11.39274 -13.86733 vertex 53.138 8.46988 -2.95801 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 52.92433 12.01736 -16.19868 vertex 55.2 12.534 -18.127 vertex 52.75 12.0246 -16.2257 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 52.014 11.9627 -15.99467 vertex 52.17121 11.98334 -16.07172 vertex 46.9 12.534 -18.127 endloop endfacet facet normal -0.01234 -0.7066 -0.7075 outer loop vertex 45.086 -44.39 12.442 vertex 34.035 -44.197 12.442 vertex 45.105 -43.347 11.4 endloop endfacet facet normal 0.70656 -0.18325 0.68352 outer loop vertex 52.017 5.33204 -3.61494 vertex 52.017 8.42381 -2.78603 vertex 51.92736 5.30887 -3.52849 endloop endfacet facet normal 0.70746 -0.18295 0.68266 outer loop vertex 51.92736 5.30887 -3.52849 vertex 51.80941 8.37017 -2.58583 vertex 51.741 5.26059 -3.3483 endloop endfacet facet normal 0.70779 0.18293 -0.68232 outer loop vertex 52.017 7.90082 -0.83403 vertex 52.017 4.80894 -1.66297 vertex 51.741 7.97239 -1.10114 endloop endfacet facet normal -0.01745 -0.99985 0 outer loop vertex 45.13562 -41.59019 10.66059 vertex 45.182 -41.591 10.5 vertex 45.13562 -41.59019 12.09626 endloop endfacet facet normal -0.01745 -0.99985 0 outer loop vertex 45.182 -41.591 13.59093 vertex 45.13562 -41.59019 12.09626 vertex 45.182 -41.591 10.5 endloop endfacet facet normal 0.70652 0.18322 -0.68357 outer loop vertex 51.737 8.41924 -15.13485 vertex 51.737 11.51035 -14.30631 vertex 51.7711 8.41043 -15.10197 endloop endfacet facet normal -0.01745 -0.99985 0 outer loop vertex 45.182 -41.591 13.59093 vertex 45.13548 -41.59019 13.59052 vertex 45.13562 -41.59019 12.09626 endloop endfacet facet normal 0.70618 0.18333 -0.68388 outer loop vertex 51.88922 11.47102 -14.15952 vertex 52.014 8.34772 -14.86795 vertex 51.7711 8.41043 -15.10197 endloop endfacet facet normal 0 0.15637 0.9877 outer loop vertex 45.1994 -40.589 13.298 vertex 34.0975 -40.589 13.298 vertex 45.18865 -41.208 13.396 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 51.54787 8.08719 -1.52965 vertex 46.1 7.67736 0 vertex 51.563 8.06241 -1.43714 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 51.502 8.1623 -1.80997 vertex 46.1 7.67736 0 vertex 51.54787 8.08719 -1.52965 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 51.563 8.06241 -1.43714 vertex 46.1 7.67736 0 vertex 51.741 7.97239 -1.10114 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 51.51712 8.18705 -1.90237 vertex 51.563 8.26222 -2.18292 vertex 46.1 7.67736 0 endloop endfacet facet normal 0.70652 0.18322 -0.68357 outer loop vertex 51.88922 11.47102 -14.15952 vertex 51.7711 8.41043 -15.10197 vertex 51.737 11.51035 -14.30631 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 51.563 8.26222 -2.18292 vertex 51.60713 8.28455 -2.26628 vertex 46.1 7.67736 0 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 46.1 7.67736 0 vertex 51.60713 8.28455 -2.26628 vertex 51.741 8.35244 -2.51968 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 52.57563 11.38408 -13.83503 vertex 52.363 11.39274 -13.86733 vertex 52.366 8.46988 -2.95801 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 52.75 11.37695 -13.80842 vertex 52.57563 11.38408 -13.83503 vertex 52.752 8.4857 -3.01706 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 52.366 8.46988 -2.95801 vertex 52.752 8.4857 -3.01706 vertex 52.57563 11.38408 -13.83503 endloop endfacet facet normal 0.99982 0.01902 0.00189 outer loop vertex 30.2 8.79181 -6.23478 vertex 30.188 9.465 -6.661 vertex 30.2 8.47575 -3.04825 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 52.752 8.4857 -3.01706 vertex 53.138 8.46988 -2.95801 vertex 52.96266 11.38561 -13.84073 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 52.96266 11.38561 -13.84073 vertex 52.75 11.37695 -13.80842 vertex 52.752 8.4857 -3.01706 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.955 -3.2 14.065 vertex 27.1 -3.2 20 vertex 40.335 -3.2 13.445 endloop endfacet facet normal 0 -1 0 outer loop vertex 41.735 -3.2 14.463 vertex 42.601 -3.2 14.6 vertex 27.1 -3.2 20 endloop endfacet facet normal -0.99982 -0.01902 -0.00189 outer loop vertex 27.36013 7.59525 0 vertex 27.338 9.42 -6.664 vertex 27.52565 -1.10702 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 58.2 -3.2 20 vertex 27.1 -3.2 20 vertex 42.601 -3.2 14.6 endloop endfacet facet normal 0 -1 0 outer loop vertex 40.955 -3.2 14.065 vertex 41.735 -3.2 14.463 vertex 27.1 -3.2 20 endloop endfacet facet normal -0.0155 0.96437 0.26412 outer loop vertex 30.188 9.465 -6.661 vertex 27.338 9.42 -6.664 vertex 30.2 8.47575 -3.04825 endloop endfacet facet normal -0.0155 0.96437 0.26412 outer loop vertex 27.36013 7.59525 0 vertex 30.2 8.47575 -3.04825 vertex 27.338 9.42 -6.664 endloop endfacet facet normal -0.0155 0.96437 0.26412 outer loop vertex 30.2 7.64091 0 vertex 30.2 8.47575 -3.04825 vertex 27.36013 7.59525 0 endloop endfacet facet normal 0 0.89121 -0.45359 outer loop vertex 45.937 -54.109 11.677 vertex 54.937 -54.109 11.677 vertex 54.937 -54.393 11.119 endloop endfacet facet normal 0.00963 -0.53473 -0.84497 outer loop vertex 29.33788 2.403 -2.20061 vertex 29.097 2.403 -2.20335 vertex 27.338 9.42 -6.664 endloop endfacet facet normal 0.00963 -0.53473 -0.84497 outer loop vertex 29.097 -0.802 -0.17512 vertex 27.52565 -1.10702 0 vertex 29.097 2.403 -2.20335 endloop endfacet facet normal 0.00963 -0.53473 -0.84497 outer loop vertex 27.338 9.42 -6.664 vertex 29.097 2.403 -2.20335 vertex 27.52565 -1.10702 0 endloop endfacet facet normal 1 0 0 outer loop vertex 29.097 -0.802 20 vertex 29.097 -0.802 -0.17512 vertex 29.097 2.403 20 endloop endfacet facet normal 0.00933 -0.53479 -0.84493 outer loop vertex 30.2592 5.47062 -4.13203 vertex 30.31388 2.403 -2.18983 vertex 30.2 5.47083 -4.13282 endloop endfacet facet normal 0.00933 -0.53479 -0.84493 outer loop vertex 30.2 8.79181 -6.23478 vertex 30.2 5.47083 -4.13282 vertex 27.338 9.42 -6.664 endloop endfacet facet normal 0.00933 -0.53479 -0.84493 outer loop vertex 30.188 9.465 -6.661 vertex 30.2 8.79181 -6.23478 vertex 27.338 9.42 -6.664 endloop endfacet facet normal 0 -1 0 outer loop vertex 29.33788 2.403 -2.20061 vertex 30.30975 2.403 0 vertex 29.097 2.403 -2.20335 endloop endfacet facet normal 1 0 0 outer loop vertex 29.097 2.403 -2.20335 vertex 29.097 2.403 20 vertex 29.097 -0.802 -0.17512 endloop endfacet facet normal -1 0 0 outer loop vertex 30.2 9.443 -18.955 vertex 30.2 8.79181 -6.23478 vertex 30.2 12.534 -18.127 endloop endfacet facet normal -1 0 0 outer loop vertex 30.2 8.79181 -6.23478 vertex 30.2 8.47575 -3.04825 vertex 30.2 12.534 -18.127 endloop endfacet facet normal -1 0 0 outer loop vertex 30.2 7.67736 0 vertex 30.2 12.534 -18.127 vertex 30.2 8.47575 -3.04825 endloop endfacet facet normal -1 0 0 outer loop vertex 30.2 8.47575 -3.04825 vertex 30.2 7.64091 0 vertex 30.2 7.67736 0 endloop endfacet facet normal -1 0 0 outer loop vertex 30.2 5.47083 -4.13282 vertex 30.2 8.79181 -6.23478 vertex 30.2 9.443 -18.955 endloop endfacet facet normal 0 -0.45295 -0.89154 outer loop vertex 45.937 -51.311 12.12 vertex 54.937 -51.311 12.12 vertex 54.937 -51.87 12.404 endloop endfacet facet normal 0.99982 0.01902 0.00189 outer loop vertex 30.37554 -1.05573 0 vertex 30.37101 -0.802 -0.16064 vertex 30.37071 -0.802 0 endloop endfacet facet normal 0 0.89121 -0.45359 outer loop vertex 45.937 -54.109 11.677 vertex 54.937 -54.393 11.119 vertex 45.937 -54.393 11.119 endloop endfacet facet normal 0.99982 0.01902 0.00189 outer loop vertex 30.30975 2.403 0 vertex 30.31388 2.403 -2.18983 vertex 30.27247 4.36328 0 endloop endfacet facet normal 0 0.9877 -0.15637 outer loop vertex 54.937 -54.393 11.119 vertex 45.937 -54.491 10.5 vertex 45.937 -54.393 11.119 endloop endfacet facet normal 0.00963 -0.53473 -0.84497 outer loop vertex 30.25132 -0.802 -0.16196 vertex 30.32389 -1.05663 0 vertex 29.097 -0.802 -0.17512 endloop endfacet facet normal 0.00963 -0.53473 -0.84497 outer loop vertex 27.52565 -1.10702 0 vertex 29.097 -0.802 -0.17512 vertex 30.32389 -1.05663 0 endloop endfacet facet normal 0 0.45295 0.89154 outer loop vertex 54.937 -53.107 8.596 vertex 45.937 -53.107 8.596 vertex 45.937 -53.666 8.88 endloop endfacet facet normal 0 1 0 outer loop vertex 29.097 -0.802 20 vertex 30.37071 -0.802 0 vertex 29.097 -0.802 -0.17512 endloop endfacet facet normal 0 0.89121 0.45359 outer loop vertex 45.937 -54.393 9.881 vertex 54.937 -54.109 9.323 vertex 45.937 -54.109 9.323 endloop endfacet facet normal 0.00933 -0.53479 -0.84493 outer loop vertex 30.25132 -0.802 -0.16196 vertex 30.37101 -0.802 -0.16064 vertex 30.32389 -1.05663 0 endloop endfacet facet normal 0.00933 -0.53479 -0.84493 outer loop vertex 30.37554 -1.05573 0 vertex 30.32389 -1.05663 0 vertex 30.37101 -0.802 -0.16064 endloop endfacet facet normal 0 0.15818 0.98741 outer loop vertex 45.937 -53.107 8.596 vertex 54.937 -53.107 8.596 vertex 45.937 -52.489 8.497 endloop endfacet facet normal 0 1 0 outer loop vertex 30.37101 -0.802 -0.16064 vertex 30.25132 -0.802 -0.16196 vertex 30.37071 -0.802 0 endloop endfacet facet normal 0 0.70711 0.70711 outer loop vertex 45.937 -54.109 9.323 vertex 54.937 -54.109 9.323 vertex 45.937 -53.666 8.88 endloop endfacet facet normal 0 -1 0 outer loop vertex 29.097 2.403 20 vertex 29.097 2.403 -2.20335 vertex 30.30975 2.403 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 30.30975 2.403 0 vertex 29.33788 2.403 -2.20061 vertex 30.31388 2.403 -2.18983 endloop endfacet facet normal 0 1 0 outer loop vertex 27.1 -33.2 0 vertex 37.298 -33.2 -36.501 vertex 26.6 -33.2 -58 endloop endfacet facet normal 0 -0.45295 0.89154 outer loop vertex 54.937 -51.311 8.88 vertex 45.937 -51.311 8.88 vertex 45.937 -51.87 8.596 endloop endfacet facet normal 0 0.25875 -0.96594 outer loop vertex 35.0753 9.443 -18.955 vertex 30.2 9.443 -18.955 vertex 30.2 12.534 -18.127 endloop endfacet facet normal 0 0.25875 -0.96594 outer loop vertex 46.9 12.534 -18.127 vertex 35.0753 9.443 -18.955 vertex 30.2 12.534 -18.127 endloop endfacet facet normal 0 -0.70711 0.70711 outer loop vertex 54.937 -51.311 8.88 vertex 45.937 -50.868 9.323 vertex 45.937 -51.311 8.88 endloop endfacet facet normal 0 -0.89121 0.45359 outer loop vertex 54.937 -50.584 9.881 vertex 45.937 -50.584 9.881 vertex 45.937 -50.868 9.323 endloop endfacet facet normal 0 -0.1378 -0.99046 outer loop vertex 32.8 22.603 1.874 vertex 37.8 22.603 1.874 vertex 32.8 21.5208 2.02456 endloop endfacet facet normal 0 -1 0 outer loop vertex 31.06376 -36.2 -10.48639 vertex 26.6 -36.2 -58 vertex 34.019 -36.2 -31.18159 endloop endfacet facet normal 0 -0.9877 0.15637 outer loop vertex 45.937 -50.584 9.881 vertex 54.937 -50.584 9.881 vertex 45.937 -50.486 10.5 endloop endfacet facet normal 0.99982 0.01902 0.00189 outer loop vertex 30.2592 5.47062 -4.13203 vertex 30.27247 4.36328 0 vertex 30.31388 2.403 -2.18983 endloop endfacet facet normal 0 -1 0 outer loop vertex 37.735 -36.2 -8.855 vertex 37.984 -36.2 -0.679 vertex 31.06376 -36.2 -10.48639 endloop endfacet facet normal 0 -1 0 outer loop vertex 26.6 -36.2 20 vertex 26.6 -36.2 -58 vertex 31.06376 -36.2 -10.48639 endloop endfacet facet normal 0.00933 -0.53479 -0.84493 outer loop vertex 30.31388 2.403 -2.18983 vertex 29.33788 2.403 -2.20061 vertex 30.2 5.47083 -4.13282 endloop endfacet facet normal 0.00933 -0.53479 -0.84493 outer loop vertex 27.338 9.42 -6.664 vertex 30.2 5.47083 -4.13282 vertex 29.33788 2.403 -2.20061 endloop endfacet facet normal 0 -0.89121 -0.45359 outer loop vertex 54.937 -50.868 11.677 vertex 45.937 -50.868 11.677 vertex 45.937 -50.584 11.119 endloop endfacet facet normal 0 -0.07338 -0.9973 outer loop vertex 37.8 22.60546 1.94475 vertex 32.8 22.60546 1.94475 vertex 37.8 26.19 1.681 endloop endfacet facet normal 0 -0.07338 -0.9973 outer loop vertex 32.8 26.19 1.681 vertex 37.8 26.19 1.681 vertex 32.8 22.60546 1.94475 endloop endfacet facet normal 0 0.70786 0.70635 outer loop vertex 32.8 26.19 1.681 vertex 32.8 8.01 19.9 vertex 37.8 26.19 1.681 endloop endfacet facet normal 0 -0.70711 -0.70711 outer loop vertex 45.937 -51.311 12.12 vertex 45.937 -50.868 11.677 vertex 54.937 -50.868 11.677 endloop endfacet facet normal 0 0.9994 -0.03477 outer loop vertex 32.8 22.60546 1.94475 vertex 37.8 22.60546 1.94475 vertex 37.8 22.603 1.874 endloop endfacet facet normal 0 0.9994 -0.03477 outer loop vertex 32.8 22.60546 1.94475 vertex 37.8 22.603 1.874 vertex 32.8 22.603 1.874 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 32.47992 8.86306 -16.79096 vertex 32.237 8.80029 -16.55671 vertex 30.2 9.443 -18.955 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 32.514 8.8719 -16.82394 vertex 32.47992 8.86306 -16.79096 vertex 30.2 9.443 -18.955 endloop endfacet facet normal 0 -0.45295 -0.89154 outer loop vertex 45.937 -51.87 12.404 vertex 45.937 -51.311 12.12 vertex 54.937 -51.87 12.404 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 32.514 8.8719 -16.82394 vertex 30.2 9.443 -18.955 vertex 32.82001 8.91225 -16.97451 endloop endfacet facet normal 0 -0.15793 -0.98745 outer loop vertex 45.937 -51.87 12.404 vertex 54.937 -51.87 12.404 vertex 45.937 -52.489 12.503 endloop endfacet facet normal 0 0 -1 outer loop vertex 34.616 -51.788 5.6 vertex 25.4 -57 5.6 vertex 25.4 -51.788 5.6 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 32.863 8.30164 -14.69601 vertex 34.503 7.394 -11.30915 vertex 30.2 5.47083 -4.13282 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 32.514 8.34773 -14.86798 vertex 32.863 8.30164 -14.69601 vertex 30.2 5.47083 -4.13282 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 32.237 8.41947 -15.13569 vertex 32.2711 8.41066 -15.10281 vertex 30.2 5.47083 -4.13282 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 32.2711 8.41066 -15.10281 vertex 32.514 8.34773 -14.86798 vertex 30.2 5.47083 -4.13282 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 32.0809 8.49871 -15.43139 vertex 32.237 8.41947 -15.13569 vertex 30.2 5.47083 -4.13282 endloop endfacet facet normal -1 0 0 outer loop vertex 46.1 -51.7 15 vertex 46.1 -51.7 14.85944 vertex 46.1 -52.58594 15 endloop endfacet facet normal 0 0 -1 outer loop vertex 34.616 -57 5.6 vertex 25.4 -57 5.6 vertex 34.616 -51.788 5.6 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 32.059 8.50982 -15.47284 vertex 32.0809 8.49871 -15.43139 vertex 30.2 5.47083 -4.13282 endloop endfacet facet normal -1 0 0 outer loop vertex 25.539 -50.584 9.881 vertex 25.539 -50.486 10.5 vertex 25.539 -47.788 10.31 endloop endfacet facet normal -1 0 0 outer loop vertex 25.539 -50.868 9.323 vertex 25.539 -50.584 9.881 vertex 25.539 -48.019 8.855 endloop endfacet facet normal -1 0 0 outer loop vertex 25.539 -48.019 8.855 vertex 25.539 -48.688 7.542 vertex 25.539 -50.868 9.323 endloop endfacet facet normal -1 0 0 outer loop vertex 25.539 -49.73 6.5 vertex 25.539 -51.311 8.88 vertex 25.539 -48.688 7.542 endloop endfacet facet normal -1 0 0 outer loop vertex 46.1 -52.712 5.6 vertex 46.1 -57 5.6 vertex 46.1 -54.168 5.831 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 31.997 8.60981 -15.84596 vertex 30.2 9.443 -18.955 vertex 32.05137 8.69769 -16.17389 endloop endfacet facet normal -1 0 0 outer loop vertex 25.539 -51.311 8.88 vertex 25.539 -49.73 6.5 vertex 25.539 -51.788 8.63766 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 32.05137 8.69769 -16.17389 vertex 30.2 9.443 -18.955 vertex 32.059 8.71 -16.21979 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 32.237 8.80029 -16.55671 vertex 32.059 8.71 -16.21979 vertex 30.2 9.443 -18.955 endloop endfacet facet normal -1 0 0 outer loop vertex 25.539 -50.868 9.323 vertex 25.539 -48.688 7.542 vertex 25.539 -51.311 8.88 endloop endfacet facet normal -1 0 0 outer loop vertex 46.1 -51.7 5.76056 vertex 46.1 -51.7 5.6 vertex 46.1 -52.712 5.6 endloop endfacet facet normal -1 0 0 outer loop vertex 46.1 -52.83806 15 vertex 46.1 -54.168 14.789 vertex 46.1 -57 15 endloop endfacet facet normal -1 0 0 outer loop vertex 46.1 -54.168 14.789 vertex 46.1 -55.482 14.12 vertex 46.1 -57 15 endloop endfacet facet normal -1 0 0 outer loop vertex 25.539 -49.73 6.5 vertex 25.539 -51.044 5.831 vertex 25.539 -51.788 8.63766 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.25 8.28582 -14.63696 vertex 34.503 7.394 -11.30915 vertex 32.863 8.30164 -14.69601 endloop endfacet facet normal -1 0 0 outer loop vertex 25.539 -48.019 11.765 vertex 25.539 -47.788 10.31 vertex 25.539 -50.486 10.5 endloop endfacet facet normal -1 0 0 outer loop vertex 25.539 -47.788 10.31 vertex 25.539 -48.019 8.855 vertex 25.539 -50.584 9.881 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 30.2592 5.47062 -4.13203 vertex 30.2 5.47083 -4.13282 vertex 34.503 7.394 -11.30915 endloop endfacet facet normal -1 0 0 outer loop vertex 25.539 -51.311 12.12 vertex 25.539 -51.788 12.36234 vertex 25.539 -51.044 14.789 endloop endfacet facet normal -1 0 0 outer loop vertex 25.539 -50.868 11.677 vertex 25.539 -51.311 12.12 vertex 25.539 -49.73 14.12 endloop endfacet facet normal -1 0 0 outer loop vertex 25.539 -51.044 14.789 vertex 25.539 -49.73 14.12 vertex 25.539 -51.311 12.12 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 32.017 5.33204 -3.61494 vertex 31.92735 5.30887 -3.52849 vertex 30.2592 5.47062 -4.13203 endloop endfacet facet normal -1 0 0 outer loop vertex 25.539 -49.73 14.12 vertex 25.539 -48.688 13.078 vertex 25.539 -50.868 11.677 endloop endfacet facet normal -1 0 0 outer loop vertex 25.539 -51.788 14.90704 vertex 25.539 -51.044 14.789 vertex 25.539 -51.788 12.36234 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 30.2592 5.47062 -4.13203 vertex 34.503 7.394 -11.30915 vertex 32.017 5.33204 -3.61494 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 32.366 5.37813 -3.78692 vertex 32.017 5.33204 -3.61494 vertex 34.503 7.394 -11.30915 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 32.752 5.39395 -3.84597 vertex 32.366 5.37813 -3.78692 vertex 34.503 7.394 -11.30915 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 34.002 4.36328 0 vertex 30.27247 4.36328 0 vertex 32.752 4.74728 -1.43288 endloop endfacet facet normal -1 0 0 outer loop vertex 25.539 -50.584 11.119 vertex 25.539 -50.868 11.677 vertex 25.539 -48.688 13.078 endloop endfacet facet normal -1 0 0 outer loop vertex 25.539 -48.688 13.078 vertex 25.539 -48.019 11.765 vertex 25.539 -50.584 11.119 endloop endfacet facet normal -1 0 0 outer loop vertex 25.539 -50.486 10.5 vertex 25.539 -50.584 11.119 vertex 25.539 -48.019 11.765 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 32.366 4.7631 -1.49193 vertex 32.752 4.74728 -1.43288 vertex 30.27247 4.36328 0 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 32.017 4.80894 -1.66297 vertex 32.366 4.7631 -1.49193 vertex 30.27247 4.36328 0 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 33.138 4.7631 -1.49193 vertex 34.002 4.36328 0 vertex 32.752 4.74728 -1.43288 endloop endfacet facet normal -1 0 0 outer loop vertex 25.539 -51.788 5.71296 vertex 25.539 -51.788 8.63766 vertex 25.539 -51.044 5.831 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 31.563 4.97056 -2.26607 vertex 30.27247 4.36328 0 vertex 31.52181 5.03807 -2.51797 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 31.54319 5.13795 -2.89068 vertex 31.502 5.0705 -2.639 vertex 30.2592 5.47062 -4.13203 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 30.27247 4.36328 0 vertex 30.2592 5.47062 -4.13203 vertex 31.502 5.0705 -2.639 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 31.563 5.17042 -3.01184 vertex 30.2592 5.47062 -4.13203 vertex 31.6832 5.23127 -3.23889 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 30.2592 5.47062 -4.13203 vertex 31.92735 5.30887 -3.52849 vertex 31.741 5.26059 -3.3483 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 31.741 5.26059 -3.3483 vertex 31.6832 5.23127 -3.23889 vertex 30.2592 5.47062 -4.13203 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 31.741 4.88052 -1.93008 vertex 32.017 4.80894 -1.66297 vertex 30.27247 4.36328 0 endloop endfacet facet normal 0 0.9877 0.15637 outer loop vertex 45.11796 -42.591 15.3 vertex 45.11821 -42.57675 15.21 vertex 34.06285 -42.57675 15.21 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 30.27247 4.36328 0 vertex 31.563 4.97056 -2.26607 vertex 31.741 4.88052 -1.93008 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 32.00463 8.59749 -15.79996 vertex 32.059 8.50982 -15.47284 vertex 30.2 9.443 -18.955 endloop endfacet facet normal 0 0.70711 0.70711 outer loop vertex 34.07707 -41.766 13.68 vertex 34.0718 -42.07143 13.98543 vertex 37.8 -41.766 13.68 endloop endfacet facet normal 0 0.70711 0.70711 outer loop vertex 34.0718 -42.07143 13.98543 vertex 34.06937 -42.209 14.123 vertex 37.8 -41.766 13.68 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 31.563 5.17042 -3.01184 vertex 31.54319 5.13795 -2.89068 vertex 30.2592 5.47062 -4.13203 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 31.502 5.0705 -2.639 vertex 31.52181 5.03807 -2.51797 vertex 30.27247 4.36328 0 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 31.997 8.60981 -15.84596 vertex 32.00463 8.59749 -15.79996 vertex 30.2 9.443 -18.955 endloop endfacet facet normal 0 -0.96592 -0.25885 outer loop vertex 30.2 9.443 -18.955 vertex 32.059 8.50982 -15.47284 vertex 30.2 5.47083 -4.13282 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 32.059 11.6008 -14.64391 vertex 31.997 11.14241 -12.933 vertex 32.1568 11.55121 -14.4588 endloop endfacet facet normal 0 0.96593 0.2588 outer loop vertex 31.997 11.70088 -15.01744 vertex 30.2 12.534 -18.127 vertex 32.03106 11.64583 -14.81199 endloop endfacet facet normal 0 0.15818 0.98741 outer loop vertex 45.937 -52.489 8.497 vertex 54.937 -53.107 8.596 vertex 54.937 -52.489 8.497 endloop endfacet facet normal 0 -0.45359 0.89121 outer loop vertex 34.10841 -39.97 13.396 vertex 45.21014 -39.97 13.396 vertex 34.11109 -39.82012 13.47229 endloop endfacet facet normal 0 -0.15793 0.98745 outer loop vertex 45.937 -52.489 8.497 vertex 54.937 -52.489 8.497 vertex 45.937 -51.87 8.596 endloop endfacet facet normal 0 -0.70711 0.70711 outer loop vertex 34.11926 -39.33152 13.76047 vertex 45.21983 -39.412 13.68 vertex 34.12587 -38.969 14.123 endloop endfacet facet normal 0 -0.15793 -0.98745 outer loop vertex 54.937 -52.489 12.503 vertex 45.937 -52.489 12.503 vertex 54.937 -51.87 12.404 endloop endfacet facet normal 0 0.15818 -0.98741 outer loop vertex 54.937 -52.489 12.503 vertex 54.937 -53.107 12.404 vertex 45.937 -52.489 12.503 endloop endfacet facet normal 0 0.9877 0.15637 outer loop vertex 54.937 -54.393 9.881 vertex 45.937 -54.393 9.881 vertex 45.937 -54.491 10.5 endloop endfacet facet normal 0 -0.9877 0.15637 outer loop vertex 45.23417 -38.586 15.3 vertex 34.13206 -38.60025 15.21 vertex 45.23247 -38.684 14.681 endloop endfacet facet normal 0 0.45295 0.89154 outer loop vertex 45.937 -53.666 8.88 vertex 54.937 -53.666 8.88 vertex 54.937 -53.107 8.596 endloop endfacet facet normal 0 0.70711 -0.70711 outer loop vertex 54.937 -54.109 11.677 vertex 45.937 -54.109 11.677 vertex 45.937 -53.666 12.12 endloop endfacet facet normal 0 -0.15793 0.98745 outer loop vertex 54.937 -51.87 8.596 vertex 45.937 -51.87 8.596 vertex 54.937 -52.489 8.497 endloop endfacet facet normal 0 -0.45295 0.89154 outer loop vertex 54.937 -51.311 8.88 vertex 45.937 -51.87 8.596 vertex 54.937 -51.87 8.596 endloop endfacet facet normal 0 1 0 outer loop vertex 38.765 -33.2 4.251 vertex 37.984 -33.2 3.853 vertex 26.6 -33.2 20 endloop endfacet facet normal 0 0.15818 -0.98741 outer loop vertex 45.937 -53.107 12.404 vertex 45.937 -52.489 12.503 vertex 54.937 -53.107 12.404 endloop endfacet facet normal 0 0.45295 -0.89154 outer loop vertex 54.937 -53.107 12.404 vertex 45.937 -53.666 12.12 vertex 45.937 -53.107 12.404 endloop endfacet facet normal 0 0.9877 0.15637 outer loop vertex 54.937 -54.393 9.881 vertex 45.937 -54.491 10.5 vertex 54.937 -54.491 10.5 endloop endfacet facet normal 0 0 -1 outer loop vertex 34.183 -41.399 10.5 vertex 34.20077 -40.38674 10.5 vertex 45.182 -41.591 10.5 endloop endfacet facet normal 0 0 -1 outer loop vertex 34.27425 -36.2 10.5 vertex 40.00412 -36.2 10.5 vertex 34.20077 -40.38674 10.5 endloop endfacet facet normal 0 0.89121 0.45359 outer loop vertex 45.937 -54.393 9.881 vertex 54.937 -54.393 9.881 vertex 54.937 -54.109 9.323 endloop endfacet facet normal 0 0.70711 0.70711 outer loop vertex 45.937 -53.666 8.88 vertex 54.937 -54.109 9.323 vertex 54.937 -53.666 8.88 endloop endfacet facet normal -0.00274 -0.15665 -0.98765 outer loop vertex 45.13562 -41.59019 10.66059 vertex 45.128 -42.034 10.731 vertex 34.183 -41.399 10.6606 endloop endfacet facet normal -0.00274 -0.15665 -0.98765 outer loop vertex 34.076 -41.841 10.731 vertex 34.183 -41.399 10.6606 vertex 45.128 -42.034 10.731 endloop endfacet facet normal 0 0.70711 -0.70711 outer loop vertex 45.937 -53.666 12.12 vertex 54.937 -53.666 12.12 vertex 54.937 -54.109 11.677 endloop endfacet facet normal -0.01745 -0.99985 0 outer loop vertex 45.182 -41.591 10.5 vertex 45.13562 -41.59019 10.66059 vertex 34.183 -41.399 10.5 endloop endfacet facet normal 0 0.9877 -0.15637 outer loop vertex 54.937 -54.393 11.119 vertex 54.937 -54.491 10.5 vertex 45.937 -54.491 10.5 endloop endfacet facet normal 0 1 0 outer loop vertex 26.6 -33.2 20 vertex 52.2 -33.2 20 vertex 39.63 -33.2 4.388 endloop endfacet facet normal 0 0.45295 -0.89154 outer loop vertex 45.937 -53.666 12.12 vertex 54.937 -53.107 12.404 vertex 54.937 -53.666 12.12 endloop endfacet facet normal 0 1 0 outer loop vertex 53.765 -57 18.06 vertex 34.539 -57 20 vertex 53.96 -57 18.444 endloop endfacet facet normal 0 1 0 outer loop vertex 54.937 -57 12.14379 vertex 55.882 -57 16.522 vertex 61 -57 0 endloop endfacet facet normal 0 1 0 outer loop vertex 61 -57 20 vertex 61 -57 0 vertex 56.381 -57 17.21 endloop endfacet facet normal 0 1 0 outer loop vertex 55.073 -57 19.011 vertex 54.937 -57 20 vertex 55.498 -57 18.943 endloop endfacet facet normal 0 1 0 outer loop vertex 54.937 -57 20 vertex 61 -57 20 vertex 55.498 -57 18.943 endloop endfacet facet normal 0 1 0 outer loop vertex 55.073 -57 19.011 vertex 54.648 -57 18.943 vertex 54.937 -57 20 endloop endfacet facet normal 0 1 0 outer loop vertex 54.648 -57 18.943 vertex 54.265 -57 18.748 vertex 54.937 -57 20 endloop endfacet facet normal 0 1 0 outer loop vertex 34.539 -57 20 vertex 54.937 -57 20 vertex 54.265 -57 18.748 endloop endfacet facet normal 0 1 0 outer loop vertex 54.265 -57 18.748 vertex 53.96 -57 18.444 vertex 34.539 -57 20 endloop endfacet facet normal 0 1 0 outer loop vertex 56.449 -57 17.635 vertex 61 -57 20 vertex 56.381 -57 17.21 endloop endfacet facet normal 0 1 0 outer loop vertex 56.449 -57 17.635 vertex 56.381 -57 18.06 vertex 61 -57 20 endloop endfacet facet normal 0 1 0 outer loop vertex 61 -57 20 vertex 56.381 -57 18.06 vertex 56.186 -57 18.444 endloop endfacet facet normal 0 1 0 outer loop vertex 61 -57 20 vertex 56.186 -57 18.444 vertex 55.882 -57 18.748 endloop endfacet facet normal 0 1 0 outer loop vertex 55.882 -57 18.748 vertex 55.498 -57 18.943 vertex 61 -57 20 endloop endfacet facet normal 0 1 0 outer loop vertex 56.186 -57 16.827 vertex 56.381 -57 17.21 vertex 61 -57 0 endloop endfacet facet normal 0 1 0 outer loop vertex 56.186 -57 16.827 vertex 61 -57 0 vertex 55.882 -57 16.522 endloop endfacet facet normal 0 1 0 outer loop vertex 54.937 -57 12.14379 vertex 54.821 -57 15 vertex 55.882 -57 16.522 endloop endfacet facet normal 0 1 0 outer loop vertex 54.937 -57 8.47621 vertex 54.937 -57 12.14379 vertex 61 -57 0 endloop endfacet facet normal 0 1 0 outer loop vertex 55.498 -57 16.327 vertex 55.882 -57 16.522 vertex 54.821 -57 15 endloop endfacet facet normal 0 1 0 outer loop vertex 20.1 -57 0 vertex 46.1 -57 5.6 vertex 61 -57 0 endloop endfacet facet normal 0 1 0 outer loop vertex 55.073 -57 16.259 vertex 55.498 -57 16.327 vertex 54.821 -57 15 endloop endfacet facet normal 0 1 0 outer loop vertex 54.821 -57 15 vertex 54.648 -57 16.327 vertex 55.073 -57 16.259 endloop endfacet facet normal 0 1 0 outer loop vertex 54.821 -57 15 vertex 54.937 -57 12.14379 vertex 54.821 -57 12.14379 endloop endfacet facet normal 0 1 0 outer loop vertex 54.821 -57 5.6 vertex 54.937 -57 8.47621 vertex 61 -57 0 endloop endfacet facet normal 0 1 0 outer loop vertex 54.821 -57 8.47621 vertex 54.937 -57 8.47621 vertex 54.821 -57 5.6 endloop endfacet facet normal 0 1 0 outer loop vertex 25.246 -57 16.559 vertex 25.4 -57 15 vertex 24.884 -57 16.617 endloop endfacet facet normal 0 1 0 outer loop vertex 26.362 -57 17.37 vertex 34.616 -57 15 vertex 26.195 -57 17.043 endloop endfacet facet normal 0 1 0 outer loop vertex 24.13 -57 18.095 vertex 20.1 -57 20 vertex 24.297 -57 18.422 endloop endfacet facet normal 0 1 0 outer loop vertex 25.609 -57 18.849 vertex 25.246 -57 18.906 vertex 34.539 -57 20 endloop endfacet facet normal 0 1 0 outer loop vertex 20.1 -57 20 vertex 34.539 -57 20 vertex 25.246 -57 18.906 endloop endfacet facet normal 0 1 0 outer loop vertex 20.1 -57 20 vertex 25.246 -57 18.906 vertex 24.884 -57 18.849 endloop endfacet facet normal 0 1 0 outer loop vertex 24.557 -57 18.682 vertex 20.1 -57 20 vertex 24.884 -57 18.849 endloop endfacet facet normal 0 1 0 outer loop vertex 34.539 -57 20 vertex 34.616 -57 15 vertex 26.419 -57 17.733 endloop endfacet facet normal 0 1 0 outer loop vertex 34.539 -57 20 vertex 26.419 -57 17.733 vertex 26.362 -57 18.095 endloop endfacet facet normal 0 1 0 outer loop vertex 34.539 -57 20 vertex 26.362 -57 18.095 vertex 26.195 -57 18.422 endloop endfacet facet normal 0 1 0 outer loop vertex 34.539 -57 20 vertex 26.195 -57 18.422 vertex 25.936 -57 18.682 endloop endfacet facet normal 0 1 0 outer loop vertex 25.936 -57 18.682 vertex 25.609 -57 18.849 vertex 34.539 -57 20 endloop endfacet facet normal 0 1 0 outer loop vertex 53.698 -57 17.635 vertex 46.1 -57 15 vertex 53.765 -57 18.06 endloop endfacet facet normal 0 1 0 outer loop vertex 53.96 -57 16.827 vertex 46.1 -57 15 vertex 53.765 -57 17.21 endloop endfacet facet normal 0 1 0 outer loop vertex 53.765 -57 17.21 vertex 46.1 -57 15 vertex 53.698 -57 17.635 endloop endfacet facet normal 0 1 0 outer loop vertex 34.539 -57 20 vertex 46.1 -57 15 vertex 34.616 -57 15 endloop endfacet facet normal 0 1 0 outer loop vertex 45.937 -57 8.47621 vertex 46.1 -57 5.6 vertex 34.616 -57 5.6 endloop endfacet facet normal 0 1 0 outer loop vertex 34.616 -57 15 vertex 45.937 -57 8.47621 vertex 34.616 -57 5.6 endloop endfacet facet normal 0 1 0 outer loop vertex 45.937 -57 8.47621 vertex 34.616 -57 15 vertex 45.937 -57 12.14379 endloop endfacet facet normal 0 1 0 outer loop vertex 45.937 -57 12.14379 vertex 34.616 -57 15 vertex 46.1 -57 15 endloop endfacet facet normal 0 1 0 outer loop vertex 26.362 -57 17.37 vertex 26.419 -57 17.733 vertex 34.616 -57 15 endloop endfacet facet normal 0 1 0 outer loop vertex 24.557 -57 16.784 vertex 24.884 -57 16.617 vertex 25.4 -57 15 endloop endfacet facet normal 0 1 0 outer loop vertex 25.4 -57 15 vertex 20.1 -57 0 vertex 24.557 -57 16.784 endloop endfacet facet normal 0 1 0 outer loop vertex 25.4 -57 5.6 vertex 20.1 -57 0 vertex 25.4 -57 15 endloop endfacet facet normal 0 1 0 outer loop vertex 25.936 -57 16.784 vertex 26.195 -57 17.043 vertex 34.616 -57 15 endloop endfacet facet normal 0 1 0 outer loop vertex 34.616 -57 15 vertex 25.4 -57 15 vertex 25.936 -57 16.784 endloop endfacet facet normal 0 1 0 outer loop vertex 25.609 -57 16.617 vertex 25.936 -57 16.784 vertex 25.4 -57 15 endloop endfacet facet normal 0 1 0 outer loop vertex 25.246 -57 16.559 vertex 25.609 -57 16.617 vertex 25.4 -57 15 endloop endfacet facet normal 0 1 0 outer loop vertex 20.1 -57 0 vertex 25.4 -57 5.6 vertex 34.616 -57 5.6 endloop endfacet facet normal 0 1 0 outer loop vertex 20.1 -57 0 vertex 34.616 -57 5.6 vertex 46.1 -57 5.6 endloop endfacet facet normal 0 1 0 outer loop vertex 34.539 -57 20 vertex 53.765 -57 18.06 vertex 46.1 -57 15 endloop endfacet facet normal 0 1 0 outer loop vertex 46.1 -57 12.14379 vertex 45.937 -57 12.14379 vertex 46.1 -57 15 endloop endfacet facet normal 0 1 0 outer loop vertex 46.1 -57 5.6 vertex 45.937 -57 8.47621 vertex 46.1 -57 8.47621 endloop endfacet facet normal 0 1 0 outer loop vertex 53.96 -57 16.827 vertex 54.265 -57 16.522 vertex 46.1 -57 15 endloop endfacet facet normal 0 1 0 outer loop vertex 54.648 -57 16.327 vertex 54.821 -57 15 vertex 54.265 -57 16.522 endloop endfacet facet normal 0 1 0 outer loop vertex 46.1 -57 15 vertex 54.265 -57 16.522 vertex 54.821 -57 15 endloop endfacet facet normal 0 1 0 outer loop vertex 54.821 -57 5.6 vertex 61 -57 0 vertex 46.1 -57 5.6 endloop endfacet facet normal 0 1 0 outer loop vertex 24.557 -57 18.682 vertex 24.297 -57 18.422 vertex 20.1 -57 20 endloop endfacet facet normal 0 1 0 outer loop vertex 24.073 -57 17.733 vertex 20.1 -57 20 vertex 24.13 -57 18.095 endloop endfacet facet normal 0 1 0 outer loop vertex 20.1 -57 0 vertex 20.1 -57 20 vertex 24.13 -57 17.37 endloop endfacet facet normal 0 1 0 outer loop vertex 24.297 -57 17.043 vertex 20.1 -57 0 vertex 24.13 -57 17.37 endloop endfacet facet normal 0 1 0 outer loop vertex 24.297 -57 17.043 vertex 24.557 -57 16.784 vertex 20.1 -57 0 endloop endfacet facet normal 0 1 0 outer loop vertex 24.073 -57 17.733 vertex 24.13 -57 17.37 vertex 20.1 -57 20 endloop endfacet facet normal 0.9878 0 -0.15572 outer loop vertex 53.698 -57 17.635 vertex 53.765 -60 18.06 vertex 53.698 -60 17.635 endloop endfacet facet normal 0.9878 0 0.15572 outer loop vertex 53.698 -57 17.635 vertex 53.698 -60 17.635 vertex 53.765 -60 17.21 endloop endfacet facet normal 0.15799 0 0.98744 outer loop vertex 54.648 -57 16.327 vertex 54.648 -60 16.327 vertex 55.073 -60 16.259 endloop endfacet facet normal -0.15799 0 0.98744 outer loop vertex 55.498 -57 16.327 vertex 55.073 -60 16.259 vertex 55.498 -60 16.327 endloop endfacet facet normal -0.45278 0 0.89162 outer loop vertex 55.882 -60 16.522 vertex 55.498 -57 16.327 vertex 55.498 -60 16.327 endloop endfacet facet normal 0.15799 0 -0.98744 outer loop vertex 55.073 -60 19.011 vertex 54.648 -60 18.943 vertex 55.073 -57 19.011 endloop endfacet facet normal 0.89115 0 0.45372 outer loop vertex 53.96 -60 16.827 vertex 53.96 -57 16.827 vertex 53.765 -60 17.21 endloop endfacet facet normal 0.70711 0 0.70711 outer loop vertex 53.96 -57 16.827 vertex 53.96 -60 16.827 vertex 54.265 -60 16.522 endloop endfacet facet normal -0.15799 0 -0.98744 outer loop vertex 55.498 -57 18.943 vertex 55.498 -60 18.943 vertex 55.073 -57 19.011 endloop endfacet facet normal -0.70827 0 0.70594 outer loop vertex 56.186 -57 16.827 vertex 55.882 -57 16.522 vertex 56.186 -60 16.827 endloop endfacet facet normal -0.89115 0 0.45372 outer loop vertex 56.381 -60 17.21 vertex 56.381 -57 17.21 vertex 56.186 -60 16.827 endloop endfacet facet normal -0.98744 0 -0.15799 outer loop vertex 56.381 -57 18.06 vertex 56.449 -57 17.635 vertex 56.381 -60 18.06 endloop endfacet facet normal -0.89162 0 -0.45278 outer loop vertex 56.186 -60 18.444 vertex 56.186 -57 18.444 vertex 56.381 -60 18.06 endloop endfacet facet normal -0.70711 0 -0.70711 outer loop vertex 56.186 -57 18.444 vertex 56.186 -60 18.444 vertex 55.882 -57 18.748 endloop endfacet facet normal -0.45278 0 -0.89162 outer loop vertex 55.498 -57 18.943 vertex 55.882 -57 18.748 vertex 55.498 -60 18.943 endloop endfacet facet normal 0.45372 0 0.89115 outer loop vertex 54.265 -57 16.522 vertex 54.265 -60 16.522 vertex 54.648 -57 16.327 endloop endfacet facet normal 0.15799 0 0.98744 outer loop vertex 55.073 -57 16.259 vertex 54.648 -57 16.327 vertex 55.073 -60 16.259 endloop endfacet facet normal -0.15799 0 0.98744 outer loop vertex 55.498 -57 16.327 vertex 55.073 -57 16.259 vertex 55.073 -60 16.259 endloop endfacet facet normal 0.15799 0 -0.98744 outer loop vertex 54.648 -60 18.943 vertex 54.648 -57 18.943 vertex 55.073 -57 19.011 endloop endfacet facet normal 0.45372 0 -0.89115 outer loop vertex 54.648 -57 18.943 vertex 54.648 -60 18.943 vertex 54.265 -60 18.748 endloop endfacet facet normal 0.45372 0 -0.89115 outer loop vertex 54.648 -57 18.943 vertex 54.265 -60 18.748 vertex 54.265 -57 18.748 endloop endfacet facet normal 0.70594 0 -0.70827 outer loop vertex 53.96 -60 18.444 vertex 53.96 -57 18.444 vertex 54.265 -60 18.748 endloop endfacet facet normal 0.70594 0 -0.70827 outer loop vertex 54.265 -57 18.748 vertex 54.265 -60 18.748 vertex 53.96 -57 18.444 endloop endfacet facet normal 0.89162 0 -0.45278 outer loop vertex 53.765 -60 18.06 vertex 53.765 -57 18.06 vertex 53.96 -60 18.444 endloop endfacet facet normal 0.89162 0 -0.45278 outer loop vertex 53.96 -57 18.444 vertex 53.96 -60 18.444 vertex 53.765 -57 18.06 endloop endfacet facet normal 0.9878 0 -0.15572 outer loop vertex 53.765 -60 18.06 vertex 53.698 -57 17.635 vertex 53.765 -57 18.06 endloop endfacet facet normal 0.9878 0 0.15572 outer loop vertex 53.698 -57 17.635 vertex 53.765 -60 17.21 vertex 53.765 -57 17.21 endloop endfacet facet normal 0.89115 0 0.45372 outer loop vertex 53.765 -57 17.21 vertex 53.765 -60 17.21 vertex 53.96 -57 16.827 endloop endfacet facet normal 0.70711 0 0.70711 outer loop vertex 53.96 -57 16.827 vertex 54.265 -60 16.522 vertex 54.265 -57 16.522 endloop endfacet facet normal 0.45372 0 0.89115 outer loop vertex 54.648 -57 16.327 vertex 54.265 -60 16.522 vertex 54.648 -60 16.327 endloop endfacet facet normal -0.45278 0 0.89162 outer loop vertex 55.882 -60 16.522 vertex 55.882 -57 16.522 vertex 55.498 -57 16.327 endloop endfacet facet normal -0.70827 0 0.70594 outer loop vertex 55.882 -60 16.522 vertex 56.186 -60 16.827 vertex 55.882 -57 16.522 endloop endfacet facet normal -0.89115 0 0.45372 outer loop vertex 56.186 -57 16.827 vertex 56.186 -60 16.827 vertex 56.381 -57 17.21 endloop endfacet facet normal -0.98744 0 0.15799 outer loop vertex 56.449 -60 17.635 vertex 56.449 -57 17.635 vertex 56.381 -60 17.21 endloop endfacet facet normal -0.98744 0 0.15799 outer loop vertex 56.381 -57 17.21 vertex 56.381 -60 17.21 vertex 56.449 -57 17.635 endloop endfacet facet normal -0.98744 0 -0.15799 outer loop vertex 56.449 -60 17.635 vertex 56.381 -60 18.06 vertex 56.449 -57 17.635 endloop endfacet facet normal -0.89162 0 -0.45278 outer loop vertex 56.381 -57 18.06 vertex 56.381 -60 18.06 vertex 56.186 -57 18.444 endloop endfacet facet normal -0.70711 0 -0.70711 outer loop vertex 55.882 -60 18.748 vertex 55.882 -57 18.748 vertex 56.186 -60 18.444 endloop endfacet facet normal -0.45278 0 -0.89162 outer loop vertex 55.882 -60 18.748 vertex 55.498 -60 18.943 vertex 55.882 -57 18.748 endloop endfacet facet normal -0.15799 0 -0.98744 outer loop vertex 55.073 -60 19.011 vertex 55.073 -57 19.011 vertex 55.498 -60 18.943 endloop endfacet facet normal 0 0 1 outer loop vertex 20.1 -59.097 10.097 vertex 20.1 -60 10.097 vertex 61 -59.097 10.097 endloop endfacet facet normal 0 0 -1 outer loop vertex 61 -59.097 16.003 vertex 61 -60 16.003 vertex 53.698 -60 16.003 endloop endfacet facet normal 0.70711 0 -0.70711 outer loop vertex 24.297 -57 18.422 vertex 24.557 -57 18.682 vertex 24.297 -60 18.422 endloop endfacet facet normal 0.89058 0 -0.45482 outer loop vertex 24.13 -60 18.095 vertex 24.13 -57 18.095 vertex 24.297 -60 18.422 endloop endfacet facet normal 0.45482 0 0.89058 outer loop vertex 24.884 -57 16.617 vertex 24.557 -60 16.784 vertex 24.884 -60 16.617 endloop endfacet facet normal 0.1582 0 0.98741 outer loop vertex 25.246 -60 16.559 vertex 25.246 -57 16.559 vertex 24.884 -60 16.617 endloop endfacet facet normal 0.1582 0 0.98741 outer loop vertex 24.884 -57 16.617 vertex 24.884 -60 16.617 vertex 25.246 -57 16.559 endloop endfacet facet normal -0.15778 0 0.98747 outer loop vertex 25.246 -60 16.559 vertex 25.609 -60 16.617 vertex 25.246 -57 16.559 endloop endfacet facet normal -0.45482 0 0.89058 outer loop vertex 25.936 -60 16.784 vertex 25.936 -57 16.784 vertex 25.609 -60 16.617 endloop endfacet facet normal -0.70711 0 0.70711 outer loop vertex 26.195 -60 17.043 vertex 25.936 -57 16.784 vertex 25.936 -60 16.784 endloop endfacet facet normal -0.89058 0 0.45482 outer loop vertex 26.362 -60 17.37 vertex 26.362 -57 17.37 vertex 26.195 -60 17.043 endloop endfacet facet normal -0.9879 0 0.15512 outer loop vertex 26.362 -60 17.37 vertex 26.419 -60 17.733 vertex 26.362 -57 17.37 endloop endfacet facet normal 0.45482 0 -0.89058 outer loop vertex 24.884 -57 18.849 vertex 24.884 -60 18.849 vertex 24.557 -57 18.682 endloop endfacet facet normal -0.70847 0 -0.70574 outer loop vertex 25.936 -60 18.682 vertex 25.936 -57 18.682 vertex 26.195 -60 18.422 endloop endfacet facet normal -0.45482 0 -0.89058 outer loop vertex 25.609 -57 18.849 vertex 25.936 -57 18.682 vertex 25.609 -60 18.849 endloop endfacet facet normal -0.15512 0 -0.9879 outer loop vertex 25.246 -60 18.906 vertex 25.246 -57 18.906 vertex 25.609 -60 18.849 endloop endfacet facet normal 0.89058 0 -0.45482 outer loop vertex 24.297 -57 18.422 vertex 24.297 -60 18.422 vertex 24.13 -57 18.095 endloop endfacet facet normal 0.98783 0 -0.15554 outer loop vertex 24.073 -57 17.733 vertex 24.13 -57 18.095 vertex 24.073 -60 17.733 endloop endfacet facet normal 0.98783 0 -0.15554 outer loop vertex 24.13 -60 18.095 vertex 24.073 -60 17.733 vertex 24.13 -57 18.095 endloop endfacet facet normal 0.9879 0 0.15512 outer loop vertex 24.13 -60 17.37 vertex 24.13 -57 17.37 vertex 24.073 -60 17.733 endloop endfacet facet normal 0.9879 0 0.15512 outer loop vertex 24.073 -57 17.733 vertex 24.073 -60 17.733 vertex 24.13 -57 17.37 endloop endfacet facet normal 0.89058 0 0.45482 outer loop vertex 24.13 -57 17.37 vertex 24.13 -60 17.37 vertex 24.297 -60 17.043 endloop endfacet facet normal 0.89058 0 0.45482 outer loop vertex 24.13 -57 17.37 vertex 24.297 -60 17.043 vertex 24.297 -57 17.043 endloop endfacet facet normal 0.70574 0 0.70847 outer loop vertex 24.557 -60 16.784 vertex 24.557 -57 16.784 vertex 24.297 -57 17.043 endloop endfacet facet normal 0.70574 0 0.70847 outer loop vertex 24.557 -60 16.784 vertex 24.297 -57 17.043 vertex 24.297 -60 17.043 endloop endfacet facet normal 0.45482 0 0.89058 outer loop vertex 24.884 -57 16.617 vertex 24.557 -57 16.784 vertex 24.557 -60 16.784 endloop endfacet facet normal -0.15778 0 0.98747 outer loop vertex 25.609 -60 16.617 vertex 25.609 -57 16.617 vertex 25.246 -57 16.559 endloop endfacet facet normal -0.45482 0 0.89058 outer loop vertex 25.936 -57 16.784 vertex 25.609 -57 16.617 vertex 25.609 -60 16.617 endloop endfacet facet normal -0.70711 0 0.70711 outer loop vertex 26.195 -60 17.043 vertex 26.195 -57 17.043 vertex 25.936 -57 16.784 endloop endfacet facet normal -0.89058 0 0.45482 outer loop vertex 26.362 -57 17.37 vertex 26.195 -57 17.043 vertex 26.195 -60 17.043 endloop endfacet facet normal -0.9879 0 0.15512 outer loop vertex 26.362 -57 17.37 vertex 26.419 -60 17.733 vertex 26.419 -57 17.733 endloop endfacet facet normal -0.98783 0 -0.15554 outer loop vertex 26.362 -60 18.095 vertex 26.362 -57 18.095 vertex 26.419 -57 17.733 endloop endfacet facet normal -0.98783 0 -0.15554 outer loop vertex 26.362 -60 18.095 vertex 26.419 -57 17.733 vertex 26.419 -60 17.733 endloop endfacet facet normal -0.89058 0 -0.45482 outer loop vertex 26.362 -60 18.095 vertex 26.195 -60 18.422 vertex 26.362 -57 18.095 endloop endfacet facet normal -0.89058 0 -0.45482 outer loop vertex 26.195 -57 18.422 vertex 26.362 -57 18.095 vertex 26.195 -60 18.422 endloop endfacet facet normal 0.15554 0 -0.98783 outer loop vertex 24.884 -60 18.849 vertex 24.884 -57 18.849 vertex 25.246 -60 18.906 endloop endfacet facet normal 0.15554 0 -0.98783 outer loop vertex 25.246 -57 18.906 vertex 25.246 -60 18.906 vertex 24.884 -57 18.849 endloop endfacet facet normal 0.45482 0 -0.89058 outer loop vertex 24.557 -60 18.682 vertex 24.557 -57 18.682 vertex 24.884 -60 18.849 endloop endfacet facet normal 0.70711 0 -0.70711 outer loop vertex 24.557 -60 18.682 vertex 24.297 -60 18.422 vertex 24.557 -57 18.682 endloop endfacet facet normal -0.70847 0 -0.70574 outer loop vertex 26.195 -57 18.422 vertex 26.195 -60 18.422 vertex 25.936 -57 18.682 endloop endfacet facet normal -0.45482 0 -0.89058 outer loop vertex 25.936 -60 18.682 vertex 25.609 -60 18.849 vertex 25.936 -57 18.682 endloop endfacet facet normal -0.15512 0 -0.9879 outer loop vertex 25.609 -57 18.849 vertex 25.609 -60 18.849 vertex 25.246 -57 18.906 endloop endfacet facet normal 0 0 1 outer loop vertex 61 -60 10.097 vertex 61 -59.097 10.097 vertex 20.1 -60 10.097 endloop endfacet facet normal 0 0 -1 outer loop vertex 24.073 -60 16.003 vertex 20.1 -59.097 16.003 vertex 53.698 -60 16.003 endloop endfacet facet normal 0 -1 0 outer loop vertex 20.1 -59.097 10.097 vertex 61 -59.097 10.097 vertex 61 -59.097 16.003 endloop endfacet facet normal 0 0 -1 outer loop vertex 61 -59.097 16.003 vertex 53.698 -60 16.003 vertex 20.1 -59.097 16.003 endloop endfacet facet normal 0 0 -1 outer loop vertex 20.1 -59.097 16.003 vertex 24.073 -60 16.003 vertex 20.1 -60 16.003 endloop endfacet facet normal 0 -1 0 outer loop vertex 61 -59.097 16.003 vertex 20.1 -59.097 16.003 vertex 20.1 -59.097 10.097 endloop endfacet endsolid stl_item0 ================================================ FILE: robotics/donkey-car/line_follower_main.py ================================================ # This file is part of the OpenMV project. # Copyright (c) 2013-2017 Ibrahim Abdelkader & Kwabena W. Agyeman # Support for OpenMV Motor Shield by Chris Anderson, DIY Robocars # This work is licensed under the MIT license, see the file LICENSE for details. import sensor, image, time, math, pyb ########### # Settings ########### COLOR_LINE_FOLLOWING = True # False to use grayscale thresholds, true to use color thresholds. COLOR_THRESHOLDS = [( 94, 100, -27, 1, 20, 127)] # Yellow Line. GRAYSCALE_THRESHOLDS = [(240, 255)] # White Line. COLOR_HIGH_LIGHT_THRESHOLDS = [(80, 100, -10, 10, -10, 10)] GRAYSCALE_HIGH_LIGHT_THRESHOLDS = [(250, 255)] BINARY_VIEW = False # Helps debugging but costs FPS if on. DO_NOTHING = False # Just capture frames... FRAME_SIZE = sensor.QQVGA # Frame size. FRAME_REGION = 0.75 # Percentage of the image from the bottom (0 - 1.0). FRAME_WIDE = 1.0 # Percentage of the frame width. AREA_THRESHOLD = 0 # Raise to filter out false detections. PIXELS_THRESHOLD = 40 # Raise to filter out false detections. MAG_THRESHOLD = 4 # Raise to filter out false detections. MIXING_RATE = 0.9 # Percentage of a new line detection to mix into current steering. # Tweak these values for your robocar. THROTTLE_CUT_OFF_ANGLE = 1.0 # Maximum angular distance from 90 before we cut speed [0.0-90.0). THROTTLE_CUT_OFF_RATE = 0.5 # How much to cut our speed boost (below) once the above is passed (0.0-1.0]. THROTTLE_GAIN = 0.0 # e.g. how much to speed up on a straight away THROTTLE_OFFSET = 30.0 # e.g. default speed (0 to 100) THROTTLE_P_GAIN = 1.0 THROTTLE_I_GAIN = 0.0 THROTTLE_I_MIN = -0.0 THROTTLE_I_MAX = 0.0 THROTTLE_D_GAIN = 0.0 # Tweak these values for your robocar. STEERING_OFFSET = 90 # Change this if you need to fix an imbalance in your car (0 to 180). STEERING_P_GAIN = -15.0 # Make this smaller as you increase your speed and vice versa. STEERING_I_GAIN = 0.0 STEERING_I_MIN = -0.0 STEERING_I_MAX = 0.0 STEERING_D_GAIN = -12 # Make this larger as you increase your speed and vice versa. # Selects motor/servo controller method... ARDUINO_SERVO_CONTROLLER = False NATIVE_SERVO_CONTROLLER = True NATIVE_MOTOR_CONTROLLER = False # Tweak these values for your robocar if you're using servos. THROTTLE_SERVO_MIN_US = 1500 THROTTLE_SERVO_MAX_US = 2000 # Tweak these values for your robocar. STEERING_SERVO_MIN_US = 700 STEERING_SERVO_MAX_US = 2300 ########### # Setup ########### FRAME_REGION = max(min(FRAME_REGION, 1.0), 0.0) FRAME_WIDE = max(min(FRAME_WIDE, 1.0), 0.0) MIXING_RATE = max(min(MIXING_RATE, 1.0), 0.0) THROTTLE_CUT_OFF_ANGLE = max(min(THROTTLE_CUT_OFF_ANGLE, 89.99), 0) THROTTLE_CUT_OFF_RATE = max(min(THROTTLE_CUT_OFF_RATE, 1.0), 0.01) THROTTLE_OFFSET = max(min(THROTTLE_OFFSET, 100), 0) STEERING_OFFSET = max(min(STEERING_OFFSET, 180), 0) # Handle if these were reversed... tmp = max(THROTTLE_SERVO_MIN_US, THROTTLE_SERVO_MAX_US) THROTTLE_SERVO_MIN_US = min(THROTTLE_SERVO_MIN_US, THROTTLE_SERVO_MAX_US) THROTTLE_SERVO_MAX_US = tmp # Handle if these were reversed... tmp = max(STEERING_SERVO_MIN_US, STEERING_SERVO_MAX_US) STEERING_SERVO_MIN_US = min(STEERING_SERVO_MIN_US, STEERING_SERVO_MAX_US) STEERING_SERVO_MAX_US = tmp device = None if ARDUINO_SERVO_CONTROLLER: device = pyb.UART(3, 19200, timeout_char = 1000) if NATIVE_SERVO_CONTROLLER: import servo import machine device = servo.Servos(machine.I2C(sda = machine.Pin("P5"), scl = machine.Pin("P4")), address = 0x40, freq = 50) if NATIVE_MOTOR_CONTROLLER: from pyb import Pin, Timer # these are motor driver pins, which set the direction of each motor pinADir0 = pyb.Pin('P0', pyb.Pin.OUT_PP, pyb.Pin.PULL_NONE) pinADir1 = pyb.Pin('P1', pyb.Pin.OUT_PP, pyb.Pin.PULL_NONE) pinBDir0 = pyb.Pin('P2', pyb.Pin.OUT_PP, pyb.Pin.PULL_NONE) pinBDir1 = pyb.Pin('P3', pyb.Pin.OUT_PP, pyb.Pin.PULL_NONE) # Dir0/1 must be not equal to each other for forward or backwards # operation. If they are equal then that's a brake operation. # If they are not equal then the motor will spin one way other the # other depending on its hookup and the value of channel 0. pinBDir0.value(0) pinBDir1.value(1) tim = Timer(4, freq=1000) # Frequency in Hz ch1 = tim.channel(1, pyb.Timer.PWM, pin=pyb.Pin("P7")) ch2 = tim.channel(2, pyb.Timer.PWM, pin=pyb.Pin("P8")) cruise_speed = 50 radians_degrees = 57.3 # constant to convert from radians to degrees steering_direction = 1 # use this to reverse the steering if your car goes in the wrong direction steering_gain = 1.0 # calibration for your car's steering sensitivity steering_center = 0 # set to your car's steering center point def constrain(value, min, max): if value < min : return min if value > max : return max else: return value def steer(throttle, angle): global steering_gain, cruise_speed, steering_center angle = int(round(angle+steering_center)) angle = constrain(angle, 0, 180) angle = angle - 90 angle = radians_degrees * math.tan(angle/radians_degrees) # take the tangent to create a non-linear response curver angle = angle * steering_gain print ("Calculated angle", angle) left = angle*steering_direction + throttle + cruise_speed left = constrain (left, 0, 100) right = -1*angle*steering_direction + throttle + cruise_speed right = constrain (right, 0, 100) print ("left: ", left) print ("right: ", right) # Generate a 1KHz square wave on TIM4 with each channel ch1.pulse_width_percent(left) ch2.pulse_width_percent(right) # This function maps the output of the linear regression function to a driving vector for steering # the robocar. See https://openmv.io/blogs/news/linear-regression-line-following for more info. old_cx_normal = None def figure_out_my_steering(line, img): global old_cx_normal # Rho is computed using the inverse of this code below in the actual OpenMV Cam code. # This formula comes from the Hough line detection formula (see the wikipedia page for more). # Anyway, the output of this calculations below are a point centered vertically in the middle # of the image and to the left or right such that the line goes through it (cx may be off the image). cy = img.height() / 2 cx = (line.rho() - (cy * math.sin(math.radians(line.theta())))) / math.cos(math.radians(line.theta())) # "cx_middle" is now the distance from the center of the line. This is our error method to stay # on the line. "cx_normal" normalizes the error to something like -1/+1 (it will go over this). cx_middle = cx - (img.width() / 2) cx_normal = cx_middle / (img.width() / 2) # Note that "cx_normal" may be larger than -1/+1. When the value is between -1/+1 this means the # robot is driving basically straight and needs to only turn lightly left or right. When the value # is outside -1/+1 it means you need to turn VERY hard to the left or right to get back on the # line. This maps to the case of the robot driving into a horizontal line. "cx_normal" will # then approach -inf/+inf depending on how horizontal the line is. What's nice is that this # is exactly the behavior we want and it gets up back on the line! if old_cx_normal != None: old_cx_normal = (cx_normal * MIXING_RATE) + (old_cx_normal * (1.0 - MIXING_RATE)) else: old_cx_normal = cx_normal return old_cx_normal # Solve: THROTTLE_CUT_OFF_RATE = pow(sin(90 +/- THROTTLE_CUT_OFF_ANGLE), x) for x... # -> sin(90 +/- THROTTLE_CUT_OFF_ANGLE) = cos(THROTTLE_CUT_OFF_ANGLE) t_power = math.log(THROTTLE_CUT_OFF_RATE) / math.log(math.cos(math.radians(THROTTLE_CUT_OFF_ANGLE))) def figure_out_my_throttle(steering): # steering -> [0:180] # pow(sin()) of the steering angle is only non-zero when driving straight... e.g. steering ~= 90 t_result = math.pow(math.sin(math.radians(max(min(steering, 179.99), 0.0))), t_power) return (t_result * THROTTLE_GAIN) + THROTTLE_OFFSET # # Servo Control Code # # throttle [0:100] (101 values) -> [THROTTLE_SERVO_MIN_US, THROTTLE_SERVO_MAX_US] # steering [0:180] (181 values) -> [STEERING_SERVO_MIN_US, STEERING_SERVO_MAX_US] def set_servos(throttle, steering): if NATIVE_MOTOR_CONTROLLER: steer(throttle, steering) if ARDUINO_SERVO_CONTROLLER: throttle = THROTTLE_SERVO_MIN_US + ((throttle * (THROTTLE_SERVO_MAX_US - THROTTLE_SERVO_MIN_US + 1)) / 101) steering = STEERING_SERVO_MIN_US + ((steering * (STEERING_SERVO_MAX_US - STEERING_SERVO_MIN_US + 1)) / 181) device.write("{%05d,%05d}\r\n" % (throttle, steering)) if NATIVE_SERVO_CONTROLLER: throttle = THROTTLE_SERVO_MIN_US + ((throttle * (THROTTLE_SERVO_MAX_US - THROTTLE_SERVO_MIN_US + 1)) / 101) steering = STEERING_SERVO_MIN_US + ((steering * (STEERING_SERVO_MAX_US - STEERING_SERVO_MIN_US + 1)) / 181) device.position(0, us=throttle) device.position(1, us=steering) # # Camera Control Code # sensor.reset() sensor.set_pixformat(sensor.RGB565 if COLOR_LINE_FOLLOWING else sensor.GRAYSCALE) sensor.set_framesize(FRAME_SIZE) sensor.set_vflip(True) sensor.set_hmirror(True) sensor.set_windowing((int((sensor.width() / 2) - ((sensor.width() / 2) * FRAME_WIDE)), int(sensor.height() * (1.0 - FRAME_REGION)), \ int((sensor.width() / 2) + ((sensor.width() / 2) * FRAME_WIDE)), int(sensor.height() * FRAME_REGION))) sensor.skip_frames(time = 200) if COLOR_LINE_FOLLOWING: sensor.set_auto_gain(False) if COLOR_LINE_FOLLOWING: sensor.set_auto_whitebal(False) clock = time.clock() #sensor.set_auto_exposure(False, \ # exposure_us = 300) ########### # Loop ########### old_time = pyb.millis() throttle_old_result = None throttle_i_output = 0 throttle_output = THROTTLE_OFFSET steering_old_result = None steering_i_output = 0 steering_output = STEERING_OFFSET while True: clock.tick() img = sensor.snapshot() img.binary(COLOR_HIGH_LIGHT_THRESHOLDS if COLOR_LINE_FOLLOWING else GRAYSCALE_HIGH_LIGHT_THRESHOLDS, zero = True) img.histeq() if BINARY_VIEW: img = img.binary(COLOR_THRESHOLDS if COLOR_LINE_FOLLOWING else GRAYSCALE_THRESHOLDS) if BINARY_VIEW: img.erode(1, threshold = 5).dilate(1, threshold = 1) if DO_NOTHING: continue # We call get regression below to get a robust linear regression of the field of view. # This returns a line object which we can use to steer the robocar. line = img.get_regression(([(50, 100, -128, 127, -128, 127)] if BINARY_VIEW else COLOR_THRESHOLDS) if COLOR_LINE_FOLLOWING \ else ([(127, 255)] if BINARY_VIEW else GRAYSCALE_THRESHOLDS), \ area_threshold = AREA_THRESHOLD, pixels_threshold = PIXELS_THRESHOLD, \ robust = True) print_string = "" if line and (line.magnitude() >= MAG_THRESHOLD): img.draw_line(line.line(), color = (127, 127, 127) if COLOR_LINE_FOLLOWING else 127) new_time = pyb.millis() delta_time = new_time - old_time old_time = new_time # # Figure out steering and do steering PID # steering_new_result = figure_out_my_steering(line, img) steering_delta_result = (steering_new_result - steering_old_result) if (steering_old_result != None) else 0 steering_old_result = steering_new_result steering_p_output = steering_new_result # Standard PID Stuff here... nothing particularly interesting :) steering_i_output = max(min(steering_i_output + steering_new_result, STEERING_I_MAX), STEERING_I_MIN) steering_d_output = ((steering_delta_result * 1000) / delta_time) if delta_time else 0 steering_pid_output = (STEERING_P_GAIN * steering_p_output) + \ (STEERING_I_GAIN * steering_i_output) + \ (STEERING_D_GAIN * steering_d_output) # Steering goes from [-90,90] but we need to output [0,180] for the servos. steering_output = STEERING_OFFSET + max(min(round(steering_pid_output), 180 - STEERING_OFFSET), STEERING_OFFSET - 180) # # Figure out throttle and do throttle PID # throttle_new_result = figure_out_my_throttle(steering_output) throttle_delta_result = (throttle_new_result - throttle_old_result) if (throttle_old_result != None) else 0 throttle_old_result = throttle_new_result throttle_p_output = throttle_new_result # Standard PID Stuff here... nothing particularly interesting :) throttle_i_output = max(min(throttle_i_output + throttle_new_result, THROTTLE_I_MAX), THROTTLE_I_MIN) throttle_d_output = ((throttle_delta_result * 1000) / delta_time) if delta_time else 0 throttle_pid_output = (THROTTLE_P_GAIN * throttle_p_output) + \ (THROTTLE_I_GAIN * throttle_i_output) + \ (THROTTLE_D_GAIN * throttle_d_output) # Throttle goes from 0% to 100%. throttle_output = max(min(round(throttle_pid_output), 100), 0) print_string = "Line Ok - throttle %d, steering %d - line t: %d, r: %d" % \ (throttle_output , steering_output, line.theta(), line.rho()) else: print_string = "Line Lost - throttle %d, steering %d" % (throttle_output , steering_output) set_servos(throttle_output, steering_output) print("FPS %f - %s" % (clock.fps(), print_string)) ================================================ FILE: robotics/donkey-car/pca9685.py ================================================ import utime import ustruct class PCA9685: def __init__(self, i2c, address=0x40): self.i2c = i2c self.address = address self.reset() def _write(self, address, value): self.i2c.writeto_mem(self.address, address, bytearray([value])) def _read(self, address): return self.i2c.readfrom_mem(self.address, address, 1)[0] def reset(self): self._write(0x00, 0x00) # Mode1 def freq(self, freq=None): if freq is None: return int(25000000.0 / 4096 / (self._read(0xfe) - 0.5)) prescale = int(25000000.0 / 4096.0 / freq + 0.5) old_mode = self._read(0x00) # Mode 1 self._write(0x00, (old_mode & 0x7F) | 0x10) # Mode 1, sleep self._write(0xfe, prescale) # Prescale self._write(0x00, old_mode) # Mode 1 utime.sleep_us(5) self._write(0x00, old_mode | 0xa1) # Mode 1, autoincrement on def pwm(self, index, on=None, off=None): if on is None or off is None: data = self.i2c.readfrom_mem(self.address, 0x06 + 4 * index, 4) return ustruct.unpack(' & Kwabena W. Agyeman // This work is licensed under the MIT license, see the file LICENSE for details. #include #define SERIAL_RX_PIN 0 #define SERIAL_TX_PIN 1 #define THROTTLE_SERVO_PIN 6 #define STEERING_SERVO_PIN 10 #define RC_THROTTLE_SERVO_PIN 11 #define RC_STEERING_SERVO_PIN 5 #define SERIAL_BUAD_RATE 19200 #define RC_THROTTLE_SERVO_REFRESH_RATE 20000UL // in us #define SERIAL_THROTTLE_SERVO_REFRESH_RATE 1000000UL // in us #define RC_THROTTLE_DEAD_ZONE_MIN 1400UL // in us #define RC_THROTTLE_DEAD_ZONE_MAX 1600UL // in us #define RC_STEERING_SERVO_REFRESH_RATE 20000UL // in us #define SERIAL_STEERING_SERVO_REFRESH_RATE 1000000UL // in us #define RC_STEERING_DEAD_ZONE_MIN 1400UL // in us #define RC_STEERING_DEAD_ZONE_MAX 1600UL // in us Servo throttle_servo, steering_servo; unsigned long last_microseconds; bool last_rc_throttle_pin_state, last_rc_steering_pin_state; unsigned long last_rc_throttle_microseconds, last_rc_steering_microseconds; unsigned long rc_throttle_servo_pulse_length = 0, rc_steering_servo_pulse_length = 0; unsigned long rc_throttle_servo_pulse_refreshed = 0, rc_steering_servo_pulse_refreshed = 0; char serial_buffer[16] = {}; unsigned long serial_throttle_servo_pulse_length = 0, serial_steering_servo_pulse_length = 0; unsigned long serial_throttle_servo_pulse_refreshed = 0, serial_steering_servo_pulse_refreshed = 0; void setup() { Serial.begin(SERIAL_BUAD_RATE); pinMode(LED_BUILTIN, OUTPUT); last_microseconds = micros(); last_rc_throttle_pin_state = digitalRead(RC_THROTTLE_SERVO_PIN) == HIGH; last_rc_steering_pin_state = digitalRead(RC_STEERING_SERVO_PIN) == HIGH; last_rc_throttle_microseconds = last_microseconds; last_rc_steering_microseconds = last_microseconds; } void loop() { unsigned long microseconds = micros(); bool rc_throttle_pin_state = digitalRead(RC_THROTTLE_SERVO_PIN) == HIGH; bool rc_steering_pin_state = digitalRead(RC_STEERING_SERVO_PIN) == HIGH; if(rc_throttle_pin_state && (!last_rc_throttle_pin_state)) // rising edge { last_rc_throttle_microseconds = microseconds; } if((!rc_throttle_pin_state) && last_rc_throttle_pin_state) // falling edge { unsigned long temp = microseconds - last_rc_throttle_microseconds; if(!rc_throttle_servo_pulse_length) { rc_throttle_servo_pulse_length = temp; } else { rc_throttle_servo_pulse_length = ((rc_throttle_servo_pulse_length * 3) + temp) >> 2; } rc_throttle_servo_pulse_refreshed = microseconds; } if(rc_throttle_servo_pulse_length // zero servo if not refreshed && ((microseconds - rc_throttle_servo_pulse_refreshed) > (2UL * RC_THROTTLE_SERVO_REFRESH_RATE))) { rc_throttle_servo_pulse_length = 0; } if(rc_steering_pin_state && (!last_rc_steering_pin_state)) // rising edge { last_rc_steering_microseconds = microseconds; } if((!rc_steering_pin_state) && last_rc_steering_pin_state) // falling edge { unsigned long temp = microseconds - last_rc_steering_microseconds; if(!rc_steering_servo_pulse_length) { rc_steering_servo_pulse_length = temp; } else { rc_steering_servo_pulse_length = ((rc_steering_servo_pulse_length * 3) + temp) >> 2; } rc_steering_servo_pulse_refreshed = microseconds; } if(rc_steering_servo_pulse_length // zero servo if not refreshed && ((microseconds - rc_steering_servo_pulse_refreshed) > (2UL * RC_STEERING_SERVO_REFRESH_RATE))) { rc_steering_servo_pulse_length = 0; } last_microseconds = microseconds; last_rc_throttle_pin_state = rc_throttle_pin_state; last_rc_steering_pin_state = rc_steering_pin_state; while(Serial.available()) { int c = Serial.read(); memmove(serial_buffer, serial_buffer + 1, sizeof(serial_buffer) - 2); serial_buffer[sizeof(serial_buffer) - 2] = c; if(c == '\n') { unsigned long serial_throttle_servo_pulse_length_tmp, serial_steering_servo_pulse_length_tmp; if(sscanf(serial_buffer, "{%lu,%lu}", &serial_throttle_servo_pulse_length_tmp, &serial_steering_servo_pulse_length_tmp) == 2) { if(!serial_throttle_servo_pulse_length) { serial_throttle_servo_pulse_length = serial_throttle_servo_pulse_length_tmp; } else { serial_throttle_servo_pulse_length = ((serial_throttle_servo_pulse_length * 3) + serial_throttle_servo_pulse_length_tmp) >> 2; } serial_throttle_servo_pulse_refreshed = microseconds; if(!serial_steering_servo_pulse_length) { serial_steering_servo_pulse_length = serial_steering_servo_pulse_length_tmp; } else { serial_steering_servo_pulse_length = ((serial_steering_servo_pulse_length * 3) + serial_steering_servo_pulse_length_tmp) >> 2; } serial_steering_servo_pulse_refreshed = microseconds; digitalWrite(LED_BUILTIN, (digitalRead(LED_BUILTIN) == HIGH) ? LOW : HIGH); } else { serial_throttle_servo_pulse_length = 0; serial_steering_servo_pulse_length = 0; } } } if(serial_throttle_servo_pulse_length // zero servo if not refreshed && ((microseconds - serial_throttle_servo_pulse_refreshed) > (2UL * SERIAL_THROTTLE_SERVO_REFRESH_RATE))) { serial_throttle_servo_pulse_length = 0; } if(serial_steering_servo_pulse_length // zero servo if not refreshed && ((microseconds - serial_steering_servo_pulse_refreshed) > (2UL * SERIAL_STEERING_SERVO_REFRESH_RATE))) { serial_steering_servo_pulse_length = 0; } if(rc_steering_servo_pulse_length) { if(!steering_servo.attached()) { throttle_servo.attach(THROTTLE_SERVO_PIN); steering_servo.attach(STEERING_SERVO_PIN); } if(serial_steering_servo_pulse_length) { if((rc_throttle_servo_pulse_length < RC_THROTTLE_DEAD_ZONE_MIN) || (rc_throttle_servo_pulse_length > RC_THROTTLE_DEAD_ZONE_MAX)) { throttle_servo.writeMicroseconds(serial_throttle_servo_pulse_length); } else { throttle_servo.writeMicroseconds(1500); } if((rc_steering_servo_pulse_length < RC_STEERING_DEAD_ZONE_MIN) || (rc_steering_servo_pulse_length > RC_STEERING_DEAD_ZONE_MAX)) { steering_servo.writeMicroseconds(rc_steering_servo_pulse_length); } else { steering_servo.writeMicroseconds(serial_steering_servo_pulse_length); } } else { throttle_servo.writeMicroseconds(rc_throttle_servo_pulse_length); steering_servo.writeMicroseconds(rc_steering_servo_pulse_length); } } else if(steering_servo.attached()) { throttle_servo.detach(); steering_servo.detach(); } } ================================================ FILE: tools/README.md ================================================ # OpenMV PC Tools Desktop 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. All 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. > **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. --- ## [GenX320 Event Streaming](genx320-event-streaming/README.md) Real-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). ![GenX320 Event Streaming GUI](genx320-event-streaming/genx320-event-streaming.png) **Key features:** - Dual visualization: event canvas + frequency heatmap side by side - Raw streaming mode (default) sends unprocessed 4-byte EVT 2.0 words vs 12-byte decoded structs — 3× less data over USB - Adaptive layout that maximizes image size as the window resizes - Colorbar legend with log or linear frequency scale - Save event CSV and frequency PNG to disk - Configurable FIFO depths, event buffer size, contrast, and colormap ``` pip install dearpygui numpy pyserial Pillow openmv python genx320-event-streaming/genx320_event_mode_streaming_on_pc.py ``` --- ## [GenX320 Overlay Calibration](genx320-overlay-calibration/README.md) Streams 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. ![GenX320 Overlay Calibration GUI](genx320-overlay-calibration/genx320_overlay_calibration.jpeg) **Key features:** - Dual live preview: main camera + GenX320 histogram side by side at matched display height - Composite view with adjustable alpha blending (0–100%) - Manual alignment: click 4 matching landmarks on each image - Automatic alignment: blob-grid detection with median filtering, Otsu thresholding, and RANSAC homography — includes a flickering calibration pattern window for event generation - GenX320 always operates in histogram mode (320×320 grayscale) — no format controls needed - Copyable 3×3 transform matrix displayed after calibration - Save main, GenX320, composite PNGs and transform TXT to disk ``` pip install dearpygui numpy pyserial Pillow openmv opencv-python python genx320-overlay-calibration/genx320_overlay_calibration_on_pc.py ``` --- ## [Thermal Overlay Calibration](thermal-overlay-calibration/README.md) Streams 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. ![Thermal Overlay Calibration GUI](thermal-overlay-calibration/thermal-overlay-calibration.jpeg) **Key features:** - Dual live preview: main camera + Lepton side by side at matched display height - Composite view with adjustable alpha blending (0–100%) - Manual alignment: click 4 matching landmarks on each image - Automatic alignment: heated checkerboard detection with CLAHE, Otsu thresholding, per-channel analysis, and RANSAC homography using all corners - Configurable pixel format (RGB565/GRAYSCALE) and color palette (IRONBOW/RAINBOW) per camera - Copyable 3×3 transform matrix displayed after calibration - Save main, Lepton, composite PNGs and transform TXT to disk ``` pip install dearpygui numpy pyserial Pillow openmv opencv-python python thermal-overlay-calibration/thermal_overlay_calibration_on_pc.py ``` --- ## [CCM Tuning](ccm-tuning/README.md) An 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. ![CCM Tuning GUI](ccm-tuning/ccm-tuning.jpg) **Key features:** - Live ISP pipeline: Raw Bayer → Debayer → Black Level → AWB → CCM → BCG - ColorChecker Classic solver: click four corners, get a least-squares CCM instantly - Multi-illuminant workflow: solve under each light source, record R/G and B/G ratios for piecewise interpolation in firmware - Save processed frame (BMP) and full pipeline state (TXT) to disk ``` pip install dearpygui opencv-python numpy pyserial Pillow openmv python ccm-tuning/ccm_tuning_on_pc.py ``` ================================================ FILE: tools/ccm-tuning/README.md ================================================ # CCM Tuning GUI for OpenMV N6 A 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. ![CCM Tuning GUI](ccm-tuning.jpg) ## Platform Notes macOS 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. On macOS and Linux the companion script's `read` method is automatically renamed to `readp` before execution (this is handled transparently by the PC script). CRC 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`. ## ISP Pipeline The tool mimics the N6 ISP pipeline in this order: ``` Raw Bayer → Debayer → Black Level Correction → AWB → CCM → BCG (Brightness / Contrast / Gamma LUT) ``` All parameters are applied in software on the PC so you can tune them interactively without reflashing the camera. ## Prerequisites 1. **OpenMV IDE** v4.8.4 or later — used to initially set up the camera firmware. 2. **OpenMV Cam Firmware** v5.0.0 or later. 3. **Python dependencies:** ``` pip install dearpygui opencv-python numpy pyserial Pillow openmv ``` ## Running ``` python ccm_tuning_on_pc.py ``` The 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: | Flag | Default | Description | |------|---------|-------------| | `--port PORT` | *(GUI selector)* | Serial port to connect on | | `--script PATH` | `ccm_tuning_on_cam.py` | MicroPython script to run on the camera | | `--baudrate N` | `921600` | Serial baud rate | | `--crc` | off (Linux/Mac), on (Windows) | Enable CRC on the serial protocol | | `--seq` | on | Enable sequence numbers | | `--ack` | off | Enable per-packet ACKs | | `--quiet` | off | Suppress camera stdout | | `--debug` | off | Enable verbose logging | | `--benchmark` | off | Headless throughput benchmark (no GUI) | ## Benchmark Mode Run without the GUI to measure raw USB frame throughput: ``` python ccm_tuning_on_pc.py --benchmark python ccm_tuning_on_pc.py --benchmark --port /dev/ttyACM0 ``` Prints at 10 Hz: ``` elapsed=4.1s fps=12.3 bw=3.76 MB/s res=640x480 total=50 frames ``` Press **Ctrl+C** to stop. ## GUI Overview ### Connection Bar (top of right panel) - **Script** — path to the MicroPython script that runs on the camera. Click the folder icon to browse. - **Port** — serial port drop-down. Hit the **R** button to refresh the list. - **Connect / Disconnect** — starts or stops the camera worker thread. ### Live Stats Display A read-only selectable text box showing the current ISP state on every frame: ``` Raw R 56.5 G 88.4 B 70.2 L 76.8 R/G 0.639 B/G 0.793 Black R 0 G 0 B 0 AWB R 1.359 G 0.869 B 1.095 CCM R: 1.479 -0.449 -0.030 G: -0.318 1.280 0.038 B: -0.086 -0.880 1.966 Sum R 1.000 G 1.000 B 1.000 Offset R 0.00 G 0.00 B 0.00 BCG B 0.000 C 1.000 G 2.200 ``` - **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. - **Black** — black level subtracted per channel. - **AWB** — auto white balance gains (or manual gains when AWB is set to manual). - **CCM** — the 3×3 color correction matrix currently applied. - **Sum** — row sums of the CCM (should be 1.000 for each row when correctly normalized). - **Offset** — per-channel additive offset applied after the CCM. - **BCG** — brightness, contrast, and gamma values applied via a LUT. ### Black Level Per-channel (R, G, B) integer black level offsets subtracted from the raw frame before debayering. ### Auto White Balance - **Auto** checkbox — when enabled, AWB gains are computed automatically each frame from the raw channel means and displayed live. - **R / G / B gain** sliders — when Auto is off, set manual gains here. ### 3×3 Matrix Per-Channel Offsets The 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. ### BCG (Brightness / Contrast / Gamma) - **B** — brightness offset (additive, applied before contrast). - **C** — contrast multiplier. - **G** — gamma exponent (no upper limit; values > 1 darken midtones, < 1 brighten midtones). ### ColorChecker CCM Solver (bottom of right panel) Used to automatically compute a CCM from a physical X-Rite ColorChecker Classic card placed in front of the camera. #### Workflow 1. Place the ColorChecker Classic card in the camera's field of view under the target light source. 2. Click **Pick ColorChecker** — the button changes to **Reset** while picking is active. 3. 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. 4. 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. 5. The grid overlay stays visible so you can verify the patch alignment. Click **Reset** (was Pick ColorChecker) to clear the corners and start over. 6. Click **Reset CCM to Identity** at any time to restore the CCM to the identity matrix (no color correction). > **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. ### Save Image + Settings Saves the current processed frame and all ISP parameters to disk: - `ccm_frame_.bmp` — the displayed (post-BCG) RGB image. - `ccm_params_.txt` — the full live stats text (same content as the stats box). Both 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`. ## Output File Format `ccm_params_*.txt` contains the complete pipeline state at the moment of saving, which can be pasted directly into firmware: ``` Raw R 56.5 G 88.4 B 70.2 L 76.8 R/G 0.639 B/G 0.793 Black R 0 G 0 B 0 ... CCM R: 1.479 -0.449 -0.030 G: -0.318 1.280 0.038 B: -0.086 -0.880 1.966 ... ``` ## Notes - The tool works on Windows, macOS, and Linux. See **Platform Notes** above for performance guidance. - The CCM solver uses the pre-CCM (post-AWB) image so that the solved matrix corrects sensor metamerism independently of the white balance. - CCM rows are normalized to sum to 1 after solving, enforcing the achromatic constraint (neutral surfaces stay neutral). - Clicking the image while **Pick ColorChecker** is active places corner markers. Clicking **Reset** at any point clears all corners and the overlay. ================================================ FILE: tools/ccm-tuning/ccm_tuning_on_cam.py ================================================ # This work is licensed under the MIT license. # Copyright (c) 2013-2026 OpenMV LLC. All rights reserved. # https://github.com/openmv/openmv/blob/master/LICENSE # # This shows off how to get the RAW image for color matrix tuning. # # This script is meant to be run using https://github.com/openmv/openmv-python # from a PC using desktop tools. No visualization or text output is generated # by this script for OpenMV IDE. import csi import protocol import json # Bayer type string to integer mapping # Maps camera's internal Bayer naming to integer pattern IDs. # # IMPORTANT: Camera's naming differs from OpenCV's by a 180° rotation. # The PC-side script handles the conversion: # Camera BGGR (0) → OpenCV RGGB # Camera GBRG (1) → OpenCV GRBG # Camera GRBG (2) → OpenCV GBRG # Camera RGGB (3) → OpenCV BGGR BAYER_TYPE_MAP = { 'bayer_bggr': 0, 'bayer_gbrg': 1, 'bayer_grbg': 2, 'bayer_rggb': 3, } # Initialize the sensor. csi0 = csi.CSI() csi0.reset() csi0.pixformat(csi.BAYER) csi0.framesize(csi.HD) csi0.framebuffers(1) img = csi0.snapshot() img_mv = memoryview(img.bytearray()) frame_available = False # Parse image info from string representation img_info = json.loads(str(img)) img_width = img_info['w'] img_height = img_info['h'] img_type = img_info['type'] img_size = img_info['size'] bayer_pattern = BAYER_TYPE_MAP.get(img_type, 0) # Default to BGGR if unknown # How to read/write sensor registers in python: # csi.write_reg(0x00, 0x01) # Example: Write 0x01 to register 0x00 # reg_value = csi.read_reg(0x00) # Example: Read register class BayerChannel: def size(self): return img_size def shape(self): return (img_height, img_width, bayer_pattern, img_size) def read(self, offset, size): global frame_available if frame_available: end = offset + size mv = img_mv[offset:end] if end == img_size: frame_available = False return mv return bytes(size) def poll(self): return frame_available protocol.register(name='bayer', backend=BayerChannel()) while True: if not frame_available: csi0.snapshot() frame_available = True ================================================ FILE: tools/ccm-tuning/ccm_tuning_on_pc.py ================================================ #!/usr/bin/env python3 # # This work is licensed under the MIT license. # Copyright (c) 2013-2026 OpenMV LLC. All rights reserved. # https://github.com/openmv/openmv/blob/master/LICENSE # # CCM tuning GUI for OpenMV cameras on PC. # Requires: pip install dearpygui # # Pipeline (mimics N6 ISP): # Raw Bayer stats → Debayer → Black Level → AWB → CCM → BCG LUT # import sys import os import argparse import time import logging import signal import threading import queue import numpy as np import cv2 import serial.tools.list_ports import dearpygui.dearpygui as dpg from openmv.camera import Camera COLOR_CAMERA = "\033[32m" COLOR_RESET = "\033[0m" # Bayer pattern integer to OpenCV conversion code mapping # # IMPORTANT: Camera's Bayer naming differs from OpenCV's by a 180° rotation. # This mapping converts from camera's pattern IDs to OpenCV's color codes: # 0 (Camera BGGR) → OpenCV RGGB (COLOR_BAYER_RG2RGB) # 1 (Camera GBRG) → OpenCV GRBG (COLOR_BAYER_GR2RGB) # 2 (Camera GRBG) → OpenCV GBRG (COLOR_BAYER_GB2RGB) # 3 (Camera RGGB) → OpenCV BGGR (COLOR_BAYER_BG2RGB) BAYER_PATTERNS = { 0: cv2.COLOR_BAYER_RG2RGB, 1: cv2.COLOR_BAYER_GR2RGB, 2: cv2.COLOR_BAYER_GB2RGB, 3: cv2.COLOR_BAYER_BG2RGB, } # For each bayer pattern ID, the (row, col) offset within the 2x2 block for R and B. # G occupies the other two positions: (r_row, b_col) and (b_row, r_col). # Pattern 0 (Camera BGGR → OpenCV RGGB): B G / G R → R at [1,1], B at [0,0] # Pattern 1 (Camera GBRG → OpenCV GRBG): G B / R G → R at [1,0], B at [0,1] # Pattern 2 (Camera GRBG → OpenCV GBRG): G R / B G → R at [0,1], B at [1,0] # Pattern 3 (Camera RGGB → OpenCV BGGR): R G / G B → R at [0,0], B at [1,1] BAYER_CHANNEL_POS = { 0: ((1, 1), (0, 0)), 1: ((1, 0), (0, 1)), 2: ((0, 1), (1, 0)), 3: ((0, 0), (1, 1)), } CTRL_WIDTH = 340 TEXTURE_TAG = "cam_tex" TEX_REG_TAG = "tex_reg" INIT_W = 1280 INIT_H = 800 # X-Rite ColorChecker Classic reference sRGB values (D65, 2-degree observer) # Row order top→bottom, left→right: Dark Skin … Black COLORCHECKER_SRGB = np.array([ [115, 82, 68], [194, 150, 130], [ 98, 122, 157], [ 87, 108, 67], [133, 128, 177], [103, 189, 170], [214, 126, 44], [ 80, 91, 166], [193, 90, 99], [ 94, 60, 108], [157, 188, 64], [224, 163, 46], [ 56, 61, 150], [ 70, 148, 73], [175, 54, 60], [231, 199, 31], [187, 86, 149], [ 8, 133, 161], [243, 243, 242], [200, 200, 200], [160, 160, 160], [122, 122, 121], [ 85, 85, 85], [ 52, 52, 52], ], dtype=np.float32) def list_com_ports(): """Return sorted list of available COM port device strings.""" return sorted(p.device for p in serial.tools.list_ports.comports()) # --------------------------------------------------------------------------- # ISP pipeline helpers # --------------------------------------------------------------------------- def bayer_channel_stats(bayer_raw, bayer_pattern): """Return per-channel (R, G, B) mean values from raw Bayer uint8 image.""" (r_row, r_col), (b_row, b_col) = BAYER_CHANNEL_POS[bayer_pattern] avg_r = float(bayer_raw[r_row::2, r_col::2].mean()) avg_b = float(bayer_raw[b_row::2, b_col::2].mean()) # G occupies two off-diagonal planes of equal size — average their means avg_g = (float(bayer_raw[r_row::2, b_col::2].mean()) + float(bayer_raw[b_row::2, r_col::2].mean())) * 0.5 return avg_r, avg_g, avg_b def compute_awb(avg_r, avg_g, avg_b): """ Compute AWB gains and luminance matching the N6 ISP algorithm. Luminance: L = R*0.299 + G*0.587 + B*0.114 Per-channel gain: gain_i = L / max(avg_i, 1) Matches stm_isp_update_awb: multi = round(L * 128 / avg), effective gain = L / avg. Returns: (gain_r, gain_g, gain_b), luminance """ luminance = avg_r * 0.299 + avg_g * 0.587 + avg_b * 0.114 return ( (luminance / max(avg_r, 1.0), luminance / max(avg_g, 1.0), luminance / max(avg_b, 1.0)), luminance, ) def build_bcg_lut(brightness, contrast, gamma): """ Build uint8[256] LUT for brightness/contrast/gamma correction. Formula (from imlib_update_gamma_table): out = clamp(round((pow(i/255, 1/gamma) * contrast + brightness) * 255), 0, 255) """ i = np.arange(256, dtype=np.float64) v = (np.power(i / 255.0, 1.0 / gamma) * contrast + brightness) * 255.0 return np.clip(np.round(v), 0, 255).astype(np.uint8) def process_frame(bayer_raw, bayer_pattern, state, lut=None): """ Run the full ISP pipeline on one raw Bayer frame. Returns (rgb_uint8 HxWx3, stats dict). lut: pre-built BCG lookup table; built from state if not provided. """ # Step 1: Raw Bayer stats (before any modification, for display) avg_r, avg_g, avg_b = bayer_channel_stats(bayer_raw, bayer_pattern) # AWB gains must be computed from BL-corrected means (AWB runs after BL in the N6) bl = state['black_level'] bl_avg_r = max(avg_r - bl[0], 0.0) bl_avg_g = max(avg_g - bl[1], 0.0) bl_avg_b = max(avg_b - bl[2], 0.0) (gain_r, gain_g, gain_b), luminance = compute_awb(bl_avg_r, bl_avg_g, bl_avg_b) # Step 2: Debayer rgb = cv2.cvtColor(bayer_raw, BAYER_PATTERNS[bayer_pattern]) px = rgb.astype(np.float32) # Step 3: Black level correction (per channel, clamped) if bl[0] or bl[1] or bl[2]: # skip if all zero px[:, :, 0] = np.clip(px[:, :, 0] - bl[0], 0, 255) px[:, :, 1] = np.clip(px[:, :, 1] - bl[1], 0, 255) px[:, :, 2] = np.clip(px[:, :, 2] - bl[2], 0, 255) # Step 4: White balance (auto-computed or manual gains) if state['awb_auto']: gr, gg, gb = gain_r, gain_g, gain_b else: gr, gg, gb = state['awb_gains'] px[:, :, 0] = np.clip(px[:, :, 0] * gr, 0, 255) px[:, :, 1] = np.clip(px[:, :, 1] * gg, 0, 255) px[:, :, 2] = np.clip(px[:, :, 2] * gb, 0, 255) pre_ccm = px.clip(0, 255).astype(np.uint8) # Step 5: Color correction matrix if state['ccm_enabled']: flat = px.reshape(-1, 3) @ state['ccm'].T off = state['ccm_offsets'] if off[0] or off[1] or off[2]: flat += np.array(off, dtype=np.float32) px = np.clip(flat, 0, 255).reshape(px.shape) # Step 6: Brightness / contrast / gamma LUT if lut is None: lut = build_bcg_lut(state['brightness'], state['contrast'], state['gamma']) out = lut[px.astype(np.uint8)] stats = { 'avg_r': avg_r, 'avg_g': avg_g, 'avg_b': avg_b, 'luminance': luminance, 'gain_r': gain_r, 'gain_g': gain_g, 'gain_b': gain_b, } return out, stats, pre_ccm def compute_homography(src, dst): """DLT homography from 4 src points to 4 dst points (each [4,2] float).""" A = [] for (x, y), (u, v) in zip(src, dst): A.append([-x, -y, -1, 0, 0, 0, u*x, u*y, u]) A.append([ 0, 0, 0, -x, -y, -1, v*x, v*y, v]) _, _, Vt = np.linalg.svd(np.array(A, dtype=np.float64)) H = Vt[-1].reshape(3, 3) return H / H[2, 2] # --------------------------------------------------------------------------- # Camera background thread # --------------------------------------------------------------------------- def camera_worker(args, state_lock, state, frame_q, stop_evt): try: # Per-connection caches (reset on each connect) lut_key = None lut = None tex_buf = None # pre-allocated float32 RGBA, reused every frame tex_shape = (0, 0) with Camera( args.port, baudrate=args.baudrate, crc=args.crc, seq=args.seq, ack=args.ack, events=args.events, timeout=args.timeout, max_retry=args.max_retry, max_payload=args.max_payload, drop_rate=args.drop_rate, ) as camera: logging.info(f"Connected to OpenMV on {args.port}") camera.stop() time.sleep(0.5) with open(args.script) as f: script = f.read() if sys.platform != 'win32': script = script.replace('def read(self, offset, size):', 'def readp(self, offset, size):') camera.exec(script) logging.info("Script running, streaming frames...") while not stop_evt.is_set(): status = camera.read_status() if not args.quiet and status and status.get('stdout'): if text := camera.read_stdout(): print(f"{COLOR_CAMERA}{text}{COLOR_RESET}", end='') if not camera.has_channel('bayer') or not status.get('bayer'): time.sleep(0.01) continue size = camera.channel_size('bayer') if size <= 0: time.sleep(0.01) continue shape = camera._channel_shape(camera.get_channel(name="bayer")) if not shape or len(shape) < 3: time.sleep(0.01) continue h, w, bayer_pat = shape[0], shape[1], shape[2] if bayer_pat not in BAYER_PATTERNS: logging.error(f"Unknown bayer pattern: {bayer_pat}") time.sleep(0.01) continue # Ensure a full frame is available before reading expected = h * w if size < expected: time.sleep(0.01) continue data = camera.channel_read('bayer', expected) if len(data) < expected: time.sleep(0.01) continue bayer_raw = np.frombuffer(data, dtype=np.uint8).reshape(h, w) # Snapshot state under lock with state_lock: s = { 'awb_auto': state['awb_auto'], 'awb_gains': list(state['awb_gains']), 'black_level': list(state['black_level']), 'ccm_enabled': state['ccm_enabled'], 'ccm': state['ccm'].copy(), 'ccm_offsets': list(state['ccm_offsets']), 'brightness': state['brightness'], 'contrast': state['contrast'], 'gamma': state['gamma'], } # Rebuild BCG LUT only when parameters change new_lut_key = (s['brightness'], s['contrast'], s['gamma']) if new_lut_key != lut_key: lut_key = new_lut_key lut = build_bcg_lut(*lut_key) rgb_out, stats, pre_ccm = process_frame(bayer_raw, bayer_pat, s, lut) # Fill pre-allocated RGBA float32 buffer (avoid per-frame allocation) h_out, w_out = rgb_out.shape[:2] if (h_out, w_out) != tex_shape: tex_buf = np.ones((h_out, w_out, 4), dtype=np.float32) tex_shape = (h_out, w_out) tex_buf[:, :, :3] = rgb_out * (1.0 / 255.0) tex_data = tex_buf.ravel() # view — no extra allocation # Keep only the latest frame if frame_q.full(): try: frame_q.get_nowait() except queue.Empty: pass frame_q.put((w, h, tex_data, stats, rgb_out, pre_ccm)) except Exception as e: logging.error(f"Camera error: {e}") if args.debug: import traceback logging.error(traceback.format_exc()) # --------------------------------------------------------------------------- # Argument parsing # --------------------------------------------------------------------------- def str2bool(v): if isinstance(v, bool): return v if v.lower() in ('yes', 'true', 't', 'y', '1'): return True if v.lower() in ('no', 'false', 'f', 'n', '0'): return False raise argparse.ArgumentTypeError('Boolean value expected.') def parse_args(): p = argparse.ArgumentParser( description='OpenMV CCM tuning GUI (mimics N6 ISP pipeline)') # Connection p.add_argument('--port', default=None, help='Serial port (auto-selected in GUI if omitted)') p.add_argument('--script', default=None, help='MicroPython script to run on the camera ' '(defaults to ccm_tuning_on_cam.py next to this file)') p.add_argument('--baudrate', type=int, default=921600) p.add_argument('--timeout', type=float, default=1.0) p.add_argument('--crc', type=str2bool, nargs='?', const=True, default=(sys.platform == 'win32')) p.add_argument('--seq', type=str2bool, nargs='?', const=True, default=True) p.add_argument('--ack', type=str2bool, nargs='?', const=True, default=False) p.add_argument('--events', type=str2bool, nargs='?', const=True, default=True) p.add_argument('--max-retry', type=int, default=3) p.add_argument('--max-payload', type=int, default=4096) p.add_argument('--drop-rate', type=float, default=0.0) p.add_argument('--quiet', action='store_true', help='Suppress camera stdout') p.add_argument('--debug', action='store_true') p.add_argument('--benchmark', action='store_true', help='Headless mode: print frame rate and bandwidth stats, no GUI') return p.parse_args() # --------------------------------------------------------------------------- # Benchmark (headless) # --------------------------------------------------------------------------- EMA_ALPHA = 0.2 def run_benchmark(args): """Headless benchmark: camera thread only, frame rate and bandwidth printed to terminal.""" if not args.port: ports = [p.device for p in serial.tools.list_ports.comports()] if not ports: print("No serial ports found. Use --port to specify one.") sys.exit(1) args.port = ports[0] print(f"Auto-selected port: {args.port}") if args.script is None: args.script = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'ccm_tuning_on_cam.py') stop_evt = threading.Event() def handle_exit(signum, frame): stop_evt.set() signal.signal(signal.SIGINT, handle_exit) signal.signal(signal.SIGTERM, handle_exit) frame_q = queue.Queue(maxsize=4) state_lock = threading.Lock() state = { 'awb_auto': True, 'awb_gains': [1.0, 1.0, 1.0], 'black_level': [0, 0, 0], 'ccm_enabled': False, 'ccm': np.eye(3, dtype=np.float32), 'ccm_offsets': [0.0, 0.0, 0.0], 'brightness': 0.0, 'contrast': 1.0, 'gamma': 1.0, } cam_t = threading.Thread( target=camera_worker, args=(args, state_lock, state, frame_q, stop_evt), daemon=True, ) print(f"Connecting to {args.port} ...") cam_t.start() total_frames = 0 total_bytes = 0 fps_ema = 0.0 mbps_ema = 0.0 last_time = time.perf_counter() start_time = last_time last_print = last_time while not stop_evt.is_set(): try: w, h, _tex, _stats, _rgb, _pre = frame_q.get(timeout=0.05) except queue.Empty: if not cam_t.is_alive(): if not stop_evt.is_set(): print("Camera thread died unexpectedly.") break continue now = time.perf_counter() dt = now - last_time last_time = now if dt <= 0.0: continue frame_bytes = w * h fps_inst = 1.0 / dt mbps_inst = frame_bytes / 1048576.0 / dt fps_ema = fps_inst if fps_ema == 0.0 else fps_ema * (1 - EMA_ALPHA) + fps_inst * EMA_ALPHA mbps_ema = mbps_inst if mbps_ema == 0.0 else mbps_ema * (1 - EMA_ALPHA) + mbps_inst * EMA_ALPHA total_frames += 1 total_bytes += frame_bytes if now - last_print >= 0.1: last_print = now elapsed = now - start_time print(f"elapsed={elapsed:.1f}s\t" f"fps={fps_ema:.1f}\t" f"bw={mbps_ema:.2f} MB/s\t" f"res={w}x{h}\t" f"total={total_frames:,} frames") stop_evt.set() print("\nDone.") # --------------------------------------------------------------------------- # main # --------------------------------------------------------------------------- def main(args=None): if args is None: args = parse_args() if args.script is None: args.script = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'ccm_tuning_on_cam.py') logging.basicConfig( format="%(relativeCreated)010.3f - %(message)s", level=logging.DEBUG if args.debug else logging.INFO, ) # Default tuning values (all adjustable live in the GUI) init_ccm = np.eye(3, dtype=np.float32) init_ccm_offsets = [0.0, 0.0, 0.0] init_black_level = [0, 0, 0] # Shared mutable state (accessed by both GUI callbacks and camera thread) state_lock = threading.Lock() # Latest frames for saving/CCM computation last_frame = [None] # latest post-processed HxWx3 uint8 last_pre_ccm = [None] # latest pre-CCM HxWx3 uint8 # ColorChecker corner picking state cc_state = {'corners': [], 'picking': False} state = { 'awb_auto': True, 'awb_gains': [1.0, 1.0, 1.0], # used when awb_auto is False 'black_level': init_black_level, 'ccm_enabled': True, 'ccm': init_ccm, 'ccm_offsets': init_ccm_offsets, 'brightness': 0.0, 'contrast': 1.0, 'gamma': 2.2, } frame_q = queue.Queue(maxsize=1) # Connection state (mutated by GUI callbacks and checked in render loop) conn = {'thread': None, 'stop_evt': None} # ----------------------------------------------------------------------- # Dear PyGui setup # ----------------------------------------------------------------------- dpg.create_context() # File dialog for script selection (created before the main window) def cb_file_selected(sender, app_data): path = app_data.get('file_path_name', '') if path: args.script = path dpg.set_value("script_path", path) with dpg.file_dialog(directory_selector=False, show=False, callback=cb_file_selected, tag="file_dialog", width=700, height=450, default_path=os.path.dirname(args.script) if args.script else os.getcwd()): dpg.add_file_extension(".py", color=(100, 255, 100, 255)) dpg.add_file_extension(".*", color=(255, 255, 255, 255)) # Placeholder dark-gray texture shown before camera connects placeholder = np.full(INIT_W * INIT_H * 4, 0.05, dtype=np.float32) placeholder[3::4] = 1.0 with dpg.texture_registry(tag=TEX_REG_TAG): dpg.add_dynamic_texture(INIT_W, INIT_H, placeholder, tag=TEXTURE_TAG) tex_wh = [INIT_W, INIT_H] # ---- Callbacks -------------------------------------------------------- # Generic scalar state key setter def cb(key): def _cb(s, v, u=None): with state_lock: state[key] = v return _cb # List-element setter (for black_level, ccm_offsets) def cb_idx(key, idx): def _cb(s, v, u=None): with state_lock: state[key][idx] = v return _cb # CCM matrix cell setter (user_data = (row, col)) def cb_ccm_cell(s, v, user_data): r, c = user_data with state_lock: state['ccm'][r, c] = v # ---- Connection callbacks --------------------------------------------- def do_connect(port): args.port = port stop_evt = threading.Event() conn['stop_evt'] = stop_evt t = threading.Thread( target=camera_worker, args=(args, state_lock, state, frame_q, stop_evt), daemon=True, ) t.start() conn['thread'] = t dpg.configure_item("connect_btn", label="Disconnect") logging.info(f"Connecting to {port}...") def do_disconnect(): if conn['stop_evt']: conn['stop_evt'].set() conn['thread'] = None conn['stop_evt'] = None dpg.configure_item("connect_btn", label="Connect") def cb_refresh(s, v, u=None): items = list_com_ports() dpg.configure_item("port_combo", items=items) if items and not dpg.get_value("port_combo"): dpg.set_value("port_combo", items[0]) def cb_connect(s, v, u=None): if conn['thread'] and conn['thread'].is_alive(): do_disconnect() else: if not args.script: return port = dpg.get_value("port_combo") if not port: return do_connect(port) # ---- ColorChecker / Save callbacks ------------------------------------ def cb_save(s=None, v=None, u=None): frame = last_frame[0] if frame is None: dpg.set_value("cc_status", "No image captured yet.") return ts = int(time.time()) try: from PIL import Image bmp_name = f"ccm_frame_{ts}.bmp" Image.fromarray(frame, 'RGB').save(bmp_name) print(f"Saved BMP: {bmp_name}") except ImportError: print("pip install Pillow to enable BMP saving.") txt_name = f"ccm_params_{ts}.txt" with open(txt_name, 'w') as f: f.write(dpg.get_value("stat_line") + "\n") print(f"Saved text: {txt_name}") def cb_pick_cc(s=None, v=None, u=None): if cc_state['picking'] or cc_state['corners']: # Reset mode cc_state['corners'] = [] cc_state['picking'] = False dpg.configure_item("btn_pick_cc", label="Pick ColorChecker") dpg.set_value("cc_status", "") dpg.delete_item("vp_overlay", children_only=True) else: # Start picking if last_frame[0] is None: dpg.set_value("cc_status", "No image captured yet.") return cc_state['corners'] = [] cc_state['picking'] = True dpg.configure_item("btn_pick_cc", label="Reset") dpg.set_value("cc_status", "Click top-left outer corner of card") def cb_compute_ccm(s=None, v=None, u=None): frame = last_pre_ccm[0] corners = cc_state['corners'] if len(corners) != 4: dpg.set_value("cc_status", "Pick 4 corners first.") return if frame is None: dpg.set_value("cc_status", "No frame captured yet.") return src = np.float64(corners) # dst: outer corners of 6-col × 4-row grid dst = np.float64([(0, 0), (6, 0), (6, 4), (0, 4)]) H_fwd = compute_homography(src, dst) H_inv = np.linalg.inv(H_fwd) fh, fw = frame.shape[:2] measured = [] for row in range(4): for col in range(6): cx, cy = col + 0.5, row + 0.5 vals = [] for dy in np.linspace(-0.3, 0.3, 7): for dx in np.linspace(-0.3, 0.3, 7): pt = H_inv @ np.array([cx+dx, cy+dy, 1.0]) px_x = int(round(pt[0] / pt[2])) px_y = int(round(pt[1] / pt[2])) if 0 <= px_x < fw and 0 <= px_y < fh: vals.append(frame[px_y, px_x].astype(np.float64)) measured.append(np.mean(vals, axis=0) if vals else np.zeros(3)) measured = np.array(measured, dtype=np.float64) # [24,3] ref_lin = np.power(COLORCHECKER_SRGB / 255.0, 2.2) * 255.0 ccm_new, _, _, _ = np.linalg.lstsq(measured, ref_lin, rcond=None) ccm_new = ccm_new.T.astype(np.float32) # [3,3] # Normalize rows to sum to 1 (achromatic constraint) for i in range(3): ccm_new[i] /= ccm_new[i].sum() with state_lock: state['ccm'] = ccm_new for r in range(3): for c in range(3): dpg.set_value(f"ccm_{r}{c}", float(ccm_new[r, c])) print(f"CCM solved:\n{ccm_new}") dpg.set_value("cc_status", "CCM applied.") cc_state['picking'] = False dpg.configure_item("btn_pick_cc", label="Reset") def cb_reset_ccm(s=None, v=None, u=None): identity = np.eye(3, dtype=np.float32) with state_lock: state['ccm'] = identity.copy() for r in range(3): for c in range(3): dpg.set_value(f"ccm_{r}{c}", float(identity[r, c])) dpg.set_value("cc_status", "CCM reset to identity.") def cb_image_click(s=None, v=None, u=None): if not cc_state['picking']: return if last_frame[0] is None: return mx, my = dpg.get_mouse_pos(local=False) try: imin = dpg.get_item_rect_min("cam_img") imax = dpg.get_item_rect_max("cam_img") except Exception: return if not (imin[0] <= mx <= imax[0] and imin[1] <= my <= imax[1]): return fw, fh = tex_wh dw = imax[0] - imin[0] dh = imax[1] - imin[1] fx = int((mx - imin[0]) / dw * fw) fy = int((my - imin[1]) / dh * fh) cc_state['corners'].append((fx, fy)) n = len(cc_state['corners']) labels = ["top-left", "top-right", "bottom-right", "bottom-left"] if n < 4: dpg.set_value("cc_status", f"Click {labels[n]} outer corner of card") else: cc_state['picking'] = False dpg.set_value("cc_status", "4 corners set - click Compute CCM") # ---- UI layout -------------------------------------------------------- cell_w = (CTRL_WIDTH - 36) // 3 with dpg.window(tag="main_win", no_scrollbar=True, no_title_bar=True): with dpg.table( header_row=False, resizable=True, borders_innerV=True, tag="layout_table", scrollX=False, scrollY=False, ): dpg.add_table_column(init_width_or_weight=1.0) # camera panel dpg.add_table_column(init_width_or_weight=CTRL_WIDTH, width_fixed=True) # controls with dpg.table_row(): # ── Left: camera preview + stats bar ────────────────────── with dpg.table_cell(): dpg.add_image(TEXTURE_TAG, tag="cam_img", width=INIT_W, height=INIT_H) dpg.add_separator() dpg.add_input_text( tag="stat_line", default_value="Waiting for camera...", multiline=True, readonly=True, width=-1, height=226) # ── Right: control panel ─────────────────────────────────── with dpg.table_cell(): with dpg.child_window(width=CTRL_WIDTH, border=False): # ── Windows performance warning ───────────────────── if sys.platform == 'win32': dpg.add_text( "Warning: Windows reduces transfer speed.\n" "Use macOS or Linux for best performance.", color=(255, 200, 0, 255)) dpg.add_separator() # ── Connection ───────────────────────────────────── with dpg.group(): # Script picker with dpg.group(horizontal=True): dpg.add_text("Script", indent=0) dpg.add_input_text( tag="script_path", default_value=args.script, hint="select a .py script...", width=CTRL_WIDTH - 112, readonly=True) dpg.add_button( label="...", width=28, callback=lambda: dpg.show_item("file_dialog")) # Port picker init_ports = list_com_ports() init_port = args.port or (init_ports[0] if init_ports else "") with dpg.group(horizontal=True): dpg.add_text("Port ") dpg.add_combo( items=init_ports, default_value=init_port, tag="port_combo", width=CTRL_WIDTH - 112) dpg.add_button(label="Ref", callback=cb_refresh, width=28) dpg.add_button(label="Connect", tag="connect_btn", callback=cb_connect, width=-1) # ── White Balance ────────────────────────────────── dpg.add_separator() with dpg.group(): dpg.add_text("Black Level (per channel, 0-255)") for lbl, idx, color in [ ("R", 0, (255, 80, 80, 255)), ("G", 1, ( 80, 200, 80, 255)), ("B", 2, ( 80, 130, 255, 255)), ]: with dpg.group(horizontal=True): dpg.add_text(lbl, color=color) dpg.add_input_int( label=f"##{lbl}bl", default_value=init_black_level[idx], min_value=0, max_value=255, min_clamped=True, max_clamped=True, step=1, step_fast=10, callback=cb_idx('black_level', idx), width=-1) dpg.add_separator() dpg.add_text("AWB Gains") def cb_awb_auto(s, v, u=None): with state_lock: state['awb_auto'] = v if not v: # Snapshot current displayed gains so they # apply immediately without needing an edit state['awb_gains'] = [ dpg.get_value("wb_gain_r"), dpg.get_value("wb_gain_g"), dpg.get_value("wb_gain_b"), ] ro = v # readonly when auto for tag in ('wb_gain_r', 'wb_gain_g', 'wb_gain_b'): dpg.configure_item(tag, readonly=ro) dpg.add_checkbox(label="Auto", default_value=True, callback=cb_awb_auto, tag="wb_auto_cb") for lbl, idx, color, tag in [ ("R", 0, (255, 80, 80, 255), "wb_gain_r"), ("G", 1, ( 80, 200, 80, 255), "wb_gain_g"), ("B", 2, ( 80, 130, 255, 255), "wb_gain_b"), ]: with dpg.group(horizontal=True): dpg.add_text(lbl, color=color) dpg.add_input_float( tag=tag, label=f"##{lbl}wb", default_value=1.0, min_value=0.0, max_value=16.0, min_clamped=True, max_clamped=True, step=0.001, step_fast=0.1, format="%.3f", readonly=True, # starts in auto mode callback=cb_idx('awb_gains', idx), width=-1) # ── Color Correction Matrix ──────────────────────── dpg.add_separator() with dpg.group(): dpg.add_text("3x3 Matrix (drag | dbl-click to type)") row_colors = [ ("R", (255, 80, 80, 255)), ("G", ( 80, 200, 80, 255)), ("B", ( 80, 130, 255, 255)), ] for r, (lbl, color) in enumerate(row_colors): with dpg.group(horizontal=True): dpg.add_text(lbl, color=color) for c in range(3): dpg.add_drag_float( tag=f"ccm_{r}{c}", default_value=float(init_ccm[r, c]), speed=0.005, min_value=-4.0, max_value=4.0, format="%.3f", width=cell_w, callback=cb_ccm_cell, user_data=(r, c)) dpg.add_separator() dpg.add_text("3x3 Matrix Per-Channel Offsets") for lbl, idx, color in [ ("R", 0, (255, 80, 80, 255)), ("G", 1, ( 80, 200, 80, 255)), ("B", 2, ( 80, 130, 255, 255)), ]: with dpg.group(horizontal=True): dpg.add_text(lbl, color=color) dpg.add_input_float( label=f"##{lbl}off", default_value=init_ccm_offsets[idx], min_value=-64.0, max_value=64.0, min_clamped=True, max_clamped=True, step=0.1, step_fast=1.0, format="%.2f", callback=cb_idx('ccm_offsets', idx), width=-1) # ── Brightness / Contrast / Gamma ────────────────── dpg.add_separator() dpg.add_text("Brightness / Contrast / Gamma") with dpg.group(): with dpg.group(horizontal=True): dpg.add_text("Brightness") dpg.add_input_float( label="##brightness", default_value=0.0, min_value=-1.0, max_value=1.0, min_clamped=True, max_clamped=True, step=0.01, step_fast=0.1, format="%.2f", callback=cb('brightness'), width=-1) with dpg.group(horizontal=True): dpg.add_text("Contrast ") dpg.add_input_float( label="##contrast", default_value=1.0, min_value=0.0, max_value=3.0, min_clamped=True, max_clamped=True, step=0.01, step_fast=0.1, format="%.2f", callback=cb('contrast'), width=-1) with dpg.group(horizontal=True): dpg.add_text("Gamma ") dpg.add_input_float( label="##gamma", default_value=2.2, min_value=0.1, min_clamped=True, step=0.01, step_fast=0.1, format="%.2f", callback=cb('gamma'), width=-1) # ── ColorChecker / Save ──────────────────────────── dpg.add_separator() dpg.add_button(label="Pick ColorChecker", tag="btn_pick_cc", callback=cb_pick_cc, width=-1) dpg.add_button(label="Compute CCM", tag="btn_compute_ccm", callback=cb_compute_ccm, width=-1) dpg.add_button(label="Reset CCM to Identity", callback=cb_reset_ccm, width=-1) dpg.add_button(label="Save Image + Settings", tag="btn_save", callback=cb_save, width=-1) dpg.add_text("", tag="cc_status") with dpg.handler_registry(): dpg.add_mouse_click_handler(button=0, callback=cb_image_click) dpg.create_viewport(title="OpenMV CCM Tuner", width=1280, height=900, resizable=True) dpg.setup_dearpygui() dpg.show_viewport() dpg.set_primary_window("main_win", True) def handle_exit(signum, frame): if conn['stop_evt']: conn['stop_evt'].set() dpg.stop_dearpygui() signal.signal(signal.SIGINT, handle_exit) signal.signal(signal.SIGTERM, handle_exit) # Auto-connect if --port (and --script) were supplied on the command line if args.port and args.script: do_connect(args.port) # Track display size to avoid redundant configure_item calls disp_wh = [0, 0] def fit_image(): """Resize cam_img to fill the left panel while keeping aspect ratio.""" fw, fh = tex_wh if fw <= 0 or fh <= 0: return avail_w = max(dpg.get_viewport_width() - CTRL_WIDTH - 30, 1) avail_h = max(dpg.get_viewport_height() - 60, 1) scale = min(avail_w / fw, avail_h / fh) dw, dh = max(int(fw * scale), 1), max(int(fh * scale), 1) if [dw, dh] != disp_wh: disp_wh[0], disp_wh[1] = dw, dh dpg.configure_item("cam_img", width=dw, height=dh) dpg.set_viewport_resize_callback(lambda: fit_image()) fit_image() dpg.add_viewport_drawlist(tag="vp_overlay", front=True) # ----------------------------------------------------------------------- # Render loop # ----------------------------------------------------------------------- while dpg.is_dearpygui_running(): # Detect thread death (e.g. camera unplugged) t = conn['thread'] if t is not None and not t.is_alive(): conn['thread'] = None conn['stop_evt'] = None dpg.configure_item("connect_btn", label="Connect") try: w, h, tex_data, stats, rgb_out, pre_ccm = frame_q.get_nowait() last_frame[0] = rgb_out last_pre_ccm[0] = pre_ccm # Recreate texture when frame dimensions change if w != tex_wh[0] or h != tex_wh[1]: tex_wh[0], tex_wh[1] = w, h dpg.delete_item(TEXTURE_TAG) dpg.remove_alias(TEXTURE_TAG) dpg.add_dynamic_texture(w, h, tex_data, tag=TEXTURE_TAG, parent=TEX_REG_TAG) dpg.configure_item("cam_img", texture_tag=TEXTURE_TAG) fit_image() else: dpg.set_value(TEXTURE_TAG, tex_data) fit_image() # Update live parameter display s = stats with state_lock: ccm = state['ccm'].copy() off = state['ccm_offsets'][:] bl = state['black_level'][:] br = state['brightness'] co = state['contrast'] ga = state['gamma'] awb_auto = state['awb_auto'] awb_gains = state['awb_gains'][:] 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]) # R/G and B/G ratios use BL-corrected means (illuminant fingerprint) bl_r = max(s['avg_r'] - bl[0], 0.0) bl_g = max(s['avg_g'] - bl[1], 0.0) bl_b = max(s['avg_b'] - bl[2], 0.0) avg_g = bl_g if bl_g > 0 else 1.0 rg = bl_r / avg_g bg = bl_b / avg_g rs = float(ccm[0].sum()) gs = float(ccm[1].sum()) bs = float(ccm[2].sum()) dpg.set_value("stat_line", "\n".join([ f"Raw R {s['avg_r']:6.3f} G {s['avg_g']:6.3f} B {s['avg_b']:6.3f}", f" L {s['luminance']:6.3f} R/G {rg:6.3f} B/G {bg:6.3f}", "", f"Black R {bl[0]:6d} G {bl[1]:6d} B {bl[2]:6d}", "", f"AWB R {gr:6.3f} G {gg:6.3f} B {gb:6.3f}", "", f"CCM R: {ccm[0,0]:7.3f} {ccm[0,1]:7.3f} {ccm[0,2]:7.3f}", f" G: {ccm[1,0]:7.3f} {ccm[1,1]:7.3f} {ccm[1,2]:7.3f}", f" B: {ccm[2,0]:7.3f} {ccm[2,1]:7.3f} {ccm[2,2]:7.3f}", "", f"Sum R {rs:6.3f} G {gs:6.3f} B {bs:6.3f}", "", f"Offset R {off[0]:6.2f} G {off[1]:6.2f} B {off[2]:6.2f}", "", f"BCG B {br:6.3f} C {co:6.3f} G {ga:6.3f}", ])) # Push auto-computed gains into the gain fields if dpg.get_value("wb_auto_cb"): dpg.set_value("wb_gain_r", s['gain_r']) dpg.set_value("wb_gain_g", s['gain_g']) dpg.set_value("wb_gain_b", s['gain_b']) except queue.Empty: pass # Draw ColorChecker corner overlays (runs every frame, camera or not) dpg.delete_item("vp_overlay", children_only=True) if cc_state['corners']: try: imin = dpg.get_item_rect_min("cam_img") imax = dpg.get_item_rect_max("cam_img") fw, fh = tex_wh dw = imax[0] - imin[0] dh = imax[1] - imin[1] labels = ["TL", "TR", "BR", "BL"] colors = [(0,255,0,255),(255,255,0,255),(255,165,0,255),(255,0,0,255)] for i, (fx, fy) in enumerate(cc_state['corners']): sx = imin[0] + fx / fw * dw sy = imin[1] + fy / fh * dh dpg.draw_circle([sx, sy], 8, color=colors[i], thickness=2, parent="vp_overlay") dpg.draw_text([sx+10, sy-8], labels[i], size=14, color=colors[i], parent="vp_overlay") if len(cc_state['corners']) == 4: # Draw the grid lines across all 4 corners src = np.float64(cc_state['corners']) dst = np.float64([(0,0),(6,0),(6,4),(0,4)]) H_inv = np.linalg.inv(compute_homography(src, dst)) def warp(cx, cy): pt = H_inv @ np.array([cx, cy, 1.0]) gx = pt[0]/pt[2]; gy = pt[1]/pt[2] return [imin[0]+gx/fw*dw, imin[1]+gy/fh*dh] for r in range(5): # 5 lines = 4 rows of patches dpg.draw_line(warp(0, r), warp(6, r), color=(0,255,0,128), parent="vp_overlay") for c in range(7): # 7 lines = 6 columns of patches dpg.draw_line(warp(c, 0), warp(c, 4), color=(0,255,0,128), parent="vp_overlay") for row in range(4): for col in range(6): dpg.draw_circle(warp(col + 0.5, row + 0.5), 3, color=(255,255,0,255), parent="vp_overlay") except Exception: pass # Reset UI if the camera thread died unexpectedly (e.g. connection error) if conn['thread'] and not conn['thread'].is_alive(): do_disconnect() dpg.render_dearpygui_frame() if conn['stop_evt']: conn['stop_evt'].set() dpg.destroy_context() if __name__ == '__main__': _args = parse_args() if _args.benchmark: run_benchmark(_args) else: main(_args) ================================================ FILE: tools/genx320-event-streaming/README.md ================================================ # GenX320 Event Streaming A 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. ![GenX320 Event Streaming GUI](genx320-event-streaming.png) ## Platform Notes macOS 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. On macOS and Linux the companion script's `read` method is automatically renamed to `readp` before execution (this is handled transparently by the PC script). CRC 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`. ## Prerequisites 1. **OpenMV IDE** v4.8.8 or later. 2. **OpenMV Cam Firmware** v5.0.0 or later. Update via `Tools → Install Latest Development Release` in the IDE. 3. **Python dependencies:** ``` pip install dearpygui numpy numba pyserial Pillow openmv ``` Numba 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. ## Running ``` python genx320_event_mode_streaming_on_pc.py ``` The camera script is selected automatically based on the **Stream** mode chosen in the GUI. You can override any option from the command line: | Flag | Default | Description | |------|---------|-------------| | `--port PORT` | *(GUI selector)* | Serial port to connect on | | `--script PATH` | *(set by Stream mode)* | MicroPython script to run on the camera | | `--baudrate N` | `921600` | Serial baud rate | | `--crc` | off (Linux/Mac), on (Windows) | Enable CRC on the serial protocol | | `--seq` | on | Enable sequence numbers | | `--ack` | off | Enable per-packet ACKs | | `--quiet` | off | Suppress camera stdout | | `--debug` | off | Enable verbose logging | | `--benchmark` | off | Headless throughput benchmark (no GUI) | ## Benchmark Mode Run without the GUI to measure raw USB throughput: ``` python genx320_event_mode_streaming_on_pc.py --benchmark python genx320_event_mode_streaming_on_pc.py --benchmark --port /dev/ttyACM0 ``` Prints at 10 Hz: ``` elapsed=3.2s rate=1,243,500 ev/s bw=8.94 MB/s total=3,982,400 ``` Press **Ctrl+C** to stop. ## GUI Overview The 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. ### Connection - **Script** — path to the MicroPython script. Click `...` to browse. - **Port** — serial port drop-down. Hit **Ref** to refresh. - **Connect / Disconnect** — starts or stops the camera worker thread. ### Camera Parameters *(applied at connect)* These patch the on-camera script before it is executed. They are locked while connected. | Control | Default | Description | |---------|---------|-------------| | Stream | Raw (fastest) | **Raw (fastest)** — streams unprocessed EVT 2.0 words, decoded on the PC; **Processed** — camera decodes events before sending | | CSI FIFO | 8 | Depth of the hardware CSI receive buffer | | EVT FIFO | 8 | Depth of the software event FIFO (Processed mode only) | | EVT Buffer | 8192 | Event array size (must be a power of two, 1024–65536) | ### Event Visualization Controls for the accumulation canvas (left image). | Control | Default | Description | |---------|---------|-------------| | Contrast | 16 | Per-event brightness step added to the canvas (±) | | Color | Grayscale | Color LUT: **Grayscale**, **Evt Dark**, or **Evt Light** (OpenMV rainbow palette) | | Mode | Sliding Window | **Sliding Window** — shows the last N batches live; **Canvas** — accumulates until N batches then auto-clears (0 = manual clear only) | | Window | 4 | Number of batches kept or accumulated | | Clear | *(button)* | Available in Canvas mode with Window = 0; manually clears the canvas | The canvas is initialized to mid-gray (128). Each event adds `±contrast` to its pixel and the result is clamped to [0, 255]. #### Frequency Visualization Real-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. Algorithm based on: [FrequencyCam — Imaging Periodic Signals in Real-Time](https://arxiv.org/abs/2211.00198) | Control | Default | Description | |---------|---------|-------------| | Cutoff T | 5.0 | Filter cutoff period in events. Higher values smooth more but respond slower. Reference recommends 5.0. | | Min Hz | 10 | Lowest frequency shown (pixels below this are black) | | Max Hz | 1000 | Highest frequency shown | | Timeout | 2 | Number of silent periods before a pixel goes dark | | Log frequency scale | on | Log₁₀ color mapping (recommended for wide frequency ranges) | | Overlay active pixels | off | Show pixels that have event activity but no locked frequency in grey | | Show legend | on | Display a colorbar on the right edge of the frequency image | | Bins | 11 | Number of labeled color patches in the legend | | Reset | *(button)* | Clear all per-pixel filter state | Colors run blue (low frequency) → red (high frequency). Black pixels either have no events yet or have timed out. ### Save Images and Events Saves the current state to disk. The button label reflects whether frequency visualization is enabled. - `events__evt.png` — the event canvas rendered with the current color LUT. - `events__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. - `events_.csv` — all events that built the current canvas (`type, sec, ms, us, x, y`). See **Camera Script Event Format** below for type values. These files are excluded from git via `.gitignore`. ### Statistics Live event throughput, updated at 5 Hz: | Field | Description | |-------|-------------| | Events/batch | Raw event count in the most recent batch | | Rate | Exponential moving average event rate (events/sec) | | Bandwidth | EMA data rate (MB/s) | | Total events | Cumulative event count since connect | | Uptime | Seconds since connect | ## Architecture The script uses a three-thread pipeline to keep USB throughput high while running the GUI: ``` camera_worker → raw_q → processing_worker → result_q → render loop ``` - **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. - **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. - **render loop** — drains `result_q`, uploads textures to DearPyGui, and updates the stats panel. ## Camera Script Event Format Both camera scripts produce the same event format on the PC side — a stream of 6 × uint16 little-endian rows: | Column | Value | |--------|-------| | 0 | Type — see table below | | 1 | Timestamp — whole seconds | | 2 | Timestamp — milliseconds within the second (0–999) | | 3 | Timestamp — microseconds within the millisecond (0–999) | | 4 | X coordinate (0–319); 0 for trigger events | | 5 | Y coordinate (0–319); 0 for trigger events | | Type value | Meaning | |------------|---------| | 0 | Pixel off event (decrease in illumination) | | 1 | Pixel on event (increase in illumination) | | 2 | External trigger — falling edge | | 3 | External trigger — rising edge | | 4 | Reset trigger — falling edge | | 5 | Reset trigger — rising edge | **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. **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. ================================================ FILE: tools/genx320-event-streaming/genx320_event_mode_streaming_on_cam.py ================================================ # This work is licensed under the MIT license. # Copyright (c) 2013-2025 OpenMV LLC. All rights reserved. # https://github.com/openmv/openmv/blob/master/LICENSE # # This example shows off using the genx320 event camera from Prophesee # using event streaming mode and sending the data back to the PC. # # This script is meant to be run using https://github.com/openmv/openmv-python # from a PC using desktop tools. No visualization or text output is generated # by this script for OpenMV IDE. import csi import protocol # https://micropython-ulab.readthedocs.io/en/latest/index.html from ulab import numpy as np # Event buffers arrive from the camera and are stored in # a fifo buffer before being processed by python. CSI_FIFO_DEPTH = 8 # Raw events post-processed by python, put into another # fifo buffer, and then sent to the PC. EVENT_FIFO_DEPTH = 8 # Must be a power of two between 1024 and 65536. EVT_RES = 8192 # Stores camera events (8 buffers) # Shape: (EVT_RES, 6) where EVT_RES is the event resolution # Columns: # [0] Event type # [1] Seconds timestamp # [2] Milliseconds timestamp # [3] Microseconds timestamp # [4] X coordinate 0 to 319 for GENX320 # [5] Y coordinate 0 to 319 for GENX320 events = [np.zeros((EVT_RES, 6), dtype=np.uint16) for i in range(EVENT_FIFO_DEPTH)] event_counts = [0 for i in range(EVENT_FIFO_DEPTH)] # ULAB .tobytes() creates shallow copy bytearrays. Wrap these in memoryviews # for fast slicing without copies. mv_events = [memoryview(events[i].tobytes()) for i in range(EVENT_FIFO_DEPTH)] # Event buffer fifo pointers. wr_index = 0 rd_index = 0 def read_available(): a = wr_index - rd_index if a < 0: a += EVENT_FIFO_DEPTH return a def write_available(): return EVENT_FIFO_DEPTH - 1 - read_available() # Initialize the sensor. csi0 = csi.CSI(cid=csi.GENX320) csi0.reset() csi0.ioctl(csi.IOCTL_GENX320_SET_MODE, csi.GENX320_MODE_EVENT, events[0].shape[0]) csi0.framebuffers(CSI_FIFO_DEPTH) class EventChannel: def size(self): if read_available(): return event_counts[rd_index] * 12 return 0 def read(self, offset, size): global rd_index if read_available(): end = offset + size mv = mv_events[rd_index][offset:end] # Free the buffer after all data has been read. if end == event_counts[rd_index] * 12: rd_index = (rd_index + 1) % EVENT_FIFO_DEPTH return mv return bytes(size) def poll(self): return read_available() protocol.register(name='events', backend=EventChannel()) while True: if (write_available()): # Reads up to 32768 events from the camera. # Returns the number of valid events (0-32768) or a negative error code. # Note that old events in the buffer are not cleared to save CPU time. event_counts[wr_index] = csi0.ioctl(csi.IOCTL_GENX320_READ_EVENTS, events[wr_index]) wr_index = (wr_index + 1) % EVENT_FIFO_DEPTH ================================================ FILE: tools/genx320-event-streaming/genx320_event_mode_streaming_on_pc.py ================================================ #!/usr/bin/env python3 # # This work is licensed under the MIT license. # Copyright (c) 2013-2026 OpenMV LLC. All rights reserved. # https://github.com/openmv/openmv/blob/master/LICENSE # # GenX320 event camera visualization GUI for PC. # Requires: pip install dearpygui numpy numba Pillow pyserial # # Two threads: camera_worker (receives events) and render loop (draws). # Canvas initialized to 128; events add contrast*polarity until clamping at 0/255. # Color modes: Grayscale, Evt Dark LUT, Evt Light LUT (RGB565 → RGB888). # import sys import os import argparse import time import logging import signal import threading import queue from collections import deque import numpy as np import numba try: from PIL import Image, ImageDraw _PIL_AVAILABLE = True except ImportError: _PIL_AVAILABLE = False import serial.tools.list_ports import dearpygui.dearpygui as dpg from openmv.camera import Camera COLOR_CAMERA = "\033[32m" COLOR_RESET = "\033[0m" # GENX320 sensor resolution SENSOR_W = 320 SENSOR_H = 320 CTRL_WIDTH = 300 LEGEND_DW = 80 # legend display width in pixels TEXTURE_TAG = "evt_tex" TEX_REG_TAG = "tex_reg" # --------------------------------------------------------------------------- # Color lookup tables (RGB565, 256 entries each) # Source: https://github.com/openmv/openmv/blob/master/lib/imlib/rainbow_tab.c # evt_dark_table @ L104 # evt_light_table @ L138 # Conversion: https://github.com/openmv/openmv/blob/master/lib/imlib/draw.c#L713 # --------------------------------------------------------------------------- _EVT_DARK_565 = np.array([ 0xD6FD, 0xD6FC, 0xD6DC, 0xD6DC, 0xD6DC, 0xCEBC, 0xCEBC, 0xCE9B, 0xCE9B, 0xCE9B, 0xC67B, 0xC67B, 0xC67B, 0xC65A, 0xC65A, 0xC65A, 0xBE3A, 0xBE3A, 0xBE1A, 0xBE19, 0xBE19, 0xB5F9, 0xB5F9, 0xB5F9, 0xB5D8, 0xB5D8, 0xB5D8, 0xADB8, 0xADB8, 0xAD98, 0xAD97, 0xAD97, 0xAD77, 0xA577, 0xA577, 0xA556, 0xA556, 0xA556, 0x9D36, 0x9D36, 0x9D36, 0x9D16, 0x9D15, 0x9D15, 0x94F5, 0x94F5, 0x94F5, 0x94D4, 0x94D4, 0x94B4, 0x8CB4, 0x8CB4, 0x8C94, 0x8C93, 0x8C93, 0x8C73, 0x8473, 0x8473, 0x8452, 0x8452, 0x8432, 0x7C32, 0x7C32, 0x7C12, 0x7C12, 0x7C11, 0x7BF1, 0x73F1, 0x73F1, 0x73D1, 0x73D0, 0x73B0, 0x6BB0, 0x6BB0, 0x6B90, 0x6B90, 0x6B8F, 0x6B6F, 0x636F, 0x636F, 0x634F, 0x634E, 0x632E, 0x632E, 0x5B2E, 0x5B0E, 0x5B0E, 0x5B0D, 0x5AED, 0x52ED, 0x52ED, 0x52CD, 0x52CD, 0x52AC, 0x52AC, 0x4AAC, 0x4AAC, 0x4A8C, 0x4A8C, 0x4A8B, 0x4A6B, 0x426B, 0x424B, 0x424B, 0x424A, 0x422A, 0x3A2A, 0x3A2A, 0x3A0A, 0x3A0A, 0x3A09, 0x39E9, 0x31E9, 0x31C9, 0x31C9, 0x31C9, 0x31A8, 0x29A8, 0x29A8, 0x2988, 0x2988, 0x2988, 0x2967, 0x2167, 0x2147, 0x2147, 0x2147, 0x2126, 0x2126, 0x2126, 0x2127, 0x2147, 0x2147, 0x2147, 0x2147, 0x2147, 0x2147, 0x2168, 0x2168, 0x2168, 0x2168, 0x2168, 0x2168, 0x2188, 0x2189, 0x2189, 0x2189, 0x2189, 0x2189, 0x21A9, 0x21A9, 0x21A9, 0x21AA, 0x21AA, 0x21CA, 0x21CA, 0x21CA, 0x21CA, 0x21CA, 0x29CB, 0x29EB, 0x29EB, 0x29EB, 0x29EB, 0x29EB, 0x29EC, 0x2A0C, 0x2A0C, 0x2A0C, 0x2A0C, 0x2A0C, 0x2A0C, 0x2A2D, 0x2A2D, 0x2A2D, 0x2A2D, 0x2A2D, 0x2A4D, 0x2A4D, 0x2A4D, 0x2A4E, 0x2A4E, 0x2A4E, 0x2A6E, 0x2A6E, 0x2A6E, 0x2A6E, 0x2A6F, 0x2A6F, 0x328F, 0x328F, 0x328F, 0x328F, 0x328F, 0x3290, 0x32B0, 0x32B0, 0x32B0, 0x32B0, 0x32B0, 0x32B0, 0x32B1, 0x32D1, 0x32D1, 0x32D1, 0x32D1, 0x32D1, 0x32D1, 0x32F2, 0x32F2, 0x32F2, 0x32F2, 0x32F2, 0x3312, 0x3312, 0x3313, 0x3313, 0x3313, 0x3313, 0x3B33, 0x3B33, 0x3B33, 0x3B34, 0x3B34, 0x3B34, 0x3B54, 0x3B54, 0x3B54, 0x3B54, 0x3B55, 0x3B55, 0x3B75, 0x3B75, 0x3B75, 0x3B75, 0x3B75, 0x3B96, 0x3B96, 0x3B96, 0x3B96, 0x3B96, 0x3B96, 0x3BB6, 0x3BB6, 0x3BB7, 0x3BB7, 0x3BB7, 0x3BB7, 0x3BD7, 0x43D7, 0x43D8, 0x43D8, 0x43D8, 0x43D8, 0x43F8, 0x43F8, ], dtype=np.uint16) _EVT_LIGHT_565 = np.array([ 0x43F8, 0x43F8, 0x43F8, 0x4418, 0x4419, 0x4419, 0x4C19, 0x4C19, 0x4C39, 0x4C39, 0x4C39, 0x4C39, 0x4C39, 0x5439, 0x5459, 0x5459, 0x5459, 0x5459, 0x5459, 0x5479, 0x5C79, 0x5C79, 0x5C79, 0x5C79, 0x5C99, 0x5C99, 0x5C99, 0x6499, 0x6499, 0x6499, 0x64B9, 0x64B9, 0x64B9, 0x6CBA, 0x6CBA, 0x6CDA, 0x6CDA, 0x6CDA, 0x6CDA, 0x6CDA, 0x6CFA, 0x74FA, 0x74FA, 0x74FA, 0x74FA, 0x751A, 0x751A, 0x751A, 0x7D1A, 0x7D1A, 0x7D1A, 0x7D3A, 0x7D3A, 0x7D3A, 0x853A, 0x853A, 0x855A, 0x855A, 0x855A, 0x855A, 0x855A, 0x8D5A, 0x8D5A, 0x8D7B, 0x8D7B, 0x8D7B, 0x8D7B, 0x8D7B, 0x959B, 0x959B, 0x959B, 0x959B, 0x959B, 0x95BB, 0x95BB, 0x9DBB, 0x9DBB, 0x9DBB, 0x9DDB, 0x9DDB, 0x9DDB, 0x9DDB, 0xA5DB, 0xA5DB, 0xA5FB, 0xA5FB, 0xA5FB, 0xA5FB, 0xA5FB, 0xAE1B, 0xAE1B, 0xAE1B, 0xAE1B, 0xAE1B, 0xAE3B, 0xAE3B, 0xB63C, 0xB63C, 0xB63C, 0xB65C, 0xB65C, 0xB65C, 0xB65C, 0xBE5C, 0xBE5C, 0xBE7C, 0xBE7C, 0xBE7C, 0xBE7C, 0xBE7C, 0xC69C, 0xC69C, 0xC69C, 0xC69C, 0xC69C, 0xC6BC, 0xC6BC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEDC, 0xCEDC, 0xD6DC, 0xD6DC, 0xD6DD, 0xD6FD, 0xD6FD, 0xD6FD, 0xD6FC, 0xD6DC, 0xD6DC, 0xD6DC, 0xCEBC, 0xCEBC, 0xCE9B, 0xCE9B, 0xCE9B, 0xC67B, 0xC67B, 0xC67B, 0xC65A, 0xC65A, 0xC65A, 0xBE3A, 0xBE3A, 0xBE1A, 0xBE19, 0xBE19, 0xB5F9, 0xB5F9, 0xB5F9, 0xB5D8, 0xB5D8, 0xB5D8, 0xADB8, 0xADB8, 0xAD98, 0xAD97, 0xAD97, 0xAD77, 0xA577, 0xA577, 0xA556, 0xA556, 0xA556, 0x9D36, 0x9D36, 0x9D36, 0x9D16, 0x9D15, 0x9D15, 0x94F5, 0x94F5, 0x94F5, 0x94D4, 0x94D4, 0x94B4, 0x8CB4, 0x8CB4, 0x8C94, 0x8C93, 0x8C93, 0x8C73, 0x8473, 0x8473, 0x8452, 0x8452, 0x8432, 0x7C32, 0x7C32, 0x7C12, 0x7C12, 0x7C11, 0x7BF1, 0x73F1, 0x73F1, 0x73D1, 0x73D0, 0x73B0, 0x6BB0, 0x6BB0, 0x6B90, 0x6B90, 0x6B8F, 0x6B6F, 0x636F, 0x636F, 0x634F, 0x634E, 0x632E, 0x632E, 0x5B2E, 0x5B0E, 0x5B0E, 0x5B0D, 0x5AED, 0x52ED, 0x52ED, 0x52CD, 0x52CD, 0x52AC, 0x52AC, 0x4AAC, 0x4AAC, 0x4A8C, 0x4A8C, 0x4A8B, 0x4A6B, 0x426B, 0x424B, 0x424B, 0x424A, 0x422A, 0x3A2A, 0x3A2A, 0x3A0A, 0x3A0A, 0x3A09, 0x39E9, 0x31E9, 0x31C9, 0x31C9, 0x31C9, 0x31A8, 0x29A8, 0x29A8, 0x2988, 0x2988, 0x2988, 0x2967, 0x2167, 0x2147, 0x2147, 0x2147, 0x2126, ], dtype=np.uint16) def _rgb565_to_rgb888(table565): """Convert a 256-entry RGB565 LUT to a (256, 3) uint8 RGB888 array. Bit-replication matches the COLOR_RGB565_TO_R8/G8/B8 macros in draw.c: R8 = (R5 << 3) | (R5 >> 2) G8 = (G6 << 2) | (G6 >> 4) B8 = (B5 << 3) | (B5 >> 2) """ v = table565.astype(np.uint32) r5 = (v >> 11) & 0x1F g6 = (v >> 5) & 0x3F b5 = v & 0x1F r8 = ((r5 << 3) | (r5 >> 2)).astype(np.uint8) g8 = ((g6 << 2) | (g6 >> 4)).astype(np.uint8) b8 = ((b5 << 3) | (b5 >> 2)).astype(np.uint8) return np.stack([r8, g8, b8], axis=1) # (256, 3) uint8 EVT_DARK_RGB = _rgb565_to_rgb888(_EVT_DARK_565) EVT_LIGHT_RGB = _rgb565_to_rgb888(_EVT_LIGHT_565) COLOR_MODES = ["Grayscale", "Evt Dark", "Evt Light"] def _canvas_to_texture(canvas_u8, color_mode): """Convert a uint8 canvas (H×W) to a flat float32 RGBA array for DearPyGui.""" if color_mode == "Grayscale": rgb = np.stack([canvas_u8, canvas_u8, canvas_u8], axis=-1) elif color_mode == "Evt Dark": rgb = EVT_DARK_RGB[canvas_u8] else: # Evt Light rgb = EVT_LIGHT_RGB[canvas_u8] rgba = np.ones((SENSOR_H, SENSOR_W, 4), dtype=np.float32) rgba[:, :, :3] = rgb * (1.0 / 255.0) return rgba.ravel() def _draw_freq_legend(tag, dh, min_freq, max_freq, use_log, n_bins): """Redraw a DPG drawlist with a frequency colorbar legend (high freq at top).""" import dearpygui.dearpygui as _dpg _dpg.delete_item(tag, children_only=True) if n_bins < 2 or dh <= 0: return # Dark background _dpg.draw_rectangle(pmin=(0, 0), pmax=(LEGEND_DW, dh), color=(30, 30, 30, 255), fill=(30, 30, 30, 255), parent=tag) color_w = 16 # width of the colored band text_x = color_w + 4 bin_h = dh / n_bins if use_log: lo = np.log10(max(min_freq, 1e-9)) hi = np.log10(max(max_freq, min_freq * 1.001 + 1e-9)) vals_tf = np.linspace(hi, lo, n_bins) # high freq at top → low at bottom freq_labels = 10.0 ** vals_tf idx_vals = np.clip(((vals_tf - lo) / (hi - lo + 1e-12)) * 255, 0, 255).astype(np.uint8) else: freq_labels = np.linspace(max_freq, min_freq, n_bins) rng = max(max_freq - min_freq, 1e-9) idx_vals = np.clip((freq_labels - min_freq) / rng * 255, 0, 255).astype(np.uint8) for i in range(n_bins): y0 = int(i * bin_h) y1 = max(int((i + 1) * bin_h), y0 + 1) rgb = FREQ_LUT[idx_vals[i]] col = (int(rgb[0]), int(rgb[1]), int(rgb[2]), 255) _dpg.draw_rectangle(pmin=(0, y0), pmax=(color_w, y1), color=col, fill=col, parent=tag) f = float(freq_labels[i]) if f >= 10000: label = f"{f / 1000:.0f}k" elif f >= 1000: label = f"{f / 1000:.1f}k" elif f >= 100: label = f"{f:.0f}" elif f >= 10: label = f"{f:.1f}" else: label = f"{f:.2f}" text_y = y0 + max(int(bin_h) // 2 - 6, 0) _dpg.draw_text(pos=(text_x, text_y), text=label, color=(210, 210, 210, 255), size=12, parent=tag) def _make_freq_legend_pil(height, min_freq, max_freq, use_log, n_bins): """Render the frequency colorbar legend as a PIL Image (height × LEGEND_DW).""" img = Image.new('RGB', (LEGEND_DW, height), color=(30, 30, 30)) draw = ImageDraw.Draw(img) color_w = 16 bin_h = height / max(n_bins, 1) if use_log: lo = np.log10(max(min_freq, 1e-9)) hi = np.log10(max(max_freq, min_freq * 1.001 + 1e-9)) vals_tf = np.linspace(hi, lo, n_bins) freq_labels = 10.0 ** vals_tf idx_vals = np.clip(((vals_tf - lo) / (hi - lo + 1e-12)) * 255, 0, 255).astype(np.uint8) else: freq_labels = np.linspace(max_freq, min_freq, n_bins) rng = max(max_freq - min_freq, 1e-9) idx_vals = np.clip((freq_labels - min_freq) / rng * 255, 0, 255).astype(np.uint8) for i in range(n_bins): y0 = int(i * bin_h) y1 = max(int((i + 1) * bin_h), y0 + 1) rgb = FREQ_LUT[idx_vals[i]] draw.rectangle([(0, y0), (color_w - 1, y1 - 1)], fill=(int(rgb[0]), int(rgb[1]), int(rgb[2]))) f = float(freq_labels[i]) if f >= 10000: label = f"{f / 1000:.0f}k" elif f >= 1000: label = f"{f / 1000:.1f}k" elif f >= 100: label = f"{f:.0f}" elif f >= 10: label = f"{f:.1f}" else: label = f"{f:.2f}" draw.text((color_w + 3, y0 + max(int(bin_h) // 2 - 6, 0)), label, fill=(210, 210, 210)) return img def list_com_ports(): return sorted(p.device for p in serial.tools.list_ports.comports()) # --------------------------------------------------------------------------- # Frequency camera helpers # Reference: https://github.com/ros-event-camera/frequency_cam # --------------------------------------------------------------------------- FREQ_TEX_TAG = "freq_tex" def _make_freq_lut(): """HSV colormap: index 0 → blue (low freq), 255 → red (high freq).""" import colorsys lut = np.zeros((256, 3), dtype=np.uint8) for i in range(256): hue = (1.0 - i / 255.0) * (240.0 / 360.0) r, g, b = colorsys.hsv_to_rgb(hue, 1.0, 1.0) lut[i] = [int(r * 255), int(g * 255), int(b * 255)] return lut FREQ_LUT = _make_freq_lut() def _freq_filter_coeffs(cutoff_period): """Compute second-order IIR bandpass coefficients (c1, c2, c3). Matches the reference implementation exactly: omega = 2π/T, phi = 2 - cos(omega) alpha = (1 - sin(omega)) / cos(omega) beta = phi - sqrt(phi² - 1) c1 = alpha + beta, c2 = -alpha·beta, c3 = 0.5·(1 + beta) Filter: L_k = c1·L_{k-1} + c2·L_{k-2} + c3·(p - p_prev) """ T = max(cutoff_period, 1.0) omega = 2.0 * np.pi / T phi = 2.0 - np.cos(omega) alpha = (1.0 - np.sin(omega)) / np.cos(omega) beta = phi - np.sqrt(max(phi * phi - 1.0, 0.0)) c1 = alpha + beta c2 = -alpha * beta # negative — used as L_k = c1·L1 + c2·L2 + c3·dp c3 = 0.5 * (1.0 + beta) return c1, c2, c3 @numba.njit(nogil=True, cache=True) def _update_freq_cam(xs, ys, pols, ts_f, fc_L2, fc_L1, fc_p1, fc_t_ud, fc_t_du, fc_per, c1, c2, c3, fc_dt_min, fc_dt_max, fc_dt_min_half, fc_dt_max_half, fc_n_to): """Per-event sequential IIR frequency camera update. Compiled with nogil=True so the camera reader thread runs concurrently. Returns the timestamp of the last processed event (or -1.0 if empty). """ n = xs.shape[0] if n == 0: return -1.0 for i in range(n): px = xs[i]; py = ys[i] p = pols[i] * 2.0 - 1.0 t = ts_f[i] l2 = fc_L2[py, px] l1 = fc_L1[py, px] dp = p - fc_p1[py, px] l_new = c1 * l1 + c2 * l2 + c3 * dp if not (abs(l_new) < 1e4): l_new = 0.0 l1 = 0.0 fc_L2[py, px] = l1 fc_L1[py, px] = l_new fc_p1[py, px] = p if l1 > 0.0 and l_new < 0.0: dt_ud = t - fc_t_ud[py, px] dt_du = t - fc_t_du[py, px] if fc_dt_min <= dt_ud <= fc_dt_max: fc_per[py, px] = dt_ud else: cur = fc_per[py, px] if cur > 0.0: if dt_ud > cur * fc_n_to and dt_du > 0.5 * cur * fc_n_to: fc_per[py, px] = 0.0 else: if fc_dt_min_half <= dt_du <= fc_dt_max_half: fc_per[py, px] = 2.0 * dt_du fc_t_ud[py, px] = t elif l1 < 0.0 and l_new > 0.0: dt_du = t - fc_t_du[py, px] dt_ud = t - fc_t_ud[py, px] cur = fc_per[py, px] if fc_dt_min <= dt_du <= fc_dt_max and cur <= 0.0: fc_per[py, px] = dt_du else: if cur > 0.0: if dt_du > cur * fc_n_to and dt_ud > 0.5 * cur * fc_n_to: fc_per[py, px] = 0.0 else: if fc_dt_min_half <= dt_ud <= fc_dt_max_half: fc_per[py, px] = 2.0 * dt_ud fc_t_du[py, px] = t return ts_f[n - 1] def _freq_to_texture(fc_per, fc_t_ud, fc_t_du, t_now, n_timeout, min_freq, max_freq, use_log=True, overlay_events=False): """Convert per-pixel frequency state to a flat float32 RGBA for DearPyGui. Timeout: pixel is inactive when t_now - max(t_ud, t_du) exceeds n_timeout periods. Two-condition check matches reference: dt < dtMax·n_timeout² AND dt·freq < n_timeout. use_log: log10 frequency color scale (True) vs linear (False). overlay_events: grey pixels that have had crossings but no active frequency. """ last_cross = np.maximum(fc_t_ud, fc_t_du) dt = t_now - last_cross # seconds since last crossing dt_max = 1.0 / max(min_freq, 1e-9) safe_per = np.where(fc_per > 0.0, fc_per, 1.0) freq = np.where(fc_per > 0.0, 1.0 / safe_per, 0.0).astype(np.float32) active = (fc_per > 0.0) & (dt < dt_max * n_timeout * n_timeout) & ( dt.astype(np.float32) * freq < n_timeout) in_range = active & (freq >= min_freq) & (freq <= max_freq) idx = np.zeros((SENSOR_H, SENSOR_W), dtype=np.uint8) if in_range.any(): clipped = np.where(in_range, np.clip(freq, min_freq, max_freq), min_freq) if use_log: lo = np.log10(max(min_freq, 1e-9)) hi = np.log10(max(max_freq, min_freq * 1.001 + 1e-9)) vals = (np.log10(clipped) - lo) / (hi - lo) * 255.0 else: rng = max(max_freq - min_freq, 1e-9) vals = (clipped - min_freq) / rng * 255.0 idx[in_range] = np.clip(vals[in_range], 0, 255).astype(np.uint8) rgba = np.zeros((SENSOR_H, SENSOR_W, 4), dtype=np.float32) rgba[:, :, 3] = 1.0 rgba[:, :, :3] = FREQ_LUT[idx].astype(np.float32) * (1.0 / 255.0) rgba[~active, :3] = 0.0 if overlay_events: # Grey out pixels with crossing history but no active frequency has_crossed = (fc_t_ud > 0.0) | (fc_t_du > 0.0) rgba[has_crossed & ~active, :3] = 0.5 return rgba.ravel() # --------------------------------------------------------------------------- # Camera background thread (receives data, puts onto queue) # --------------------------------------------------------------------------- EMA_ALPHA = 0.2 EVT_RES_OPTIONS = [1024, 2048, 4096, 8192, 16384, 32768, 65536] def patch_script(script, csi_fifo_depth, evt_fifo_depth, evt_res, raw_mode=False): """Patch the on-camera script with GUI-controlled parameters before exec. Substitutions made (processed mode): CSI_FIFO_DEPTH = EVENT_FIFO_DEPTH = np.zeros((EVT_RES, 6), ...) — the array shape (EVT_RES constant) def read / def readp — use readp on Mac/Linux, read on Windows Substitutions made (raw mode): CSI_FIFO_DEPTH = EVT_RES = — only the constant assignment def read / def readp """ import re script = re.sub(r'CSI_FIFO_DEPTH\s*=\s*\d+', f'CSI_FIFO_DEPTH = {csi_fifo_depth}', script) if raw_mode: script = re.sub(r'EVT_RES\s*=\s*\d+', f'EVT_RES = {evt_res}', script) else: script = re.sub(r'EVENT_FIFO_DEPTH\s*=\s*\d+', f'EVENT_FIFO_DEPTH = {evt_fifo_depth}', script) script = re.sub(r'np\.zeros\(\((?:\d+|EVT_RES),\s*6\)', f'np.zeros(({evt_res}, 6)', script) if sys.platform != 'win32': script = script.replace('def read(self, offset, size):', 'def readp(self, offset, size):') return script def decode_raw_events(buf, time_high_ref): """Vectorized EVT 2.0 decoder. Decodes a buffer of raw 32-bit little-endian EVT 2.0 words into an (N, 6) uint16 array matching the ec_event_t layout from the processed cam script: [0] type — EC_PIX_OFF_EVENT(0), EC_PIX_ON_EVENT(1), EC_EXT_TRIGGER_FALLING(2), EC_EXT_TRIGGER_RISING(3), EC_RST_TRIGGER_FALLING(4), EC_RST_TRIGGER_RISING(5) [1] ts_s — whole seconds of timestamp [2] ts_ms — milliseconds within the second (0-999) [3] ts_us — microseconds within the millisecond (0-999) [4] x — pixel column (0 for trigger events) [5] y — pixel row (0 for trigger events) Handles TD pixel events (0x0/0x1) and EXT_TRIGGER events (0xA). EV_TIME_HIGH (0x8) words update the running timestamp accumulator. time_high_ref is a one-element list carrying the running EV_TIME_HIGH value across consecutive calls (updated in-place). """ n_words = len(buf) // 4 if n_words == 0: return np.zeros((0, 6), dtype=np.uint16) words = np.frombuffer(buf, dtype=np.uint32) types = (words >> 28) & 0xF # --- EV_TIME_HIGH (0x8): update running timestamp accumulator --- th_mask = types == 0x8 th_idx = np.where(th_mask)[0] th_vals = ((words[th_mask] & 0x0FFFFFFF).astype(np.uint64)) << 6 # --- all output events: TD pixel (0x0, 0x1) + EXT_TRIGGER (0xA) --- evt_mask = (types <= 0x1) | (types == 0xA) evt_idx = np.where(evt_mask)[0] if evt_idx.size == 0: if th_vals.size > 0: time_high_ref[0] = int(th_vals[-1]) return np.zeros((0, 6), dtype=np.uint16) # --- assign the correct time_high to every event (vectorized) --- # The applicable time_high for event at position i is the last EV_TIME_HIGH # whose stream position is strictly before i. if th_idx.size > 0: ins = np.searchsorted(th_idx, evt_idx, side='right') - 1 th_for_evt = np.empty(evt_idx.size, dtype=np.uint64) before_first = ins < 0 th_for_evt[before_first] = time_high_ref[0] th_for_evt[~before_first] = th_vals[ins[~before_first]] time_high_ref[0] = int(th_vals[-1]) else: th_for_evt = np.full(evt_idx.size, time_high_ref[0], dtype=np.uint64) # --- reconstruct full microsecond timestamp --- evt_words = words[evt_idx] evt_types = types[evt_idx] ts_low = ((evt_words >> 22) & 0x3F).astype(np.uint64) t_us = th_for_evt | ts_low ts_s = (t_us // 1_000_000).astype(np.uint16) ts_ms = ((t_us // 1_000) % 1_000).astype(np.uint16) ts_us = (t_us % 1_000).astype(np.uint16) # --- pixel events: type is 0 (off) or 1 (on), x/y from bit fields --- out_type = evt_types.astype(np.uint16) # 0 or 1 for TD events x = ((evt_words >> 11) & 0x7FF).astype(np.uint16) y = (evt_words & 0x7FF).astype(np.uint16) # --- trigger events: remap type to EC_TRIGGER_EVENT(id, polarity) --- # EC_TRIGGER_EVENT = EC_EXT_TRIGGER_FALLING(2) + ((id & 1) << 1) + polarity # x and y are 0 for trigger events (no pixel coordinate). is_trig = evt_types == 0xA if is_trig.any(): tw = evt_words[is_trig] trig_id = ((tw >> 8) & 0x1F).astype(np.uint16) trig_pol = (tw & 0x1).astype(np.uint16) out_type[is_trig] = 2 + ((trig_id & 1) << 1) + trig_pol x[is_trig] = 0 y[is_trig] = 0 return np.stack([out_type, ts_s, ts_ms, ts_us, x, y], axis=1) def camera_worker(args, state_lock, state, event_q, stop_evt): try: with Camera( args.port, baudrate=args.baudrate, crc=args.crc, seq=args.seq, ack=args.ack, events=args.events, timeout=args.timeout, max_retry=args.max_retry, max_payload=args.max_payload, drop_rate=args.drop_rate, ) as camera: logging.info(f"Connected to OpenMV on {args.port}") camera.stop() time.sleep(0.5) with open(args.script) as f: script = f.read() with state_lock: csi_fifo = state['csi_fifo_depth'] evt_fifo = state['evt_fifo_depth'] evt_res = state['evt_res'] raw_mode = state['stream_mode'] == 'Raw (fastest)' script = patch_script(script, csi_fifo, evt_fifo, evt_res, raw_mode) logging.debug(f"Patched script: CSI_FIFO={csi_fifo} EVT_FIFO={evt_fifo} " f"EVT_RES={evt_res} raw={raw_mode} " f"readp={'yes' if sys.platform != 'win32' else 'no'}") camera.exec(script) logging.info(f"Script running, streaming events ({'raw' if raw_mode else 'processed'})...") channel = 'raw_events' if raw_mode else 'events' time_high_ref = [0] # running EV_TIME_HIGH accumulator for raw decoding start_time = time.perf_counter() last_time = start_time total_events = 0 total_bytes = 0 event_rate_ema = 0.0 mbps_ema = 0.0 while not stop_evt.is_set(): status = camera.read_status() if not args.quiet and status and status.get('stdout'): if text := camera.read_stdout(): print(f"{COLOR_CAMERA}{text}{COLOR_RESET}", end='') if not camera.has_channel(channel): time.sleep(0.01) continue if not status or not status.get(channel): time.sleep(0.01) continue size = camera.channel_size(channel) if size <= 0: time.sleep(0.01) continue now = time.perf_counter() dt = now - last_time last_time = now if dt <= 0.0: continue data = camera.channel_read(channel, size) if raw_mode: if (len(data) % 4) != 0: logging.warning(f"Misaligned raw packet: {len(data)} bytes (not multiple of 4)") continue events = decode_raw_events(data, time_high_ref) else: if (len(data) % 12) != 0: logging.warning(f"Misaligned packet: {len(data)} bytes (not multiple of 12)") continue # Each event row: 6 × uint16 little-endian # [0] polarity (0=neg, 1=pos) [1] sec [2] ms [3] us [4] x [5] y events = np.frombuffer(data, dtype='= 0) & (xs < SENSOR_W) & (ys >= 0) & (ys < SENSOR_H) xs, ys, pols = xs[valid], ys[valid], pols[valid] batch_delta = None if xs.size > 0: signs = pols * 2 - 1 flat_idx = ys * SENSOR_W + xs pos = np.bincount(flat_idx[signs > 0], minlength=SENSOR_H * SENSOR_W) neg = np.bincount(flat_idx[signs < 0], minlength=SENSOR_H * SENSOR_W) batch_delta = (pos.astype(np.int32) - neg.astype(np.int32)).reshape(SENSOR_H, SENSOR_W) with state_lock: fc_enabled = state['fc_enabled'] fc_min = state['fc_min_freq'] fc_max = state['fc_max_freq'] fc_n_to = state['fc_n_timeout'] if fc_enabled: ts_f = (events[valid, 1].astype(np.float64) + events[valid, 2].astype(np.float64) * 1e-3 + events[valid, 3].astype(np.float64) * 1e-6) c1, c2, c3 = fc_coeffs_ref[0], fc_coeffs_ref[1], fc_coeffs_ref[2] fc_dt_min = 1.0 / max(fc_max, 1e-9) fc_dt_max = 1.0 / max(fc_min, 1e-9) fc_dt_min_half = 0.5 * fc_dt_min fc_dt_max_half = 0.5 * fc_dt_max # GIL-free compiled IIR update t_last = _update_freq_cam( xs.astype(np.int32), ys.astype(np.int32), pols.astype(np.float64), ts_f, fc_L2, fc_L1, fc_p1, fc_t_ud, fc_t_du, fc_per, c1, c2, c3, fc_dt_min, fc_dt_max, fc_dt_min_half, fc_dt_max_half, float(fc_n_to), ) if t_last >= 0.0: fc_t_now[0] = t_last with state_lock: contrast = state['contrast'] mode = state['mode'] window = state['window'] do_clear = state['clear'] if do_clear: state['clear'] = False if do_clear: canvas[:] = 128 batch_counter = 0 slide_buf.clear() event_buf.clear() if mode == 'Canvas': if window > 0 and batch_counter >= window: canvas[:] = 128 batch_counter = 0 event_buf.clear() batch_counter += 1 if batch_delta is not None: canvas += batch_delta * contrast np.clip(canvas, 0, 255, out=canvas) event_buf.append(events) else: # Sliding Window w = max(1, window) if batch_delta is not None: slide_buf.append(batch_delta) event_buf.append(events) while len(slide_buf) > w: slide_buf.popleft() event_buf.popleft() canvas[:] = 128 for d in slide_buf: canvas += d * contrast np.clip(canvas, 0, 255, out=canvas) # Only snapshot and enqueue a result if the render loop has room. # This avoids three expensive 320×320 array copies on every batch # when the render thread is already backed up. if not result_q.full(): canvas_u8 = canvas.astype(np.uint8) result = { 'canvas_u8': canvas_u8, 'fc_enabled': fc_enabled, 'fc_per': fc_per.copy() if fc_enabled else None, 'fc_t_ud': fc_t_ud.copy() if fc_enabled else None, 'fc_t_du': fc_t_du.copy() if fc_enabled else None, 'fc_t_now': fc_t_now[0], 'event_buf': list(event_buf), 'stats': stats, } result_q.put(result) # --------------------------------------------------------------------------- # Argument parsing # --------------------------------------------------------------------------- def str2bool(v): if isinstance(v, bool): return v if v.lower() in ('yes', 'true', 't', 'y', '1'): return True if v.lower() in ('no', 'false', 'f', 'n', '0'): return False raise argparse.ArgumentTypeError('Boolean value expected.') def parse_args(): p = argparse.ArgumentParser( description='GenX320 event camera visualization GUI') p.add_argument('--port', default=None, help='Serial port (auto-selected in GUI if omitted)') p.add_argument('--script', default=None, help='MicroPython script to run on the camera ' '(defaults to genx320_event_mode_streaming_on_cam.py next to this file)') p.add_argument('--baudrate', type=int, default=921600) p.add_argument('--timeout', type=float, default=1.0) p.add_argument('--crc', type=str2bool, nargs='?', const=True, default=(sys.platform == 'win32')) p.add_argument('--seq', type=str2bool, nargs='?', const=True, default=True) p.add_argument('--ack', type=str2bool, nargs='?', const=True, default=False) p.add_argument('--events', type=str2bool, nargs='?', const=True, default=True) p.add_argument('--max-retry', type=int, default=3) p.add_argument('--max-payload', type=int, default=4096) p.add_argument('--drop-rate', type=float, default=0.0) p.add_argument('--quiet', action='store_true', help='Suppress camera stdout') p.add_argument('--debug', action='store_true') p.add_argument('--benchmark', action='store_true', help='Headless mode: print throughput stats, no GUI') p.add_argument('--raw', type=str2bool, nargs='?', const=True, default=True, help='Use raw event streaming (default: true)') p.add_argument('--evt-res', type=int, default=8192, help='Event buffer resolution (default: 8192)') return p.parse_args() # --------------------------------------------------------------------------- # main (render / GUI thread) # --------------------------------------------------------------------------- def run_benchmark(args): """Headless benchmark: camera + processing threads, stats printed to terminal.""" if not args.port: ports = list_com_ports() if not ports: print("No serial ports found. Use --port to specify one.") sys.exit(1) args.port = ports[0] print(f"Auto-selected port: {args.port}") state_lock = threading.Lock() state = { 'stream_mode': 'Raw (fastest)' if args.raw else 'Processed', 'csi_fifo_depth': 8, 'evt_fifo_depth': 8, 'evt_res': args.evt_res, 'contrast': 16, 'color_mode': 'Grayscale', 'mode': 'Sliding Window', 'window': 4, 'clear': False, 'fc_cutoff_period': 5.0, 'fc_enabled': True, 'fc_min_freq': 10.0, 'fc_max_freq': 1000.0, 'fc_n_timeout': 2, 'fc_log_freq': True, 'fc_overlay': False, 'fc_legend_show': False, 'fc_legend_bins': 11, } if args.script is None: raw_mode = state['stream_mode'] == 'Raw (fastest)' args.script = os.path.join( os.path.dirname(os.path.abspath(__file__)), 'genx320_raw_event_mode_streaming_on_cam.py' if raw_mode else 'genx320_event_mode_streaming_on_cam.py', ) fc_L2 = np.zeros((SENSOR_H, SENSOR_W), dtype=np.float32) fc_L1 = np.zeros((SENSOR_H, SENSOR_W), dtype=np.float32) fc_p1 = np.full((SENSOR_H, SENSOR_W), -1.0, dtype=np.float32) fc_t_ud = np.zeros((SENSOR_H, SENSOR_W), dtype=np.float64) fc_t_du = np.zeros((SENSOR_H, SENSOR_W), dtype=np.float64) fc_per = np.full((SENSOR_H, SENSOR_W), -1.0, dtype=np.float64) fc_coeffs = list(_freq_filter_coeffs(state['fc_cutoff_period'])) fc_t_now = [0.0] raw_q = queue.Queue(maxsize=8) result_q = queue.Queue(maxsize=4) reset_evt = threading.Event() stop_evt = threading.Event() def handle_exit(signum, frame): stop_evt.set() signal.signal(signal.SIGINT, handle_exit) signal.signal(signal.SIGTERM, handle_exit) cam_t = threading.Thread( target=camera_worker, args=(args, state_lock, state, raw_q, stop_evt), daemon=True, ) proc_t = threading.Thread( target=processing_worker, args=(state_lock, state, raw_q, result_q, stop_evt, fc_L2, fc_L1, fc_p1, fc_t_ud, fc_t_du, fc_per, fc_coeffs, fc_t_now, reset_evt), daemon=True, ) print(f"Connecting to {args.port} ...") cam_t.start() proc_t.start() last_print = time.perf_counter() while not stop_evt.is_set(): try: result = result_q.get(timeout=0.05) except queue.Empty: if not cam_t.is_alive(): if not stop_evt.is_set(): print("Camera thread died unexpectedly.") break continue now = time.perf_counter() if now - last_print >= 0.1: last_print = now s = result['stats'] print(f"elapsed={s['elapsed']:.1f}s\t" f"rate={s['event_rate']:,.0f} ev/s\t" f"bw={s['mbps']:.2f} MB/s\t" f"total={s['total_events']:,}") stop_evt.set() print("\nDone.") def main(args=None): if args is None: args = parse_args() if args.script is None: args.script = os.path.join( os.path.dirname(os.path.abspath(__file__)), 'genx320_event_mode_streaming_on_cam.py', ) logging.basicConfig( format="%(relativeCreated)010.3f - %(message)s", level=logging.DEBUG if args.debug else logging.INFO, ) # Shared state accessed by GUI callbacks and camera thread state_lock = threading.Lock() state = { # Camera script parameters (locked while connected) 'stream_mode': 'Raw (fastest)' if args.raw else 'Processed', 'csi_fifo_depth': 8, 'evt_fifo_depth': 8, 'evt_res': args.evt_res, # Visualization 'contrast': 16, 'color_mode': 'Grayscale', 'mode': 'Sliding Window', # 'Canvas' or 'Sliding Window' 'window': 4, # Canvas: batches before auto-clear (0=manual); Sliding Window: batches to keep (min 1) 'clear': False, # Frequency visualization 'fc_enabled': True, 'fc_cutoff_period': 5.0, 'fc_min_freq': 10.0, 'fc_max_freq': 1000.0, 'fc_n_timeout': 2, 'fc_log_freq': True, 'fc_overlay': False, 'fc_legend_show': True, 'fc_legend_bins': 11, } last_canvas_u8 = [None] # latest rendered uint8 canvas, for saving last_freq_rgba = [None] # latest freq texture (H×W×4 float32), for saving event_buf = deque() # raw event arrays from last result, for saving # Frequency camera per-pixel IIR filter state (owned by processing_worker). # Allocated here so they can be passed to the thread at connect time. # fc_p1 : previous raw polarity (0 or 1); dp = p - p1 drives the filter # fc_t_ud: time of last L+ → L− zero crossing ("up-down") # fc_t_du: time of last L− → L+ zero crossing ("down-up") # fc_per : estimated period; -1 = uninitialized, 0 = stale, >0 = valid fc_L2 = np.zeros((SENSOR_H, SENSOR_W), dtype=np.float32) fc_L1 = np.zeros((SENSOR_H, SENSOR_W), dtype=np.float32) fc_p1 = np.full((SENSOR_H, SENSOR_W), -1.0, dtype=np.float32) # ±1 convention, init -1 fc_t_ud = np.zeros((SENSOR_H, SENSOR_W), dtype=np.float64) fc_t_du = np.zeros((SENSOR_H, SENSOR_W), dtype=np.float64) fc_per = np.full((SENSOR_H, SENSOR_W), -1.0, dtype=np.float64) fc_coeffs = list(_freq_filter_coeffs(state['fc_cutoff_period'])) fc_t_now = [0.0] # last camera timestamp processed # Lock-free mirrors of state, readable by fit_image() without taking the lock fc_enabled_ref = [state['fc_enabled']] fc_legend_show_ref = [state['fc_legend_show']] legend_redraw_needed = [True] raw_q = queue.Queue(maxsize=8) # camera → processing (larger: absorb bursts) result_q = queue.Queue(maxsize=4) # processing → render reset_evt = threading.Event() # render → processing: reset filter/canvas state conn = {'cam_thread': None, 'proc_thread': None, 'stop_evt': None} # ----------------------------------------------------------------------- # Dear PyGui setup # ----------------------------------------------------------------------- dpg.create_context() def cb_file_selected(sender, app_data): path = app_data.get('file_path_name', '') if path: args.script = path dpg.set_value("script_path", path) with dpg.file_dialog( directory_selector=False, show=False, callback=cb_file_selected, tag="file_dialog", width=700, height=450, default_path=os.path.dirname(args.script) if args.script else os.getcwd()): dpg.add_file_extension(".py", color=(100, 255, 100, 255)) dpg.add_file_extension(".*", color=(255, 255, 255, 255)) # Placeholder texture (mid-gray, matching canvas init value) _ph = np.full(SENSOR_W * SENSOR_H * 4, 0.5, dtype=np.float32) _ph[3::4] = 1.0 with dpg.texture_registry(tag=TEX_REG_TAG): dpg.add_dynamic_texture(SENSOR_W, SENSOR_H, _ph, tag=TEXTURE_TAG) _ph_freq = np.zeros(SENSOR_W * SENSOR_H * 4, dtype=np.float32) _ph_freq[3::4] = 1.0 dpg.add_dynamic_texture(SENSOR_W, SENSOR_H, _ph_freq, tag=FREQ_TEX_TAG) tex_wh = [SENSOR_W, SENSOR_H] # ---- Connection callbacks ---------------------------------------------- def do_connect(port): args.port = port # Select cam script based on stream mode script_dir = os.path.dirname(os.path.abspath(__file__)) with state_lock: raw_mode = state['stream_mode'] == 'Raw (fastest)' cam_script = os.path.join( script_dir, 'genx320_raw_event_mode_streaming_on_cam.py' if raw_mode else 'genx320_event_mode_streaming_on_cam.py', ) args.script = cam_script dpg.set_value("script_path", cam_script) last_freq_rgba[0] = None reset_evt.set() # processing_worker will reset filter/canvas on startup stop_evt = threading.Event() conn['stop_evt'] = stop_evt cam_t = threading.Thread( target=camera_worker, args=(args, state_lock, state, raw_q, stop_evt), daemon=True, ) proc_t = threading.Thread( target=processing_worker, args=(state_lock, state, raw_q, result_q, stop_evt, fc_L2, fc_L1, fc_p1, fc_t_ud, fc_t_du, fc_per, fc_coeffs, fc_t_now, reset_evt), daemon=True, ) cam_t.start() proc_t.start() conn['cam_thread'] = cam_t conn['proc_thread'] = proc_t dpg.configure_item("connect_btn", label="Disconnect") _set_cam_settings_enabled(False) logging.info(f"Connecting to {port}...") def do_disconnect(): if conn['stop_evt']: conn['stop_evt'].set() conn['cam_thread'] = None conn['proc_thread'] = None conn['stop_evt'] = None dpg.configure_item("connect_btn", label="Connect") _set_cam_settings_enabled(True) CAM_SETTING_TAGS = ["stream_mode_combo", "csi_fifo_input", "evt_fifo_input"] def _set_cam_settings_enabled(enabled): for tag in CAM_SETTING_TAGS: dpg.configure_item(tag, enabled=enabled) # Swap combo ↔ readonly text — DearPyGui clears combo preview on disable if enabled: dpg.show_item("evt_res_combo") dpg.hide_item("evt_res_display") else: with state_lock: val = str(state['evt_res']) dpg.set_value("evt_res_display", val) dpg.hide_item("evt_res_combo") dpg.show_item("evt_res_display") def cb_refresh(s, v, u=None): items = list_com_ports() dpg.configure_item("port_combo", items=items) if items and not dpg.get_value("port_combo"): dpg.set_value("port_combo", items[0]) def cb_connect(s, v, u=None): if conn['cam_thread'] and conn['cam_thread'].is_alive(): do_disconnect() else: if not args.script: return port = dpg.get_value("port_combo") if not port: return do_connect(port) # ---- Camera settings callbacks (applied at connect time) --------------- STREAM_MODES = ['Raw (fastest)', 'Processed'] def cb_stream_mode(s, v, u=None): with state_lock: state['stream_mode'] = v raw = v == 'Raw (fastest)' # EVT FIFO only applies to the processed cam script (dpg.hide_item if raw else dpg.show_item)("evt_fifo_row") def cb_csi_fifo(s, v, u=None): with state_lock: state['csi_fifo_depth'] = max(4, v) def cb_evt_fifo(s, v, u=None): with state_lock: state['evt_fifo_depth'] = max(4, v) def cb_evt_res(s, v, u=None): with state_lock: state['evt_res'] = int(v) # ---- Visualization callbacks ------------------------------------------- # Per-mode window memory: remembered independently so switching back restores last value window_by_mode = {'Sliding Window': 4, 'Canvas': 0} def _sync_window_ui(window_val, mode): """Update window input value/min and show Clear button only for Canvas+0.""" dpg.configure_item("window_input", min_value=(0 if mode == 'Canvas' else 1)) dpg.set_value("window_input", window_val) show_clear = (mode == 'Canvas' and window_val == 0) (dpg.show_item if show_clear else dpg.hide_item)("clear_btn") def cb_clear(s=None, v=None, u=None): with state_lock: state['clear'] = True def cb_contrast(s, v, u=None): with state_lock: state['contrast'] = v def cb_color_mode(s, v, u=None): with state_lock: state['color_mode'] = v def cb_mode(s, v, u=None): # Save current window value for the old mode, restore for the new mode with state_lock: old_mode = state['mode'] window_by_mode[old_mode] = state['window'] w = window_by_mode[v] state['mode'] = v state['window'] = w state['clear'] = True _sync_window_ui(w, v) def cb_window(s, v, u=None): with state_lock: state['window'] = v mode = state['mode'] window_by_mode[mode] = v _sync_window_ui(v, mode) def cb_save(s=None, v=None, u=None): img = last_canvas_u8[0] freq_img = last_freq_rgba[0] if img is None: return with state_lock: color_mode = state['color_mode'] legend_show = state['fc_legend_show'] legend_bins = state['fc_legend_bins'] fc_min = state['fc_min_freq'] fc_max = state['fc_max_freq'] fc_log_freq = state['fc_log_freq'] ts = int(time.time()) base = f"events_{ts}" if not _PIL_AVAILABLE: logging.warning("pip install Pillow to enable image saving") return try: # Save event canvas image if color_mode == "Grayscale": pil_evt = Image.fromarray(img, 'L') else: rgb = (EVT_DARK_RGB if color_mode == "Evt Dark" else EVT_LIGHT_RGB)[img] pil_evt = Image.fromarray(rgb, 'RGB') pil_evt.save(f"{base}_evt.png") logging.info(f"Saved {base}_evt.png") # Save frequency image, compositing legend onto the right if enabled if freq_img is not None: freq_u8 = (np.clip(freq_img[:, :, :3], 0.0, 1.0) * 255).astype(np.uint8) pil_freq = Image.fromarray(freq_u8, 'RGB') if legend_show: legend_pil = _make_freq_legend_pil( SENSOR_H, fc_min, fc_max, fc_log_freq, legend_bins) combined = Image.new('RGB', (SENSOR_W + LEGEND_DW, SENSOR_H)) combined.paste(pil_freq, (0, 0)) combined.paste(legend_pil, (SENSOR_W, 0)) combined.save(f"{base}_freq.png") else: pil_freq.save(f"{base}_freq.png") logging.info(f"Saved {base}_freq.png") except Exception as e: logging.warning(f"Failed to save images: {e}") # Save raw events as CSV batches = list(event_buf) if batches: all_events = np.concatenate(batches, axis=0) csv_path = f"{base}.csv" np.savetxt( csv_path, all_events, delimiter=',', fmt='%d', header='type,sec,ms,us,x,y', comments='', ) logging.info(f"Saved {csv_path} ({len(all_events):,} events)") # ---- Frequency camera callbacks ---------------------------------------- def cb_fc_enabled(s, v, u=None): with state_lock: state['fc_enabled'] = v fc_enabled_ref[0] = v dpg.configure_item("fc_controls", show=v) for tag in ("freq_img_h", "freq_img_v", "freq_legend_h", "freq_legend_v"): (dpg.show_item if v else dpg.hide_item)(tag) if not v: last_freq_rgba[0] = None dpg.configure_item("save_btn", label="Save Images and Events" if v else "Save Image and Events") fit_image() def cb_fc_cutoff(s, v, u=None): with state_lock: state['fc_cutoff_period'] = v fc_coeffs[:] = list(_freq_filter_coeffs(v)) def cb_fc_min_freq(s, v, u=None): with state_lock: state['fc_min_freq'] = max(v, 0.01) legend_redraw_needed[0] = True def cb_fc_max_freq(s, v, u=None): with state_lock: state['fc_max_freq'] = max(v, 1.0) legend_redraw_needed[0] = True def cb_fc_n_timeout(s, v, u=None): with state_lock: state['fc_n_timeout'] = max(v, 1) def cb_fc_log_freq(s, v, u=None): with state_lock: state['fc_log_freq'] = v legend_redraw_needed[0] = True def cb_fc_overlay(s, v, u=None): with state_lock: state['fc_overlay'] = v def cb_fc_legend_bins(s, v, u=None): with state_lock: state['fc_legend_bins'] = max(v, 2) legend_redraw_needed[0] = True def cb_fc_legend_show(s, v, u=None): with state_lock: state['fc_legend_show'] = v fc_legend_show_ref[0] = v dpg.configure_item("freq_legend_h", show=v) dpg.configure_item("freq_legend_v", show=v) legend_redraw_needed[0] = True fit_image() def cb_fc_reset(s=None, v=None, u=None): reset_evt.set() # processing_worker handles the actual reset safely # ---- UI layout --------------------------------------------------------- with dpg.window(tag="main_win", no_scrollbar=True, no_title_bar=True): with dpg.table( header_row=False, resizable=True, borders_innerV=True, tag="layout_table", scrollX=False, scrollY=False, ): dpg.add_table_column(init_width_or_weight=1.0) dpg.add_table_column(init_width_or_weight=CTRL_WIDTH, width_fixed=True) with dpg.table_row(): # ── Left: event canvas ───────────────────────────────────── with dpg.table_cell(): # Horizontal layout (side by side) with dpg.group(horizontal=True, tag="images_horiz"): dpg.add_image(TEXTURE_TAG, tag="evt_img_h", width=SENSOR_W, height=SENSOR_H) dpg.add_image(FREQ_TEX_TAG, tag="freq_img_h", width=SENSOR_W, height=SENSOR_H) dpg.add_drawlist(tag="freq_legend_h", width=LEGEND_DW, height=SENSOR_H) # Vertical layout (stacked), hidden initially with dpg.group(tag="images_vert", show=False): dpg.add_image(TEXTURE_TAG, tag="evt_img_v", width=SENSOR_W, height=SENSOR_H) with dpg.group(horizontal=True): dpg.add_image(FREQ_TEX_TAG, tag="freq_img_v", width=SENSOR_W, height=SENSOR_H) dpg.add_drawlist(tag="freq_legend_v", width=LEGEND_DW, height=SENSOR_H) # ── Right: controls ───────────────────────────────────────── with dpg.table_cell(): with dpg.child_window(width=CTRL_WIDTH, border=False): # ── Windows performance warning ────────────────────── if sys.platform == 'win32': dpg.add_text( "Warning: Windows reduces transfer speed.\n" "Use macOS or Linux for best performance.", color=(255, 200, 0, 255)) dpg.add_separator() # ── Connection ────────────────────────────────────── with dpg.group(): with dpg.group(horizontal=True): dpg.add_text("Script") dpg.add_input_text( tag="script_path", default_value=args.script or "", hint="select a .py script...", width=CTRL_WIDTH - 112, readonly=True) dpg.add_button( label="...", width=28, callback=lambda: dpg.show_item("file_dialog")) init_ports = list_com_ports() init_port = args.port or (init_ports[0] if init_ports else "") with dpg.group(horizontal=True): dpg.add_text("Port ") dpg.add_combo( items=init_ports, default_value=init_port, tag="port_combo", width=CTRL_WIDTH - 112) dpg.add_button(label="Ref", callback=cb_refresh, width=28) # ── Camera script parameters ──────────────────────── dpg.add_separator() dpg.add_text("Camera Parameters (applied at connect)") with dpg.group(horizontal=True): dpg.add_text("Stream ") dpg.add_combo( tag="stream_mode_combo", items=STREAM_MODES, default_value=state['stream_mode'], callback=cb_stream_mode, width=-1) with dpg.group(horizontal=True): dpg.add_text("CSI FIFO ") dpg.add_input_int( tag="csi_fifo_input", label="##csi_fifo", default_value=state['csi_fifo_depth'], min_value=4, min_clamped=True, step=1, step_fast=4, callback=cb_csi_fifo, width=-1) with dpg.group(horizontal=True, tag="evt_fifo_row", show=False): dpg.add_text("EVT FIFO ") dpg.add_input_int( tag="evt_fifo_input", label="##evt_fifo", default_value=state['evt_fifo_depth'], min_value=4, min_clamped=True, step=1, step_fast=4, callback=cb_evt_fifo, width=-1) with dpg.group(horizontal=True): dpg.add_text("EVT Buffer") dpg.add_combo( tag="evt_res_combo", items=[str(v) for v in EVT_RES_OPTIONS], default_value=str(state['evt_res']), callback=cb_evt_res, width=-1) dpg.add_input_text( tag="evt_res_display", default_value=str(state['evt_res']), readonly=True, show=False, width=-1) dpg.add_separator() dpg.add_button(label="Connect", tag="connect_btn", callback=cb_connect, width=-1) # ── Event Visualization ───────────────────────────── dpg.add_separator() dpg.add_text("Event Visualization") with dpg.group(horizontal=True): dpg.add_text("Contrast ") dpg.add_input_int( label="##contrast", default_value=state['contrast'], min_value=1, max_value=128, min_clamped=True, max_clamped=True, step=1, step_fast=8, callback=cb_contrast, width=-1) with dpg.group(horizontal=True): dpg.add_text("Color ") dpg.add_combo( items=COLOR_MODES, default_value=state['color_mode'], tag="color_mode_combo", callback=cb_color_mode, width=-1) with dpg.group(horizontal=True): dpg.add_text("Mode ") dpg.add_combo( items=["Sliding Window", "Canvas"], default_value=state['mode'], tag="mode_combo", callback=cb_mode, width=-1) with dpg.group(horizontal=True): dpg.add_text("Window ") dpg.add_input_int( tag="window_input", label="##window", default_value=state['window'], min_value=1, min_clamped=True, step=1, step_fast=10, callback=cb_window, width=-60) dpg.add_button(label="Clear", tag="clear_btn", callback=cb_clear, width=50, show=False) # ── Frequency Visualization ───────────────────────── with dpg.group(horizontal=True): dpg.add_checkbox(tag="fc_enabled_check", default_value=state['fc_enabled'], callback=cb_fc_enabled) dpg.add_text("Frequency Visualization") with dpg.group(tag="fc_controls", show=state['fc_enabled']): with dpg.group(horizontal=True): dpg.add_text("Cutoff T ") dpg.add_input_float( tag="fc_cutoff_input", label="##fc_cutoff", default_value=state['fc_cutoff_period'], min_value=1.0, min_clamped=True, step=0.5, step_fast=5.0, callback=cb_fc_cutoff, width=-1) with dpg.group(horizontal=True): dpg.add_text("Min Hz ") dpg.add_input_float( tag="fc_min_input", label="##fc_min", default_value=state['fc_min_freq'], min_value=0.01, min_clamped=True, step=1.0, step_fast=10.0, callback=cb_fc_min_freq, width=-1) with dpg.group(horizontal=True): dpg.add_text("Max Hz ") dpg.add_input_float( tag="fc_max_input", label="##fc_max", default_value=state['fc_max_freq'], min_value=1.0, min_clamped=True, step=10.0, step_fast=100.0, callback=cb_fc_max_freq, width=-1) with dpg.group(horizontal=True): dpg.add_text("Timeout ") dpg.add_input_int( tag="fc_timeout_input", label="##fc_timeout", default_value=state['fc_n_timeout'], min_value=1, min_clamped=True, step=1, callback=cb_fc_n_timeout, width=-60) dpg.add_button(label="Reset", tag="fc_reset_btn", callback=cb_fc_reset, width=50) with dpg.group(horizontal=True): dpg.add_checkbox(tag="fc_log_check", default_value=state['fc_log_freq'], callback=cb_fc_log_freq) dpg.add_text("Log frequency scale") with dpg.group(horizontal=True): dpg.add_checkbox(tag="fc_overlay_check", default_value=state['fc_overlay'], callback=cb_fc_overlay) dpg.add_text("Overlay active pixels") with dpg.group(horizontal=True): dpg.add_checkbox(tag="fc_legend_check", default_value=state['fc_legend_show'], callback=cb_fc_legend_show) dpg.add_text("Show legend") with dpg.group(horizontal=True): dpg.add_text("Bins ") dpg.add_input_int( tag="fc_legend_bins_input", label="##fc_legend_bins", default_value=state['fc_legend_bins'], min_value=2, min_clamped=True, step=1, step_fast=5, callback=cb_fc_legend_bins, width=-1) # ── Save ──────────────────────────────────────────── dpg.add_separator() dpg.add_button(label="Save Images and Events", tag="save_btn", callback=cb_save, width=-1) # ── Stats ─────────────────────────────────────────── dpg.add_separator() dpg.add_text("Statistics") with dpg.table(header_row=False, borders_innerV=False, policy=dpg.mvTable_SizingFixedFit): dpg.add_table_column(init_width_or_weight=95, width_fixed=True) dpg.add_table_column(init_width_or_weight=150, width_fixed=True) for lbl, tag in [ ("Events/batch", "stat_ev_batch"), ("Rate", "stat_rate"), ("Bandwidth", "stat_bw"), ("Total events", "stat_total"), ("Uptime", "stat_uptime"), ]: with dpg.table_row(): dpg.add_text(lbl) dpg.add_text("—", tag=tag) dpg.create_viewport(title="GenX320 Event Viewer", width=1280, height=800, resizable=True) dpg.setup_dearpygui() dpg.show_viewport() dpg.set_primary_window("main_win", True) def handle_exit(signum, frame): if conn['stop_evt']: conn['stop_evt'].set() dpg.stop_dearpygui() signal.signal(signal.SIGINT, handle_exit) signal.signal(signal.SIGTERM, handle_exit) if args.port and args.script: do_connect(args.port) # Apply initial UI state (default mode is Sliding Window, so C button stays hidden) _sync_window_ui(state['window'], state['mode']) disp_wh = [0, 0, None] # [dw, dh, layout ('h' or 'v')] def fit_image(): fw, fh = tex_wh if fw <= 0 or fh <= 0: return fc_en = fc_enabled_ref[0] legend_dw = (LEGEND_DW if fc_legend_show_ref[0] else 0) if fc_en else 0 n_images = 2 if fc_en else 1 avail_w = max(dpg.get_viewport_width() - CTRL_WIDTH - 30 - legend_dw, 1) avail_h = max(dpg.get_viewport_height() - 60, 1) # Scale for each arrangement; pick whichever makes images larger scale_h = min(avail_w / (n_images * fw), avail_h / fh) # side by side scale_v = min(avail_w / fw, avail_h / (n_images * fh)) # stacked if scale_h >= scale_v: layout = 'h' scale = scale_h else: layout = 'v' scale = scale_v dw, dh = max(int(fw * scale), 1), max(int(fh * scale), 1) if [dw, dh, layout] != disp_wh: disp_wh[0], disp_wh[1], disp_wh[2] = dw, dh, layout if layout == 'h': dpg.show_item("images_horiz") dpg.hide_item("images_vert") dpg.configure_item("evt_img_h", width=dw, height=dh) dpg.configure_item("freq_img_h", width=dw, height=dh) else: dpg.hide_item("images_horiz") dpg.show_item("images_vert") dpg.configure_item("evt_img_v", width=dw, height=dh) dpg.configure_item("freq_img_v", width=dw, height=dh) # Resize both drawlists so the active one is correct on next redraw dpg.configure_item("freq_legend_h", height=dh) dpg.configure_item("freq_legend_v", height=dh) legend_redraw_needed[0] = True dpg.set_viewport_resize_callback(lambda: fit_image()) fit_image() # ----------------------------------------------------------------------- # Render loop (drawing thread — texture uploads and GUI only) # ----------------------------------------------------------------------- last_stat_update = 0.0 while dpg.is_dearpygui_running(): # Detect camera thread death (e.g. unplugged) t = conn['cam_thread'] if t is not None and not t.is_alive(): conn['cam_thread'] = None conn['proc_thread'] = None conn['stop_evt'] = None dpg.configure_item("connect_btn", label="Connect") _set_cam_settings_enabled(True) # Snapshot visualization parameters (needed for texture conversion + legend) with state_lock: color_mode = state['color_mode'] fc_enabled = state['fc_enabled'] fc_min = state['fc_min_freq'] fc_max = state['fc_max_freq'] fc_n_to = state['fc_n_timeout'] fc_log_freq = state['fc_log_freq'] fc_overlay = state['fc_overlay'] fc_legend_show = state['fc_legend_show'] fc_legend_bins = state['fc_legend_bins'] # Drain all available processed results; keep the latest got_result = False result_latest = None try: while True: result_latest = result_q.get_nowait() got_result = True except queue.Empty: pass if got_result and result_latest is not None: r = result_latest canvas_u8 = r['canvas_u8'] last_canvas_u8[0] = canvas_u8 event_buf.clear() event_buf.extend(r['event_buf']) tex_data = _canvas_to_texture(canvas_u8, color_mode) dpg.set_value(TEXTURE_TAG, tex_data) if fc_enabled and r['fc_enabled']: freq_tex = _freq_to_texture( r['fc_per'], r['fc_t_ud'], r['fc_t_du'], r['fc_t_now'], fc_n_to, fc_min, fc_max, use_log=fc_log_freq, overlay_events=fc_overlay) last_freq_rgba[0] = freq_tex.reshape(SENSOR_H, SENSOR_W, 4) dpg.set_value(FREQ_TEX_TAG, freq_tex) now = time.perf_counter() if now - last_stat_update >= 0.2: last_stat_update = now s = r['stats'] dpg.set_value("stat_ev_batch", f"{s['event_count']:,}") dpg.set_value("stat_rate", f"{s['event_rate']:,.0f} ev/s") dpg.set_value("stat_bw", f"{s['mbps']:.2f} MB/s") dpg.set_value("stat_total", f"{s['total_events']:,}") dpg.set_value("stat_uptime", f"{s['elapsed']:.1f} s") # Redraw legend only when parameters changed, not every frame if legend_redraw_needed[0]: if fc_legend_show: legend_dh = max(disp_wh[1], 1) _draw_freq_legend("freq_legend_h", legend_dh, fc_min, fc_max, fc_log_freq, fc_legend_bins) _draw_freq_legend("freq_legend_v", legend_dh, fc_min, fc_max, fc_log_freq, fc_legend_bins) legend_redraw_needed[0] = False # Reset UI if the camera thread died unexpectedly (e.g. connection error) if conn['cam_thread'] and not conn['cam_thread'].is_alive(): do_disconnect() dpg.render_dearpygui_frame() dpg.destroy_context() if __name__ == '__main__': _args = parse_args() if _args.benchmark: run_benchmark(_args) else: main(_args) ================================================ FILE: tools/genx320-event-streaming/genx320_raw_event_mode_streaming_on_cam.py ================================================ # This work is licensed under the MIT license. # Copyright (c) 2013-2026 OpenMV LLC. All rights reserved. # https://github.com/openmv/openmv/blob/master/LICENSE # # This example shows off using the genx320 raw event camera from Prophesee # using event streaming mode and sending the data back to the PC. # # This script is meant to be run using https://github.com/openmv/openmv-python # from a PC using desktop tools. No visualization or text output is generated # by this script for OpenMV IDE. # # Raw EVT 2.0 format # ------------------ # Each event is a 32-bit little-endian word. The firmware streams these words # directly from the sensor without any decoding. # # Bit layout of each 32-bit word: # # Bits [31:28] type (4 bits) — event type: # 0x0 TD_LOW Pixel event — decrease in illumination (negative polarity) # 0x1 TD_HIGH Pixel event — increase in illumination (positive polarity) # 0x8 EV_TIME_HIGH Upper 28 bits of the microsecond timestamp counter # 0xA EXT_TRIGGER External trigger event # 0xE OTHERS Reserved for future extension # 0xF CONTINUED Extra data appended to the previous event # # TD_LOW / TD_HIGH pixel event (type == 0x0 or 0x1): # Bits [27:22] ts (6 bits) — timestamp low, microseconds (0–63 µs) # Bits [21:11] x (11 bits) — pixel column (0–319 for GenX320) # Bits [10:0] y (11 bits) — pixel row (0–319 for GenX320) # # Decoding: # type = (word >> 28) & 0xF # ts = (word >> 22) & 0x3F # x = (word >> 11) & 0x7FF # y = (word ) & 0x7FF # t_us = time_high | ts # full microsecond timestamp # polarity = type # 0 = negative, 1 = positive # # EV_TIME_HIGH (type == 0x8): # Bits [27:0] time_high (28 bits) — upper bits of timestamp counter # # Decoding: # time_high = (word & 0x0FFFFFFF) << 6 # units: microseconds # # Must be tracked across the stream. Combine with ts from pixel events: # t_us = time_high | ts # # Split into seconds / milliseconds / microseconds: # ts_s = t_us // 1_000_000 # ts_ms = (t_us // 1_000) % 1_000 # ts_us = t_us % 1_000 # # EXT_TRIGGER (type == 0xA): # Bits [27:22] ts (6 bits) — timestamp low, microseconds # Bits [12:8] trigger_id (5 bits) — trigger channel ID # Bit [0] polarity (1 bit) — 0 = falling, 1 = rising # # Decoding: # ts = (word >> 22) & 0x3F # trigger_id = (word >> 8) & 0x1F # polarity = (word ) & 0x1 # t_us = time_high | ts # # Parsing pseudocode (Python): # # time_high = 0 # for word in struct.unpack_from('<' + 'I' * n, buf): # event_type = (word >> 28) & 0xF # if event_type == 0x8: # EV_TIME_HIGH # time_high = (word & 0x0FFFFFFF) << 6 # elif event_type in (0x0, 0x1): # TD pixel event # ts = (word >> 22) & 0x3F # x = (word >> 11) & 0x7FF # y = (word ) & 0x7FF # t_us = time_high | ts # pol = event_type # 0=neg, 1=pos import csi import protocol # Event buffers arrive from the camera and are stored in # a fifo buffer before being processed by python. CSI_FIFO_DEPTH = 8 # Must be a power of two between 1024 and 65536. EVT_RES = 8192 # Initialize the sensor. csi0 = csi.CSI(cid=csi.GENX320) csi0.reset() csi0.ioctl(csi.IOCTL_GENX320_SET_MODE, csi.GENX320_MODE_EVENT, EVT_RES) csi0.framebuffers(CSI_FIFO_DEPTH) # Grab pointer to the internal FIFO buffer. events = csi0.ioctl(csi.IOCTL_GENX320_READ_EVENTS_RAW) events_mv = memoryview(events.bytearray()) frame_available = True class RawEventChannel: def size(self): return len(events_mv) def shape(self): return (len(events_mv), 1) def read(self, offset, size): global frame_available if frame_available: end = offset + size mv = events_mv[offset:end] if end == len(events_mv): frame_available = False return mv return bytes(size) def poll(self): return frame_available protocol.register(name='raw_events', backend=RawEventChannel()) while True: if not frame_available: events = csi0.ioctl(csi.IOCTL_GENX320_READ_EVENTS_RAW) events_mv = memoryview(events.bytearray()) frame_available = True ================================================ FILE: tools/genx320-overlay-calibration/README.md ================================================ # GenX320 Overlay Calibration A 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. ![GenX320 Overlay Calibration GUI](genx320_overlay_calibration.jpeg) ## Platform Notes macOS 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. On macOS and Linux the companion script's `read` method is automatically renamed to `readp` before execution (this is handled transparently by the PC script). CRC 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`. ## Prerequisites 1. **OpenMV IDE** v4.8.4 or later. 2. **OpenMV Cam Firmware** v5.0.0 or later. 3. **Python dependencies:** ``` pip install dearpygui numpy pyserial Pillow openmv ``` Optionally install OpenCV for automatic checkerboard detection and better warp quality: ``` pip install opencv-python ``` Without OpenCV, the composite falls back to PIL bilinear resize and automatic alignment is unavailable. ## Running ``` python genx320_overlay_calibration_on_pc.py ``` The 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: | Flag | Default | Description | |------|---------|-------------| | `--port PORT` | *(GUI selector)* | Serial port to connect on | | `--script PATH` | `genx320_overlay_calibration_on_cam.py` | MicroPython script to run on the camera | | `--baudrate N` | `921600` | Serial baud rate | | `--crc` | off (Linux/Mac), on (Windows) | Enable CRC on the serial protocol | | `--quiet` | off | Suppress camera stdout | | `--debug` | off | Enable verbose logging | | `--benchmark` | off | Headless throughput benchmark (no GUI) | ## Benchmark Mode Run without the GUI to measure raw USB throughput: ``` python genx320_overlay_calibration_on_pc.py --benchmark python genx320_overlay_calibration_on_pc.py --benchmark --port /dev/ttyACM0 ``` Prints at 10 Hz: ``` elapsed=3.2s fps=9.1 bw=1.24 MB/s frames=29 ``` Press **Ctrl+C** to stop. ## GUI Overview The window has two panes: a **left image area** and a **right control panel**. ### Image Area - **Top row** — main color camera (left) and GenX320 histogram (right), each scaled to occupy half the available width at the same display height. - **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. All images resize automatically when the window is resized. ### Camera Parameters *(applied at connect)* These patch the on-camera script before it is executed. They are locked while connected. | Control | Default | Description | |---------|---------|-------------| | Main Res | VGA (640×480) | Main camera resolution: QVGA, VGA, or HD | | Main Fmt | RGB565 | Main camera pixel format: RGB565 or GRAYSCALE | The GenX320 always outputs 320×320 grayscale in histogram mode — no additional controls are needed. ### Overlay Alpha A slider from 0% to 100% controlling how much of the GenX320 frame is blended over the main frame in the composite. Defaults to 50%. ### Calibration Pattern Opens 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. ### Overlay Alignment Computes a homography (perspective warp) that maps GenX320 pixel coordinates to main camera pixel coordinates for a geometrically correct overlay. #### Manual Mode Click **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. > **Tip:** Spread the 4 points across the full frame for the most accurate warp. Avoid clustering all points in one region. #### Automatic Mode Click **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. The 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. The grid size is detected automatically -- no manual corner count is needed. The status line reports the number of inliers after detection. #### Shared Controls - **Reset Homography** -- clears all points and the transform. - **transform =** -- read-only copyable text box showing the computed 3x3 perspective matrix, ready to paste into firmware or a processing script. ### Save Images Saves the current frames and transform to disk. The button label changes to **Save Images + Transform** once a homography has been computed. - `genx320_overlay_main_.png` — main camera frame (RGB). - `genx320_overlay_genx320_.png` — GenX320 histogram frame. - `genx320_overlay_composite_.png` — composited overlay image. - `genx320_overlay_transform_.txt` — the 3×3 homography matrix. These files are excluded from git via `.gitignore`. ### Statistics | Field | Description | |-------|-------------| | FPS | Frame pair rate (EMA) | | Bandwidth | Combined USB data rate (MB/s, EMA) | | Total frames | Cumulative frame pairs since connect | | Uptime | Seconds since connect | ================================================ FILE: tools/genx320-overlay-calibration/genx320_overlay_calibration_on_cam.py ================================================ # This work is licensed under the MIT license. # Copyright (c) 2013-2026 OpenMV LLC. All rights reserved. # https://github.com/openmv/openmv/blob/master/LICENSE # # This script pulls color and event images from the camera. # # This script is meant to be run using https://github.com/openmv/openmv-python # from a PC using desktop tools. No visualization or text output is generated # by this script for OpenMV IDE. import csi import protocol import json MAIN_PIXFORMAT = csi.RGB565 MAIN_FRAME_SIZE = csi.VGA # Initialize the main camera. csi0 = csi.CSI() csi0.reset(hard=True) csi0.pixformat(MAIN_PIXFORMAT) csi0.framesize(MAIN_FRAME_SIZE) csi0_img = csi0.snapshot() csi0_img_mv = memoryview(csi0_img.bytearray()) csi0_frame_available = True # Parse image info from string representation. csi0_img_info = json.loads(str(csi0_img)) csi0_img_width = csi0_img_info['w'] csi0_img_height = csi0_img_info['h'] csi0_img_size = csi0_img_info['size'] # Initialize the GenX320 in histogram mode — outputs 320x320 grayscale. csi1 = csi.CSI(cid=csi.GENX320) csi1.reset(hard=False) csi1.pixformat(csi.GRAYSCALE) csi1.framesize((320, 320)) csi1.brightness(128) csi1.contrast(64) csi1_img = csi1.snapshot() csi1_img_mv = memoryview(csi1_img.bytearray()) csi1_frame_available = True # Parse image info from string representation. csi1_img_info = json.loads(str(csi1_img)) csi1_img_width = csi1_img_info['w'] csi1_img_height = csi1_img_info['h'] csi1_img_size = csi1_img_info['size'] class MainChannel: def size(self): return csi0_img_size def shape(self): return (csi0_img_height, csi0_img_width, csi0_img_size) def read(self, offset, size): global csi0_frame_available if csi0_frame_available: end = offset + size mv = csi0_img_mv[offset:end] if end == csi0_img_size: csi0_frame_available = False return mv return bytes(size) def poll(self): return csi0_frame_available class GenX320Channel: def size(self): return csi1_img_size def shape(self): return (csi1_img_height, csi1_img_width, csi1_img_size) def read(self, offset, size): global csi1_frame_available if csi1_frame_available: end = offset + size mv = csi1_img_mv[offset:end] if end == csi1_img_size: csi1_frame_available = False return mv return bytes(size) def poll(self): return csi1_frame_available protocol.register(name='main', backend=MainChannel()) protocol.register(name='genx320', backend=GenX320Channel()) while True: if not csi0_frame_available: csi0_img = csi0.snapshot() csi0_img_mv = memoryview(csi0_img.bytearray()) csi0_frame_available = True if not csi1_frame_available: csi1_img = csi1.snapshot() csi1_img_mv = memoryview(csi1_img.bytearray()) csi1_frame_available = True ================================================ FILE: tools/genx320-overlay-calibration/genx320_overlay_calibration_on_pc.py ================================================ #!/usr/bin/env python3 # # This work is licensed under the MIT license. # Copyright (c) 2013-2026 OpenMV LLC. All rights reserved. # https://github.com/openmv/openmv/blob/master/LICENSE # # GenX320 overlay calibration GUI for OpenMV cameras on PC. # Requires: pip install dearpygui numpy pyserial Pillow openmv # # Streams RGB565/Grayscale frames from the main camera and 320x320 grayscale # histogram frames from the GenX320 event camera simultaneously, displays them # side by side, and composites them into a third image below. A homography # computed from point correspondences aligns the GenX320 onto the main camera # frame for a pixel-accurate overlay. import sys import os import argparse import time import logging import signal import threading import queue import numpy as np try: from PIL import Image _PIL_AVAILABLE = True except ImportError: _PIL_AVAILABLE = False import serial.tools.list_ports import dearpygui.dearpygui as dpg from openmv.camera import Camera COLOR_CAMERA = "\033[32m" COLOR_RESET = "\033[0m" EMA_ALPHA = 0.2 CTRL_WIDTH = 320 # Main camera resolution options (GenX320 is always 320x320 grayscale). MAIN_RES_OPTIONS = ['QVGA (320×240)', 'VGA (640×480)', 'HD (1280×720)'] PIXFMT_OPTIONS = ['RGB565', 'GRAYSCALE'] MAIN_RES_MAP = { 'QVGA (320×240)': 'csi.QVGA', 'VGA (640×480)': 'csi.VGA', 'HD (1280×720)': 'csi.HD', } PIXFMT_MAP = { 'RGB565': 'csi.RGB565', 'GRAYSCALE': 'csi.GRAYSCALE', } # Tags MAIN_TEX_TAG = "main_tex" GENX320_TEX_TAG = "genx320_tex" COMP_TEX_TAG = "comp_tex" TEX_REG_TAG = "tex_reg" # --------------------------------------------------------------------------- # RGB565 → RGB888 conversion (vectorized) # --------------------------------------------------------------------------- def rgb565_to_rgb888(data, w, h): """Convert a bytes-like object of RGB565 pixels to (H,W,3) uint8.""" words = np.frombuffer(data, dtype='> 11) & 0x1F) * 255 // 31 g = ((words >> 5) & 0x3F) * 255 // 63 b = ( words & 0x1F) * 255 // 31 return np.stack([r, g, b], axis=2).astype(np.uint8) def gray_to_rgb888(data, w, h): """Convert a bytes-like object of 8-bit grayscale to (H,W,3) uint8.""" gray = np.frombuffer(data, dtype=np.uint8).reshape(h, w) return np.stack([gray, gray, gray], axis=2) def to_dpg_rgba(rgb888): """Convert (H,W,3) uint8 RGB to flat float32 RGBA for DearPyGui texture.""" h, w = rgb888.shape[:2] rgba = np.empty((h, w, 4), dtype=np.float32) rgba[:, :, :3] = rgb888.astype(np.float32) * (1.0 / 255.0) rgba[:, :, 3] = 1.0 return rgba.ravel() # --------------------------------------------------------------------------- # Script patching # --------------------------------------------------------------------------- def patch_script(script, main_res, main_pixfmt): """Patch cam script constants before exec. Replaces MAIN_FRAME_SIZE and MAIN_PIXFORMAT constant assignments. On macOS/Linux also renames 'def read' → 'def readp'. """ import re main_csi = MAIN_RES_MAP[main_res] main_fmt = PIXFMT_MAP[main_pixfmt] script = re.sub(r'MAIN_FRAME_SIZE\s*=\s*\S+', f'MAIN_FRAME_SIZE = {main_csi}', script) script = re.sub(r'MAIN_PIXFORMAT\s*=\s*\S+', f'MAIN_PIXFORMAT = {main_fmt}', script) if sys.platform != 'win32': script = script.replace('def read(self, offset, size):', 'def readp(self, offset, size):') return script # --------------------------------------------------------------------------- # Camera worker # --------------------------------------------------------------------------- def camera_worker(args, state_lock, state, frame_q, stop_evt): try: with Camera( args.port, baudrate=args.baudrate, crc=args.crc, seq=args.seq, ack=args.ack, events=args.events, timeout=args.timeout, max_retry=args.max_retry, max_payload=args.max_payload, drop_rate=args.drop_rate, ) as camera: logging.info(f"Connected to OpenMV on {args.port}") camera.stop() time.sleep(0.5) with open(args.script) as f: script = f.read() with state_lock: main_res = state['main_res'] main_pixfmt = state['main_pixfmt'] script = patch_script(script, main_res, main_pixfmt) logging.debug(f"Patched script: main={main_res}/{main_pixfmt} " f"readp={'yes' if sys.platform != 'win32' else 'no'}") camera.exec(script) logging.info("Script running, streaming frames...") start_time = time.perf_counter() last_time = start_time total_bytes = 0 mbps_ema = 0.0 fps_ema = 0.0 frame_count = 0 while not stop_evt.is_set(): status = camera.read_status() if not args.quiet and status and status.get('stdout'): if text := camera.read_stdout(): print(f"{COLOR_CAMERA}{text}{COLOR_RESET}", end='') has_main = camera.has_channel('main') and status and status.get('main') has_genx320 = camera.has_channel('genx320') and status and status.get('genx320') if not has_main and not has_genx320: time.sleep(0.005) continue main_frame = None # (data, w, h) genx320_frame = None if has_main: sz = camera.channel_size('main') if sz > 0: shape = camera._channel_shape(camera.get_channel(name='main')) if shape and len(shape) >= 2: h, w = shape[0], shape[1] data = camera.channel_read('main', sz) if data: main_frame = (data, w, h) if has_genx320: sz = camera.channel_size('genx320') if sz > 0: shape = camera._channel_shape(camera.get_channel(name='genx320')) if shape and len(shape) >= 2: h, w = shape[0], shape[1] data = camera.channel_read('genx320', sz) if data: genx320_frame = (data, w, h) if main_frame is None and genx320_frame is None: time.sleep(0.005) continue now = time.perf_counter() dt = max(now - last_time, 1e-6) last_time = now batch_bytes = ((len(main_frame[0]) if main_frame else 0) + (len(genx320_frame[0]) if genx320_frame else 0)) total_bytes += batch_bytes frame_count += 1 elapsed = now - start_time mb_per_sec = batch_bytes / 1048576.0 / dt frames_per_sec = 1.0 / dt mbps_ema = (mb_per_sec if mbps_ema == 0.0 else mbps_ema * (1 - EMA_ALPHA) + mb_per_sec * EMA_ALPHA) fps_ema = (frames_per_sec if fps_ema == 0.0 else fps_ema * (1 - EMA_ALPHA) + frames_per_sec * EMA_ALPHA) stats = { 'fps': fps_ema, 'mbps': mbps_ema, 'total_frames': frame_count, 'elapsed': elapsed, } if frame_q.full(): try: frame_q.get_nowait() except queue.Empty: pass frame_q.put((main_frame, genx320_frame, stats)) except Exception as e: logging.error(f"Camera error: {e}") if args.debug: import traceback logging.error(traceback.format_exc()) # --------------------------------------------------------------------------- # Argument parsing # --------------------------------------------------------------------------- def parse_args(): p = argparse.ArgumentParser(description='OpenMV GenX320 overlay calibration GUI') p.add_argument('--port', default=None) p.add_argument('--script', default=None) p.add_argument('--baudrate', default=921600, type=int) p.add_argument('--crc', default=None, action=argparse.BooleanOptionalAction) p.add_argument('--seq', default=True, action=argparse.BooleanOptionalAction) p.add_argument('--ack', default=False, action=argparse.BooleanOptionalAction) p.add_argument('--events', default=True, action=argparse.BooleanOptionalAction) p.add_argument('--timeout', default=5.0, type=float) p.add_argument('--max_retry', default=5, type=int) p.add_argument('--max_payload', default=65536, type=int) p.add_argument('--drop_rate', default=0, type=int) p.add_argument('--quiet', default=False, action='store_true') p.add_argument('--debug', default=False, action='store_true') p.add_argument('--benchmark', default=False, action='store_true', help='Headless throughput benchmark — no GUI') args = p.parse_args() if args.crc is None: args.crc = sys.platform == 'win32' return args def list_com_ports(): return sorted(p.device for p in serial.tools.list_ports.comports()) # --------------------------------------------------------------------------- # Benchmark (headless) # --------------------------------------------------------------------------- def run_benchmark(args): """Headless throughput benchmark — no GUI, prints stats to terminal.""" if not args.port: ports = list_com_ports() if not ports: print("No serial ports found. Use --port to specify one.") sys.exit(1) args.port = ports[0] print(f"Auto-selected port: {args.port}") if args.script is None: args.script = os.path.join( os.path.dirname(os.path.abspath(__file__)), 'genx320_overlay_calibration_on_cam.py', ) state_lock = threading.Lock() state = { 'main_res': 'VGA (640×480)', 'main_pixfmt': 'RGB565', } frame_q = queue.Queue(maxsize=4) stop_evt = threading.Event() def handle_exit(signum, frame): stop_evt.set() signal.signal(signal.SIGINT, handle_exit) signal.signal(signal.SIGTERM, handle_exit) t = threading.Thread( target=camera_worker, args=(args, state_lock, state, frame_q, stop_evt), daemon=True, ) t.start() print(f"Connecting to {args.port} ...") last_print = time.perf_counter() while not stop_evt.is_set(): try: _, _, stats = frame_q.get(timeout=0.1) except queue.Empty: if not t.is_alive(): print("Camera thread died unexpectedly.") break continue now = time.perf_counter() if now - last_print >= 0.1: last_print = now print(f"elapsed={stats['elapsed']:.1f}s\t" f"fps={stats['fps']:.1f}\t" f"bw={stats['mbps']:.2f} MB/s\t" f"frames={stats['total_frames']:,}") stop_evt.set() print("\nDone.") # --------------------------------------------------------------------------- # Main # --------------------------------------------------------------------------- def main(args=None): if args is None: _args = parse_args() if _args.benchmark: run_benchmark(_args) return args = _args if args.script is None: args.script = os.path.join( os.path.dirname(os.path.abspath(__file__)), 'genx320_overlay_calibration_on_cam.py', ) logging.basicConfig( format="%(relativeCreated)010.3f - %(message)s", level=logging.DEBUG if args.debug else logging.INFO, ) state_lock = threading.Lock() state = { 'main_res': 'VGA (640×480)', 'main_pixfmt': 'RGB565', } # Current pixel dimensions — start at 1×1, updated on first received frame main_wh = [1, 1] genx320_wh = [1, 1] # Overlay alpha: fraction of GenX320 blended onto main (0.0–1.0) overlay_alpha = [0.5] # Homography matrix (3×3 float64), None = no warp homography = [None] # Point correspondences for homography computation main_pts = [] genx320_pts = [] pick_state = [None] # Latest decoded frames (H,W,3 uint8) last_main_rgb = [None] last_genx320_rgb = [None] # Flickering calibration pattern window pattern_stop_evt = [None] pattern_thread = [None] pattern_root = [None] conn = {'thread': None, 'stop_evt': None} frame_q = queue.Queue(maxsize=4) signal.signal(signal.SIGINT, lambda *_: dpg.stop_dearpygui()) # ----------------------------------------------------------------------- # DPG setup # ----------------------------------------------------------------------- dpg.create_context() def _make_placeholder(w, h): buf = np.full(w * h * 4, 0.05, dtype=np.float32) buf[3::4] = 1.0 return buf with dpg.texture_registry(tag=TEX_REG_TAG): dpg.add_dynamic_texture(1, 1, _make_placeholder(1, 1), tag=MAIN_TEX_TAG) dpg.add_dynamic_texture(1, 1, _make_placeholder(1, 1), tag=GENX320_TEX_TAG) dpg.add_dynamic_texture(1, 1, _make_placeholder(1, 1), tag=COMP_TEX_TAG) # ----------------------------------------------------------------------- # Helpers # ----------------------------------------------------------------------- def _do_connect(port): args.port = port # Reset size tracking; main loop will recreate textures on first frame. main_wh[0], main_wh[1] = 1, 1 genx320_wh[0], genx320_wh[1] = 1, 1 homography[0] = None main_pts.clear() genx320_pts.clear() pick_state[0] = None stop_evt = threading.Event() conn['stop_evt'] = stop_evt t = threading.Thread( target=camera_worker, args=(args, state_lock, state, frame_q, stop_evt), daemon=True, ) t.start() conn['thread'] = t dpg.configure_item("connect_btn", label="Disconnect") _set_cam_settings_enabled(False) logging.info(f"Connecting to {port}...") def _do_disconnect(): if conn['stop_evt']: conn['stop_evt'].set() conn['thread'] = None conn['stop_evt'] = None dpg.configure_item("connect_btn", label="Connect") _set_cam_settings_enabled(True) CAM_SETTING_TAGS = ["main_res_combo", "main_pixfmt_combo"] def _set_cam_settings_enabled(enabled): for tag in CAM_SETTING_TAGS: dpg.configure_item(tag, enabled=enabled) def _fmt_homography(H): rows = [] for row in H: rows.append(" [ " + ", ".join(f"{v:12.6f}" for v in row) + " ]") return "transform =\n[\n" + ",\n".join(rows) + "\n]" def _recompute_homography(): if len(main_pts) == 4 and len(genx320_pts) == 4: try: import cv2 src = np.float32(genx320_pts) dst = np.float32(main_pts) H, _ = cv2.findHomography(src, dst) homography[0] = H dpg.set_value("pick_status", "Homography computed.") except ImportError: A = [] for (sx, sy), (dx, dy) in zip(genx320_pts, main_pts): A.append([-sx, -sy, -1, 0, 0, 0, sx*dx, sy*dx, dx]) A.append([ 0, 0, 0, -sx, -sy, -1, sx*dy, sy*dy, dy]) A = np.array(A, dtype=np.float64) _, _, Vt = np.linalg.svd(A) H = Vt[-1].reshape(3, 3) H /= H[2, 2] homography[0] = H dpg.set_value("pick_status", "Homography computed (no cv2).") if homography[0] is not None: dpg.set_value("homography_text", _fmt_homography(homography[0])) dpg.configure_item("save_btn", label="Save Images + Transform") def _make_composite(): main_rgb = last_main_rgb[0] genx320_rgb = last_genx320_rgb[0] if main_rgb is None: return None mw, mh = main_wh alpha = overlay_alpha[0] comp = main_rgb.copy().astype(np.float32) if genx320_rgb is not None: gh, gw = genx320_rgb.shape[:2] H = homography[0] if H is not None: try: import cv2 warped = cv2.warpPerspective(genx320_rgb, H, (mw, mh)) coverage = cv2.warpPerspective( np.ones((gh, gw), dtype=np.float32), H, (mw, mh), flags=cv2.INTER_NEAREST) except ImportError: warped = np.array(Image.fromarray(genx320_rgb).resize( (mw, mh), Image.BILINEAR)) coverage = np.ones((mh, mw), dtype=np.float32) mask = (coverage > 0).reshape(mh, mw, 1).astype(np.float32) comp = comp * (1 - mask * alpha) + warped.astype(np.float32) * alpha else: try: import cv2 warped = cv2.resize(genx320_rgb, (mw, mh)) except ImportError: warped = np.array(Image.fromarray(genx320_rgb).resize( (mw, mh), Image.BILINEAR)) comp = comp * (1 - alpha) + warped.astype(np.float32) * alpha return np.clip(comp, 0, 255).astype(np.uint8) def _fit_images(): vp_w = max(dpg.get_viewport_width() - CTRL_WIDTH - 30, 1) vp_h = max(dpg.get_viewport_height() - 60, 1) mw, mh = main_wh gw, gh = genx320_wh slot_w = vp_w / 2 slot_h = vp_h * 0.55 main_s = min(slot_w / max(mw, 1), slot_h / max(mh, 1)) genx320_s = min(slot_w / max(gw, 1), slot_h / max(gh, 1)) target_h = min(mh * main_s, gh * genx320_s) main_s = target_h / max(mh, 1) genx320_s = target_h / max(gh, 1) comp_scale = min(vp_w / max(mw, 1), (vp_h * 0.4) / max(mh, 1)) for tag, w, h, s in [ ("main_img", mw, mh, main_s), ("genx320_img", gw, gh, genx320_s), ("comp_img", mw, mh, comp_scale), ]: dpg.configure_item(tag, width=max(1, int(w * s)), height=max(1, int(h * s))) comp_w = max(1, int(mw * comp_scale)) indent = max(0, (vp_w - comp_w) // 2) dpg.configure_item("comp_row", indent=indent) # ----------------------------------------------------------------------- # Callbacks # ----------------------------------------------------------------------- def cb_main_res(s, v, u=None): with state_lock: state['main_res'] = v def cb_main_pixfmt(s, v, u=None): with state_lock: state['main_pixfmt'] = v def cb_refresh(s=None, v=None, u=None): items = list_com_ports() dpg.configure_item("port_combo", items=items) if items and not dpg.get_value("port_combo"): dpg.set_value("port_combo", items[0]) def cb_connect(s=None, v=None, u=None): if conn['thread'] and conn['thread'].is_alive(): _do_disconnect() else: port = dpg.get_value("port_combo") if not port: return _do_connect(port) def cb_save(s=None, v=None, u=None): ts = int(time.time()) if _PIL_AVAILABLE: if last_main_rgb[0] is not None: name = f"genx320_overlay_main_{ts}.png" Image.fromarray(last_main_rgb[0]).save(name) print(f"Saved: {name}") if last_genx320_rgb[0] is not None: name = f"genx320_overlay_genx320_{ts}.png" Image.fromarray(last_genx320_rgb[0]).save(name) print(f"Saved: {name}") comp = _make_composite() if comp is not None: name = f"genx320_overlay_composite_{ts}.png" Image.fromarray(comp).save(name) print(f"Saved: {name}") else: print("pip install Pillow to enable image saving.") H = homography[0] if H is not None: name = f"genx320_overlay_transform_{ts}.txt" with open(name, 'w') as f: f.write(_fmt_homography(H) + "\n") print(f"Saved: {name}") def cb_align_mode(s, v, u=None): is_auto = (v == 'Automatic') dpg.configure_item("manual_group", show=not is_auto) dpg.configure_item("auto_group", show=is_auto) def _find_board_blobs(img_rgb): """Blob-grid detection for event camera images. Returns (True, corners, grid_shape) or (False, None, None). corners is an Nx1x2 array of inner corner points (like findChessboardCorners). grid_shape is (inner_cols, inner_rows) for the detected grid. """ import cv2 gray = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2GRAY) # Heavy median to denoise event speckle, then Otsu binarize med = cv2.medianBlur(gray, 21) _, binary = cv2.threshold(med, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) # Find contours of the dark squares (now foreground after INV) contours, _ = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) raw_centers = [] raw_areas = [] for cnt in contours: area = cv2.contourArea(cnt) if area < 100: continue M = cv2.moments(cnt) if M['m00'] == 0: continue raw_centers.append([M['m10'] / M['m00'], M['m01'] / M['m00']]) raw_areas.append(area) if len(raw_areas) < 6: return False, None, None raw_areas = np.array(raw_areas) raw_centers = np.array(raw_centers, dtype=np.float32) # Keep contours whose area is within 3x of the median median_area = np.median(raw_areas) mask = (raw_areas > median_area / 3) & (raw_areas < median_area * 3) centers = raw_centers[mask] if len(centers) < 6: return False, None, None # Cluster into rows by Y coordinate sorted_by_y = centers[centers[:, 1].argsort()] y_gaps = np.diff(sorted_by_y[:, 1]) sorted_gaps = np.sort(y_gaps) gap_diffs = np.diff(sorted_gaps) # Find threshold at the first significant jump in sorted gaps threshold = sorted_gaps[-1] for i, gd in enumerate(gap_diffs): prev_median = np.median(gap_diffs[:max(1, i)]) if gd > max(prev_median * 5, 10): threshold = (sorted_gaps[i] + sorted_gaps[i + 1]) / 2 break rows = [] current_row = [sorted_by_y[0]] for i in range(1, len(sorted_by_y)): if sorted_by_y[i, 1] - current_row[-1][1] < threshold: current_row.append(sorted_by_y[i]) else: rows.append(np.array(current_row)) current_row = [sorted_by_y[i]] rows.append(np.array(current_row)) # Sort each row by X for i in range(len(rows)): rows[i] = rows[i][rows[i][:, 0].argsort()] # Keep rows with the most common column count col_counts = [len(r) for r in rows] most_common = max(set(col_counts), key=col_counts.count) grid_rows = [r for r in rows if len(r) == most_common] if len(grid_rows) < 2 or most_common < 2: return False, None, None # Inner corners: centroid of each 2x2 block of adjacent blob centers inner_corners = [] for r in range(len(grid_rows) - 1): row_corners = [] for c in range(most_common - 1): tl = grid_rows[r][c] tr = grid_rows[r][c + 1] bl = grid_rows[r + 1][c] br = grid_rows[r + 1][c + 1] row_corners.append((tl + tr + bl + br) / 4.0) inner_corners.append(row_corners) n_rows = len(inner_corners) n_cols = len(inner_corners[0]) pts = np.array([pt for row in inner_corners for pt in row], dtype=np.float32).reshape(-1, 1, 2) logging.debug(f"Blob grid: {len(grid_rows)}x{most_common} blobs -> " f"{n_rows}x{n_cols} inner corners") return True, pts, (n_cols, n_rows) def _run_pattern_window(cols, rows, hz, stop_evt): import tkinter as tk squares_x = cols + 1 squares_y = rows + 1 PHASE_MS = max(33, int(500 / hz)) # half-period in ms root = tk.Tk() pattern_root[0] = root root.title("Calibration Pattern") root.geometry("800x600") root.resizable(True, True) root.configure(bg='black') canvas = tk.Canvas(root, bg='black', highlightthickness=0) canvas.pack(fill='both', expand=True) phase = [0] def draw(): w = canvas.winfo_width() h = canvas.winfo_height() canvas.delete('all') if phase[0] == 0: return # blank — black canvas bg covers it sq_w = w / squares_x sq_h = h / squares_y for row in range(squares_y): for col in range(squares_x): if (row + col) % 2 == 0: x0 = col * sq_w y0 = row * sq_h canvas.create_rectangle(x0, y0, x0 + sq_w, y0 + sq_h, fill='white', outline='') def flip(): phase[0] ^= 1 draw() root.after(PHASE_MS, flip) def check_stop(): if stop_evt.is_set(): root.quit() return root.after(100, check_stop) def on_close(): stop_evt.set() root.protocol("WM_DELETE_WINDOW", on_close) root.bind('', lambda e: on_close()) root.after(PHASE_MS, flip) root.after(100, check_stop) root.mainloop() root.destroy() pattern_root[0] = None stop_evt.set() if dpg.does_item_exist("pattern_btn"): dpg.configure_item("pattern_btn", label="Show Calibration Pattern") def cb_show_hide_pattern(s=None, v=None, u=None): if pattern_thread[0] is not None and pattern_thread[0].is_alive(): pattern_stop_evt[0].set() # signals flip_thread to call root.destroy pattern_thread[0] = None pattern_stop_evt[0] = None dpg.configure_item("pattern_btn", label="Show Calibration Pattern") else: cols = dpg.get_value("board_cols") rows = dpg.get_value("board_rows") hz = dpg.get_value("pattern_hz") stop_evt = threading.Event() pattern_stop_evt[0] = stop_evt t = threading.Thread( target=_run_pattern_window, args=(cols, rows, hz, stop_evt), daemon=True, ) pattern_thread[0] = t t.start() dpg.configure_item("pattern_btn", label="Hide Calibration Pattern") def cb_auto_detect(s=None, v=None, u=None): try: import cv2 except ImportError: dpg.set_value("pick_status", "Auto mode requires opencv-python.") return main_rgb = last_main_rgb[0] genx320_rgb = last_genx320_rgb[0] if main_rgb is None or genx320_rgb is None: dpg.set_value("pick_status", "No frames available yet.") return cols = dpg.get_value("board_cols") rows = dpg.get_value("board_rows") board_size = (cols, rows) gw, gh = genx320_wh SCALE = 4 genx320_up = cv2.resize(genx320_rgb, (gw * SCALE, gh * SCALE), interpolation=cv2.INTER_CUBIC) # Freeze copies for the background thread main_snap = main_rgb.copy() genx320_snap = genx320_up.copy() dpg.set_value("pick_status", "Running detection pipeline...") MAX_ATTEMPTS = 10 RETRY_SEC = 0.1 def _detect(): import cv2 for attempt in range(1, MAX_ATTEMPTS + 1): # Grab fresh frames each attempt if attempt > 1: time.sleep(RETRY_SEC) m_rgb = last_main_rgb[0] g_rgb = last_genx320_rgb[0] if m_rgb is None or g_rgb is None: continue m_snap = m_rgb.copy() g_snap = cv2.resize(g_rgb, (gw * SCALE, gh * SCALE), interpolation=cv2.INTER_CUBIC) dpg.set_value("pick_status", f"Detecting... attempt {attempt}/{MAX_ATTEMPTS}") ret_g, corners_g, grid_g = _find_board_blobs(g_snap) if not ret_g: continue ret_m, corners_m, grid_m = _find_board_blobs(m_snap) if not ret_m: continue if grid_g != grid_m: continue corners_g_scaled = corners_g / SCALE src = corners_g_scaled.reshape(-1, 2).astype(np.float32) dst = corners_m.reshape(-1, 2).astype(np.float32) H, inlier_mask = cv2.findHomography(src, dst, cv2.RANSAC, 5.0) if H is None: continue n = len(src) inliers = int(inlier_mask.sum()) if inlier_mask is not None else n homography[0] = H dpg.set_value("homography_text", _fmt_homography(H)) dpg.configure_item("save_btn", label="Save Images + Transform") dpg.set_value("pick_status", f"Auto: {grid_g[0]}x{grid_g[1]} grid, " f"{inliers}/{n} inliers " f"(attempt {attempt}/{MAX_ATTEMPTS}).") return dpg.set_value("pick_status", f"Board not found after {MAX_ATTEMPTS} attempts.\n" f"Ensure the pattern is visible to both cameras.") threading.Thread(target=_detect, daemon=True).start() def cb_pick_main(s=None, v=None, u=None): main_pts.clear() genx320_pts.clear() homography[0] = None pick_state[0] = 'main' dpg.set_value("pick_status", "Click 4 points on the main image.") def cb_pick_genx320(s=None, v=None, u=None): genx320_pts.clear() pick_state[0] = 'genx320' dpg.set_value("pick_status", f"Click 4 matching points on the GenX320 image " f"({len(main_pts)}/4 main points set).") def cb_reset_homography(s=None, v=None, u=None): homography[0] = None main_pts.clear() genx320_pts.clear() pick_state[0] = None dpg.set_value("pick_status", "Homography reset.") dpg.set_value("homography_text", "") dpg.configure_item("save_btn", label="Save Images") def _handle_image_click(tag, img_wh, pts_list, other_list, this_label, other_label): mx, my = dpg.get_mouse_pos(local=False) try: imin = dpg.get_item_rect_min(tag) imax = dpg.get_item_rect_max(tag) except Exception: return if not (imin[0] <= mx <= imax[0] and imin[1] <= my <= imax[1]): return w, h = img_wh dw = imax[0] - imin[0] dh = imax[1] - imin[1] px = int((mx - imin[0]) / max(dw, 1) * w) py = int((my - imin[1]) / max(dh, 1) * h) pts_list.append((px, py)) n = len(pts_list) if n < 4: dpg.set_value("pick_status", f"{n}/4 {this_label} points. Keep clicking.") else: if len(other_list) == 4: _recompute_homography() else: dpg.set_value("pick_status", f"4 {this_label} points set. Now click 4 {other_label} points.") def cb_mouse_click(s=None, v=None, u=None): if pick_state[0] == 'main': if len(main_pts) < 4: _handle_image_click("main_img", main_wh, main_pts, genx320_pts, 'main', 'GenX320') elif pick_state[0] == 'genx320': if len(genx320_pts) < 4: _handle_image_click("genx320_img", genx320_wh, genx320_pts, main_pts, 'GenX320', 'main') # ----------------------------------------------------------------------- # UI layout # ----------------------------------------------------------------------- with dpg.window(tag="main_win", no_scrollbar=True, no_title_bar=True): with dpg.table( header_row=False, resizable=True, borders_innerV=True, tag="layout_table", scrollX=False, scrollY=False, ): dpg.add_table_column(init_width_or_weight=1.0) dpg.add_table_column(init_width_or_weight=CTRL_WIDTH, width_fixed=True) with dpg.table_row(): # ── Left: image panels ────────────────────────────────────── with dpg.table_cell(): with dpg.group(horizontal=True, tag="top_images"): dpg.add_image(MAIN_TEX_TAG, tag="main_img", width=1, height=1) dpg.add_image(GENX320_TEX_TAG, tag="genx320_img", width=1, height=1) dpg.add_separator() with dpg.group(tag="comp_row"): dpg.add_image(COMP_TEX_TAG, tag="comp_img", width=1, height=1) # ── Right: controls ───────────────────────────────────────── with dpg.table_cell(): with dpg.child_window(width=CTRL_WIDTH, border=False): if sys.platform == 'win32': dpg.add_text( "Warning: Windows reduces transfer speed.\n" "Use macOS or Linux for best performance.", color=(255, 200, 0, 255)) dpg.add_separator() # ── Connection ────────────────────────────────────── init_ports = list_com_ports() init_port = args.port or (init_ports[0] if init_ports else "") with dpg.group(horizontal=True): dpg.add_text("Port ") dpg.add_combo( items=init_ports, default_value=init_port, tag="port_combo", width=CTRL_WIDTH - 90) dpg.add_button(label="Ref", callback=cb_refresh, width=28) # ── Camera Parameters ─────────────────────────────── dpg.add_separator() dpg.add_text("Camera Parameters (applied at connect)") dpg.add_text("GenX320 is always 320×320 grayscale.", color=(150, 150, 150, 255)) with dpg.group(horizontal=True): dpg.add_text("Main Res ") dpg.add_combo( tag="main_res_combo", items=MAIN_RES_OPTIONS, default_value=state['main_res'], callback=cb_main_res, width=-1) with dpg.group(horizontal=True): dpg.add_text("Main Fmt ") dpg.add_combo( tag="main_pixfmt_combo", items=PIXFMT_OPTIONS, default_value=state['main_pixfmt'], callback=cb_main_pixfmt, width=-1) dpg.add_separator() dpg.add_button(label="Connect", tag="connect_btn", callback=cb_connect, width=-1) # ── Overlay Alpha ─────────────────────────────────── dpg.add_separator() dpg.add_text("Overlay Alpha") dpg.add_slider_int( tag="alpha_slider", default_value=int(overlay_alpha[0] * 100), min_value=0, max_value=100, format="%d%%", width=-1, callback=lambda s, v, u=None: overlay_alpha.__setitem__(0, v / 100.0)) # ── Calibration Pattern ───────────────────────────── dpg.add_separator() dpg.add_text("Calibration Pattern") with dpg.group(horizontal=True): dpg.add_text("Cols ") dpg.add_input_int(tag="board_cols", default_value=7, min_value=2, max_value=20, width=-1) with dpg.group(horizontal=True): dpg.add_text("Rows ") dpg.add_input_int(tag="board_rows", default_value=7, min_value=2, max_value=20, width=-1) with dpg.group(horizontal=True): dpg.add_text("Hz ") dpg.add_input_int(tag="pattern_hz", default_value=2, min_value=1, max_value=30, width=-1) dpg.add_button(label="Show Calibration Pattern", tag="pattern_btn", callback=cb_show_hide_pattern, width=-1) # ── Overlay Alignment ─────────────────────────────── dpg.add_separator() dpg.add_text("Overlay Alignment") with dpg.group(horizontal=True): dpg.add_text("Mode ") dpg.add_combo( items=["Manual", "Automatic"], default_value="Manual", tag="align_mode_combo", callback=cb_align_mode, width=-1) with dpg.group(tag="manual_group", show=True): dpg.add_text( "Click 4 matching points on each image to " "compute a homography that aligns the GenX320 " "onto the main camera frame.", wrap=CTRL_WIDTH - 10) dpg.add_button(label="Pick Main Points", callback=cb_pick_main, width=-1) dpg.add_button(label="Pick GenX320 Points", callback=cb_pick_genx320, width=-1) with dpg.group(tag="auto_group", show=False): dpg.add_text( "Click Auto Detect to find the checkerboard " "in both images. The grid is detected " "automatically.", wrap=CTRL_WIDTH - 10) dpg.add_button(label="Auto Detect", callback=cb_auto_detect, width=-1) dpg.add_button(label="Reset Homography", callback=cb_reset_homography, width=-1) dpg.add_text("", tag="pick_status", wrap=CTRL_WIDTH - 10) dpg.add_input_text( tag="homography_text", default_value="", multiline=True, readonly=True, width=-1, height=90) # ── Save ──────────────────────────────────────────── dpg.add_separator() dpg.add_button(label="Save Images", tag="save_btn", callback=cb_save, width=-1) # ── Statistics ────────────────────────────────────── dpg.add_separator() dpg.add_text("Statistics") stat_defs = [ ("FPS", "stat_fps"), ("Bandwidth", "stat_mbps"), ("Total frames", "stat_frames"), ("Uptime", "stat_uptime"), ] for lbl, tag in stat_defs: with dpg.group(horizontal=True): dpg.add_text(f"{lbl:<14}") dpg.add_text("-", tag=tag) with dpg.handler_registry(): dpg.add_mouse_click_handler(callback=cb_mouse_click) dpg.create_viewport( title="GenX320 Overlay Calibration", width=1400, height=900, resizable=True, ) dpg.setup_dearpygui() dpg.show_viewport() dpg.set_primary_window("main_win", True) dpg.add_viewport_drawlist(tag="vp_overlay", front=True) if args.port: _do_connect(args.port) # ----------------------------------------------------------------------- # Render loop # ----------------------------------------------------------------------- last_stat_time = time.perf_counter() pending_stats = None _PT_COLORS = [ (0, 255, 0, 255), (255, 255, 0, 255), (255, 165, 0, 255), (255, 0, 0, 255), ] while dpg.is_dearpygui_running(): while True: try: main_frame, genx320_frame, stats = frame_q.get_nowait() except queue.Empty: break pending_stats = stats # Decode and upload main frame if main_frame is not None: data, w, h = main_frame if w != main_wh[0] or h != main_wh[1]: main_wh[0], main_wh[1] = w, h for t in (MAIN_TEX_TAG, COMP_TEX_TAG): dpg.delete_item(t) if dpg.does_alias_exist(t): dpg.remove_alias(t) dpg.add_dynamic_texture(w, h, _make_placeholder(w, h), tag=MAIN_TEX_TAG, parent=TEX_REG_TAG) dpg.add_dynamic_texture(w, h, _make_placeholder(w, h), tag=COMP_TEX_TAG, parent=TEX_REG_TAG) dpg.configure_item("main_img", texture_tag=MAIN_TEX_TAG) dpg.configure_item("comp_img", texture_tag=COMP_TEX_TAG) expected_rgb565 = w * h * 2 expected_gray = w * h if len(data) == expected_rgb565: rgb = rgb565_to_rgb888(data, w, h) elif len(data) == expected_gray: rgb = gray_to_rgb888(data, w, h) else: rgb = None if rgb is not None: last_main_rgb[0] = rgb dpg.set_value(MAIN_TEX_TAG, to_dpg_rgba(rgb)) # Decode and upload GenX320 frame (always grayscale) if genx320_frame is not None: data, w, h = genx320_frame if w != genx320_wh[0] or h != genx320_wh[1]: genx320_wh[0], genx320_wh[1] = w, h dpg.delete_item(GENX320_TEX_TAG) if dpg.does_alias_exist(GENX320_TEX_TAG): dpg.remove_alias(GENX320_TEX_TAG) dpg.add_dynamic_texture(w, h, _make_placeholder(w, h), tag=GENX320_TEX_TAG, parent=TEX_REG_TAG) dpg.configure_item("genx320_img", texture_tag=GENX320_TEX_TAG) expected_gray = w * h if len(data) == expected_gray: rgb = gray_to_rgb888(data, w, h) last_genx320_rgb[0] = rgb dpg.set_value(GENX320_TEX_TAG, to_dpg_rgba(rgb)) # Update composite comp = _make_composite() if comp is not None: dpg.set_value(COMP_TEX_TAG, to_dpg_rgba(comp)) # Stats update at ~5 Hz now = time.perf_counter() if pending_stats and (now - last_stat_time) >= 0.2: s = pending_stats dpg.set_value("stat_fps", f"{s['fps']:.1f} fps") dpg.set_value("stat_mbps", f"{s['mbps']:.2f} MB/s") dpg.set_value("stat_frames", f"{s['total_frames']:,}") dpg.set_value("stat_uptime", f"{s['elapsed']:.1f} s") last_stat_time = now if conn['thread'] and not conn['thread'].is_alive(): _do_disconnect() _fit_images() # Draw point overlays dpg.delete_item("vp_overlay", children_only=True) try: for img_tag, pts, wh in [ ("main_img", main_pts, main_wh), ("genx320_img", genx320_pts, genx320_wh), ]: if not pts: continue imin = dpg.get_item_rect_min(img_tag) imax = dpg.get_item_rect_max(img_tag) fw, fh = wh dw = imax[0] - imin[0] dh = imax[1] - imin[1] for i, (px, py) in enumerate(pts): sx = imin[0] + px / max(fw, 1) * dw sy = imin[1] + py / max(fh, 1) * dh col = _PT_COLORS[i % len(_PT_COLORS)] dpg.draw_circle([sx, sy], 8, color=col, thickness=2, parent="vp_overlay") dpg.draw_text([sx + 10, sy - 8], str(i + 1), size=14, color=col, parent="vp_overlay") except Exception: pass dpg.render_dearpygui_frame() dpg.destroy_context() if pattern_stop_evt[0]: pattern_stop_evt[0].set() if conn['stop_evt']: conn['stop_evt'].set() print("\nDone.") if __name__ == '__main__': _args = parse_args() if _args.benchmark: run_benchmark(_args) else: main(_args) ================================================ FILE: tools/thermal-overlay-calibration/README.md ================================================ # Thermal Overlay Calibration A 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. ![Thermal Overlay Calibration GUI](thermal-overlay-calibration.jpeg) ## Platform Notes macOS 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. On macOS and Linux the companion script's `read` method is automatically renamed to `readp` before execution (this is handled transparently by the PC script). CRC 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`. ## Prerequisites 1. **OpenMV IDE** v4.8.4 or later. 2. **OpenMV Cam Firmware** v5.0.0 or later. 3. **Python dependencies:** ``` pip install dearpygui numpy pyserial Pillow openmv ``` Optionally install OpenCV for automatic checkerboard detection and better warp quality: ``` pip install opencv-python ``` Without OpenCV, the composite falls back to PIL bilinear resize and automatic alignment is unavailable. ## Running ``` python thermal_overlay_calibration_on_pc.py ``` The 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: | Flag | Default | Description | |------|---------|-------------| | `--port PORT` | *(GUI selector)* | Serial port to connect on | | `--script PATH` | `thermal_overlay_calibration_on_cam.py` | MicroPython script to run on the camera | | `--baudrate N` | `921600` | Serial baud rate | | `--crc` | off (Linux/Mac), on (Windows) | Enable CRC on the serial protocol | | `--quiet` | off | Suppress camera stdout | | `--debug` | off | Enable verbose logging | | `--benchmark` | off | Headless throughput benchmark (no GUI) | ## Benchmark Mode Run without the GUI to measure raw USB throughput: ``` python thermal_overlay_calibration_on_pc.py --benchmark python thermal_overlay_calibration_on_pc.py --benchmark --port /dev/ttyACM0 ``` Prints at 10 Hz: ``` elapsed=3.2s fps=9.1 bw=1.24 MB/s frames=29 ``` Press **Ctrl+C** to stop. ## GUI Overview The window has two panes: a **left image area** and a **right control panel**. ### Image Area - **Top row** — main color camera (left) and Lepton thermal (right), each scaled to occupy half the available width at the same display height. - **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. All images resize automatically when the window is resized. ### Camera Parameters *(applied at connect)* These patch the on-camera script before it is executed. They are locked while connected. | Control | Default | Description | |---------|---------|-------------| | Main Res | VGA (640×480) | Main camera resolution: QVGA, VGA, or HD | | Main Fmt | RGB565 | Main camera pixel format: RGB565 or GRAYSCALE | | Lepton | QQVGA (160×120) | Lepton resolution: QQVGA, QVGA, or VGA | | Lep Fmt | RGB565 | Lepton pixel format: RGB565 or GRAYSCALE | | Lep Pal | IRONBOW | Color palette applied when Lep Fmt is RGB565: IRONBOW or RAINBOW | The palette combo is hidden when Lep Fmt is set to GRAYSCALE. ### Overlay Alpha A slider from 0% to 100% controlling how much of the Lepton is blended over the main frame in the composite. Defaults to 50%. ### Overlay Alignment Computes a homography (perspective warp) that maps Lepton pixel coordinates to main camera pixel coordinates for a geometrically correct overlay. #### Manual Mode ![Manual Point Picking](thermal-overlay-calibration-manual.jpeg) Click **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. > **Tip:** Spread the 4 points across the full frame for the most accurate warp. Avoid clustering all points in one region. #### Automatic Mode Place 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**. The 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. The status line reports the number of inliers after detection. #### Shared Controls - **Reset Homography** — clears all points and the transform. - **transform =** — read-only copyable text box showing the computed 3×3 perspective matrix, ready to paste into firmware or a processing script. ### Save Images Saves the current frames and transform to disk. The button label changes to **Save Images + Transform** once a homography has been computed. - `thermal_main_.png` — main camera frame (RGB). - `thermal_lepton_.png` — Lepton frame. - `thermal_composite_.png` — composited overlay image. - `thermal_transform_.txt` — the 3×3 homography matrix. These files are excluded from git via `.gitignore`. ### Statistics | Field | Description | |-------|-------------| | FPS | Frame pair rate (EMA) | | Bandwidth | Combined USB data rate (MB/s, EMA) | | Total frames | Cumulative frame pairs since connect | | Uptime | Seconds since connect | ================================================ FILE: tools/thermal-overlay-calibration/thermal_overlay_calibration_on_cam.py ================================================ # This work is licensed under the MIT license. # Copyright (c) 2013-2026 OpenMV LLC. All rights reserved. # https://github.com/openmv/openmv/blob/master/LICENSE # # This script pulls color and thermal images from the camera. # # This script is meant to be run using https://github.com/openmv/openmv-python # from a PC using desktop tools. No visualization or text output is generated # by this script for OpenMV IDE. import csi import protocol import json import image MAIN_PIXFORMAT = csi.RGB565 MAIN_FRAME_SIZE = csi.VGA LEPTON_FRAME_SIZE = csi.QVGA LEPTON_PIXFORMAT = csi.RGB565 LEPTON_PALETTE = image.PALETTE_IRONBOW # Initialize the sensor. csi0 = csi.CSI() csi0.reset(hard=True) csi0.pixformat(MAIN_PIXFORMAT) csi0.framesize(MAIN_FRAME_SIZE) csi0_img = csi0.snapshot() csi0_img_mv = memoryview(csi0_img.bytearray()) csi0_frame_available = True # Parse image info from string representation csi0_img_info = json.loads(str(csi0_img)) csi0_img_width = csi0_img_info['w'] csi0_img_height = csi0_img_info['h'] csi0_img_size = csi0_img_info['size'] # Initialize the LEPTON sensor. csi1 = csi.CSI(cid=csi.LEPTON) csi1.reset(hard=False) csi1.pixformat(LEPTON_PIXFORMAT) csi1.framesize(LEPTON_FRAME_SIZE) csi1.color_palette(LEPTON_PALETTE) csi1_img = csi1.snapshot() csi1_img_mv = memoryview(csi1_img.bytearray()) csi1_frame_available = True # Parse image info from string representation csi1_img_info = json.loads(str(csi1_img)) csi1_img_width = csi1_img_info['w'] csi1_img_height = csi1_img_info['h'] csi1_img_size = csi1_img_info['size'] class MainChannel: def size(self): return csi0_img_size def shape(self): return (csi0_img_height, csi0_img_width, csi0_img_size) def read(self, offset, size): global csi0_frame_available if csi0_frame_available: end = offset + size mv = csi0_img_mv[offset:end] if end == csi0_img_size: csi0_frame_available = False return mv return bytes(size) def poll(self): return csi0_frame_available class LeptonChannel: def size(self): return csi1_img_size def shape(self): return (csi1_img_height, csi1_img_width, csi1_img_size) def read(self, offset, size): global csi1_frame_available if csi1_frame_available: end = offset + size mv = csi1_img_mv[offset:end] if end == csi1_img_size: csi1_frame_available = False return mv return bytes(size) def poll(self): return csi1_frame_available protocol.register(name='main', backend=MainChannel()) protocol.register(name='lepton', backend=LeptonChannel()) while True: if not csi0_frame_available: csi0_img = csi0.snapshot() csi0_img_mv = memoryview(csi0_img.bytearray()) csi0_frame_available = True if not csi1_frame_available: csi1_img = csi1.snapshot() csi1_img_mv = memoryview(csi1_img.bytearray()) csi1_frame_available = True ================================================ FILE: tools/thermal-overlay-calibration/thermal_overlay_calibration_on_pc.py ================================================ #!/usr/bin/env python3 # # This work is licensed under the MIT license. # Copyright (c) 2013-2026 OpenMV LLC. All rights reserved. # https://github.com/openmv/openmv/blob/master/LICENSE # # Thermal overlay calibration GUI for OpenMV cameras on PC. # Requires: pip install dearpygui numpy pyserial Pillow openmv # # Streams RGB565/Grayscale frames from a main camera and a FLIR Lepton # simultaneously, displays them side by side, and composites them into # a third image below. A homography computed from 4 point correspondences # can be used to align the Lepton onto the main camera frame. import sys import os import argparse import time import logging import signal import threading import queue import numpy as np try: from PIL import Image _PIL_AVAILABLE = True except ImportError: _PIL_AVAILABLE = False import serial.tools.list_ports import dearpygui.dearpygui as dpg from openmv.camera import Camera COLOR_CAMERA = "\033[32m" COLOR_RESET = "\033[0m" EMA_ALPHA = 0.2 CTRL_WIDTH = 320 # Resolution options sent to the camera script as constants. MAIN_RES_OPTIONS = ['QVGA (320×240)', 'VGA (640×480)', 'HD (1280×720)'] LEPTON_RES_OPTIONS = ['QQVGA (160×120)', 'QVGA (320×240)', 'VGA (640×480)'] PIXFMT_OPTIONS = ['RGB565', 'GRAYSCALE'] PALETTE_OPTIONS = ['IRONBOW', 'RAINBOW'] MAIN_RES_MAP = { 'QVGA (320×240)': 'csi.QVGA', 'VGA (640×480)': 'csi.VGA', 'HD (1280×720)': 'csi.HD', } LEPTON_RES_MAP = { 'QQVGA (160×120)': 'csi.QQVGA', 'QVGA (320×240)': 'csi.QVGA', 'VGA (640×480)': 'csi.VGA', } PIXFMT_MAP = { 'RGB565': 'csi.RGB565', 'GRAYSCALE': 'csi.GRAYSCALE', } PALETTE_MAP = { 'IRONBOW': 'image.PALETTE_IRONBOW', 'RAINBOW': 'image.PALETTE_RAINBOW', } # Tags MAIN_TEX_TAG = "main_tex" LEPTON_TEX_TAG = "lepton_tex" COMP_TEX_TAG = "comp_tex" TEX_REG_TAG = "tex_reg" # --------------------------------------------------------------------------- # RGB565 → RGB888 conversion (vectorized) # --------------------------------------------------------------------------- def rgb565_to_rgb888(data, w, h): """Convert a bytes-like object of RGB565 pixels to (H,W,3) uint8.""" words = np.frombuffer(data, dtype='> 11) & 0x1F) * 255 // 31 g = ((words >> 5) & 0x3F) * 255 // 63 b = ( words & 0x1F) * 255 // 31 return np.stack([r, g, b], axis=2).astype(np.uint8) def gray_to_rgb888(data, w, h): """Convert a bytes-like object of 8-bit grayscale to (H,W,3) uint8.""" gray = np.frombuffer(data, dtype=np.uint8).reshape(h, w) return np.stack([gray, gray, gray], axis=2) def to_dpg_rgba(rgb888): """Convert (H,W,3) uint8 RGB to flat float32 RGBA for DearPyGui texture.""" h, w = rgb888.shape[:2] rgba = np.empty((h, w, 4), dtype=np.float32) rgba[:, :, :3] = rgb888.astype(np.float32) * (1.0 / 255.0) rgba[:, :, 3] = 1.0 return rgba.ravel() # --------------------------------------------------------------------------- # Script patching # --------------------------------------------------------------------------- def patch_script(script, main_res, lepton_res, main_pixfmt, lepton_pixfmt, lepton_palette): """Patch cam script constants before exec. Replaces MAIN_FRAME_SIZE, LEPTON_FRAME_SIZE, MAIN_PIXFORMAT, LEPTON_PIXFORMAT, and LEPTON_PALETTE constant assignments. On macOS/Linux also renames 'def read' → 'def readp'. """ import re main_csi = MAIN_RES_MAP[main_res] lepton_csi = LEPTON_RES_MAP[lepton_res] main_fmt = PIXFMT_MAP[main_pixfmt] lepton_fmt = PIXFMT_MAP[lepton_pixfmt] palette = PALETTE_MAP[lepton_palette] script = re.sub(r'MAIN_FRAME_SIZE\s*=\s*\S+', f'MAIN_FRAME_SIZE = {main_csi}', script) script = re.sub(r'LEPTON_FRAME_SIZE\s*=\s*\S+', f'LEPTON_FRAME_SIZE = {lepton_csi}', script) script = re.sub(r'MAIN_PIXFORMAT\s*=\s*\S+', f'MAIN_PIXFORMAT = {main_fmt}', script) script = re.sub(r'LEPTON_PIXFORMAT\s*=\s*\S+', f'LEPTON_PIXFORMAT = {lepton_fmt}', script) script = re.sub(r'LEPTON_PALETTE\s*=\s*\S+', f'LEPTON_PALETTE = {palette}', script) if sys.platform != 'win32': script = script.replace('def read(self, offset, size):', 'def readp(self, offset, size):') return script # --------------------------------------------------------------------------- # Camera worker # --------------------------------------------------------------------------- def camera_worker(args, state_lock, state, frame_q, stop_evt): try: with Camera( args.port, baudrate=args.baudrate, crc=args.crc, seq=args.seq, ack=args.ack, events=args.events, timeout=args.timeout, max_retry=args.max_retry, max_payload=args.max_payload, drop_rate=args.drop_rate, ) as camera: logging.info(f"Connected to OpenMV on {args.port}") camera.stop() time.sleep(0.5) with open(args.script) as f: script = f.read() with state_lock: main_res = state['main_res'] lepton_res = state['lepton_res'] main_pixfmt = state['main_pixfmt'] lepton_pixfmt = state['lepton_pixfmt'] lepton_palette = state['lepton_palette'] script = patch_script(script, main_res, lepton_res, main_pixfmt, lepton_pixfmt, lepton_palette) logging.debug(f"Patched script: main={main_res}/{main_pixfmt} " f"lepton={lepton_res}/{lepton_pixfmt}/{lepton_palette} " f"readp={'yes' if sys.platform != 'win32' else 'no'}") camera.exec(script) logging.info("Script running, streaming frames...") start_time = time.perf_counter() last_time = start_time total_bytes = 0 mbps_ema = 0.0 fps_ema = 0.0 frame_count = 0 while not stop_evt.is_set(): status = camera.read_status() if not args.quiet and status and status.get('stdout'): if text := camera.read_stdout(): print(f"{COLOR_CAMERA}{text}{COLOR_RESET}", end='') has_main = camera.has_channel('main') and status and status.get('main') has_lepton = camera.has_channel('lepton') and status and status.get('lepton') if not has_main and not has_lepton: time.sleep(0.005) continue main_frame = None # (data, w, h) lepton_frame = None if has_main: sz = camera.channel_size('main') if sz > 0: shape = camera._channel_shape(camera.get_channel(name='main')) if shape and len(shape) >= 2: h, w = shape[0], shape[1] data = camera.channel_read('main', sz) if data: main_frame = (data, w, h) if has_lepton: sz = camera.channel_size('lepton') if sz > 0: shape = camera._channel_shape(camera.get_channel(name='lepton')) if shape and len(shape) >= 2: h, w = shape[0], shape[1] data = camera.channel_read('lepton', sz) if data: lepton_frame = (data, w, h) if main_frame is None and lepton_frame is None: time.sleep(0.005) continue now = time.perf_counter() dt = max(now - last_time, 1e-6) last_time = now batch_bytes = ((len(main_frame[0]) if main_frame else 0) + (len(lepton_frame[0]) if lepton_frame else 0)) total_bytes += batch_bytes frame_count += 1 elapsed = now - start_time mb_per_sec = batch_bytes / 1048576.0 / dt frames_per_sec = 1.0 / dt mbps_ema = (mb_per_sec if mbps_ema == 0.0 else mbps_ema * (1 - EMA_ALPHA) + mb_per_sec * EMA_ALPHA) fps_ema = (frames_per_sec if fps_ema == 0.0 else fps_ema * (1 - EMA_ALPHA) + frames_per_sec * EMA_ALPHA) stats = { 'fps': fps_ema, 'mbps': mbps_ema, 'total_frames': frame_count, 'elapsed': elapsed, } if frame_q.full(): try: frame_q.get_nowait() except queue.Empty: pass frame_q.put((main_frame, lepton_frame, stats)) except Exception as e: logging.error(f"Camera error: {e}") if args.debug: import traceback logging.error(traceback.format_exc()) # --------------------------------------------------------------------------- # Argument parsing # --------------------------------------------------------------------------- def parse_args(): p = argparse.ArgumentParser(description='OpenMV thermal overlay calibration GUI') p.add_argument('--port', default=None) p.add_argument('--script', default=None) p.add_argument('--baudrate', default=921600, type=int) p.add_argument('--crc', default=None, action=argparse.BooleanOptionalAction) p.add_argument('--seq', default=True, action=argparse.BooleanOptionalAction) p.add_argument('--ack', default=False, action=argparse.BooleanOptionalAction) p.add_argument('--events', default=True, action=argparse.BooleanOptionalAction) p.add_argument('--timeout', default=5.0, type=float) p.add_argument('--max_retry', default=5, type=int) p.add_argument('--max_payload', default=65536, type=int) p.add_argument('--drop_rate', default=0, type=int) p.add_argument('--quiet', default=False, action='store_true') p.add_argument('--debug', default=False, action='store_true') p.add_argument('--benchmark', default=False, action='store_true', help='Headless throughput benchmark — no GUI') args = p.parse_args() # CRC default: off on Mac/Linux (faster), on on Windows (more reliable) if args.crc is None: args.crc = sys.platform == 'win32' return args def list_com_ports(): return sorted(p.device for p in serial.tools.list_ports.comports()) # --------------------------------------------------------------------------- # Benchmark (headless) # --------------------------------------------------------------------------- def run_benchmark(args): """Headless throughput benchmark — no GUI, prints stats to terminal.""" if not args.port: ports = list_com_ports() if not ports: print("No serial ports found. Use --port to specify one.") sys.exit(1) args.port = ports[0] print(f"Auto-selected port: {args.port}") if args.script is None: args.script = os.path.join( os.path.dirname(os.path.abspath(__file__)), 'thermal_overlay_calibration_on_cam.py', ) state_lock = threading.Lock() state = { 'main_res': 'VGA (640×480)', 'lepton_res': 'QQVGA (160×120)', 'main_pixfmt': 'RGB565', 'lepton_pixfmt': 'RGB565', 'lepton_palette': 'IRONBOW', } frame_q = queue.Queue(maxsize=4) stop_evt = threading.Event() def handle_exit(signum, frame): stop_evt.set() signal.signal(signal.SIGINT, handle_exit) signal.signal(signal.SIGTERM, handle_exit) t = threading.Thread( target=camera_worker, args=(args, state_lock, state, frame_q, stop_evt), daemon=True, ) t.start() print(f"Connecting to {args.port} ...") last_print = time.perf_counter() while not stop_evt.is_set(): try: _, _, stats = frame_q.get(timeout=0.1) except queue.Empty: if not t.is_alive(): print("Camera thread died unexpectedly.") break continue now = time.perf_counter() if now - last_print >= 0.1: last_print = now print(f"elapsed={stats['elapsed']:.1f}s\t" f"fps={stats['fps']:.1f}\t" f"bw={stats['mbps']:.2f} MB/s\t" f"frames={stats['total_frames']:,}") stop_evt.set() print("\nDone.") # --------------------------------------------------------------------------- # Main # --------------------------------------------------------------------------- def main(args=None): if args is None: _args = parse_args() if _args.benchmark: run_benchmark(_args) return args = _args if args.script is None: args.script = os.path.join( os.path.dirname(os.path.abspath(__file__)), 'thermal_overlay_calibration_on_cam.py', ) logging.basicConfig( format="%(relativeCreated)010.3f - %(message)s", level=logging.DEBUG if args.debug else logging.INFO, ) state_lock = threading.Lock() state = { 'main_res': 'VGA (640×480)', 'lepton_res': 'QQVGA (160×120)', 'main_pixfmt': 'RGB565', 'lepton_pixfmt': 'RGB565', 'lepton_palette': 'IRONBOW', } # Current pixel dimensions — start at 1×1, updated on first received frame main_wh = [1, 1] lepton_wh = [1, 1] # Overlay alpha: fraction of Lepton blended onto main (0.0–1.0) overlay_alpha = [0.5] # Homography matrix (3×3 float64), None = identity / no warp homography = [None] # Point correspondences for homography computation: # Each list holds up to 4 (x, y) points in image pixel space # pick_state: None | 'main' | 'lepton' main_pts = [] lepton_pts = [] pick_state = [None] # Latest decoded frames (H,W,3 uint8), kept for save and composite last_main_rgb = [None] last_lepton_rgb = [None] conn = {'thread': None, 'stop_evt': None} frame_q = queue.Queue(maxsize=4) signal.signal(signal.SIGINT, lambda *_: dpg.stop_dearpygui()) # ----------------------------------------------------------------------- # DPG setup # ----------------------------------------------------------------------- dpg.create_context() # Placeholder textures (dark gray) def _make_placeholder(w, h): buf = np.full(w * h * 4, 0.05, dtype=np.float32) buf[3::4] = 1.0 return buf with dpg.texture_registry(tag=TEX_REG_TAG): dpg.add_dynamic_texture(1, 1, _make_placeholder(1, 1), tag=MAIN_TEX_TAG) dpg.add_dynamic_texture(1, 1, _make_placeholder(1, 1), tag=LEPTON_TEX_TAG) dpg.add_dynamic_texture(1, 1, _make_placeholder(1, 1), tag=COMP_TEX_TAG) # ----------------------------------------------------------------------- # Helpers # ----------------------------------------------------------------------- def _do_connect(port): args.port = port # Reset size tracking; main loop will recreate textures on first frame. main_wh[0], main_wh[1] = 1, 1 lepton_wh[0], lepton_wh[1] = 1, 1 homography[0] = None main_pts.clear() lepton_pts.clear() pick_state[0] = None stop_evt = threading.Event() conn['stop_evt'] = stop_evt t = threading.Thread( target=camera_worker, args=(args, state_lock, state, frame_q, stop_evt), daemon=True, ) t.start() conn['thread'] = t dpg.configure_item("connect_btn", label="Disconnect") _set_cam_settings_enabled(False) logging.info(f"Connecting to {port}...") def _do_disconnect(): if conn['stop_evt']: conn['stop_evt'].set() conn['thread'] = None conn['stop_evt'] = None dpg.configure_item("connect_btn", label="Connect") _set_cam_settings_enabled(True) CAM_SETTING_TAGS = ["main_res_combo", "lepton_res_combo", "main_pixfmt_combo", "lepton_pixfmt_combo", "lepton_palette_combo"] def _set_cam_settings_enabled(enabled): for tag in CAM_SETTING_TAGS: dpg.configure_item(tag, enabled=enabled) def _fmt_homography(H): rows = [] for row in H: rows.append(" [ " + ", ".join(f"{v:12.6f}" for v in row) + " ]") return "transform =\n[\n" + ",\n".join(rows) + "\n]" def _recompute_homography(): if len(main_pts) == 4 and len(lepton_pts) == 4: try: import cv2 src = np.float32(lepton_pts) dst = np.float32(main_pts) H, _ = cv2.findHomography(src, dst) homography[0] = H dpg.set_value("pick_status", "Homography computed.") except ImportError: # Manual least-squares DLT without cv2 A = [] lw, lh = lepton_wh for (sx, sy), (dx, dy) in zip(lepton_pts, main_pts): A.append([-sx, -sy, -1, 0, 0, 0, sx*dx, sy*dx, dx]) A.append([ 0, 0, 0, -sx, -sy, -1, sx*dy, sy*dy, dy]) A = np.array(A, dtype=np.float64) _, _, Vt = np.linalg.svd(A) H = Vt[-1].reshape(3, 3) H /= H[2, 2] homography[0] = H dpg.set_value("pick_status", "Homography computed (no cv2).") if homography[0] is not None: dpg.set_value("homography_text", _fmt_homography(homography[0])) dpg.configure_item("save_btn", label="Save Images + Transform") def _make_composite(): main_rgb = last_main_rgb[0] lepton_rgb = last_lepton_rgb[0] if main_rgb is None: return None mw, mh = main_wh alpha = overlay_alpha[0] comp = main_rgb.copy().astype(np.float32) if lepton_rgb is not None: lh, lw = lepton_rgb.shape[:2] H = homography[0] if H is not None: try: import cv2 warped = cv2.warpPerspective(lepton_rgb, H, (mw, mh)) # Warp an all-ones mask to find which output pixels are # actually covered by the lepton — avoids false positives # from palette colors that map to exactly (0,0,0). # INTER_NEAREST keeps coverage exactly 0 or 1 so the # mask has a hard edge with no dark fringe. coverage = cv2.warpPerspective( np.ones((lh, lw), dtype=np.float32), H, (mw, mh), flags=cv2.INTER_NEAREST) except ImportError: warped = np.array(Image.fromarray(lepton_rgb).resize( (mw, mh), Image.BILINEAR)) coverage = np.ones((mh, mw), dtype=np.float32) mask = (coverage > 0).reshape(mh, mw, 1).astype(np.float32) comp = comp * (1 - mask * alpha) + warped.astype(np.float32) * alpha else: # Stretch Lepton over main frame — full coverage, no mask needed try: import cv2 warped = cv2.resize(lepton_rgb, (mw, mh)) except ImportError: warped = np.array(Image.fromarray(lepton_rgb).resize( (mw, mh), Image.BILINEAR)) comp = comp * (1 - alpha) + warped.astype(np.float32) * alpha return np.clip(comp, 0, 255).astype(np.uint8) def _fit_images(): """Scale all three image widgets to fill the available space.""" vp_w = max(dpg.get_viewport_width() - CTRL_WIDTH - 30, 1) vp_h = max(dpg.get_viewport_height() - 60, 1) mw, mh = main_wh lw, lh = lepton_wh # Top row: each image gets half the available width as its slot. # Scale each to fit its slot, then clamp both to the same display height. slot_w = vp_w / 2 slot_h = vp_h * 0.55 main_s = min(slot_w / max(mw, 1), slot_h / max(mh, 1)) lepton_s = min(slot_w / max(lw, 1), slot_h / max(lh, 1)) target_h = min(mh * main_s, lh * lepton_s) main_s = target_h / max(mh, 1) lepton_s = target_h / max(lh, 1) # Bottom: composite fills the remaining height comp_scale = min(vp_w / max(mw, 1), (vp_h * 0.4) / max(mh, 1)) for tag, w, h, s in [ ("main_img", mw, mh, main_s), ("lepton_img", lw, lh, lepton_s), ("comp_img", mw, mh, comp_scale), ]: dpg.configure_item(tag, width=max(1, int(w * s)), height=max(1, int(h * s))) # Center the composite horizontally comp_w = max(1, int(mw * comp_scale)) indent = max(0, (vp_w - comp_w) // 2) dpg.configure_item("comp_row", indent=indent) # ----------------------------------------------------------------------- # Callbacks # ----------------------------------------------------------------------- def cb_main_res(s, v, u=None): with state_lock: state['main_res'] = v def cb_lepton_res(s, v, u=None): with state_lock: state['lepton_res'] = v def cb_main_pixfmt(s, v, u=None): with state_lock: state['main_pixfmt'] = v def cb_lepton_pixfmt(s, v, u=None): with state_lock: state['lepton_pixfmt'] = v dpg.configure_item("lepton_palette_group", show=(v == 'RGB565')) def cb_lepton_palette(s, v, u=None): with state_lock: state['lepton_palette'] = v def cb_refresh(s=None, v=None, u=None): items = list_com_ports() dpg.configure_item("port_combo", items=items) if items and not dpg.get_value("port_combo"): dpg.set_value("port_combo", items[0]) def cb_connect(s=None, v=None, u=None): if conn['thread'] and conn['thread'].is_alive(): _do_disconnect() else: port = dpg.get_value("port_combo") if not port: return _do_connect(port) def cb_save(s=None, v=None, u=None): ts = int(time.time()) if _PIL_AVAILABLE: if last_main_rgb[0] is not None: name = f"thermal_main_{ts}.png" Image.fromarray(last_main_rgb[0]).save(name) print(f"Saved: {name}") if last_lepton_rgb[0] is not None: name = f"thermal_lepton_{ts}.png" Image.fromarray(last_lepton_rgb[0]).save(name) print(f"Saved: {name}") comp = _make_composite() if comp is not None: name = f"thermal_composite_{ts}.png" Image.fromarray(comp).save(name) print(f"Saved: {name}") else: print("pip install Pillow to enable image saving.") H = homography[0] if H is not None: name = f"thermal_transform_{ts}.txt" with open(name, 'w') as f: f.write(_fmt_homography(H) + "\n") print(f"Saved: {name}") def cb_pick_main(s=None, v=None, u=None): main_pts.clear() lepton_pts.clear() homography[0] = None pick_state[0] = 'main' dpg.set_value("pick_status", "Click 4 points on the main image.") def cb_pick_lepton(s=None, v=None, u=None): lepton_pts.clear() pick_state[0] = 'lepton' dpg.set_value("pick_status", f"Click 4 matching points on the Lepton image " f"({len(main_pts)}/4 main points set).") def cb_align_mode(s, v, u=None): is_auto = (v == 'Automatic') dpg.configure_item("manual_group", show=not is_auto) dpg.configure_item("auto_group", show=is_auto) def _find_board(img_rgb, board_size): """Try multiple detection methods and preprocessing variants. Accepts an RGB image so individual channels can be tried — important because different thermal palettes (IRONBOW, RAINBOW, etc.) achieve best hot/cold contrast on different channels after grayscale conversion. Returns (True, corners) or (False, None). """ import cv2 clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(4, 4)) def _variants(g): enhanced = clahe.apply(g) blurred = cv2.GaussianBlur(enhanced, (0, 0), 3) sharp = cv2.addWeighted(enhanced, 2.0, blurred, -1.0, 0) _, otsu = cv2.threshold(g, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) _, otsu_inv = cv2.threshold(255-g, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) return [enhanced, 255 - enhanced, sharp, 255 - sharp, otsu, otsu_inv, g, 255 - g] # Build candidate list: standard grayscale + each individual channel gray = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2GRAY) r, g, b = img_rgb[:, :, 0], img_rgb[:, :, 1], img_rgb[:, :, 2] candidates = (_variants(gray) + _variants(r) + _variants(g) + _variants(b)) flags_classic = cv2.CALIB_CB_ADAPTIVE_THRESH | cv2.CALIB_CB_NORMALIZE_IMAGE # findChessboardCornersSB (OpenCV 4+, saddle-point, most robust) if hasattr(cv2, 'findChessboardCornersSB'): for img in candidates: ret, corners = cv2.findChessboardCornersSB(img, board_size, flags=0) if ret: return True, corners # Classic detector fallback for img in candidates: ret, corners = cv2.findChessboardCorners(img, board_size, flags=flags_classic) if ret: return True, corners return False, None def cb_auto_detect(s=None, v=None, u=None): try: import cv2 except ImportError: dpg.set_value("pick_status", "Auto mode requires opencv-python.") return main_rgb = last_main_rgb[0] lepton_rgb = last_lepton_rgb[0] if main_rgb is None or lepton_rgb is None: dpg.set_value("pick_status", "No frames available yet.") return cols = dpg.get_value("board_cols") rows = dpg.get_value("board_rows") board_size = (cols, rows) # Lepton is very low-res; upscale 4× so corners have enough spread lh, lw = lepton_rgb.shape[:2] SCALE = 4 lepton_up = cv2.resize(lepton_rgb, (lw * SCALE, lh * SCALE), interpolation=cv2.INTER_CUBIC) ret_m, corners_m = _find_board(main_rgb, board_size) ret_l, corners_l = _find_board(lepton_up, board_size) if not ret_m and not ret_l: dpg.set_value("pick_status", f"Board ({cols}×{rows}) not found in either image. " f"Ensure the full board is visible in both cameras.") return if not ret_m: dpg.set_value("pick_status", f"Board ({cols}×{rows}) not found in main image.") return if not ret_l: dpg.set_value("pick_status", f"Board ({cols}×{rows}) not found in Lepton image.") return criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) gray_m = cv2.cvtColor(main_rgb, cv2.COLOR_RGB2GRAY) gray_l = cv2.cvtColor(lepton_up, cv2.COLOR_RGB2GRAY) corners_m = cv2.cornerSubPix(gray_m, corners_m, (11, 11), (-1, -1), criteria) corners_l = cv2.cornerSubPix(gray_l, corners_l, (5, 5), (-1, -1), criteria) # Scale Lepton corners back to original pixel space corners_l = corners_l / SCALE src = corners_l.reshape(-1, 2).astype(np.float32) dst = corners_m.reshape(-1, 2).astype(np.float32) H, inlier_mask = cv2.findHomography(src, dst, cv2.RANSAC, 5.0) if H is None: dpg.set_value("pick_status", "Homography computation failed.") return inliers = int(inlier_mask.sum()) if inlier_mask is not None else len(src) homography[0] = H dpg.set_value("homography_text", _fmt_homography(H)) dpg.configure_item("save_btn", label="Save Images + Transform") dpg.set_value("pick_status", f"Auto: {cols}×{rows} board, {inliers}/{len(src)} inliers.") def cb_reset_homography(s=None, v=None, u=None): homography[0] = None main_pts.clear() lepton_pts.clear() pick_state[0] = None dpg.set_value("pick_status", "Homography reset.") dpg.set_value("homography_text", "") dpg.configure_item("save_btn", label="Save Images") def _handle_image_click(tag, img_wh, pts_list, other_list, this_label): """Record a clicked point in image pixel space.""" mx, my = dpg.get_mouse_pos(local=False) try: imin = dpg.get_item_rect_min(tag) imax = dpg.get_item_rect_max(tag) except Exception: return if not (imin[0] <= mx <= imax[0] and imin[1] <= my <= imax[1]): return w, h = img_wh dw = imax[0] - imin[0] dh = imax[1] - imin[1] px = int((mx - imin[0]) / max(dw, 1) * w) py = int((my - imin[1]) / max(dh, 1) * h) pts_list.append((px, py)) n = len(pts_list) if n < 4: dpg.set_value("pick_status", f"{n}/4 {this_label} points. Keep clicking.") else: if len(other_list) == 4: _recompute_homography() else: other_label = 'Lepton' if this_label == 'main' else 'main' dpg.set_value("pick_status", f"4 {this_label} points set. Now click 4 {other_label} points.") def cb_mouse_click(s=None, v=None, u=None): if pick_state[0] == 'main': if len(main_pts) < 4: _handle_image_click("main_img", main_wh, main_pts, lepton_pts, 'main') elif pick_state[0] == 'lepton': if len(lepton_pts) < 4: _handle_image_click("lepton_img", lepton_wh, lepton_pts, main_pts, 'Lepton') # ----------------------------------------------------------------------- # UI layout # ----------------------------------------------------------------------- with dpg.window(tag="main_win", no_scrollbar=True, no_title_bar=True): with dpg.table( header_row=False, resizable=True, borders_innerV=True, tag="layout_table", scrollX=False, scrollY=False, ): dpg.add_table_column(init_width_or_weight=1.0) dpg.add_table_column(init_width_or_weight=CTRL_WIDTH, width_fixed=True) with dpg.table_row(): # ── Left: image panels ────────────────────────────────────── with dpg.table_cell(): # Top row: main + lepton side by side with dpg.group(horizontal=True, tag="top_images"): dpg.add_image(MAIN_TEX_TAG, tag="main_img", width=1, height=1) dpg.add_image(LEPTON_TEX_TAG, tag="lepton_img", width=1, height=1) dpg.add_separator() # Bottom: composite (centered via indent set in _fit_images) with dpg.group(tag="comp_row"): dpg.add_image(COMP_TEX_TAG, tag="comp_img", width=1, height=1) # ── Right: controls ───────────────────────────────────────── with dpg.table_cell(): with dpg.child_window(width=CTRL_WIDTH, border=False): # Windows performance warning if sys.platform == 'win32': dpg.add_text( "Warning: Windows reduces transfer speed.\n" "Use macOS or Linux for best performance.", color=(255, 200, 0, 255)) dpg.add_separator() # ── Connection ────────────────────────────────────── init_ports = list_com_ports() init_port = args.port or (init_ports[0] if init_ports else "") with dpg.group(horizontal=True): dpg.add_text("Port ") dpg.add_combo( items=init_ports, default_value=init_port, tag="port_combo", width=CTRL_WIDTH - 90) dpg.add_button(label="Ref", callback=cb_refresh, width=28) # ── Camera Parameters ─────────────────────────────── dpg.add_separator() dpg.add_text("Camera Parameters (applied at connect)") with dpg.group(horizontal=True): dpg.add_text("Main Res ") dpg.add_combo( tag="main_res_combo", items=MAIN_RES_OPTIONS, default_value=state['main_res'], callback=cb_main_res, width=-1) with dpg.group(horizontal=True): dpg.add_text("Main Fmt ") dpg.add_combo( tag="main_pixfmt_combo", items=PIXFMT_OPTIONS, default_value=state['main_pixfmt'], callback=cb_main_pixfmt, width=-1) with dpg.group(horizontal=True): dpg.add_text("Lepton ") dpg.add_combo( tag="lepton_res_combo", items=LEPTON_RES_OPTIONS, default_value=state['lepton_res'], callback=cb_lepton_res, width=-1) with dpg.group(horizontal=True): dpg.add_text("Lep Fmt ") dpg.add_combo( tag="lepton_pixfmt_combo", items=PIXFMT_OPTIONS, default_value=state['lepton_pixfmt'], callback=cb_lepton_pixfmt, width=-1) with dpg.group(horizontal=True, tag="lepton_palette_group", show=True): dpg.add_text("Lep Pal ") dpg.add_combo( tag="lepton_palette_combo", items=PALETTE_OPTIONS, default_value=state['lepton_palette'], callback=cb_lepton_palette, width=-1) dpg.add_separator() dpg.add_button(label="Connect", tag="connect_btn", callback=cb_connect, width=-1) # ── Overlay Alpha ─────────────────────────────────── dpg.add_separator() dpg.add_text("Overlay Alpha") dpg.add_slider_int( tag="alpha_slider", default_value=int(overlay_alpha[0] * 100), min_value=0, max_value=100, format="%d%%", width=-1, callback=lambda s, v, u=None: overlay_alpha.__setitem__(0, v / 100.0)) # ── Overlay Alignment ─────────────────────────────── dpg.add_separator() dpg.add_text("Overlay Alignment") with dpg.group(horizontal=True): dpg.add_text("Mode ") dpg.add_combo( items=["Manual", "Automatic"], default_value="Manual", tag="align_mode_combo", callback=cb_align_mode, width=-1) # Manual mode with dpg.group(tag="manual_group", show=True): dpg.add_text( "Click 4 matching points on each image to " "compute a homography that aligns the Lepton " "onto the main camera frame. Without a " "homography the Lepton is stretched to fill " "the composite.", wrap=CTRL_WIDTH - 10) dpg.add_button(label="Pick Main Points", callback=cb_pick_main, width=-1) dpg.add_button(label="Pick Lepton Points", callback=cb_pick_lepton, width=-1) # Automatic mode with dpg.group(tag="auto_group", show=False): dpg.add_text( "Place a heated checkerboard in view of both " "cameras, then click Detect. Inner corners " "(cols × rows) must match the board.", wrap=CTRL_WIDTH - 10) with dpg.group(horizontal=True): dpg.add_text("Cols ") dpg.add_input_int(tag="board_cols", default_value=7, min_value=2, max_value=20, width=-1) with dpg.group(horizontal=True): dpg.add_text("Rows ") dpg.add_input_int(tag="board_rows", default_value=6, min_value=2, max_value=20, width=-1) dpg.add_button(label="Auto Detect", callback=cb_auto_detect, width=-1) dpg.add_button(label="Reset Homography", callback=cb_reset_homography, width=-1) dpg.add_text("", tag="pick_status", wrap=CTRL_WIDTH - 10) dpg.add_input_text( tag="homography_text", default_value="", multiline=True, readonly=True, width=-1, height=90) # ── Save ──────────────────────────────────────────── dpg.add_separator() dpg.add_button(label="Save Images", tag="save_btn", callback=cb_save, width=-1) # ── Statistics ────────────────────────────────────── dpg.add_separator() dpg.add_text("Statistics") stat_defs = [ ("FPS", "stat_fps"), ("Bandwidth", "stat_mbps"), ("Total frames", "stat_frames"), ("Uptime", "stat_uptime"), ] for lbl, tag in stat_defs: with dpg.group(horizontal=True): dpg.add_text(f"{lbl:<14}") dpg.add_text("—", tag=tag) # Mouse handler for point picking with dpg.handler_registry(): dpg.add_mouse_click_handler(callback=cb_mouse_click) dpg.create_viewport( title="Thermal Overlay Calibration", width=1280, height=800, resizable=True, ) dpg.setup_dearpygui() dpg.show_viewport() dpg.set_primary_window("main_win", True) dpg.add_viewport_drawlist(tag="vp_overlay", front=True) if args.port: _do_connect(args.port) # ----------------------------------------------------------------------- # Render loop # ----------------------------------------------------------------------- last_stat_time = time.perf_counter() pending_stats = None while dpg.is_dearpygui_running(): # Drain frame queue while True: try: main_frame, lepton_frame, stats = frame_q.get_nowait() except queue.Empty: break pending_stats = stats # Decode and upload main frame if main_frame is not None: data, w, h = main_frame if w != main_wh[0] or h != main_wh[1]: main_wh[0], main_wh[1] = w, h for t in (MAIN_TEX_TAG, COMP_TEX_TAG): dpg.delete_item(t) if dpg.does_alias_exist(t): dpg.remove_alias(t) dpg.add_dynamic_texture(w, h, _make_placeholder(w, h), tag=MAIN_TEX_TAG, parent=TEX_REG_TAG) dpg.add_dynamic_texture(w, h, _make_placeholder(w, h), tag=COMP_TEX_TAG, parent=TEX_REG_TAG) dpg.configure_item("main_img", texture_tag=MAIN_TEX_TAG) dpg.configure_item("comp_img", texture_tag=COMP_TEX_TAG) expected_rgb565 = w * h * 2 expected_gray = w * h if len(data) == expected_rgb565: rgb = rgb565_to_rgb888(data, w, h) elif len(data) == expected_gray: rgb = gray_to_rgb888(data, w, h) else: rgb = None if rgb is not None: last_main_rgb[0] = rgb dpg.set_value(MAIN_TEX_TAG, to_dpg_rgba(rgb)) # Decode and upload lepton frame if lepton_frame is not None: data, w, h = lepton_frame if w != lepton_wh[0] or h != lepton_wh[1]: lepton_wh[0], lepton_wh[1] = w, h dpg.delete_item(LEPTON_TEX_TAG) if dpg.does_alias_exist(LEPTON_TEX_TAG): dpg.remove_alias(LEPTON_TEX_TAG) dpg.add_dynamic_texture(w, h, _make_placeholder(w, h), tag=LEPTON_TEX_TAG, parent=TEX_REG_TAG) dpg.configure_item("lepton_img", texture_tag=LEPTON_TEX_TAG) expected_rgb565 = w * h * 2 expected_gray = w * h if len(data) == expected_rgb565: rgb = rgb565_to_rgb888(data, w, h) elif len(data) == expected_gray: rgb = gray_to_rgb888(data, w, h) else: rgb = None if rgb is not None: last_lepton_rgb[0] = rgb dpg.set_value(LEPTON_TEX_TAG, to_dpg_rgba(rgb)) # Update composite comp = _make_composite() if comp is not None: dpg.set_value(COMP_TEX_TAG, to_dpg_rgba(comp)) # Stats update at ~5 Hz now = time.perf_counter() if pending_stats and (now - last_stat_time) >= 0.2: s = pending_stats dpg.set_value("stat_fps", f"{s['fps']:.1f} fps") dpg.set_value("stat_mbps", f"{s['mbps']:.2f} MB/s") dpg.set_value("stat_frames", f"{s['total_frames']:,}") dpg.set_value("stat_uptime", f"{s['elapsed']:.1f} s") last_stat_time = now # Reset UI if the camera thread died unexpectedly (e.g. connection error) if conn['thread'] and not conn['thread'].is_alive(): _do_disconnect() _fit_images() # Draw point overlays on top of the image widgets _PT_COLORS = [ (0, 255, 0, 255), (255, 255, 0, 255), (255, 165, 0, 255), (255, 0, 0, 255), ] dpg.delete_item("vp_overlay", children_only=True) try: for img_tag, pts, wh in [ ("main_img", main_pts, main_wh), ("lepton_img", lepton_pts, lepton_wh), ]: if not pts: continue imin = dpg.get_item_rect_min(img_tag) imax = dpg.get_item_rect_max(img_tag) fw, fh = wh dw = imax[0] - imin[0] dh = imax[1] - imin[1] for i, (px, py) in enumerate(pts): sx = imin[0] + px / max(fw, 1) * dw sy = imin[1] + py / max(fh, 1) * dh col = _PT_COLORS[i % len(_PT_COLORS)] dpg.draw_circle([sx, sy], 8, color=col, thickness=2, parent="vp_overlay") dpg.draw_text([sx + 10, sy - 8], str(i + 1), size=14, color=col, parent="vp_overlay") except Exception: pass dpg.render_dearpygui_frame() dpg.destroy_context() if conn['stop_evt']: conn['stop_evt'].set() print("\nDone.") if __name__ == '__main__': _args = parse_args() if _args.benchmark: run_benchmark(_args) else: main(_args)